Trigger
Un trigger (sau declanşator) este:
- un bloc sau o procedură PL/SQL
- o procedură C sau Java
care se asociază la:
- un tabel
- un view
- o schemă
- întreaga bază de date
Sirul de instrucţiuni (bloc, procedură) asociat la un trigger se execută automat în momentul în care apare un anumit eveniment
la obiectul la care se asociază.
Rolul unui trigger:
- audit
- generarea automată de valori derivate din diverse coloane
- validarea datelor cu condiţii în plus faţă de cele memorate
- autorizări complexe ale unor operaţii
Un trigger se poate preciza astfel:
- Instrucţiuni de gestiune a datelor dintr-un tabel (DELETE, INSERT, UPDATE), unde sintaxa de definire a trigger-ului este:
CREATE [OR REPLACE] TRIGGER nume_trigger
[ENABLE | DISABLE]
{BEFORE | AFTER} eveniment1 [OR eveniment2 [OR eveniment3]]
ON {[schema.]nume_tabel | NESTED TABLE coloana_cu_tabel_inclus OF nume_tabel}
[FOR EACH {ROW [WHEN conditie] | STATEMENT} ]
[REFERENCING {OLD [AS] nume | NEW [AS} nume} | PARENT [AS} nume]
Corp-trigger
Explicaţii:
- La definirea unui trigger se precizează că acesta va fi activat sau dezactivat imediat după definire
- "eveniment" poate fi: INSERT | DELETE | UPDATE [OF lista_coloane]
- Pot apare maximum 3 evenimente pentru un trigger
- "Corp-trigger" este un bloc PL/SQL (care poate apela proceduri memorate):
[DECLARE
declaratii]
BEGIN
instructiuni
[EXCEPTION
tratare exceptii]
END [nume_trigger];
Intr-un astfel de bloc trebuie respectate anumite condiţii, pentru a se evita apariţia unor bucle infinite:
un trigger declanşează un al doilea trigger care declanşează un al treilea, şi aşa mai departe.
Dintre aceste restricţii amintim:
- nu se poate modifica tabelul la care se ataşează trigger-ul
- nu se poate modifica un tabel legat de cel curent prin condiţii (de ex. de cheie externă)
- Trigger-ul se poate executa pentru fiecare linie (din tabel) afectată,
sau o singură dată pentru instrucţiunea de modificare (Insert, Delete, Update).
Implicit se consideră asociat la o instrucţiune. Dacă asocierea se face la nivel de linie,
atunci se poate preciza o condiţie (trigger-ul se va executa dacă această condiţie are
valoarea true). Se poate preciza o condiţie SQL care nu conţine subinterogări.
- Referirile la vechile înregistrări (înregistrări care se modifică - valorile existente înainte de modificare, înregistrări care se şterg)
şi noile înregistrări (inregistrări care se adaugă,
înregistrări care se modifică - valorile existente după modificare) se face prin :OLD.componenta sau
:NEW.componenta, sau prin denumiri precizate de clauza REFERENCING.
Referirea la înregistrarea părinte a unui tabel inclus se face prin :PARENT.componenta sau un nume definit.
- La crearea unui trigger pentru mai multe evenimente se pot folosi următoarele predicate, pentru a
verifica operaţia curentă care se execută (şi care a generat execuţia trigger-ului):
- INSERTING - care dă valoarea true dacă se execută instrucţiunea Insert
- DELETIND - care dă valoarea true dacă se execută instrucţiunea Delete
- UPDATING - care dă valoarea true dacă se execută instrucţiunea Update
- UPDATING(coloana) - care dă valoarea true dacă se execută instrucţiunea Update pe coloana precizată
Instructiuni de gestiune a componentelor dintr-o schemă
CREATE [OR REPLACE] TRIGGER nume_trigger
{BEFORE | AFTER} eveniment1 [OR eveniment2 [OR eveniment3]]
ON {SCHEMA | DATABASE}
Corp-trigger
unde eveniment poate fi:
ALTER, COMMENT, CREATE, DROP, RENAME, TRUNCATE, ANALYZE,
ASSOCIATE STATISTICS, AUDIT, DDL, DISASSOCIATE STATISTICS,
GRANT, NOAUDIT, REVOKE, SUSPEND (numai pentru evenimentul AFTER)
Operaţii asupra bazei de date (STARTUP, SHUTDOWN, SERVERERROR, LOGON, LOGOFF)
CREATE [OR REPLACE] TRIGGER nume_trigger
{BEFORE | AFTER} eveniment1 [OR eveniment2 [OR eveniment3]]
ON {SCHEMA | DATABASE}
Corp-trigger
unde eveniment poate fi:
AFTER STARTUP
BEFORE SHUTDOWN
AFTER LOGON
BEFORE LOGOFF
AFTER DB_ROLE_CHANGE
AFTER SUSPEND
AFTER SERVERERROR, pentru urmatoarele erori:
ORA-01403: no data found (este precizat in documentatie, uneori nu functioneaza)
ORA-01422: exact fetch returns more than requested number of rows
ORA-01423: error encountered while checking for extra rows in exact fetch
ORA-01034: ORACLE not available
ORA-04030: out of process memory when trying to allocate string bytes
Observaţie. Pentru un astfel de trigger se va executa procedura asociată pentru evenimentul precizat asupra
tuturor utilizatorilor, iar pentru un trigger pe o SCHEMA din baza de date se execută procedura pentru
evenimentul ce apare la schema precizată.
In afara definirii unui trigger, mai există următoarele instrucţiuni SQL care gestionează triggere,
cu semnificaţia care se deduce din sintaxa:
- ALTER TRIGGER nume_trigger DISABLE;
- ALTER TABLE nume_tabel DISABLE ALL TRIGGERS;
- ALTER TRIGGER nume_trigger ENABLE;
- ALTER TABLE nume_tabel ENABLE ALL TRIGGERS;
- ALTER TRIGGER nume_trigger_vechi RENAME TO nume_trigger_nou;
- DROP TRIGGER nume_trigger;
Observaţii:
- Dimensiunea unui trigger poate fi de cel mult 32Kb
- In corpul unui trigger nu se pot folosi instrucţiuni de gestiune a tranzacţiilor: ROLLBACK, COMMIT, SAVEPOINT
- Pentru informaţii despre triggere se pot folosi următoarele view-uri sistem:
{USER | ALL | DBA}_TRIGGERS
Exemplu:
select trigger_type, triggering_event, table_name, referencing_names, trigger_body
from user_triggers
where trigger_name = 'VERIFIC1';
- Inainte de crearea unui trigger, utilizatorul SYS trebuie să execute fişierul DBMSSTDX.SQL
Pentru gestiunea unui trigger sunt utile următoarele privilegii sistem:
- create trigger
- create any trigger
- administer database trigger
- alter any trigger
- drop any trigger
Exemple
Fişierele din directorul: exemple/Trigger