Muazzez KONUKLU

Cumartesi, Şubat 03, 2007

SQL TRIGGERS


Triggers(Tetikleyiciler)

Trigger'lar, bir tablo üstünde tanımlanabilen ve TRANSACTION'dan sonra çalışabilen programlanabilir öğelerdir. Daha açıklayıcı olarak, kayıt eklendiğinde, silindiğinde veya değiştirildiğinde otomatik olarak devreye giren özel bir çeşit SP'lerdir

Triggers(Tetikleyiciler), aslında özel bir Stored Procedure’dür. SP’lerden farkı, bir tablo üstünde UPDATE ,INSERT,DELETE komutları ile bir işlem yapılmak istendiğinde, ilk olarak bu SP’lere bakılması ve gerekli ise çalıştırılmasıdır.

Trigger'lar izin verilmeyen ya da tutarsızlığa neden olacak işlemleri engelleyerek veri bütünlüğünün korunmasına yardımcı olurlar.
Triggerlar genellikle değişik tablolar üzerinde bulunan ve birbirleri arasında mantıksal ilişkilere sahip verilerin tutarlılığını sağlamak üzere oluşturulurlar. İhtiyaca göre uygulamanın getirdiği bazı kuralları kontrol etmek için de kullanılabilirler.

UYARI:Recursive olarak çalışmazlar. Yani bir tablonun herhangi bir sütununda yapılan değişiklik üzerine bir trigger çalışıp aynı tablonun başka bir sütünunda değişikliğe neden oluyorsa ikinci yapılan değişiklik trigger için tetiklenmeye neden olmaz. Kısaca update triggerı tekrar tekrar çalışmaz, yalnızca bir kez çalışır.

Genel kullanımı:

CREATE TRIGGER trigger_adi
ON tablo_adi
FOR INSERT [,UPDATE,DELETE]
AS
SQL ifadesi


Şeklindedir.

Trigger’lerin bir UPDATE, INSERT veya DELETE komutuna cevap olarak çalışması, Transaction mantığı ile aynıdır.

Bir tablo için TRIGGER tanımlı ise INSERT, DELETE veya UPDATE işlemi başlamadan hemen önce bir Transaction başlatılır.

INSERT, DELETE veya UPDATE komutu yerine getirilir.

Trigger çağrılır ve içindeki SQL ifadesi çalıştırılır.

Trigger işlemi onaylarsa geçerli kılar veya onaylamaz ve geçersiz bulur. Transaction geri alınır. (ROLLBACK TRANSACTION).

Bir Trigger oluştururken şu durumlara dikkat etmek gerekir:

View ya da geçici tablolar üzerinde oluşturulamazlar. Fakat bunlara referans içerebilirler.

Çalıştıktan sonra bir kullanıcıya değer kümesi döndüremezler. Dolayısıyla
SELECT ifadesi dahil edileceği zaman dikkatli olunmalıdır.

Veri bütünlüğünü, farklı tablolardan birbirine referans yapan verilerin tutarlılığını sağlamak için ve uygulamanın ihtiyacına göre bazı kuralları tanımlamak üzere kullanılabilirler. Ancak zorlayıcılarla düzenlenebilecek trigger kullanmamak daha faydalıdır.

İstenirse syscomments tablosunda şifrelenmiş tekilde saklanabilirler.

CREATE, DROP, ALTER TABLE, ALTER DATABASE, SELECT INTO gibi ifadeler trigger içinde kullanılmazlar.


Trigger OluŞturmak

Enterprise Manager kullarak tetikleyici oluşturmak istersek, bunun için;
Enterprise Manager'i başlatip.

Trigger oluşturmak istediğiniz tabloya sağ tıklayarak All Tasks başlığından Manage Triggers seçeneği secilir. Açılan pencere tetikleyici oluşturmak ve düzenlemek için bir arabirim sunar.




Bu arabirim bize tetikleyici için bir şablon sunar. Köşeli parantezlerin ( [ ] ) içindeki değerleri değiştirerek istediğimiz işlevi yerine getrirecek tetikleyiciyi oluşturabiliriz.

İlk değişkenimizi ( [TRIGGER NAME] ) tetikleyicimize vermek istediğimiz isim ile değiştirin. İkinci değişken, tetikleyicinin hangi tablo üzerinde oluşturulacağını belirler.

Trigger oluşturmak için sağ tıkladığımız tablonun adı (resimde [dbo].[musteri] olan kısım) varsayılan olarak şablona yazılmış durumda gelecektir.

For ifadesinden sonraki kısım tetikleyicinin hangi işlemlerden sonra çalışacağını belirler.

As ifadesinden hemen sonra ise tetikleyicinin ne iş yapacağı belirlenir.


Örnek:Bir tablodaki kayıtlar üstünde değişiklik yapıldığında kaç kaydı etkilediğini yazan bir trigger oluşturalım:

CREATE TRIGGER trAffectedRows
ON odunc
FOR INSERT, UPDATE,DELETE
AS
raiserror ("%d kayıt üzerinde değişiklik yapılmıştır",0,1,@@rowcount)
RETURN

EK BILGI --> RAISERROR: Hata mesajları, SQL Server'in kendi iç hatalarını da ifade etmek için kullandığı mesajlardır. Bunların bir listesini almak için, SQL Server'de şu sorguyu çalıştırabilirsiniz.

SELECT * FROM master.dbo.sysmesseges
Hata mesajları master veritabanında tutulmaktadır. Ek bir hata mesajı tanımını buraya ekleyebilirsiniz.

Bir kullanıcı tanımlı hata mesajını kullanmak iki aşamada ele alınabilir.
Hata mesajının sysmessages tablosuna eklenmesi
İlgili durum oluştuğu anda, hata mesajının RAISERROR ile ilan edilmesi.
raiserror ("%d kayıt üzerinde değişiklik yapılmıştır",0,1,@@rowcount)


Burada, RAISERROR fonksiyonunun nasıl kullanıldığına dikkat etmek gerekir. Tirnak icinde yazilan yazi ekrana gelecek olan hata mesajidir. Birinci parametre olarak bir hata sistem kodudur. İkinci parametre bu hatanın oluşumundaki kritiklik seviyesidir. Son parametre ise, bu hatanın iç işleyişte nasıl ele alınacağı ile ilgili bir parametredir.


Eklenen-Silinen Kayıtlar

Triggerlar çalıştığı zaman Inserted ve Deleted tablolarını kullanırlar. Bu tabloların her ikisi de ana tabloyla yani triggerın tetiklendiği tabloyla eşdeğer alanlara sahiptirler. Bu tablolar, mantıksal tablo şeklinde RAM' de bulunurlar.

Ana tabloya bir kayıt eklendiği zaman bu kayıt aynı zamanda inserted tablosuna da eklenir. İhtiyacımız olduğu zaman yeni eklenen değerlere bu tablodan ulaşarak, bu bilgileri tutmak maksadıyla değişken tanımlamak zorunda kalmaktan kurtuluruz.

Tablodan bir kayıt silindiğinde silinen kayıt deleted tablosunda saklanır.
Update işlemi ise delete ve hemen ardından yapılmış bir insert işlemi olarak ele alınır. Bir kayıt update edildiğinde orjinal kayıt deleted tablosuna işlenir, değişen kayıt da inserted tablosunda (ve ana tabloda) saklanır.

Trigger’lere dışarıdan parametre yollayamayız. Ancak, INSERTED ve DELETED tabloları sayesinde kısıtlı da olsa, son işlemden etkilenmekte olan kayıtları tespit edebiliriz.
Örnek:
Kitaplardan bir kısmı, ödünç verildiği ve gelmediği halde bir başkasına daha ödünç verilmiş görünebiliyor. Böyle bir hata yapılmasını kökten çözmek için bir Trigger oluşturalım:

CREATE TRIGGER tr_oduncKontrol
ON odunc
FOR INSERT,UPDATE
AS
IF(SELECT COUNT(kitapNo) FROM odunc,inserted WHERE geldiMi=0 AND inserted.kitapNo=odunc.KitapNo)>1
BEGIN
PRINT ‘disaridaki kitab bir baskasina veremezsiniz…’
ROLLBACK TRANSACTION
END

Bu örnekte verilen durumun içerisinden foreign key zorlayıcısı ile çıkılamayacağına dikkat edin. Trigger’ler, uygulamaya özgü kuralları veritabanı sisteminin bir parçası olarak tayin etmek istenildiğinde de kullanılır.

Trigger ve Stored Procedure' lerı karşılaştırırsak, her ikisi de önceden derlenmiş SQL ifadeleri olduğundan hemen hemen aynı hızda ve aynı külfet miktarına sahiptirler.

SQL Server' ın işlem sırası, önce View ve Stored Procedure' lerı sonra Trigger' ları çalıştıracak şekildedir. Daha iyi performans elde etmek için mümkün olduğu kadar trigger seviyesine inilmemeye gayret edilmelidir.

Eğer problemi,Zorlayıcılar seviyesinde yakalayabiliyorsak bu seviyede, stored procedure içinde yakalayabiliyorsak sp seviyesinde o da olmuyorsa, trigger seviyesinde yakalamak gerekir. Sp ile yakalanan bir durum olduğunda, trigger yüzünden, yapılan her şeyin geri alınması gerekmez. Ancak sp’lerin otomatik devreye girmediğini unutulmamalidir.

0 Comments:

Yorum Gönder

<< Home