26
KULLANICI TANIMLI FONKSİYON KULLANICI TANIMLI FONKSİYON ÇEŞİTLERİ Yerleşik fonksiyonlar dışında bizim de tanımlayacağımız fonksiyonlar vardır. Bu tür fonksiyonlara Kullanıcı tanımlı fonksiyonlar (User Defined Function) adı verilir. Bir kullanıcı tanımlı fonksiyon "0" veya birden fazla değer alabilir ve tek bir değer veya bir tablo döndürebilir. Aldığı değerler timestamp, cursor ve table dışında, herhangi bir veri tipi olabilir. Sabit fonksiyonlar gibi, tek bir değer döndürebilir(Scalar Function). Stored Procedure gibi bir veya daha fazla Transact-SQL ifadesi kullanarak tablo döndürebilir(Multi-Statement Table-Valued Function). Tek bir Select ifadesi ile bir tablo değeri döndürebilir. View yapısına benzer, ancak çok daha kullanışlıdır. (In-Line Table-Valued Function) Aynen Stored Procedure veya view gibi fonksiyon oluşturabiliriz. CREATE FUNCTİON ifadesi kullanılır. Kullanım Sekli: Bir fonksiyonda değişiklik yapmak için; ALTER FUNCTİON ve mevcut olan bir fonksiyonu silmek için; DROP FUNCTİON ifadeleri kullanılır. SCALAR FUNCTION: Bu tür fonksiyonlar tek bir değer döndürebilirler. Fonksiyon içinde birden fazla Transact-SQL komutu BEGIN..END blokları arasında kullanılabilir. Text, ntext, image, cursor veya timestamp veri tipleri dışında herhangi bir veri tipinde de değer döndürebilir. Yerleşik fonksiyonlara benzer ve oluşturulduktan sonra farklı yerlerde yeniden kullanılabilir. UYGULAMA: 1) Aşağıdaki tanımladığımız fonksiyonda; dışarıdan nvarchar tipinde bir değer alarak bunu kontrol ediyoruz. Eğer bu değer boş olursa; adres girilmemiş ifadesini değişkene yükleyerek, aynı veri tipinde döndürüyoruz. Bu oluşturduğumuz fonksiyonu

kullanıcı tanımlı fonksiyonlar

Embed Size (px)

Citation preview

Page 1: kullanıcı tanımlı fonksiyonlar

KULLANICI TANIMLI FONKSİYON

KULLANICI TANIMLI FONKSİYON ÇEŞİTLERİ

Yerleşik fonksiyonlar dışında bizim de tanımlayacağımız fonksiyonlar vardır. Bu

tür fonksiyonlara Kullanıcı tanımlı fonksiyonlar (User Defined Function) adı verilir.

Bir kullanıcı tanımlı fonksiyon "0" veya birden fazla değer alabilir ve tek

bir değer veya bir tablo döndürebilir.

Aldığı değerler timestamp, cursor ve table dışında, herhangi bir veri tipi

olabilir.

Sabit fonksiyonlar gibi, tek bir değer döndürebilir(Scalar Function).

Stored Procedure gibi bir veya daha fazla Transact-SQL ifadesi

kullanarak tablo döndürebilir(Multi-Statement Table-Valued Function).

Tek bir Select ifadesi ile bir tablo değeri döndürebilir. View yapısına

benzer, ancak çok daha kullanışlıdır. (In-Line Table-Valued Function)

Aynen Stored Procedure veya view gibi fonksiyon oluşturabiliriz.

CREATE FUNCTİON ifadesi kullanılır.

Kullanım Sekli:

Bir fonksiyonda değişiklik yapmak için; ALTER FUNCTİON ve mevcut olan bir

fonksiyonu silmek için; DROP FUNCTİON ifadeleri kullanılır.

SCALAR FUNCTION:

Bu tür fonksiyonlar tek bir değer döndürebilirler. Fonksiyon içinde birden fazla Transact-SQL komutu BEGIN..END blokları arasında kullanılabilir. Text, ntext, image, cursor veya timestamp veri tipleri dışında herhangi bir veri tipinde de değer döndürebilir. Yerleşik fonksiyonlara benzer ve oluşturulduktan sonra farklı yerlerde yeniden kullanılabilir.

UYGULAMA:

1) Aşağıdaki tanımladığımız fonksiyonda; dışarıdan nvarchar tipinde bir değer alarak bunu kontrol ediyoruz. Eğer bu değer boş olursa; adres girilmemiş ifadesini değişkene yükleyerek, aynı veri tipinde döndürüyoruz. Bu oluşturduğumuz fonksiyonu

Page 2: kullanıcı tanımlı fonksiyonlar

bir tabloda bulunan boş adres sütunlarına "adresi yok" ifadesini yazdırmak için kullanabiliriz.

2) Yukarıdaki kodu çalıştırdıktan sonra, belirttiğimiz veri tabanı içinde

fonksiyonumuz oluşur. Bunu kontrol etmek için; veri tabanımız altında bulunan Functions\ Scalar-valued Function nesnesi seçilerek, oluşturduğumuz fonksiyon görüntülenir. Ayrıca bu kısımdan da fonksiyon oluşturulabilir veya oluşturulan fonksiyon üzerinde değişiklik yapılabilir. Eğer bir tablo fonksiyonu olsa idi o zaman Functions\ Table-valued Function kısmına eklenecekti.

3) Oluşturduğumuz fonksiyonu, daha önce oluşturduğumuz "merkez" tablosunda kullanalım, "merkez" tablomuzun son görüntüsünün aşağıdaki gibi olduğunu varsayalım.

Page 3: kullanıcı tanımlı fonksiyonlar

4) Bu fonksiyonu aşağıdaki gibi kullanabiliriz. Bunu SQL Query Editör içine

yazarak çalıştıralım. Dikkat edilirse adresdurum fonksiyonuna değer olarak; adres sütununu atıyoruz. Eğer bu sütunda Null değerler varsa adres girilmemiş olarak gösterecektir. Tabiki orijinal tabloda bir değişiklik yapmayacak, bunu sadece sorgulama ekranına yansıtacaktır.

5) Çalıştırdıktan sonra görüntü, aşağıdaki gibi olur.

Page 4: kullanıcı tanımlı fonksiyonlar

6) Eğer veri tabanında değişiklik yapmak istersek o zaman komutumuzu şu şekilde yazmamız gerekir.

MULTI-STATEMENT TABLE- VALUED FUNCTION:

View ve Stored Procedure birleşimidir. Bir tablo döndürebiliriz.

Temel özellikleri;

Fonksiyonun ana kısmı BEGIN..END blokları arasındadır.

Tablo olarak dönebilir (table veri tipi).

Tablo formatı belirlenebilir.

UYGULAMA:

1) Aşağıdaki elemanlO isimli fonksiyon, dışarıdan bir değer alıyor ve bu değeri kullanarak; musterino ve [eleman ad] sütunlarından oluşan tablo olarak değeri döndürüyor. Eğer dışarıdan girilen değer kisa ise o zaman tablo içine; müşteriler tablosundan musterino ve mad sütunlarını koyuyor. Girilen değer uzun ise tablo içinde musterino'yu ilk sütuna, madresi ikinci sütuna koyuyor.

2) İlk olarak kısa parametresi ile çalıştıralım ve çıktısını gözlemleyelim;

Page 5: kullanıcı tanımlı fonksiyonlar

Çıktısı şekildeki gibi olur

3) Ardından "uzun" parametresi ile çalıştıralım.

4) Çalıştırıldığında görüntü, aşağıdaki gibi olacaktır.

Page 6: kullanıcı tanımlı fonksiyonlar

IN-LINE TABLE- VALUED FUNCTION:

Table veri tipi döndürülebilen bu fonksiyonlarda, özel format

tanımlanamaz. Daha çok View yapısına benzer.

UYGULAMA:

1) Aşağıdaki fonksiyonu kullanarak; belirtilen adrese göre, kayıtları listeleyebiliriz.

2) Çalıştırmak için;

3) Görüntü, aşağıdaki gibi olacaktır.

Page 7: kullanıcı tanımlı fonksiyonlar

UYGULAMA:

1) Bu uygulamamızda, aşağıdaki kayıtları barındıran "satis" tablomuzu kullanacağız. Burada kayitno sütununda Primary Key olduğunu hatırlatalım.

2) Alttaki yazılım ile kayitno sütununun değerine göre, çeşitli değerler

döndürüyor. Bu değerleri KDV oranı olarak kullanacağız.

3) Aşağıdaki yazılım tüm kayıtları tarayarak, "kayitno" değerine göre,

döndürülen değeri gösterecek ve aynı zamanda bu değeri, fiyat ile çarparak KDV'li fiyatı verecektir.

Page 8: kullanıcı tanımlı fonksiyonlar

4) Görüntü, şekildeki gibi olacaktır.

TRİGGER

TRİGGER NEDİR? Bir tablo içindeki verileri yapılandırmak için kullanılan bir tür stored procedure'dür.

Genellikle ilişkisel bütünlüğü sürdürmek veya tablolar arasındaki bütünlüğü korumak için kullanılır. Karmaşık kurallar ile veri bütünlüğünün devam etmesi için tercih edilir.

Temel kural ve özelliklerini listeleyecek olursak;

Bir tablo için oluşturulur.

Stored Procedure'ün bir çeşitidir.

Otomatik olarak çalışır. Stored Procedure'e benzemeyen özelliği; direkt olarak çalışmamasıdır. Transaction'un bir parçasıdır. ROLLBACK TRANSACTION ifadesi bir zorlukla karşı karşıya kalmışsa,

işlem geri döner. Eğer Trigger içerisinde ROLLBACK TRANSACTION ifadesi varsa ifade çalıştırılır. Böyle bir durumda, IF komut dizilimi içerisinde RETURN cümleciği kullanılır. Bu diğer işlemleri önler.

Trigger, kullanıcı tanımlı bir fonksiyon tarafından tetiklenen ROLLBACK

TRANSACTION ifadesi içerebilir. Trigger; bu toplu işlem ile ROLLBACK TRANSACTION ifadesini çalıştırır ve toplu işlem de hata olursa, alt bir ifade içerisinde çalıştıramaz.

Trigger içinde minimum düzeyde ROLLBACK TRANSACTION ifadesi kullanınız. Çünkü bu işlem yapılırken, ek yük oluşturulur. Bu durum da sistem

performansınızın düşmesini sağlar. Trigger'ı çalıştıracak olan kullanıcının; ilgili tablolarda izninin olması gerekir.

Page 9: kullanıcı tanımlı fonksiyonlar

Trigger'ları sıralamak için, sp_settriggerorder kullanılır. Bu sp ile yalnızca ilk ve son trigger belirlenir. Tek bir tablo üzerindeki her bir ekleme, güncelleme veya silme işlemini; mevcut db içerisindeki db_owner ve db_ddladmin grubunun üyeleri yapabilir. Tabiki sysadmin grubu da her şeyi yaptığı için bu işlemi de yapabilir.

sp_settriggerorder @triggername='guncelle', @order='first', @stmttype=,UPDATE'

Yeni bir Trigger oluşturulduğunda bilgileri; sysobjects ve syscomments tablolarında

tutulurlar. Eğer aynı isimli bir Trigger oluşturulursa yeni oluşturulan Trigger, eskisinin üzerine yazılır.

CHECK Constraint'ine göre daha işlevseldir, sorgulama sonucu döndürmez. Özel mesajlar tanımlanabilir ve olaylardan önce veya sonra kıyaslama yapabilir. Cascade Update ve Delete özellikleri kullanılabilir. Çoklu satır Trigger oluşturulabilir. Birçok Trigger, uygulanan ifadeden sonra çalışır. Sadece INSTEAD OF ifadesi,

Constraint'ler gibi ifadelerden önce çalışır. Örneğin: CHECK Constraint'i ile INSERT ifadesi bir tabloya uygulanacak ise, ilk önce kontrol yapılır ve sorun yoksa uygulanır. Trigger'da ise ilk önce INSERT ardından otomatik olarak Trigger çalışır.

Bir tablo içinde çeşitli amaçlar için, birden fazla Trigger bulunabilir.

CREATE TRIGGER :

Trigger oluşturmak için CREATE TRIGGER ifadesi kullanılır.

Kullanım sekli:

CRETAE TRİGGER trigger_adı ON tablo_adı [WITH ENCRYPTION] {FOR|AFTER|INSTEAD OF} {INSERT|UPDATE|DELETE} AS [IF UPDATE (sütun_adı)] [{AND|OR}UPDATE(sütun_adı)]

SQL ifadeleri;

Trigger bilgileri; sysobjects ve syscomments sistem tablolarında tutulur. Kullanıcı tanımlı Trigger desteği sistem tablolarında olmadığı için sistem tabloları üzerinde Trigger oluşturulamaz.Trigger oluşturmak için db_owner ve sysadmin grubunun üyesi olmak gerekir.

Triaaer tanımlamalarında aşağıdaki ifadeler kullanılamaz;

• ALTER DATABASE

• CREATE DATABASE

• DROP DATABASE

Page 10: kullanıcı tanımlı fonksiyonlar

• LOAD DATABASE

• LOAD LOG

• RECONFIGURE

• RESTORE DATABASE

• RESTORE LOG

sp_depends tablo_adı, sp_helptext trigger_adı, sphelptrigger tablo_adı gibi sistem stored procedure'leri ile bilgi edinilebilir.

UYGULAMA:

Bu örneğimizde; aşağıdaki kayıtları içeren satis tablosunu kullanacağız.

1) İlk olarak bu isimli bir trigger varsa onu siliyoruz ve yeniden oluşturuyoruz. Bu Trigger yapısı ile aynı anda birden fazla kayıt silinmesini engelliyoruz. Bu kod, bir kez çalıştıktan sonra devreye girer ve işlem yapıldıktan sonra kontrolü yapar, eğer standartlara uymuyor ise bilgileri geri kurtaran Rollback Transaction çalışır.

IF OBJECT_ID ('tektektemizle') IS NOT NULL DROP TRİGGER tektektemizle; GO

CREATE TRİGGER tektektemizle

ON satis

FOR DELETE AS IF (SELECT COUNT(*) FROM Deleted) > 1 BEGIN RAISERROR('Ayni anda birden fazla kayıt silinemez!!!’,16,1) ROLLBACK TRANSACTION RETURN END GO

2) Yukarıdaki kodu çalıştırdıktan sonra test etmek için aşağıdaki kodu yazalım. Dikkat edilirse burada Trigger'ı çalıştırmak söz konusu değil, bir kez oluşturduktan sonra kendisi otomatik olarak çalışacaktır. Aşağıdaki komut sonucunda RAISERROR kısmında belirtilen mesaj karşımıza çıkar. Bunun sebebi de "3" değerinden büyük beş kayıt vardır ve bunları aynı anda silemeyiz.

Page 11: kullanıcı tanımlı fonksiyonlar

3) Oysa aşağıdaki yazılımlarda kayıtları tek tek sildiğimiz için, hiçbir sorun yaşamayız.

DELETE FROM satis WHERE kayitno=12

DELETE FROM satis WHERE kayitno=17

4) Bu temizlikten sonra tablomuzdaki son durum, aşağıdaki gibi olacaktır.

ALTER VE DROP TRİGGER;

Oluşturulan Trigger üzerinde değişiklik yapmak için ALTER TRİGGER, var olan bir Trigger'ı silmek için ise DROP TRİGGER ifadeleri kullanılır.

Bir Trigger bir tabloya atandıktan sonra istenirse, geçici olarak devre dışı bırakılabilir ve sonradan yeniden aktif hale getirilebilir. Bunun için ALTER TABLE ifadesi, aşağıdaki şekilde kullanılır.

ALTER TABLE tablo_adı

{ENABLE|DISABLE} TRİGGER

(ALL|trigger_adı[,n])

Şimdi bu üç yapıyı test edebileceğimiz bir örnek yapalım.

UYGULAMA:

1) Daha önce oluşturduğumuz tektektemizle Trigger'ı aynı anda birden fazla kayıt silmeyi engelliyordu. Şimdi ise hiç kayıt silinmesin, istiyoruz.. Bunun için aşağıdaki kodu yazıyoruz.

ALTER TRİGGER tektektemizle ON satis FOR DELETE AS

IF (SELECT COUNT{*l FROM Deleted) > 0 BEGIN RAISERROR!'kayit silinemez!'!', 16, 11

ROLLBACK TRANSACTİON

END

Page 12: kullanıcı tanımlı fonksiyonlar

2) Test için 6 numaralı kayıdı aşağıdaki şekilde silmeye çalışalım.

3) Çalıştırdığımız zaman bu işlemin başarısız olduğunu belirten, aşağıdaki

mesaj ile karşılaşırız.

4) Aşağıdaki yazılım ile tektektemizle isimli Trigger'ımızı geçici olarak devre dışı bırakalım.

5) Şimdi test için 6 numaralı kayıdı tekrar silmeye çalıştığımızda, başarılı olduğumuzu göreceğiz.

6) "Tektektemizle" isimli Trigger'ımızı tekrar devreye sokmak için aşağıdaki kod yazılır.

ALTER TABLE satis ENABLE TRIGGER

7) "5" numaralı kaydı silmeye çalıştığımızda, başarılı olamadığımızı göreceğiz. Çünkü

Trigger devrede.

DELETE FROM satis WHERE kayitno = 6

ALTER TABLE satis

DİSABLE TRİGGER

tektektemizle

DELETE FROM satis WHERE kayitno = 6

DELETE FROM satis WHERE kayitno = 5

Page 13: kullanıcı tanımlı fonksiyonlar

8) Bir tablo içinde Trigger'ın bağlı olup- olmadığını görmek için, tablo altındaki Triggers klasörünü açmak yeterli olacaktır. Buradan istenirse değişiklik yapılabilir.

Yine istenirse yeni bir Trigger buradan da oluşturulabilir.

9) Trigger'ı tamamen silmek içinse aşağıdaki kodu yazalım ve çalıştıralım.

DROP TRİGGER tektektemizle

Page 14: kullanıcı tanımlı fonksiyonlar

UYGULAMA:

1) Bir Trigger ile istediğimiz bir kişiye e-mail bile yollayabilirsiz. Ancak bu Trigger'ı

yazmadan önce ilk olarak SQL içinden mail yapılandırmamızı gerçekleştirmek için Management klasörü altındaki Database Mail üzerinde sağ tuşa basarak Configure Database Mail seçeneğine tıklayalım.

Page 15: kullanıcı tanımlı fonksiyonlar

2) ilk ekranı Next butonu ile geçtikten sonra, aşağıdaki ekranda ilk seçenek işaretli iken tekrar Next butonuna basılır.

Page 16: kullanıcı tanımlı fonksiyonlar

3) Add butonunu kullanarak postamız hakkında gerekli bilgileri girelim ve Next tuşlarına basarak Finish butonu ile bitirelim.

Page 17: kullanıcı tanımlı fonksiyonlar

4) Trigger'ı yazmadan önce varsayılan olarak kapalı olan posta yollama özelliğini aşağıdaki ifadelerle açmak gerekir.

5) Trigger'ımız hem kayıt eklemede, hem değiştirmede hem de silmede posta yollayacaktır ve yazılımı aşağıdaki gibidir.

Burada [email protected] adresine gerekli bilgiyi yollayacaktır.

6) Test etmek için aşağıdaki ifadeyi yazabilirsiniz.

Sp_confiqur’show advenced options’,1; GO RECONFIGURE GO Sp_configure ‘Database Mail XPs’,1; GO RECONFIGURE

IF OBJECT_ID (‘postayolla’) IS NOT NULL

DROP TRIGGER postayolla;

GO

CREATE TRIGGER postayolla

ON satis

AFTER INSERT,UPDATE,DELETE

AS

EXEC msdb.dbo.sp_send_dbmail

@profile_name=’zirvedekiler’

@recipients=’[email protected]

@body=’Satis tablosunda ilsem

yapildi.’

@subject=’Dikkat!’;

Page 18: kullanıcı tanımlı fonksiyonlar

TRIGGER NASIL ÇALIŞIR?

Bir Trigger'ı iyi bir şekilde tasarlamak için nasıl çalıştığını anlamak gerekir. Bu kısımda INSERT, UPDATE, DELETE ve INSTEAD OF Trigger yapılarının nasıl çalıştığını inceleyeceğiz.

INSERT TRIGGER:

Bir tablo içine veri eklemek için kullanılan INSERT ifadesi ile Trigger oluşturulabilir.

Bir INSERT Trigger tetiklendiği zaman, Trigger'lı tabloya eklenen yeni satır aynı zamanda inserted tablosuna eklenir, inserted tablo mantıksal bir tablodur ve yeni eklenen satırın bir kopyasını tutar. INSERT ifadesi ile ilgili log'lar; inserted tablosunun içinde tutulur ve bu INSERT ifadesine referans edilir. Trigger, inserted tablosunu inceleyerek ne yapacağına karar verir.

Tüm veri yapılandırma aktiviteleri(INSERT, DELETE, UPDATE) bir olay günlüğü (log) yapısına sahiptir. Ancak bu bilgiler transaction log içinden değil, inserted tablosundan okunur.

UYGULAMA:

1) Bu örnekte kullanacağımız "satis" tablosundaki kayıtların, aşağıdaki şekilde olmasına dikkat ediniz ve kayitno sütununda Primary Key olduğunu unutmayınız.

update satis set fiyat=44 where kayitno=6

Page 19: kullanıcı tanımlı fonksiyonlar

2) depodurumu ismindeki yeni bir tabloyu şekildeki gibi tasarlayalım. Bu tabloda filmad sütununa Primary Key özelliğini kazandırıyoruz. Ayrıca kalan sütununun Formula kısmına (stokadet-satilan) ifadesini yazalım. Bunu yazmamızdaki amaç, "stokadet" sütununda bulunan değerden; "satilan" sütunundaki değeri çıkartarak, depoda kalan film miktarını "kalan" sütununa otomatik olarak yazdırmaktır.

3) Aşağıdaki örnek kayıtları, bu yeni oluşturduğumuz tablonun içine yazalım.

Kayıtları girerken filmad kısmına; bugüne kadar satılan film isimlerini yazdık, stok adedi kısmını varsayılan değer olarak 100 atadık. Yani ilk etapta tüm filmlerden depomuzda 100 adet var kabul ediyoruz. Satis tablomuza bakarak hangi filmlerden ne kadar satıldığını hesaplayıp, satilan sütununa yazdık, kalan sütununa bir şey yazmadık. Kalan sütunundaki değer otomatik olarak hesaplanacak ve hangi filmden ne kadar kaldığını kalan sütununda göreceğiz.

4) Evet buraya kadar herşey iyi de, ben her film sattığımda bu tabloyu açarak o filme ait

satilan sütununa bir ilave mi edeceğim? O zaman işin içinden çıkamam. İşte bir INSERT Trigger; bu yapı için çok uygun olur. Ben satis tablosuna yeni bir kayıt girdiğim zaman otomatik olarak bu filmin satılan sütununa ilave etsin, dolayısı ile kalan sütunu da otomatik olarak hesapladığı için, işim oldukça kolaylaşsın.

İşte tüm bu özellikleri sağlayan INSERT Trigger'ı aşağıdaki şekilde oluşturalım. Burada Trigger; satis tablosuna kayıt girileceği zaman çalışacağından dolayı satış trigger'ı olarak adlandırılır ve depodurumu ile inserted tablosu ilişkilendirilerek, gerekli hesaplama yapılır. Çünkü inserted tablosunda en son girilen değerler, yeni bir değer gelene kadar tutulur. O zaman en son kayıta ait bilgileri, bu tablodan öğrenebiliriz.

Page 20: kullanıcı tanımlı fonksiyonlar

5) Şimdi test etmek amacı ile satis tablosunu açarak, aşağıdaki kayıtları girelim.

Burada iki adet superman filminden ve bir adet 2012 filminden satıyoruz. Kayıtları girdikten sonra tabloyu kaydedip, kapatalım.

6) depodurumu tablomuzu açtığımız zaman, superman filminin satilan değerinin

2'den 4'e ve 2012 filminin satilan değerinin ise 2'den 3'e çıktığını ve kalan sütunun da otomatik olarak hesaplandığını, şekildeki gibi göreceğiz.

CREATE TRIGGER depodurumu_satilan_guncelle

ON satis

FOR

INSERT

AS

UPDATE depodurumu

SET

depodurumu.satilan=depodurumu.satilan+1

FROM depodurumu iner join inserted

ON depodurumu.filmad=inserted.filmad

GO

Page 21: kullanıcı tanımlı fonksiyonlar

7) Evet işler ne kadar kolaylaştı değil mi? Madem başladık, bu özelliği bir kez daha kullanarak, depoya yeni film girişi olduğu zaman otomatik olarak depodurumu tablosundaki stokadet sütununa girilen değer ilave edilsin. Bunun için depogir isimli tabloyu aşağıdaki şekilde tasarlayalım, irsaliyeno sütununa Primary Key özelliği kazandıralım.

8) Aşağıdaki kayıtları girelim. 9) depogir tablosuna yeni bir kayıt girildiği zaman, depodurumu tablosunda bulunan

stokadet sütununu güncelleyen Trigger'ı depogiris üzerinde oluşturalım.

10) depogir tablosunu açarak depoya; superman filminden 25 adet, 2012 filminden 33

adet ve tekrar superman filminden 11 adet giriş yaparak, tablomuzu kapatalım.

CREATE TRIGGER depodurumu_depogiris_guncelle

ON depogir

FOR INSERT

AS

UPDATE depodurumu

SET

depodurumu.stokadet=depodurumu.stokadet+inserted.alinanadet

FROM inserted iner join depodurumu

ON depodurumu.filmad=inserted.filmad

GO

Page 22: kullanıcı tanımlı fonksiyonlar

11) depodurumu tablosunu açtığımızda, en son girilen değerlerle birlikte superman filminin

136 ve 2012 filminin 133 olduğunu göreceğiz. Tabiki kalan sütununun da otomatik olarak değiştiğini gözlemleyeceğiz.

DELETE TRIGGER

Bu çeşit Trigger'lar, bir tabloda silme işlemi meydana gelince çalışırlar ve silinen kayıtlar deleted mantıksal tablosu içinde tutulur. Bir tablodan bir kayıt silindiğinde bu kayıt; ana tablodan tamamen silinir, ancak deleted tablosunda yer aldığından iki tablo arasında bir ortak yön yoktur. Deleted tablo her zaman Cache içinde tutulur. TRUNCATE TABLE ifadesi içeren bir tablo silme işleminde log oluşmadığından dolayı Delete Trigger çalıştırılamaz.

UYGULAMA:

1) Aşağıdaki yazılım kullanılarak, eğer satış tablosundan bir kayıt silinirse, otomatik olarak depodurumu tablosundaki satılan sütunundan silinen filmin değeri azalacaktır.

2) Yukarıdaki kodu çalıştırdıktan sonra "satis" tablosunu açarak son iki kayıdı silelim

ve tablomuzu kaydederek kapatalım.

3) depodurumu tablosunu açtığımız zaman, otomatik olarak değerlerin değiştiğini

gözlemleriz.

CREATE TRIGGER depodurumu_satilan_sil

ON satis

FOR

DELETE

AS

UPDATE depodurumu

SET depodurumu.satilan=depodurumu.satilan-1

FROM depodurumu iner join deleted

ON depodurumu.filmad=deleted.filmad

Page 23: kullanıcı tanımlı fonksiyonlar

UPDATE TRIGGER:

Bu yapıda iki olay meydana gelir. Bu olayların ilki DELETE adımıdır ve Before Image olarak, diğeri ise INSERT adımıdır ve After Image olarak adlandırılır. Yani UPDATE ifadesi çalıştığında, tablo içinde bulunan orijinal kayıtlar(before image) deleted tablosuna taşınırken, güncellenen kayıtlar inserted tablosuna taşınır. Eğer güncellenmesini istemediğiniz bir sütun varsa, bu sütunu kontrol etmek için; IF UPDATE ifadesi ile beraber güncellenmesini istemediğimiz sütun adını yazmamız gerekir.

UYGULAMA:

1) Aşağıdaki yazılım ile depogir tablosunda bulunan; irsaliyeno sütunumuzdaki verilerde bir değişiklik yapılmasını engelliyoruz.

2) depogir tablosunu açarak irsaliyeno sütunundaki değerleri değiştirmeye

çalıştığımızda, şekildeki gibi hata mesajı ile karşılaşacağız ve değişikliği gerçekleştiremeyeceğiz. OK butonuna bastıktan sonra ESC tuşu ile orijinal değerine geri dönelim.

CREATE TRIGGER depogiris_irsaliye_onle

ON depogir

FOR

UPDATE

AS

IF UPDATE (irsaliyeno)

BEGİN

BEGİN TRANSACTION

RAISERROR(‘Yapilan işlem

tamamlandi’,10,1)

ROLLBACK TRANSACTION

RETURN

END

GO

Page 24: kullanıcı tanımlı fonksiyonlar

3) Biraz daha ileri gidelim ve satis tablosunda bir film adını değiştirdiğimiz zaman depodurumu tablosunda bulunan değerler, otomatik olarak değişsin.

4) satis tablosunu açarak, 18 numaralı kayitno ya sahip kayıdın filmad değerini;

2012'den (before image) benten'e(after image) çevirelim ve tabloyu kaydederek, çıkalım. Burada aynı anda birden fazla kayıt üzerinde değişiklik yapabileceğimizi de hatırlatmak isterim.

5) depodurumu tablosunu açtığımız zaman 2012'nin satılan değerinin 1 azaldığını ve kalan sütununun 1 arttığını, aynı zamanda benten filminin satılan değerinin de 1 arttığını ve kalan değerinin 1 azaldığını gözlemleyeceğiz.

INSTEAD OF TRİGGER:

Bu tür Trigger'lar; Constraintler gibi çalışır ve hem tablo üzerine hem de view üzerine uygulanabilir. Bu Trigger, orijinal Trigger eylemleri yerine çalıştırılır. İNSTEAD OF Trigger'ları güncelleme çeşitliliğini arttırır.

Her tablo veya vievv'larda her bir INSERT, DELETE, UPDATE olan eylemler için bir adet İNSTEAD OF Trigger'ı oluşturulabilir. View'larda İNSTEAD OF Trigger'ı; WITH CHECK OPTION parametresi ile oluşturulamaz.

CREATE TRIGGER satis_filmad_degistir

ON

satis

FOR

UPDATE

AS

UPDATE depodurumu

SET depodurumu.satilan=depodurumu.satilan-1

FROM depodurumu iner join deleted

ON depodurumu.filmad=deleted.filmad

UPDATE depodurumu

SET depodurumu.satilan=depodurumu.satilan+1

FROM depodurumu iner join inserted

ON depodurumu.filmad=inserted.filmad

GO

Page 25: kullanıcı tanımlı fonksiyonlar

UYGULAMA:

1) Aşağıdaki yazılım; otomatik olarak benten ve superman isimli j| tablo oluşturur ve içlerine sadece kendileri ile ilgili kayıtları kopyalar.

2) Yukarıdaki kodu çalıştırdıktan sonra, veri tabanımız içinde bu iki tablo oluşacaktır ve içlerine kendileri ile ilgili kayıtları otomatik olarak kopyalayacaktır.

3) Şimdi bu iki tabloyu kullanarak, "filmler" isimli bir view oluşturmak için aşağıdaki kodu yazalım.

4) Kodu çalıştırdığımızda, view nesnesi altında "filmlerim" isimli bir view oluşacak ve içinde aşağıdaki kayıtlar olacaktır.

5) Şimdi bu view için bir INSTEAD OF Trigger'ını aşağıdaki şekilde oluşturalım. Bu

yazılım, "filmler" isimli view üzerinde "fiyat" sütununda bir değişiklik yapıldığında, bunu kabul edecek ve bağlı bulunduğu tablolardaki verileri de güncelleyecektir ve "fiyat" sütununun dışındaki başka bir sütunda değişiklik yapılamayacaktır.

SELECT * INTO benten from satis WHERE filmad=’benten’

SELECT * INTO superman from satis WHERE filmad=’superman’

CREATE VIEW filmlerim

AS

SELECT * FROM benten

UNION

SELECT * FROM superman

Page 26: kullanıcı tanımlı fonksiyonlar

6) Kodu çalıştırdıktan sonra filmlerim View'ını açarak; ilk önce 4 numaralı kayıdın fiyat sütununu 8,8 olarak, ardından da 5 numaralı kayıdın fiyat sütununu 9,9 olarak değiştirelim. Vievv'ı kaydederek çıkalım. Tekrar açtığımızda, bu değişikliklerin gerçekleştiğini gözlemleyelim. Daha sonra musterino sütunundaki değeri değiştirelim ve kaydederek kapatalım. Tekrar açtığımız zaman, bu değişikliklerin yansımadığını gözlemleyelim.

OLUR

OLMAZ

CREATE TRIGGER değişim ON filmlerim

INSTEAD OF UPDATE AS

DECLARE @filmad nvarchar(15)

SET @filmad = (SELECT filmad FROM Inserted)

IF @filmad = 'benten'

BEGIN

UPDATE benten SET benten.fiyat = Inserted.fiyat

FROM benten JOIN Inserted

ON benten. kayitno =Inserted.kayitno

END

ELSE IF @filmad = 'superman'

BEGIN UPDATE superman SET superman.fiyat = Inserted.fiyat

FROM superman JOIN Inserted

ON superman.kayitno = Inserted.kayitno

END

Update filmlerim set fiyat=88 where kayitno=4 Update filmlerim set fiyat=99 where kayitno=5

Update filmlerim set musterino=22 where kayitno=5