Tüm veritabanı hatta daha geniş kapsamlı olarak Server bazında gerçekleştirilen Create, Alter Drop gibi ddl (Data Definition Language) işlemlerini kontrol etmek istediğimiz durumlarda DDL trigger’larını kullanabiliriz.Sadece veritabanı üzerindeki ddl işlemlerini kontrol etmek için DDL trigger’ımızı ilgili veritabanı üzerinde oluşturmamız gerekir. Server seviyesinde ddl işlemleri için trigger’ımızı master veritabanında oluşturmalıyız. Ddl trigger’larının tetiklenmesi ile oluşan event hakkında bize bilgi veren EVENTDATA() fonksiyonunu kullanabiliriz.
Veritabanı Seviyesinde DDL Trigger
Trigger’ımız tetiklendiğinde loglarımızı tutacak log tablomuzu oluşturalım ve ardından create_index ve drop_index komutları ile tetikleneceğini belirttiğimiz trigger’ımızı yazalım. Non-clustered indeksimizi yaratıp, eventdata çıktısını trigger sayesinde log tablomuza insert ettik.
create table DdlEventData ( EvenData xml not null,--kullanacağımız eventdata() fonksiyonun çıktısı için veri tipinin xml olması gerekmektedir. ActionDate datetime not null default GETDATE() ) create trigger Trg_IndexOperation on Database for CREATE_INDEX, DROP_INDEX AS SET NOCOUNT ON INSERT DdlEventData (EvenData) values (EVENTDATA()) create nonclustered Index IX_ContactID ON HumanResources.Employee(LoginID) select EvenData from DdlEventData
Çıkan resultta çıkan linke tıklayıp gelen xmli açalım. Xml oldukça detaylı bilgi içermektedir. ServerName, LoginName,DatabaseName gibi alanları göreceksiniz.
Server Seviyesinde DDL Triggerlar
Create login, create database gibi ddl komutlar server seviyesinde event’lerdir. Server seviyesinde ki ddl triggler’larımızda dml trigger’larımız gibi eventdata() fonksiyonunu kullanarak aynı şekilde detaylı bilgi elde edilebilir.Örnek olarak bir tane logon trigger yazalım. Logon triggler’lar sql servere login olduğunda tetiklenen triggler’lardır.
Örneğimizde barısy adlı kullanıcımız sabah 9 ile akşam 6 arasında sql servere bağlanma izni vermeyelim.
create login barisy with password='1234' create trigger Trg_Logon_Control on all server for logon as begin if ORIGINAL_LOGIN()='barisy' and DATEPART(hh,getdate()) between 9 and 16 begin rollback end end
Trigger’ımızı yazdıktan sonra barisy adlı kullanıcımızın mesai saatlerinde login olamadığını göreceksiniz.
Triggler’ların Yönetilmesi
Nested trigger kavramı bir trigger tetiklendikten sonra yaptığı işlemin başka bir trigger’ı tetiklemesi ve ikinci tetiklenen trigger’ın başka bir trigger’ı tetiklemesi ve bu zincirin böyle artarak uzaması anlamına gelmektedir. Sql server böyle sonsuz döngü oluşturabilecek durumları önlemek için iç içe çağırılabilecek trigger sayısını en fazla 32 olarak sınırlandırmıştır. Eğer iç içe trigger kullanmayacaksak sql server özelliker advanced tabında allow triggers to fire others seçeneğini false yapmalıyız.
Recursive trigger yani tetiklenen triggerın yine kendini tetiklenmesiye oluşan yapıdır. Bu da sql server tarafından 32 ile sınırlandırılmıştır.
Bir tablo üzerinde herhangi bir dml işlemi ile tetiklenen birden fazla trigger varsa bunları çalışma sırasını ayarlayabiliriz.Böyle 3 tane triggerımız var diyelim sp_settriggerorder adlı sistem sp’si ile ilk çalışmasını istediğimiz triggera first, son triggerımıza ise last diyerek belirli bir sıraya koyabiliriz. 3 ten fazla ise trigger’larımız çalışma sırasını garanti edemeyiz.
sp_settriggerorder 'trigger_name','First','process type (insert,delete)' sp_settriggerorder 'trigger_name','Last','process type (insert,delete)'
İyi çalışmalar.