Sunteți pe pagina 1din 18

DECLANATOARE

Un declanator (trigger) este o procedur care este executat n mod implicit cnd asupra tabelului asociat se execut o comand insert, update sau delete. Declanatoarele sunt medii prin care SQL ofer programatorilor de aplicaii proiectantilor de BD s asigure integritatea BD. Declanatoarele sunt utile deoarece impun reguli far a fi cuprinse n aplicaiile utilizatorilor. Proiectantul declanatorului specific i momentul cnd trebuie executat n raport cu instruciunile LMD.SQL Server ia n seama regulile i valorile implicite nainte ca informaiile s fie scrise n BD. Acestea reprezint pre-filtre care pot s impiedice manipulrile de date, prin controlarea activitilor din cadrul BD. Un declanator poate fi i un post-filtru care se execut dup ce modificarea datelor a trecut de reguli. Declanatorii permit s executm o procedur rezident ori de cte ori este executat o instruciune INSERT, UPDATE sau DELETE asupra unui tabel predefinit. Declanatorul este o procedur special stocat care: - genereaz automat anumite valori ce deriv din valorile coloanelor; - determin respectarea restriciilor i privilegiilor ; - face posibil jurnalizarea transparent a evenimentelor; - strnge informaii statistice n legtur cu accesarea tabelelor. Un declanator este o procedur stocat special care este executat de SQL Server la efectuarea unei operaii de inserare, modificare sau stergere. Pentru c declanatorii sunt executai dup efectuarea operaiei de inserare, modificare sau tergere ei reprezint un fel de ultim cuvnt la acestea. Dac un declanator respinge cererea, modificarea informaiilor este refuzat, iar aplicaia care a iniiat operaia deine un mesaj de eroare. Cea mai simpl utilizare este determinat de impunerea regulilor de integritate n BD. i

Observaie: Deoarece declanatoarele sunt executate dup regulile de integritate dac acestea nu sunt trecute atunci declanatorul nu este executat. Pentru ca un declanator s fie executat trebuie ca operaia n cauz s nu fi euat.

Componentele unui declanator Un declanator are trei componente: - o instruciune de declarare aceasta specific instruciunile SQL care activeaz declanatorul; - o restricie de declanare specific condiia care trebui s fie adevarat pentru ca declanatorul s fie activat; - aciunea declanatorului care specific blocul de instruciuni care trebuie executate. Pentru a crea un declanator trebuie s fii posesorul BD. Atunci cnd se adaug un declanator pentru o coloana, linie sau tabel se schimb uneori i modul de accesare i modul cum interacioneaz alte obiecte cu acesta. La folosirea obiectelor declanator se presupune respectarea condiiilor: Declanatoarele nu pot fi create pentru tabele temporare, Declanatoarele trebuie s fie create numai pentru tabele din baza de date curent, La eliminarea unui tabel, toate obicetele declanator asociate cu acest tabel sunt, eliminate automat mpreun cu tabelul. Crearea unui declanator se realizeaz cu instruciunea: CREATE TRIGGER nume_declanator ON { Nume_ tabel | Nume_ view } [ WITH ENCRYPTION ] { { { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] } [ WITH APPEND ] [ NOT FOR REPLICATION ] AS

[ { IF UPDATE ( coloana ) [ { AND | OR } UPDATE ( coloana ) ] [ ...n ] | IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask ) { operator de comparare } coloana_bitmask [ ...n ] }] Instruciuni_SQL [ ...n ] } } Sau urmtoarea form mai simpl CREATE TRIGGER [posesor.]nume_declanator ON [posesor.]nume_tabela FOR {INSERT, UPDATE, DELETE } [WITH ENCRYPTION] AS Instruciuni SQL Nume_declanator este numele declanatorului (trigger-ului). Un nume de declanator trebuie s respecte regulile pentru identificatori i trebuie s fie unic ncadrul unei baze de date. Nume_ tabel | Nume_ view este numele tabelului sau vederii n care declanatorul este executat. INSERT, UPDATE, DELETE acestea definesc scopul declanatorului operaiile care iniiaz declanatorul. WITH ENCRYPTION aceast opiune este utilizat pentru a mpiedica ca utilizatorii s citesc definiia declanatorului dup ncrcarea lui pe server. SQL Server stocheaz definiia unui declanator n fiierul Syscomment. Cripteaz intrrile n tabela syscomments care conine textul comenzii CREATE TRIGGER. AFTER specific faptul c declanatorul este executat doar cnd toate operaiile din enunul SQL al declanatorului au fost execuate cu succes. Toate aciunile refereniale n cascad i verificrile de constrngere deasemenea trebuie s reuseasc nainte de executarea acestui trigger. Folosirea clauzei AFTER este identic cu folosirea clauzei i specific

FOR utilizat mai mult n ultimele versiuni de SQL Server. Declanatorii AFTER nu pot fi definii pentru vederi. INSTEAD OF Specific faptul c declanatorul este executat n locul enunului SQL declanat, astfel suprapunnd operaiile din enunul declanatorului. Acest tip de declanator poate fi definit pentru un tabel sau pentru o vedere cnd se realizeaz; INSERT, UPDATE sau DELETE. Este posibil s definim vederi INSTEAD OF. { [DELETE] [,] [INSERT] [,] [UPDATE] } Sunt cuvinte cheie care specific pentru ce operaie are loc declanatorul. Este obligatorie apariia cel puin a unei opiuni. Pentru declanatori INSTEAD OF, opiunea DELETE nu este permis pentru tabelele care au legturi refereniale ce specific o aciune ncascad pentru opiunea ON DELETE. Asemntor, opiunea UPDATE nu este permis pe tabele care au legturi refereniale ce specific o aciune ncascad pentru opiunea ON UPDATE. Instruciuni_sql Reprezint condiia (condiiile) i aciunea (aciunile) declanatorului. Aciunile declanatorului sunt scrise n Transact-SQL i pot cuprinde oricte instrucini sau comenzi Transact-SQL. Cteva tabele speciale, de care am mai amintit, sunt folosite n instruciunea CREATE TRIGGER i anume: inserted i deleted. IF UPDATE (coloana)Testeaz aciunea unei comenzi INSERT sau UPDATE pentru coloana specificat i nu este folosit pentru DELETE. Mai multe coloane pot fi specificate. Deoarece numele tabelului este specificat dup clauza ON, nu este nevoie s includem numele tabelului nainte de numele coloanei n clauza IF UPDATE. Pentru a testa o adugare sau o modificare pentru mai multe coloane, specificm separat clauza UPDATE(coloana) dup ce am scris-o pe prima. IF UPDATE va returna valoarea TRUE n aciunea INSERT deoarece coloanele vor fi explicit sau implicit (NULL) inserate. Nota Clauza IF UPDATE (coloana) functioneaz identic cu IF, IF...ELSE sau WHILE poate folosi i blocul BEGIN...END. UPDATE(coloana) poate fi folosit oriunde n corpul declanatorului. unde fiecare vedere s aib propriul declanator

Coloana este numele unei coloane pentru testarea aciunii INSERT sau UPDATE. Aceast coloan poate avea orice tip de date SQL Server.Oricum coloanele calculate nu pot fi utilizate n acest context. IF (COLOANAS_UPDATED()) Testeaz, dac ntr-un declanator INSERT sau UPDATE, coloanele menionate au fost inserate respectiv modificate. COLOANAS_UPDATED returneaz un tip varbinary (tip binar variabil) ce indic ce coloane din tabel au fost inserate sau modificate. Funcia COLOANAS_UPDATED returneaz biii n ordine de la stanga la dreapta, cu cel mai puin semnificativ bit n partea cea mai din stnga. Cel mai din stnga bit reprezentnd prima coloana din tabel, urm torul bit reprezentnd cea de-a dou coloan etc. COLOANAS_UPDATED returneaz mai muli octei pentru declanatorul care a fost creat coninnd mai mult de 8 coloane, cu cel mai puin semnificativ byte n partea din stnga. COLOANAS_UPDATED va returna TRUE pentru toate coloanele din aciunea INSERT deoarece coloanele au fost inserate cu valori explicite sau cu valori implicite (NULL). COLOANAS_UPDATED poate fi folosit oriunde n corpul declanatorului. bitwise_operator Operaor pe bit folosit n comparri. Updated_bitmask Este o masc de tip ntreg pentru acele coloanele care tocmai au fost modificate sau inserate. De exemplu, tabela t1 conine coloanele C1, C2, C3, C4, i C5. Pentru a verifica dac coloanele C2, C3, i C4 sunt toate modificate (tabela t1 avnd un declanator UPDATE), specific valoarea 14 (01110). Pentru a verifica dac doar coloana C2 este modificat, specific valoarea 2(00010). Operaor de comparare.Este unul din operatorii de comparare. Folosii semnul egal (=) pentru a verifica dac toate coloanele specificate n updated_bitmask sunt realmente modificate.Folosii semnul mai mare (>) pentru a verifica dac oricare sau cteva din coloanele specificate n updated_bitmask sunt modificate. Coloana_bitmask Este o masc de tip ntreg pentru acele coloane pentru care verificm dac ele au fost modificate sau inserate. SQL Server permite declanatori multiplii ce pot fi creai pentru fiecare eveniment de modificare de date (DELETE, INSERT, or UPDATE). De exemplu, dac este executat CREATE TRIGGER FOR UPDATE pentru un tabel care deja are un declanator UPDATE, atunci este creat un declanator adiional de tip UPDATE.

Exemplul 1 Declanator ce afiseaz pe ecran un mesaj cnd se adaug sau se modific date din tabela Catalog IF EXISTS (SELECT name FROM sysobjects WHERE name = 'declan_mesaj ' AND type = 'TR') DROP TRIGGER GO CREATE TRIGGER declan_mesaj ON Catalog FOR INSERT, UPDATE AS RAISERROR ('S-a executat un INSERT sau un UPDATE', 16, 1) GO INSERT INTO Catalog VALUES ('101','5',7,'11-17-2006') GO UPDATE Catalog SET Nota=5 WHERE NrLeg='101' and Cod_disciplina='5' Exemplul 2 Acest declanator afiseaz pe ecran anumite mesaje pentru oricine ncearc s adauge sau s modifice date din tabelul Catalog IF EXISTS (SELECT name FROM sysobjects WHERE name = ' declan1' AND type = 'TR') DROP TRIGGER declan1 GO CREATE TRIGGER declan1 ON Catalog FOR INSERT, UPDATE AS DECLARE @@nota integer, @@Nr_leg varchar(5) SELECT @@Nr_leg = i.NrLeg, @@nota = i.Nota FROM Catalog C, inserted i WHERE C.NrLeg = i.NrLeg IF (@@nota <5 )and(@@Nr_leg like '101') declan_mesaj

BEGIN RAISERROR ('Studentul cu NrLeg=101 are nota <5', 16, 1) END ELSE BEGIN RAISERROR ('Studentul cu NrLeg=%s are note de 16, 1, @@Nr_leg, @@nota) END go INSERT INTO Catalog VALUES ('101','4',6,'11-06-2006') go INSERT INTO Catalog VALUES ('101','4',2,'12-07-2006') Go UPDATE Catalog SET Nota=5 WHERE NrLeg='101' and Cod_materie='4' go Exemplul 3 Declanator pentru tergeri i modificri ntabelul Catalog IF EXISTS (SELECT name FROM sysobjects WHERE name = 'dec1' AND type = 'TR') DROP TRIGGER dec1 GO CREATE TRIGGER dec1 ON Catalog FOR INSERT, UPDATE AS DECLARE @@nota integer, @@nota = i.Nota @@Nr_leg varchar(5) SELECT @@Nr_leg = i.NrLeg, WHERE C.NrLeg = i.NrLeg FROM Catalog C, inserted i %d ',

IF (@@nota <5 )AND(@@Nr_leg like '101') BEGIN RAISERROR ('Studentul cu NrLeg=111 are Catalog <6', 16, 1) ROLLBACK TRANSACTION END ELSE BEGIN RAISERROR ('Studentul cu NrLeg=%s are Catalog de 16, 1, @@Nr_leg, @@nota) ROLLBACK TRANSACTION END go INSERT INTO Catalog VALUES ('101','5',6,'11-10-2006') Go INSERT INTO Catalog VALUES ('101','5',2,'12-01-2006') go UPDATE Catalog SET Nota=7 WHERE NrLeg='101' AND Cod_disciplina='4' go Exemplul 4 Declanator ce nu permite introducerea unor date nevalide n Catalog IF EXISTS (SELECT name FROM sysobjects WHERE name = ' dec2' AND type = 'TR') DROP TRIGGER dec2 GO CREATE TRIGGER dec2 ON Catalog FOR INSERT, UPDATE AS DECLARE @nota integer SELECT @nota=Catalog.nota from Catalog, inserted WHERE Catalog.NrLeg=inserted.NrLeg IF(@nota<=0) or (@nota>10) BEGIN %d ',

RAISERROR ('Nota invalida', 16, 1) ROLLBACK TRANSACTION END go INSERT INTO Catalog VALUES ('102','4',-2,'12-01-2006') go SELECT * FROM Catalog WHERE NrLeg='102' Exemplul 5 Declanator ce adaug 1 punct la orice not din tabelul Catalog IF EXISTS (SELECT name FROM sysobjects WHERE name = ' dec3' AND type = 'TR') DROP TRIGGER dec3 GO CREATE TRIGGER dec3

ON Catalog AFTER INSERT AS UPDATE Catalog SET Catalog.nota = Catalog.nota + 1 FROM inserted WHERE Catalog.NrLeg = inserted.NrLeg go INSERT INTO Catalog VALUES ('103','4',4,'12-01-2006') go SELECT * FROM Catalog WHERE NrLeg='105' Exemplul 6 Declanator inlocuieste o operaie INSERT cu operaia UPDATE din enunul SQL al declanatorului astfel dac se doreste inserarea unei Catalog pentru un student la o anumit materie se va face o modificarea adic se adaug 1 punct la nota introdus anterior la acea materie pentru studentul dat n tabelul Catalog IF EXISTS (SELECT name FROM sysobjects WHERE name = 'dec3' AND type = 'TR') DROP TRIGGER dec3

GO CREATE TRIGGER dec3

ON Catalog INSTEAD OF INSERT AS UPDATE Catalog SET Catalog.nota = Catalog.nota+1 FROM inserted WHERE Catalog.NrLeg = inserted.NrLeg go INSERT INTO Catalog VALUES ('102','4',4,'12-01-2006') go SELECT * FROM Catalog WHERE NrLeg='102' Exemplul7 Crearea unui declanator ce afiseaz un mesaj dac s-a modificat Nota i un alt mesaj ncaz contrar IF EXISTS (SELECT name FROM sysobjects WHERE name = 'dec4' ND type = 'TR') DROP TRIGGER dec4 GO CREATE TRIGGER dec4

ON Catalog FOR UPDATE AS IF UPDATE(Nota) RAISERROR ('S-a modificat campul Nota',16,1) ELSE RAISERROR ('S-a modificat alt camp al tabelei CATALOG',16,1) go UPDATE Catalog SET Nota=10 WHERE NrLeg='105' go SELECT * FROM Catalog WHERE NrLeg='105' go UPDATE Catalog SET Cod_materie='3' WHERE NrLeg='105' go

UPDATE Catalog SET Cod_materie='3', Nota=8 WHERE NrLeg='105' Exemplul 8 Crearea unui declanator care afiseaz un mesaj dac s-au modificat Cod_disciplina i ***** ncaz contrar IF EXISTS (SELECT name FROM sysobjects WHERE name = 'dec5' AND type = 'TR') DROP TRIGGER dec5 GO CREATE TRIGGER dec5 Nota i

ON Catalog FOR UPDATE AS IF UPDATE(Nota) AND UPDATE(Cod_diciplina) RAISERROR('S-au modificat atributele Nota i Cod_disciplina',16,1) ELSE RAISERROR ('*****',16,1) go UPDATE Catalog SET Nota=10 WHERE NrLeg='105' go SELECT * FROM Catalog WHERE NrLeg='105' go UPDATE Catalog SET Cod_diciplina ='3', Nota=8 WHERE NrLeg='105' Exemplul 9 Crearea unui declanator care afiseaz un mesaj dac s-au modificat atributele Nota sau Cod_disciplina i *.*.* n caz contrar. IF EXISTS (SELECT name FROM sysobjects WHERE name = 'dec6' AND type = 'TR') DROP TRIGGER dec6 GO CREATE TRIGGER dec6 ON Catalog FOR UPDATE

AS IF (COLOANAS_UPDATED()&6)>0 RAISERROR ('S-au modificat atrib. Nota sau Cod_materie',16,1) ELSE RAISERROR ('*.*.*',16,1) go UPDATE Catalog SET Nota=10 WHERE NrLeg='105' go SELECT * FROM Catalog WHERE NrLeg='105' go UPDATE Catalog SET Cod_materie='3', Nota=8 WHERE NrLeg='105' go UPDATE Catalog SET Data='3-3-2002' WHERE NrLeg='105' Exemplul 9 Crearea unui declanator care verifica dac au fost modificate printr-o comanda UPDATE coloanele 3, 6 i 9 din tabelul Student IF EXISTS (SELECT name FROM sysobjects WHERE name = 'dec7' AND type = 'TR') DROP TRIGGER dec7 GO CREATE TRIGGER dec7 ON Student FOR UPDATE AS IF ( (SUBSTRING(COLOANAS_UPDATED(),1,1)=power(2,(3-1))--coloana 3+ power(2,(6-1))) --coloana 6 AND (SUBSTRING(COLOANAS_UPDATED(),2,1)=power(2,(1-1)))--coloana 9 (coloana 1 din cel de-al II-lea octet ) PRINT 'Coloanele 3, 6 i 9 au fost modificate' GO UPDATE Student SET Initiala='O', Data_nastere='12-12-1980', NrLeg_sot='105' WHERE NrLeg='105' GO SELECT * FROM Student WHERE NrLeg='105' Exemplul 10 Crearea unui declanator pentru DELETE

IF EXISTS (SELECT name FROM sysobjects WHERE name = 'sterge_stud' ND type = 'TR') DROP TRIGGER sterge_stud GO CREATE TRIGGER sterge_stud ON Student FOR DELETE AS DECLARE @NL varchar(5) SELECT @NL=deleted.NrLeg FROM deleted IF (cast(@NL as integer)>0) PRINT 'S-a Sters' ELSE BEGIN PRINT 'Acest NrLeg nu exista' ROLLBACK TRANSACTION END GO DELETE FROM Student WHERE NrLeg='17' Modificarea unui declanator se face cu comanda ALTER TRIGGER care are sintaxa:

ALTER TRIGGER nume_declan ON ( table | view ) [ WITH ENCRYPTION ] { { ( FOR | AFTER | INSTEAD OF ) { [ DELETE ] [ , ] [ INSERT ] [ , ] [ UPDATE ] } [ NOT FOR REPLICATION ] AS sql_statement [ ...n ] } | { ( FOR | AFTER | INSTEAD OF ) { [ INSERT ] [ , ] [ UPDATE ] }

[ NOT FOR REPLICATION ] AS { IF UPDATE ( coloana ) [ { AND | OR } UPDATE ( coloana ) ] [ ...n ] | IF ( COLOANAS_UPDATED ( ) { bitwise_operaor } updated_bitmask ) { comparison_operaor } coloana_bitmask [ ...n ] } sql_statement [ ...n ] } }

tergerea unui declanator se face cu comanda:


DROP TRIGGER { nume_declan } [ ,...n ]

Un declanator poate s conin oricte instruciuni cu condiia s fie ncadrate ntr-un bloc BeginEND. La executarea unui declanator SQL serverul acceseaz o tabel special cu datele ce au determinat rularea declanatorului.Aceasta tabel este INSERTED pentru operaiile INSERT i UPDATE i respectiv DELETED pentru operaiile DELETE i UPDATE. Deoarece un declanator este executat ntotdeauna dup operaie, liniile din INSERTED reprezint ntotdeauna o dublur a uneia sau a mai multor nregistrri din tabela de baz. Restricii de utilizare a declanatorilor SQL-Serverul impune anumite restricii asupra tipurilor de instruciuni care pot fi executate n cadrul unui declanator. Majoritatea restriciilor sunt determinate de imposibilitatea de anulare a consecinelor unei operaii insert, update sau delete. n corpul unui declanator nu poate apare nici una din instruciunile: CREATE DATABASE, CREATE TABLE INDEX, PROCEDURE, DEFAULT, RULE, TRIGGER i VIEW.

toate instruciunile DROP; instruciunile de modificare a obiectelor din baz ALTER TABLE, ALTER DATABASE i TRUNCATE TABLE;

UPDATE STATISTICS; Operaii de ncrcare a BD LOAD DATABASE i LOAD TRANZACTION; Toate instruciunile care realizeaz modificri fizice pe disc:DISK. Crearea de fiiere temporare fie implicita fie prin SELECT; Nu se poate crea un declanator pentru o vedere ci numai pentru tabel de baz care definete vederea. Manipularea unor coloane care conin bloc nu determin execuia unui declanator.

Tipuri de declanatoare Atunci cnd se creeaz un declanator se specific de cte ori se execut. Exist 2 tipuri de declanatoare: -Declanator linie care se execut ori de cte ori tabelul este afectat de instruciunea declanatoare. Dac o instruciune UPDATE actualizeaz 20 de linii, declanatorul se execut de 20 de ori. Dac instruciunea nu afectez nici o linie declanatorul nu este executat. -Declanatorul instruciune este executat o singur dat pentru instruciunea declanatoare. De exemplu dac este executat o instruciune UPDATE care actualizeaz 10 linii este executat o singur dat Declanatorele INSERT i UPDATE sunt utile pentru ca impun restriciile refereniale i asigur validarea datelor nainte de a le scrie n tabele. De obicei se folosete pentru a verific dac datele urmrite satisfac anumite criterii. La declanatoare se apeleaz numai cnd criteriile de integritate sunt foarte complete. Declanatorul de mai jos este activat ori de cte ori se nsereaz sau se modific o nregistrare n tabelul vnzri.

CREATE TRIGGER ins_vanzari ON vanzari FOR INSERT,UPDATE AS DECLARE @zidinluna tinyint SELECT @zidinluna=DataPart(Day, iData_comenzi) FROM vanzari v, Inserted i WHERE v.star_id=i.star_id AND v.nr_com=i.nr_com AND v.denumire=i.denumire IF @zidinluna>15 Begin ROLLBACK END GO CREATE TRIGGER elimart ON articole FOR DELETE AS FOR EACH row WHERE (pretart)<100 DELETE END CREATE TRIGGER ins.art
ON articol FOR INSERT

FOR EACH row BEGIN INSERT INTO art

END Se poate crea declanatorul care s reacioneze dac se modific doar o coloan. Instruciunea IF update poate fi utilizat ntr-un declanator pentru a decide dac se coninu execuia acestuia. IF UPDATE (pre )AND (@@row COUNT=1) BEGIN END In acest caz blocul se execut numai dac s-a modificat coloana pret .Modificarea unei coloane nu nseamn neaprat schimbarea valorii ei. Declanatoare pentru stergere Se folosesc pentru a preveni tergerea acolo unde acestea ar afecta integritatea datelor (Este exemplul cheilor strine pentru alte tabele. Al doilea este tergerea unui articol n cascad care s elimine nregistrrile copie ale unei nregistrri particulare )

CREATE TRIGGER sterg ON vanzri FOR DELETE AS IF @@row COUNT>1 /*verifica nr de linii afectate impiedicnd

stergerea a mai mult de o linie*/ BEGIN ROLLBACK RAISERROR(puteti sterge o singur instruciune la un moment dat,16, 10) END DECLARE @stare_id char(4) SELECT @stare_id=s.stare-id

FROM vanzri v deleted s IF EXIST (SELECT * FROM vanzri WHERE stare_id=@s.stare_id) BEGIN ROLLBACK RAISERROR(nu poate fi sters,16,10) END GO

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