TRIGGER’ların kullanım amaçları ;
Ø Tablolar üzerindeki işlemlerin denetim ve kontrol altında tutulmasına yönelik,
Ø Tabloların alanlarına verilebilecek değerlerin kontrol edilmesi,
Ø Tablolar arasındaki ilişkilendirmelerin denetlenmesi,
şeklindedir. Trigger’lar sunucu üzerinde çalışacakları için yönetim ve değişiklik yapılması kolaydır. Böylece veritabanında yer alan tabloların alanlarında yer alacak değerlerin son bir kez denetlenmesi mümkün olmaktadır. Programlar tarafından kontrol edilmekle beraber özellikle çeşitli yerlerden tablolara işlem yapılması mümkün olduğundan kritik kontrollerin, denetlemelerin bu triggerlar üzerinde yapılması önerilmektedir.
Sunucuya gönderilen INSERT, UPDATE veya DELETE komutundan ÖNCE ve/veya SONRA trigger devreye girecektir. Bu esnada tablo üzerinde değişiklikler kontrol edilir ve COMMIT komutuna kadar bu işlemler diğer kullanıcılara yansıtılmaz.
Trigger içersinde yer alacak kontrollerin, denetimlerin kısacası işlemlerin her kayıt için yapılacağının bilinmesi lazımdır. Gereksiz hiçbir işlemin özellikle kontrollerin trigger içersinde yer almamasına dikkat edilmelidir. Çünkü her kayıt eklemede veya değiştirmede veya silmede trigger devreye girecek ve kontrolleri yapacaktır. Bu da sistemin performansını etkileyecektir. Genel olarak kullanıcıların işlem yapma zamanlarını etkileyeceğinden özellikle üzerinde çok INSERT, UPDATE ve DELETE işlemlerinin sıkça yapıldığı tablolarda etki komutları içeren trigger’lar kullanılmasına dikkat edilmelidir.
Trigger yaratma komutu aşağıdaki gibidir.
CREATE or REPLACE TRIGGER trigger_adi
BEFORE INSERT OR DELETE OR UPDATE ON tablo_adi
FOR EACH ROW
BEGIN
IF INSERTING THEN
............
END IF;
IF DELETING THEN
............
END IF;
IF UPDATING('alan_adi') THEN
............
IF UPDATING THEN
............
END IF;
END;
Veritabanında herşey bir obje olduğundan ve bu objeler SYSTEM altında ilgili tablolar içerisinde tutulduğundan dolayı yaratılacak her trigger’a biri isim verilecektir. Trigger isimlendirilmesinde de anlaşılır, kolayca çözülebilir notasyonların kullanılması önerilmektedir. (Trg_biud_tablo_adi veya Trg_aiud_tablo_adi şeklinde...)
Burada CREATE komutuyla birlikte aynı zamanda REPLACE seçeneği de kullanılmıştır. Böylece ileride trigger üzerinde değişiklik yapılmak istendiği zaman var olan trigger değiştirilmiş olacaktır.
BEFORE INSERT or UPDATE or DELETE şeklindeki ifade ile bu trigger ; INSERT, UPDATE veya DELETE komutlarından ÖNCE çalışacaktır.
AFTER INSERT or UPDATE or DELETE şeklindeki ifade ile bu trigger ; INSERT, UPDATE veya DELETE komutlarından SONRA çalışacaktır.
ON tablo_adi ifadesi ile bu trigger’ın hangi tabloya ait olduğu belirtilmektedir.
FOR EACH ROW ifadesi ile bu trigger içindeki komutlar tabloda ki tüm kayıtlar için çalışacak anlamındadır.
IF INSERTING ifadesi ile bu trigger içinde sadece tabloya kayıt ekleme esnasında devreye girecek SQL ifadeleri yer alacaktır.
IF DELETING ifadesi ile bu trigger içinde sadece tablodan kayıt silinmesi esnasında devreye girecek SQL ifadeleri yer alacaktır.
IF UPDATING ifadesi ile bu trigger içinde sadece tabloda ki kayıtların değiştirilmesi esnasında devreye girecek SQL ifadeleri yer alacaktır.
IF UPDATING(‘alan_adi’) ifadesi ile bu trigger içinde sadece tablonun bir alanında değişiklik yapıldığında devreye girecek SQL ifadeleri yer alacaktır.
Görüldüğü üzere bir trigger içinde aynı anda tüm işlemlerin kontrolü ÖNCE’den (BEFORE) sağlanmış olacaktır. Aynı şekilde bu kontroller veya diğer tablolara etkileri SONRA’da (AFTER) olabilir.
Ø Trigger’lar içinde kullanılacak SQL komutlarının 60 satırı geçmemesi önerilmektedir.
Ø Tablo üzerindeki işlemlerin kontrolü sırasında tablo üzerinde başka bir işlemin (Insert, Update, Delete) devreye girmemesine dikkat edilmelidir. Bu takdirde aynı trigger devreye gireceğinden işlemler başarısız olur ve trigger hatası verilir.
Ø Trigger’ların kolayca yönetilmesi için çoğunlukla INSERT, UPDATE ve DELETE işlemleri için ayrı ayrı trigger’lar yazılması önerilir. Böylece bir tabloya ait en fazla 6 adet trigger olabilir.
Trigger komutu içinde kullanılan FOR EACH ROW ifadesi eğer kullanılmaz ise trigger içersinde tüm kayıtlar için değil, tablo genelinde kontroller yapılacak anlamındadır.
CREATE TRIGGER trg_biud_emp
BEFORE DELETE OR INSERT OR UPDATE ON emp
DECLARE
kaysay INTEGER;
BEGIN
/* Cumartesi veya Pazar Kontrolü */
IF (TO_CHAR(SYSDATE,'DY') = 'CMT' OR TO_CHAR(SYSDATE, 'DY') = 'PAZ')
THEN raise_application_error( -20501,
'Tatil günlerinde tablo üzerinde değişiklik yapılamaz');
END IF;
/* Resmi tatillerin kontrolü */
SELECT COUNT(*)
INTO dummy
FROM tatil_gunleri WHERE gun = TRUNC(SYSDATE);
IF dummy > 0
THEN raise_application_error( -20501,
'Resmi Tatil günlerinde tabloda değişiklik yapılamaz');
END IF;
/* 8:00 ve 18:00 kontrolü */
IF (TO_CHAR(SYSDATE, 'HH24') < 8 OR TO_CHAR(SYSDATE, 'HH24') >= 18)
THEN raise_application_error( -20502,
'Çalışma saatleri dışında tabloda işlem yapılamaz');
END IF;
END;
Yukarıda ki örnek trigger, EMP tablosu üzerinde INSERT, UPDATE ve DELETE işlemlerinden önce çalışacaktır. Ancak her kayıt için değil tablo genelinde devrededir.
Trigger içinde değişken kullanıldığından bu değişken adı ve tipi DECLARE satırında gösterilmiştir.
Eğer trigger içinde ki kontroller geçersiz sonuç verirse RAISE_APPLICATION_TRIGGER komutu ile hata mesajı kullanıcıya verilecek ve trigger’dan çıkılmış olacaktır. Diğer satırlar çalışmayacaktır.
Eğer bir trigger içinde SELECT ifadesi sonucunda bir değer ataması yapılacaksa bu SELECT .. INTO ifadesinin kullanılmasıyla olacaktır. Burada ;
SELECT COUNT(*)
INTO kaysay
FROM tatil_gunleri
WHERE gun = TRUNC(SYSDATE);
DECLARE ifadesi ile tam sayı olarak tanımlanmış olan KAYSAY değişkenine, tatil_gunleri dosyasında ki GUN alanı ile işlem tarihi eşit olan kayıt sayıları COUNT(*) komutuyla bulunmuş ve INTO ifadesi ile değeri atanmıştır.
TRIGGER’lar veritabanında yaratıldıktan veya üzerinde değişiklikler yapıldıktan sonra derlenmeleri gerekmektedir. Eğer bir trigger içersinde yer alan bir tablo DROP edilmişse bu trigger geçersiz duruma düşecek ve o komut satırı çalıştığında hata vererek çalışması kesilecektir. Bunun için özellikle veritabanı yöneticilerinin sistem içersinde yer alan tabloları ve ilgili triggerları sürekli kontrol altında tutmaları gerekmektedir.
Trigger içersinde tabloda kullanılan alanların YENI (NEW) ve ESKI (OLD) değerleri aynı anda kullanılmaktadır.
Ø INSERT ifadesi sırasında alanların :NEW değeri bulunur. Tabloya yeni bir kayıt ilave edildiğinden alanların ilk değerleri yenidir ve :NEW olarak kullanılır. Alanın eski değeri null dur.
Ø DELETE ifadesi sırasında alanların :OLD değeri bulunur. Tabloda var olan bir kayıt silindiğinde alanların eski değerleri (:OLD) mevcuttur, yeni değeri null dur.
Ø UPDATE ifadesi sırasında alanların hem :NEW hem de :OLD değeri bulunur. Tabloda kayıtlarda üzerindeki alanlarda değişiklik yapıldığından alanın eski (İOLD) ve yeni (:NEW) değerleri mevcuttur.
Ancak alanların :NEW ve :OLD değerleri BEFORE TRIGGER işleminde geçerli olmaktadır çünkü AFTER TRIGGER’da tablodaki değişiklikler yapıldığından alanın yeni değerini kullanacaktır.
Trigger’larda BEFORE seçeneği daha çok kullanılmaktadır. Çünkü tabloya etki edecek değişikliklerin yapılmadan önce kontrol edilmesi gerek şarttır. AFTER seçeneği ise bir tablonun değişiminden sonra etkilemesi gereken başka bir tablolar varsa onların üzerinde işlem yapılmasını sağlayacaktır.
Bir trigger içersinde, veritabanında yaratılmış olan bir PROCEDURE veya FUNCTION çağrılması mümkündür. Özellikle tekrar eden durumlarda, SQL satır sayısının fazla olduğu durumlarda kullanılabilir.
Bir tablo üzerinde bir seferinde çok sayıda kayıt üzerinde işlem yapılmak istendiği durumlarda veya girilmiş olan kayıtların tekrar düzenlemesi durumlarında, veritabanı yöneticisi trigger’ların çalışmasını geçici olarak durdurabilir. İşlemlerden sonra tekrar trigger’ı aktif edecektir. Bu işlemlerin, veritabanında kimsenin çalışmayacağı zamanda olması mutlak şarttır. Aksi takdirde, tabloların ve alanların bilgi girişleri güvenli olmayacak ve tutarsız değerler olabilecektir.
Trigger’ların çalışmasını geçici olarak durduran komut ALTER TRIGGER’dır.
Kaynak