Egy triggernek két állapota lehet: engedélyezett és letiltott. A letiltott trigger nem indul el, ha a kiváltó esemény bekövetkezik. Az engedélyezett trigger esetén az Oracle automatikusan a következő tevékenységeket hajtja végre:
Lefuttatja a triggert. Ha ugyanarra az utasításra több azonos típusú trigger van definiálva, akkor ezek sorrendje határozatlan.
Ellenőrzi az integritási megszorításokat és biztosítja, hogy a trigger ne sértse meg azokat.
Olvasási konzisztenciát biztosít a lekérdezésekhez.
Kezeli a trigger és a sémaobjektumok közötti függőségeket.
Osztott adatbázis esetén, ha a trigger távoli táblát módosított, kétfázisú véglegesítést alkalmaz.
A CREATE utasítás automatikusan engedélyezi a triggert. Triggert letiltani és engedélyezni az ALTER TRIGGER (lásd később ebben a fejezetben) és az ALTER TABLE (lásd [8]) utasítással lehet.
A DML triggerek futtatási konzisztenciájának biztosítása érdekében az Oracle a következő végrehajtási modellt követi, ha ugyanazon utasításon különböző típusú triggerek vannak értelmezve:
Végrehajtja az összes utasításszintű BEFORE triggert.
A DML utasítás által érintett minden sorra ciklikusan:
a) végrehajtja a sorszintű BEFORE triggereket;
b) zárolja és megváltoztatja a sort és ellenőrzi az integritási megszorításokat. A zár csak a tranzakció végeztével oldódik;
c) végrehajtja a sorszintű AFTER triggereket.
Ellenőrzi a késleltetett integritási megszorításokat.
Végrehajtja az utasítás szintű AFTER triggereket.
A végrehajtási modell rekurzív. Egy trigger működése közben újabb triggerek indulhatnak el, azok végrehajtása ugyanezt a modellt követi. A modell igen lényeges tulajdonsága, hogy az összes tevékenység és ellenőrzés befolyásolja a DML utasítás sikerességét. Ha egy trigger futása közben kivétel következik be, és azt nem kezeljük le, akkor az összes tevékenység (az SQL utasítás és a trigger hatását is beleértve) visszagörgetésre kerül. Így egy trigger működése nem sérthet integritási megszorítást.
1. példa
/* A következő példa demonstrálja
a triggerek végrehajtási sorrendjét. */
CREATE TABLE tabla (a NUMBER);
DELETE FROM tabla;
INSERT INTO tabla VALUES(1);
INSERT INTO tabla VALUES(2);
INSERT INTO tabla VALUES(3);
CREATE TABLE tabla_log(s VARCHAR2(30));
DELETE FROM tabla_log;
CREATE OR REPLACE PROCEDURE tabla_insert(p tabla_log.s%TYPE) IS
BEGIN
INSERT INTO tabla_log VALUES(p);
END tabla_insert;
/
CREATE OR REPLACE TRIGGER tr_utasitas_before
BEFORE INSERT OR UPDATE OR DELETE ON tabla
CALL tabla_insert('UTASITAS BEFORE')
/
CREATE OR REPLACE TRIGGER tr_utasitas_after
AFTER INSERT OR UPDATE OR DELETE ON tabla
CALL tabla_insert('UTASITAS AFTER')
/
CREATE OR REPLACE TRIGGER tr_sor_before
BEFORE INSERT OR UPDATE OR DELETE ON tabla
FOR EACH ROW
CALL tabla_insert('sor before ' || :OLD.a || ', ' || :NEW.a)
/
CREATE OR REPLACE TRIGGER tr_sor_after
AFTER INSERT OR UPDATE OR DELETE ON tabla
FOR EACH ROW
CALL tabla_insert('sor after ' || :OLD.a || ', ' || :NEW.a)
/
UPDATE tabla SET a = a+10;
SELECT * FROM tabla_log;
/*
S
------------------------------
UTASITAS BEFORE
sor before 1, 11
sor after 1, 11
sor before 2, 12
sor after 2, 12
sor before 3, 13
sor after 3, 13
UTASITAS AFTER
*/
2. példa
/*
Rekurzív triggerek.
*/
CREATE TABLE tab_1 (a NUMBER);
INSERT INTO tab_1 VALUES(1);
CREATE TABLE tab_2 (a NUMBER);
INSERT INTO tab_2 VALUES(1);
CREATE OR REPLACE TRIGGER tr_tab1
BEFORE DELETE ON tab_1
BEGIN
DELETE FROM tab_2;
END tr_tab1;
/
CREATE OR REPLACE TRIGGER tr_tab2
BEFOREDELETE ON tab_2
BEGIN
DELETE FROM tab_1;
END tr_tab2;
/
DELETE FROM tab_1;
/*
Hiba a(z) 1. sorban:
ORA-00036: a rekurzív SQL szintek maximális számának (50) túllépése
...
*/
/* Mi lesz az eredmény sorszintű triggerek esetén? */