Documente online.
Username / Parola inexistente
  Zona de administrare documente. Fisierele tale  
Am uitat parola x Creaza cont nou
  Home Exploreaza
Upload




























Triggeri pe baza de date

Informatica




Triggeri pe baza de date

Sunt asociati cu o tabela, view, schema sau database



Sunt stocati īn baza de date

Se executa 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 restrictiilor de integritate complexe, monitorizare, centralizarea operatiilor. Nu se recomanda constru 22522x234w irea in exces a triggerilor.

Pentru fiecare trigger se stabileste:

comanda care-l declanseaza (insert| update| delete) - Un trigger poate fi declansat de mai multe comenzi

momentul de timp la care se declanseaza (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) - daca triggerul este la nivel de rānd se executa 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 creeaza un trigger care se declanseaza īnaintea fiecarei operatii de inserare īn tabela PRODUSE.

CREATE OR REPLACE TRIGGER produse_trig

BEFORE INSERT ON produse

BEGIN

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

END;

Clauzele INSERTING, UPDATING, DELETING

Exemplu:

Triggerul se declanseaza la operatiile de INSERT, DELETE sau UPDATE pe tabela Produse. In tabela TEMP_LOG se introduce tipul operatiei, utilizatorul care a executat-o, data curenta.

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;
/
--inserarea in tabela
insert into produse values (300, 'cafea', 'buc', 60);
--stergere
delete from produse where stoc>=300;

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 update

valoare noua, modificata

DELETE

valoare veche, anterioara lui delete

NULL

(:OLD) nu este definit pentru INSERT si (:NEW) nu e definit pentru DELETE

Desi sintactic sunt tratate ca tip de data record, īn realitate ele nu sunt si operatiile de atribuire directa var_record:=:old ce sunt valide pentru record nu sunt valide pentru (:new) si (: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 (vezi seminarul 8).

Utilizarea clauzei WHEN pentru a conditiona executia unui trigger:

clauza [when conditie] este valida pentru triggerii la nivel de rānd

corpul triggerului va fi executat numai pentru acele rānduri ce indeplinesc conditia specificata

Exemple:

--Se creeaza un trigger pentru a nu se permite depasirea stocului maxim ce poate fi depozitat

CREATE OR REPLACE TRIGGER restrict_stoc



BEFORE INSERT or UPDATE on produse
FOR EACH ROW

WHEN (old.um='buc')
BEGIN
IF :new.stoc>9000 then
RAISE_APPLICATION_ERROR (-20202, 'Pentru un produs nu se poate depasi stocul de 9000');
end if;
END;
/
update produse
set stoc =9500
where codprodus=222;

--Se creeaza un trigger care asigura unicitatea codului produsului folosind valorile generate de o secventa

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.codprodus FROM dual;

END;

show errors;

--Trigger care sa actualizeze cod client si in COMENZI cand el e modificat in FIRME.

CREATE OR REPLACE TRIGGER inlocuieste_cod

BEFORE UPDATE OF codfirma ON firme

FOR EACH ROW

BEGIN

update comenzi

set codfirma = :new.codfirma

where codfirma = :old.codfirma;

END;

CREATE OR REPLACE TRIGGER sterge_cod
BEFORE delete ON comenzi
FOR EACH ROW
BEGIN
delete from rindcom where nrcom = :old.nrcom;
END;
/

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 as
select f.codfirma, f.denfirma, f.loc, c.nrcom, c.data, a.codagent, a.numeagent
from firme f, comenzi c, agenti a
where f.codfirma=c.codfirma
and c.codagent=a.codagent;

--crearea triggerului

create or replace trigger exemplu_trigger
instead of insert or update or delete on clienti
for each row
begin

if inserting then

insert into firme values (:new.codfirma, :new.denfirma, :new.loc, null, null);
insert into agenti (codagent, numeagent) values (:new.codagent, :new.numeagent);
insert into comenzi values (:new.nrcom, :new.codfirma, :new.codagent, :new.data);


elsif deleting then
delete from comenzi where nrcom=:old.nrcom;


elsif updating ('denfirma') then
update firme
set denfirma=:new.denfirma
where codfirma=:old.codfirma;

elsif updating ('data') then
update comenzi
set data=:new.data
where nrcom=:old.nrcom;

end if;

end;
/
show errors;

--testare trigger
insert into clienti values (11,'zuzu','Bucuresti',82,'12-APR-04',3,'ionescu');

delete from clienti where denfirma='zuzu';

update clienti
set denfirma='cucu'
where loc='Bucuresti';

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, ROLLBACK, SAVEPOINT, insa pot contine un apel de procedura in care apar aceste comenzi, dar nu se recomanda

Sunt permise comenzile: COMMIT, ROLLBACK, SAVEPOINT

cānd un trigger e creat, codul sursa al triggerului este stocat īn dictionarul 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 sterge cu:

DROP TRIGGER nume_trigger;

Observatie: In momentul stergerii unei tabele se sterg automat toti triggerii asociati acelei tabele.

PL/SQL stocheaza triggerii īn forma compilata la fel ca procedurile, functiile si pachetele. Aceasta permite triggerilor sa fie apelati fara recompilare.





Document Info


Accesari: 1754
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate




Copyright © Contact (SCRIGROUP Int. 2023 )