A triggerek működése

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:

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:

  1. Végrehajtja az összes utasításszintű BEFORE triggert.

  2. 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.

  1. Ellenőrzi a késleltetett integritási megszorításokat.

  2. 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? */