Documente Academic
Documente Profesional
Documente Cultură
BEGIN
dbms_output.put_line('triggerul s-a executat');
END;
/
Clauzele INSERTING, UPDATING, DELETING
Exemplu:
Triggerul se declaneaz la operaiile de INSERT, DELETE sau UPDATE pe tabela Produse.
In tabela TEMP_LOG se introduce tipul operaiei, 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 execuiei:
--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 rnd se poate accesa rndul 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
2
UPDATE
DELETE
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 condiie] este valid pentru triggerii la nivel de rnd
corpul triggerului va fi executat numai pentru acele rnduri ce indeplinesc condiia
specificat
Exemple:
--Se creeaz un trigger pentru a nu se permite depirea 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 execuie se declaneaz triggerul i va apare excepia 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
3
end;
/
show errors;
--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
codul sursa: USER_TRIGGERS
Sunt declansati implicit de DML
Nu sunt permise comenzile: COMMIT,
ROLLBACK, SAVEPOINT, insa pot
contine un apel de procedura in care apar
aceste comenzi, dar nu se recomanda
Procedure
codul sursa: USER_SOURCE
Sunt apelate in mod explicit
Sunt permise comenzile: COMMIT,
ROLLBACK, SAVEPOINT
cnd un trigger e creat, codul surs al triggerului este stocat n dicionarul de date in