100% ont trouvé ce document utile (6 votes)
10K vues34 pages

Trigger SQL

Ce document décrit les triggers SQL, y compris les différents types de triggers, leurs utilisations et les différences entre les standards SQL et les implémentations d'Oracle et d'Informix.

Transféré par

muzoxi
Copyright
© Attribution Non-Commercial (BY-NC)
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF ou lisez en ligne sur Scribd
100% ont trouvé ce document utile (6 votes)
10K vues34 pages

Trigger SQL

Ce document décrit les triggers SQL, y compris les différents types de triggers, leurs utilisations et les différences entre les standards SQL et les implémentations d'Oracle et d'Informix.

Transféré par

muzoxi
Copyright
© Attribution Non-Commercial (BY-NC)
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF ou lisez en ligne sur Scribd
Vous êtes sur la page 1/ 34

KWWSZZZDGHOHLPDJIUaGRQVH]FRXUV

/HV7ULJJHUV64/

Didier DONSEZ
Université Joseph Fourier
IMA –IMAG/LSR/ADELE
'LGLHU'RQVH]#LPDJIU
'LGLHU'RQVH]#LHHHRUJ

1

2

Sommaire

■ Motivations
■ Trigger Ordre
■ Trigger Ligne
■ Condition
■ Trigger INSTEAD OF
■ Limitations
■ Différences entre SQL3, Oracle et Informix
'LGLHU'RQVH]7ULJJHUV64/

3

Principe
■ Base de Données Active
• réagit aux changements d ’état de la base de données

■ Déclencheur = Evénement-Condition-Action
• Evénement dans la base
• Condition
• Déclenchement d ’une action
'LGLHU'RQVH]7ULJJHUV64/

■ Trigger SQL
• Evénement
= INSERT, DELETE, UPDATE dans une relation
• Action = un ou plusieurs ordres SQL, SQL procédural

4

Motivations

■ Séparation des préoccupations


• AOP (Aspect Oriented Programming)
■ Pourquoi faire ?
• valider les données entrées
• créer un audit de la base de données
• dériver des données additionnelles
• maintenir des règles d ’intégrité complexes
• implanter des règles de métier (par l’administrateur)
• supporter des alertes (envoi de e-mails par exemple)
• faire évoluer l’application
'LGLHU'RQVH]7ULJJHUV64/

■ Gains
• développement plus rapide
• les triggers sont stockées dans la base
• maintien global des règles d ’ intégrité

5

Différents triggers SQL

TRIGGER

ORDRE LIGNE (FOR EACH ROW)

BEFORE AFTER BEFORE AFTER INSTEAD OF

INSERT INSERT INSERT INSERT INSERT


'LGLHU'RQVH]7ULJJHUV64/

UPDATE UPDATE UPDATE UPDATE UPDATE

DELETE DELETE DELETE DELETE DELETE



6
SQL3
Remarques Informix9.1
Oracle8.1

■ Différence entre produits et standards


• SQL3 (n ’ est pas dans SQL2)
• Oracle
• Informix
■ Différent des contraintes et des assertions SQL2
• l’ événement est programmable
• Pas de condition dans les CHECK.
'LGLHU'RQVH]7ULJJHUV64/

7
SQL3
Trigger Ordre Informix9.1
Oracle8.1

CREATE TRIGGER nom_du_trigger


type_interposition type_ordre
ON nom_de_la_table
action
• l ’ action est exécutée une seule fois
avant (type_interposition=BEFORE) ou après (=AFTER)
l ’ exécution d ’ un ordre
sur la relation nom_de_la_table
'LGLHU'RQVH]7ULJJHUV64/

• le type de l ’ ordre type_ordre peut être


INSERT, UPDATE, DELETE,
type_ordre OR type_ordre,
UPDATE OF liste_de_colonnes

8
SQL3
Action Informix9.1
Oracle8.1

• Différences entre
■ SQL3
• 1 ou plusieurs SQL/DML et SQL/PSM
■ Informix 9
• 1 seul ordre SQL
INSERT, UPDATE, DELETE
• 1 seul appel de procédure ou fonction
EXEC PROCEDURE, EXEC FUNCTION
'LGLHU'RQVH]7ULJJHUV64/

■ Oracle 8
• 1 procédure anonyme PL/SQL
DECLARE … BEGIN … EXCEPTION … END;

9

Exemple de Trigger Ordre


Oracle8.1

Vente(gencod, qte, prix) VolumeAffaire(total,date)

CREATE TRIGGER tg_modifVolume AFTER INSERT ON Vente


DECLARE s number;
BEGIN
select sum(prix*qte) into s from Vente;
insert into VolumeAffaire value(s,current);
END;
'LGLHU'RQVH]7ULJJHUV64/

CREATE TRIGGERtg_modifInterdit
AFTER UPDATE OF prix, qte ON Vente
BEGIN raise_application_error(-9998, ’Modification interdite ’); END;

10
SQL3
Trigger Ligne (FOR EACH ROW) Informix9.1
Oracle8.1

CREATE TRIGGER nom_du_trigger


type_interposition type_ordre
ON nom_de_la_table
FOR EACH ROW
action

• l ’ action est exécutée


avant (type_interposition=BEFORE) ou après (=AFTER)
l ’ opération réalisée sur chaque ligne
'LGLHU'RQVH]7ULJJHUV64/

de la relation nom_de_la_table

11
SQL3
Variables de Transition des Triggers Ligne Informix9.1
Oracle8.1

• l ’ action du trigger ligne peut utiliser deux variables de


transition (old et new) contenant les valeurs de la ligne avant et
après l ’ événement

Oracle8.1
• Variables implicites dans Oracle
ROG et QHZ
SQL3 • Déclaration explicite dans Informix et SQL3
5()(5(1&,1*2/'$6 variable_avant 1(:$6 variable_apres
Informix9.1
'LGLHU'RQVH]7ULJJHUV64/

■ Remarque
• la variable avant n’ a pas de sens dans un INSERT
• la variable après n’ a pas de sens dans un DELETE

12

Exemple de Trigger Ligne


Oracle8.1

Vente(gencod, qte, prix) Stock(gencod, qte)

CREATE TRIGGER tg_nouvVente AFTER INSERT ON Vente


FOR EACH ROW
BEGIN
if :new.qte > (select qte fromStock where gencod = :new.gencod)
then raise_application_error(-9997, ‘ Stock insuffisant ’);
else update Stock set qte := Stock.qte - :new.qte
'LGLHU'RQVH]7ULJJHUV64/

where gencod = :new.gencod;


END;

13

Exemple de Trigger Ligne


Oracle8.1

Commande(gencod, qte, prix)

CREATE TRIGGERtg_nouvCmd AFTER UPDATE ON Commande


FOR EACH ROW
BEGIN
if :new.qte < :old.qte
then raise_application_error(-9996,
‘ Impossible de diminuer la commande ’);
'LGLHU'RQVH]7ULJJHUV64/

else ...
END;

14
SQL3
Condition de déclenchement WHEN Informix9.1
Oracle8.1

CREATE TRIGGER nom_du_trigger


type_interposition type_ordre
ON nom_de_la_table
FOR EACH ROW
:+(1 DWWULEXWFRQGLWLRQB64/YDOHXU
action
• l ’ attribut est une colonne de la ligne avant (:old.FRORQQH) ou
après (:new.FRORQQH) l ’ événement
'LGLHU'RQVH]7ULJJHUV64/

• la condition est une condition SQL


=,!=, >, <, IN, BETWEEN
• la valeur ne peut être le résultat d ’ un ordre SELECT

15
Exemple de Condition sur le
déclenchement d ’un trigger Oracle8.1

Commande(gencod, typeprod, qte, prix)

CREATE TRIGGERtg_nouvCmd AFTER UPDATE ON Commande


FOR EACH ROW
WHEN (new.qte < old.qte AND new.typeprod IN (‘Viande’, ‘Poisson’))
BEGIN
raise_application_error(-9996,
‘ Impossible de diminuer la commande pour ce type de produit’);
'LGLHU'RQVH]7ULJJHUV64/

END;

16

Limite de la clause WHEN


Oracle8.1

Commande(gencod, qte, prix) Produit(gencod, descr, typeprod)

CREATE TRIGGERtg_nouvCmd AFTER UPDATE ON Commande


FOR EACH ROW
WHEN (QHZJHQFRG ,1
VHOHFW JHQFRGIURP 3URGXLW ZKHUHW\SHSURG LQ µ9LDQGH ¶µ 3RLVVRQ¶
)
BEGIN
raise_application_error(-9995,
'LGLHU'RQVH]7ULJJHUV64/

‘Impossible de diminuer la commande pour ce type de produit’);


END;
-- NE FONCTIONNE PAS

17

Traitements différenciés
Oracle8.1

• les prédicats INSERTING, UPDATING, DELETING sont


utilisables en PL/SQL pour différencier le type de l ’ ordre qui
a déclenché le trigger.
CREATE TRIGGERtg_modifCmd
AFTER UPDATE OR DELETE ON Commande FOR EACH ROW
BEGIN
if DELETING
then raise_application_error(-9995,
‘Impossible d ’ ’annuler la commande’);
'LGLHU'RQVH]7ULJJHUV64/

else if UPDATING and :new.qte < :old.qte


then raise_application_error(-9996,
‘Impossible de diminuer la commande’);
END;

18

Limitations

■ Pas d ’ordre (statement) dans l ’action


• de transaction COMMIT, ROLLBACK, SAVEPOINT
• de connection ou de session
• mais l ’ action peut lever une exception
• raise_application_error
■ Attention aux tables en mutation
'LGLHU'RQVH]7ULJJHUV64/

19
SQL3
Action sur une table en mutation Informix9.1
Oracle8.1

Produit(gencod, descr, typeprod)

CREATE TRIGGER tg_prod


BEFORE INSERT OR UPDATE OR DELETE ON Produit
FOR EACH ROW DECLARE n integer
BEGIN
select gencod into n fromProduit where typeprod=‘Viande ’; ...
END;
• Suppresion
'LGLHU'RQVH]7ULJJHUV64/

DELETE FROM Produit; (5525«WDEOH'(023URGXLWLVPXWDWLQJ


• Insertion
INSERT INTO Produit VALUES(8736, ‘Lentilles’, ‘Epicerie’); 2.

20
Action sur une table en mutation SQL3
Informix9.1
SELECT autorisé Oracle8.1

TRIGGER

ORDRE LIGNE (FOR EACH ROW)

BEFORE AFTER BEFORE AFTER INSTEAD OF

INSERT INSERT INSERT INSERT INSERT


'LGLHU'RQVH]7ULJJHUV64/

UPDATE UPDATE UPDATE UPDATE UPDATE

DELETE DELETE DELETE DELETE DELETE

pas de SELECT
sur la table en mutation

21
SQL3
Trigger INSTEAD OF
Oracle8.1

CREATE TRIGGER nom_du_trigger


,167($'2) type_ordre
ON nom_de_la_table
FOR EACH ROW
action
• La modification sur la WDEOH (ou sur la YXH
est remplacée par l ’ action
• les variables :old et :new sont utilisées dans l ’ action
comme si l ’ événement avait lieu
'LGLHU'RQVH]7ULJJHUV64/

■ Usage
• permet les modifications sur une vue
• par exemple une vue Objet Relationnelle
d ’ une base Relationnelle

22

Exemple de Trigger INSTEAD OF (i)


Oracle8.1

■ Base relationnelle
create table Pers( numss number, nom varchar2(10), prenomvarchar2(10));
create table Tel(numss number, numtel varchar2(10));

■ Vue Objet
create type listtel_t AS as varray(10) of varchar2(10);
create type ovPers_t as object ( numss number, nom varchar2(10), prenomvarchar2(10),
listtel listtel_t);
FUHDWHYLHZ ovPers RI ovPers_t with objectoid(numss) as
'LGLHU'RQVH]7ULJJHUV64/

select numss, nom, prenom, cast( multiset(


select numtel from Tel t where t.numss=p.numss) as listtel_t)
fromPers p;

23

Exemple de Trigger INSTEAD OF (ii)


Oracle8.1

■ Trigger INSTEAD OF
FUHDWH WULJJHU tg_ins_ovPers LQVWHDG RILQVHUWRQ ovPers
IRUHDFK URZdeclare i: integer;
begin
insert into Pers values(:new.numss, :new.nom, :new.prenom);
if :new.listtel is not null and :new.listtel.count > O then
for i in :new.listtel.first … :new.listtel.last loop
insert into Tel values (:new.numss, :new.listtel(i));
'LGLHU'RQVH]7ULJJHUV64/

end loop;
end if; end;
> insert into ovPers values ( 1390120989, ‘Dupont ’, ‘Jean ’,
listtel_t( ‘0327141234 ’, ‘0320445962 ’ ) );

24
SQL3
Gestion des Triggers Informix9.1
Oracle8.1

• CREATE TRIGGER nom_trigger ...


• le trigger nom_trigger est crée et activé.
• CREATE OR REPLACE TRIGGER nom_trigger ...
• le trigger nom_trigger est modifié.
• DROP TRIGGER nom_trigger
• le trigger nom_trigger est supprimé de la base.
• ALTER TRIGGER nom_trigger DISABLE
• le trigger nom_trigger est déactivé.
• ALTER TRIGGER nom_trigger ENABLE
'LGLHU'RQVH]7ULJJHUV64/

• le trigger nom_trigger est réactivé.

CREATE TRIGGER incendie_entrepot AFTER INSERT ON Vente


BEGIN raise_application_error(-9999, « Vente impossible »); END;
ALTER TRIGGER incendie_entrepot DISABLE;

25

Trigger dans Informix (i) Informix9.1

■ l’Action
• 1 seul ordre SQL
INSERT, UPDATE, DELETE,
EXEC PROCEDURE, EXEC FUNCTION
• MAIS il peut y avoir 1 ordre avant et 1 ordre après

CREATE TRIGGER tg_modif_stock


UPDATE OF qte ON Stock
%()25((EXECUTE PROCEDURE procavantmodif())
'LGLHU'RQVH]7ULJJHUV64/

$)7(5(EXECUTE PROCEDURE procavantmodif());



26

Trigger d ’Informix (ii) Informix9.1

■ Variables de transition
Cmd(numprod, qte, prixtotal)
Stock(numprod, prixunit, qte)

CREATE TRIGGERtg_modif_cmd UPDATE OF Cmd ON qte


REFERENCING OLD AS pre NEW AS post
FOR EACH ROW (
UPDATE Stock
'LGLHU'RQVH]7ULJJHUV64/

SET qte=Stock.qte -(post.qte-pre.qte)


WHERE numprod=pre.numprod
);

27

Trigger d ’Informix (iii) Informix9.1

■ Fonctions d ’un trigger


&PG QXPSURG TWH SUL[WRWDO

CREATE TRIGGERtg_modif_cmd UPDATE OF Cmd ON qte


REFERENCING OLD AS pre NEW AS post
FOR EACH ROW (
(;(&87()81&7,21 fnouveauprixtotal( pre.qte, post.qte, pre.prixtotal)
,172SUL[WRWDO) )
CREATE FUNCTION fnouveauprixtotal( oldqte INT, newqte INT, total MONEY(8))
RETURNING MONEY(8);
'LGLHU'RQVH]7ULJJHUV64/

DEFINE u_price LIKE Cmd. prixtotal;


DEFINE n_total LIKE Cmd. prixtotal;
LET u_price = total / oldqte ;
LET n_total = newqte * u_price;
RETURN n_total;
END FUNCTION;

28

Interactions

■ Cascade de triggers
• l ’ action d ’ un trigger peut déclencher d ’ autres triggers
■ Interactions avec les contraintes
• l ’ action d ’ un trigger peut causer la vérification des
contraintes
• les actions des constraintes référencielles peuvent déclencher
des triggers
• les triggers DELETE sont déclenchés par
'LGLHU'RQVH]7ULJJHUV64/

ON DELETE CASCADE
• les triggers UPDATE sont déclenchés par
ON DELETE SET NULL|DEFAULT, ON UPDATE CASCADE, ON
UPDATE SET NULL|DEFAULT

29

Ordonnancement de triggers multiples

■ Plusieurs triggers peuvent être définis


pour le même événement
• La date de création d ’ un trigger est conservée dans la base
• Les triggers sont activés dans l ’ ordre ascendant de leur date
de création

■ Remarque pour Oracle


• Un seul trigger sur la même table avec les mêmes événements
'LGLHU'RQVH]7ULJJHUV64/

de déclenchement.
• Oracle est un produit, SQL3 du papier

30

Modèle SQL3 de traitement des Triggers


'LGLHU'RQVH]7ULJJHUV64/

31

Triggers et Vue Object-Relationnelle

■ Voir le cours « Les objets dans SQL 3 »


'LGLHU'RQVH]7ULJJHUV64/

32

Conclusion

■ SGBD Actif
■ Contrôle dynamique et évolutif des manipulations
dans la base
■ Duplication contrôle d ’information
■ Etendre les mécanismes de contrôle d ’intégrité
• palier aux limites des contraintes
'LGLHU'RQVH]7ULJJHUV64/

33

Bibliographie

■ Nelson Mattos, "An Overview of the SQL3 Standard", presentation


foils, Database Technology Institute, IBM Santa Teresa Lab., San
Jose, CA, July 1996, ftp://jerry.ece.umassd.edu
/isowg3/dbl/BASEdocs/descriptions/SQL3_foils.ps
■ Scott Urman , « Oracle8 PL/SQL Programming », ed Osborne-
McGraw-Hill, Oracle Press Series, ISBN 0-07-882305-6.
■ " Using Oracle8™ Object Views: An Example, An Oracle Technical
White Paper, October 1997,
'LGLHU'RQVH]7ULJJHUV64/

http://www.oracle.com/st/o8collateral/html/objview2.html
■ Steven Feuerstein, « Oracle PL/SQL Programming »,2nd Edition, ed
O'
Reilly. ISBN 1-56592-335-9.

34

Exercices
Oracle8.1

■ Soit la base
Vente(gencod, qte, prix) VolumeAffaire(total,date)

■ Donner un trigger ligne qui modifie le Volume d ’Affaire en cas


d ’insertion, de modification et du suppression dans Vente.
• Version 1 : VolumeAffaire ne contient qu ’une ligne qui sera
modifiée
• Version 2 : VolumeAffaire contient une ligne par mise à jour dans
'LGLHU'RQVH]7ULJJHUV64/

Vente
• Version 3 : VolumeAffaire contient une ligne par journée de Vente

Vous aimerez peut-être aussi