Sunteți pe pagina 1din 6

Facultatea de Științe Economice - SIG - Oracle – Laboratorul 10

Triggeri pe baza de date

 Sunt asociati cu o tabela, view, schema sau database


 Sunt stocaţi în baza de date
 Se execută când are loc un eveniment. Tipuri de evenimente:
 operatii LMD pe o tabela (insert/ update/ delete)
 operatii LMD pe o tabela virtuala (view) cu clauza INSTEAD OF
 operatii LDD (Create, Alter, Drop) la nivel de database sau schema
 evenimente la nivelul schemei sau bazei de date (shutdown sau logon/off)
 Se folosesc pentru gestionarea restricţiilor de integritate complexe, monitorizare, centralizarea
operatiilor. Nu se recomanda construirea in exces a triggerilor.
 Pentru fiecare trigger se stabileşte:
 comanda care-l declanşează (insert| update| delete) - Un trigger poate fi declanşat de mai
multe comenzi
 momentul de timp la care se declanşează (before| after| instead of). Pentru view se
utilizeaza instead of, actiunile DML vor fi inlocuite de corpul triggerului si vor fi afectate
tabelele din care este construit view-ul.
 nivelul (row| statement) - dacă triggerul este la nivel de rând se execută pentru fiecare rând
afectat de comenzile: insert| update| delete. Daca nu este afectat nici un rand triggerul nu se
executa.
 Dimensiunea unui trigger nu poate depasi 32 kb! Se poate include apelul unei proceduri in corpul
triggerului pentru a micsora dimensiunea acestuia.
 Pentru a vedea erorile la compilare:
SHOW ERRORS TRIGGER nume_trigger;

 Sintaxa de creare a unui trigger:


CREATE [OR REPLACE] TRIGGER nume_trigger
[BEFORE| AFTER| INSTEAD OF]
[INSERT| [OR] | UPDATE [OF coloana,…]| [OR] | DELETE]
ON tabela
[FOR EACH ROW ]
[WHEN conditie]
corp_trigger

Corp_trigger poate fi un bloc PL/SQL (Begin…End) sau un apel de procedura. Procedura poate fi
implementata in PL/SQL, C sau JAVA, iar apelul se realizeaza: CALL nume_proc (fara ; dupa
numele sau!!!)

Exemplu:
--Se creează un trigger care se declanşează înaintea fiecărei operaţii de inserare în tabela
PRODUSE.

CREATE OR REPLACE TRIGGER produse_trig


BEFORE INSERT ON produse

BEGIN
dbms_output.put_line('triggerul s-a executat');

-1-
Facultatea de Științe Economice - SIG - Oracle – Laboratorul 10

END;
/

Clauzele INSERTING, UPDATING, DELETING

Exemplu:
Triggerul se declanşează la operaţiile de INSERT, DELETE sau UPDATE pe tabela Produse.
In tabela TEMP_LOG se introduce tipul operaţiei, utilizatorul care a executat-o, data
curentă.

CREATE TABLE temp_log


(tip CHAR(1),
utilizator VARCHAR2(50),
data DATE DEFAULT SYSDATE);

CREATE OR REPLACE TRIGGER produse_trig_log


BEFORE INSERT or UPDATE or DELETE on produse
DECLARE
v_tip temp_log.tip%TYPE;
BEGIN
case
when INSERTING then v_tip :='I';
when UPDATING then v_tip:='U';
ELSE v_tip :='D';
END case;
INSERT INTO temp_log(tip, utilizator, data) VALUES (v_tip, user, sysdate);

END;
/

Verificarea execuţiei:

--inserarea in tabela
insert into produse (id_produs, denumire_produs) values (300, 'cafea');
--stergere
delete from produse where id_produs=300;

commit;

Select * from temp_log;

Triggeri la nivel de rand – FOR EACH ROW


In triggerul la nivel de rând se poate accesa rândul curent procesat folosind doua pseudo-records (
:old, :new). Tipul lor este:
nume_tabela_pe_care_actioneaza_triggerul%ROWTYPE
Valorile pentru :old si :new
Operatie Valoare pt Old Valoare pt New
INSERT NULL valoarea noua, inserata
UPDATE valoare veche, anterioara lui valoare noua, modificata
update

-2-
Facultatea de Științe Economice - SIG - Oracle – Laboratorul 10

DELETE valoare veche, anterioara lui NULL


delete

 (:OLD) nu este definit pentru INSERT şi (:NEW) nu e definit pentru DELETE


 Deşi sintactic sunt tratate ca tip de dată record, în realitate ele nu sunt şi operaţiile de atribuire
directa var_record:=:old ce sunt valide pentru record nu sunt valide pentru (:new) şi (:old). Din
acest motiv trebuie precizate exact campurile din pseudo-record :old.camp sau :new.camp.
 Nu se recomanda realizarea de triggeri la nivel de rind care utilizeaza valori ale coloanelor din
tabele si care sunt supuse actualizarilor prin comenzile DML ce declanseaza triggerul (mutating
table). Va apare aceeasi eroare ca la functii.
 Utilizarea clauzei WHEN pentru a conditiona executia unui trigger:
 clauza [when condiţie] este validă pentru triggerii la nivel de rând
 corpul triggerului va fi executat numai pentru acele rânduri ce indeplinesc condiţia
specificată

Exemple:
--Se creează un trigger pentru a nu se permite depăşirea unei limite maxime a salariului unui
angajat
CREATE OR REPLACE TRIGGER restrict_salariul
BEFORE INSERT or UPDATE on angajati
FOR EACH ROW
DECLARE
v_sal_max number;
BEGIN
select salariu_max into v_sal_max from functii where id_functie= :new.id_functie;
IF :new.salariul>v_sal_max then
RAISE_APPLICATION_ERROR (-20202, 'Nu se poate depasi salariul maxim
pentru functia data');
end if;
END;
/

Verificare execuţie – se declanşează triggerul şi va apare excepţia definită de utilizator.


update angajati
set salariul =15000
where id_angajat=104;

--Se creează un trigger care asigură unicitatea codului produsului folosind valorile generate de o
secvenţă
CREATE SEQUENCE produse_secv
START WITH 1
INCREMENT BY 1
MAXVALUE 100
NOCYCLE;

CREATE OR REPLACE TRIGGER generare_codprodus


BEFORE INSERT ON produse
FOR EACH ROW
BEGIN
SELECT produse_secv.nextval INTO :new.id_produs FROM dual;
-3-
Facultatea de Științe Economice - SIG - Oracle – Laboratorul 10

END;
/
show errors;

Clauza INSTEAD OF
 Sunt triggeri realizati doar pentru view-uri
 Se utilizeaza pentru actualizarea tabelelor din care este construit un view neactualizabil.
 Realizeaza operatii DML pe aceste tabele, iar Oracle Server declanseaza triggerii pe tabelele
respective.
 Daca un view este actualizabil, triggerii respectivi se declanseaza automat.
 Sunt triggeri la nivel de rand.
 Nu permit utilizarea clauzelor BEFORE|AFTER

--crearea tabelei virtuale


create or replace view clienti_v as
select cl.id_client, cl.prenume_client, cl.nume_client, cl.limita_credit,co.nr_comanda,
co.data
from clienti cl, comenzi co
where cl.id_client=co.id_client;

--crearea triggerului
create or replace trigger exemplu_trigger
instead of insert or update or delete on clienti_v
for each row
begin

if inserting then
insert into clienti (id_client, prenume_client, nume_client, limita_credit) values
(:new.id_client, :new.prenume_client, :new.nume_client, :new.limita_credit);
insert into comenzi (nr_comanda, data, id_client) values (:new.nr_comanda, :new.data,
:new.id_client);

elsif deleting then


delete from comenzi where nr_comanda=:old.nr_comanda;

elsif updating ('nume_client') then


update clienti
set nume_client=:new.nume_client
where id_client=:old.id_client;

elsif updating ('data') then


update comenzi
set data=:new.data
where nr_comanda=:old.nr_comanda;
end if;

end;
/
show errors;

-4-
Facultatea de Științe Economice - SIG - Oracle – Laboratorul 10

--testare trigger
insert into clienti_v values (10,'Ioan','Bucur',200,100,sysdate);
insert into clienti_v values (20,'Dana','Popa',250,110,sysdate);
select * from clienti where id_client in (10, 20);
select * from comenzi where id_client in (10, 20);

delete from clienti_v where nume_client='Bucur';


select * from clienti where id_client in (10, 20);
select * from comenzi where id_client in (10, 20);

update clienti_v
set nume_client='Popescu'
where id_client=20;
select * from clienti where id_client in (10, 20);

Comparatie intre triggeri si proceduri


Trigger Procedure
codul sursa: USER_TRIGGERS codul sursa: USER_SOURCE
Sunt declansati implicit de DML Sunt apelate in mod explicit
Nu sunt permise comenzile: COMMIT, Sunt permise comenzile: COMMIT,
ROLLBACK, SAVEPOINT, insa pot ROLLBACK, SAVEPOINT
contine un apel de procedura in care apar
aceste comenzi, dar nu se recomanda

 când un trigger e creat, codul sursă al triggerului este stocat în dicţionarul de date in
user_triggers si se poate afisa:

SELECT trigger_type, trigger_name, triggering_event


FROM user_triggers
WHERE table_name='PRODUSE';

Gestiunea triggerilor:

 Un trigger poate fi dezactivat


ALTER TRIGGER nume_trigger DISABLE|ENABLE;
Sau:
ALTER TABLE nume_tabela
DISABLE|ENABLE ALL TRIGGERS;

Exemplu:
ALTER TABLE produse
ENABLE ALL TRIGGERS;

 Recompilarea unui trigger se realizeaza prin:


ALTER TRIGGER nume_trigger COMPILE;

 Un trigger se şterge cu:


DROP TRIGGER nume_trigger;

-5-
Facultatea de Științe Economice - SIG - Oracle – Laboratorul 10

Observatie: In momentul stergerii unei tabele se sterg automat toti triggerii asociati acelei tabele.
 PL/SQL stochează triggerii în forma compilată la fel ca procedurile, funcţiile şi pachetele.
Aceasta permite triggerilor să fie apelaţi fără recompilare.

-6-

S-ar putea să vă placă și