Özet: Veritabanında “trigger” tanımı ve kullanımı örneklerle anlatılıyor.

Tablo üzerindeki yapılacak dml/ddl işlemlerine göre hareket eden yapılara trigger (tetikleyici) diyoruz. Aşağıdaki trigger örneklerini inceleyerek neler yapabileceğinizi keşfedebilirsiniz;

“hastalar” tablomuza “cinsiyet” kolonu ekleyelim ve default olarak ‘E’ tanımlayalım;

alter table hastalar add cinsiyet char(1) default 'E';

insert into hastalar(hasta_id,hasta_no,hasta_adi,klinik_id) values(20,225,'can',2);
CREATE OR REPLACE TRIGGER TRG_CINSIYET
BEFORE INSERT
ON HASTALAR
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
:NEW.CINSIYET := 'K';
END;
/

Tablomuza yeni kayıt girdiğimizde cinsiyet kolonu ‘K’ olarak trigger sayesinde atanır;

insert into hastalar(hasta_id,hasta_no,hasta_adi,klinik_id) values(30,250,'ayşe',1);

Aşağıdaki trigger tablonun hasta_no kolonu üzerinde kontrol yapar ve engele takılınca mesaj verir;

CREATE OR REPLACE TRIGGER TRG_HASTA_NO
 AFTER INSERT OR UPDATE OF HASTA_NO
 ON HASTALAR
 REFERENCING NEW AS NEW OLD AS OLD
 FOR EACH ROW
DECLARE
BEGIN
 IF (:NEW.HASTA_NO IS NOT NULL) AND (LENGTH (:NEW.HASTA_NO) > 2)
 THEN
 raise_application_error (
 -20070,
 'HASTA NUMARASI 2 KARAKTERDEN FAZLA OLAMAZ!!!ISLEM İPTAL!');
 END IF;
END;
update hastalar set hasta_no=100 where hasta_no=400;

ORA-20070: HASTA NUMARASI 2 KARAKTERDEN FAZLA OLAMAZ!!!ISLEM İPTAL!
ORA-06512: konum "ORHAN.TRG_HASTA_NO", satır 5
ORA-04088: 'ORHAN.TRG_HASTA_NO' tetikleyicisinin yürütülmesi sırasında hata

insert into hastalar (hasta_no, hasta_adi) values (100, 'ali')

ORA-20070: HASTA NUMARASI 2 KARAKTERDEN FAZLA OLAMAZ!!!ISLEM İPTAL!
ORA-06512: konum "ORHAN.TRG_HASTA_NO", satır 5
ORA-04088: 'ORHAN.TRG_HASTA_NO' tetikleyicisinin yürütülmesi sırasında hata

Aşağıdaki trigger da yine hasta_no üzerinden kayıt kontrolü yapar;

CREATE OR REPLACE TRIGGER TRG_SORGULAMA
 BEFORE INSERT
 ON HASTALAR
 REFERENCING NEW AS NEW OLD AS OLD
 FOR EACH ROW
DECLARE
 VHASTA_NO NUMBER;
BEGIN
 SELECT HASTA_NO
 INTO VHASTA_NO
 FROM HASTALAR
 WHERE HASTA_ADI = :NEW.HASTA_ADI;

IF VHASTA_NO > 0
 THEN
 raise_application_error (
 -20090,
 VHASTA_NO || ' NOLU HASTA DA AYNI İSİM VAR.İŞLEM İPTAL!!!');
 END IF;
EXCEPTION
 WHEN NO_DATA_FOUND
 THEN
 NULL;
END;
select * from hastalar;

insert into hastalar (hasta_no,hasta_adi) values(200,'deniz');

ORA-20090: 50 NOLU HASTA DA AYNI İSİM VAR.İŞLEM İPTAL!!!
ORA-06512: konum "ORHAN.TRG_SORGULAMA", satır 11
ORA-04088: 'ORHAN.TRG_SORGULAMA' tetikleyicisinin yürütülmesi sırasında hata

Bazen aynı yapıdaki tablolardan birinde yapılan değişikliğin diğer tabloya da otomatikmen uygulanmasını isteyebiliriz. Bu durumda aşağıdaki gibi bir trigger işinizi görecektir;

create table hastalar2 as select * from hastalar;
CREATE OR REPLACE TRIGGER TRG_TABLOLARA_UYGULA
AFTER UPDATE OF HASTA_ADI
ON HASTALAR
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
declare
begin
UPDATE HASTALAR2 SET HASTA_ADI=:NEW.HASTA_ADI WHERE HASTA_ID=:NEW.HASTA_ID;
end TRG_TABLOLARA_UYGULA;
/
update hastalar set hasta_adi='canan' where hasta_adi='can';

Veya aşağıdaki gibi yeni bir kaydın diğer tabloya da eklenmesini isteyebiliriz;

CREATE TABLE HASTALAR_LOG AS SELECT * FROM HASTALAR;
CREATE OR REPLACE TRIGGER TRG_HASTALAR_LOG
AFTER INSERT OR UPDATE
ON HASTALAR
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
declare
begin
if inserting then
INSERT INTO HASTALAR_LOG
(HASTA_ID,HASTA_NO,HASTA_ADI,KLINIK_ID,CINSIYET)
VALUES
(:NEW.HASTA_ID,:NEW.HASTA_NO,:NEW.HASTA_ADI,:NEW.KLINIK_ID,:NEW.CINSIYET);
end if;
end TRG_HASTALAR_LOG;
/
insert into hastalar(hasta_id,hasta_no,hasta_adi,klinik_id) values(50,450,'mustafa',1);

select * from hastalar_log;

Aşağıdaki trigger örneğinde hasta_no karakter uzunluğu kontrolü söz konusu;

CREATE OR REPLACE TRIGGER TRG_HASTA_NO
AFTER INSERT OR UPDATE OF HASTA_NO
ON HASTALAR
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
declare
begin
IF (:NEW.HASTA_NO IS NOT NULL) AND (LENGTH(:NEW.HASTA_NO) < 3)
THEN
raise_application_error(-20070,'HASTA NUMARASI 3 KARAKTERDEN AZ OLAMAZ!!!İŞLEM İPTAL!');
END IF;

end ;
/
insert into hastalar(hasta_id,hasta_no,hasta_adi,klinik_id) values(70,50,'mehmet',1);

Aşağıdaki trigger örneğinde kayıt karşılaştırılması sözkonusu;

CREATE OR REPLACE TRIGGER TRG_SORGULAMA
BEFORE INSERT
ON HASTALAR
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
declare
VHASTA_NO NUMBER;
begin
begin
SELECT HASTA_NO INTO VHASTA_NO
FROM HASTALAR WHERE HASTA_ADI=:NEW.HASTA_ADI AND HASTA_NO= :NEW.HASTA_NO;

IF VHASTA_NO > 0 THEN
raise_application_error(-20090,VHASTA_NO||' NOLU HASTA DA AYNI İSİM VAR.İŞLEM İPTAL!!!');
END IF;

exception when no_data_found then
null;
end;
end;
/
insert into hastalar(hasta_id,hasta_no,hasta_adi,klinik_id) values(70,50,'ahmet',1);