Vous êtes sur la page 1sur 8

Objectifs

A la fin de ce chapitre, vous pourrez :


dcrire les diffrents types de dclencheur
dcrire les dclencheurs de base de donnes et
leur utilisation
crer des dclencheurs de base de donnes
dcrire les rgles d'activation des dclencheurs
de base de donnes
supprimer des dclencheurs de base de donnes

10

Crer des dclencheurs

Copyright 2004, Oracle. Tous droits rservs.

Types de dclencheur
Un dclencheur :
est une procdure ou un bloc PL/SQL associ la base
de donnes, une table, une vue ou un schma
s'excute de faon implicite lorsqu'un vnement
particulier se produit
peut prsenter deux types diffrents :
Dclencheur applicatif : s'excute lorsqu'un vnement
se produit dans une application donne
Dclencheur de base de donnes : s'excute lorsqu'un
vnement de type donnes (par exemple une opration
LMD) ou systme (par exemple une connexion ou un
arrt) se produit dans un schma ou une base de
donnes

10-3

Copyright 2004, Oracle. Tous droits rservs.

10-2

Copyright 2004, Oracle. Tous droits rservs.

Rgles relatives la conception de dclencheurs

Vous pouvez crer des dclencheurs pour :


excuter des actions associes
centraliser des oprations globales

Vous ne devez pas crer de dclencheurs :


lorsque la fonctionnalit est dj intgre au serveur
Oracle
lorsqu'ils constituent des doublons d'autres dclencheurs

10-4

Si le code PL/SQL est trs long, vous pouvez crer des


procdures stockes et les appeler dans un dclencheur.
L'utilisation excessive de dclencheurs peut entraner
des interdpendances complexes dont la gestion peut
s'avrer difficile dans les applications volumineuses.

Copyright 2004, Oracle. Tous droits rservs.

Crer des dclencheurs LMD


Crez des dclencheurs LMD sur instruction ou
sur ligne via :
CREATE [OR REPLACE] TRIGGER trigger_name
timing
event1 [OR event2 OR event3]
ON object_name
[[REFERENCING OLD AS old | NEW AS new]
FOR EACH ROW
[WHEN (condition)]]
trigger_body

Un dclencheur sur instruction s'excute une fois


pour une instruction LMD.
Un dclencheur sur ligne s'excute une fois pour
chaque ligne affecte.
Remarque : Les noms des dclencheurs doivent tre
uniques au sein d'un mme schma.
10-5

Copyright 2004, Oracle. Tous droits rservs.

Types de dclencheur LMD


Le type de dclencheur dtermine si le corps s'excute
pour chaque ligne ou une seule fois pour l'instruction de
dclenchement.
Un dclencheur sur instruction :
s'excute une fois pour l'vnement dclencheur
est le type de dclencheur par dfaut
s'excute une fois mme si aucune ligne n'est affecte

s'excute une fois pour chaque ligne affecte par


l'vnement dclencheur
n'est pas excut si l'vnement dclencheur n'affecte
aucune ligne
est dfini l'aide de la clause FOR EACH ROW

10-6

Moment du dclenchement
Quand le dclencheur doit-il s'excuter ?
BEFORE : excution du corps du dclencheur avant le
dclenchement de l'vnement LMD sur une table.
AFTER : excution du corps du dclencheur aprs le
dclenchement de l'vnement LMD sur une table.
INSTEAD OF : excution du corps du dclencheur au
lieu de l'instruction de dclenchement. Ce
dclencheur est utilis pour les vues qui ne peuvent
pas tre modifies autrement.
Remarque : Si plusieurs dclencheurs sont dfinis pour
le mme objet, l'ordre d'excution des dclencheurs est
arbitraire.

10-7

Copyright 2004, Oracle. Tous droits rservs.

Un dclencheur sur ligne :

Copyright 2004, Oracle. Tous droits rservs.

Squence d'excution des dclencheurs


Lorsque la manipulation concerne une seule ligne, utilisez la
squence d'excution suivante pour un dclencheur sur une
table :
Instruction LMD
INSERT INTO departments
(department_id,department_name, location_id)
VALUES (400, 'CONSULTING', 2400);
Action de dclenchement

10-8

Dclencheur sur
instruction BEFORE

Dclencheur sur ligne BEFORE


Dclencheur sur ligne AFTER
Dclencheur sur instruction AFTER
Copyright 2004, Oracle. Tous droits rservs.

Squence d'excution des dclencheurs


Lorsque la manipulation concerne plusieurs lignes,
utilisez la squence d'excution suivante pour un
dclencheur sur une table :
UPDATE employees
SET salary = salary * 1.1
WHERE department_id = 30;

Types d'vnement dclencheur et corps

Un vnement dclencheur :
dtermine l'instruction LMD qui provoque
l'excution du dclencheur
Les types sont les suivants :
INSERT
UPDATE [OF column]
DELETE

Dclencheur sur instruction BEFORE


Dclencheur sur ligne BEFORE
Dclencheur sur ligne AFTER

...

Dclencheur sur ligne BEFORE


Dclencheur sur ligne AFTER
...

Le corps d'un dclencheur :


dtermine l'action excute
est un bloc PL/SQL ou un appel (CALL) d'une
procdure

Dclencheur sur instruction AFTER


10-9

10-10

Copyright 2004, Oracle. Tous droits rservs.

Copyright 2004, Oracle. Tous droits rservs.

Tester SECURE_EMP

Crer un dclencheur sur instruction LMD

Application
INSERT INTO employees (employee_id, last_name,
first_name, email, hire_date,
job_id, salary, department_id)
VALUES (300, 'Smith', 'Rob', 'RSMITH', SYSDATE,
'IT_PROG', 4500, 60);

Table EMPLOYEES
INSERT INTO EMPLOYEES...;

Dclencheur SECURE_EMP
CREATE OR REPLACE TRIGGER secure_emp
BEFORE INSERT ON employees BEGIN
IF (TO_CHAR(SYSDATE,'DY') IN ('SAT','SUN')) OR
(TO_CHAR(SYSDATE,'HH24:MI')
NOT BETWEEN '08:00' AND '18:00') THEN
RAISE_APPLICATION_ERROR(-20500, 'You may insert'
||' into EMPLOYEES table only during '
||' business hours.');
END IF;
END;
10-11

Copyright 2004, Oracle. Tous droits rservs.

10-12

Copyright 2004, Oracle. Tous droits rservs.

Utiliser des prdicats conditionnels

Crer un dclencheur sur ligne LMD

CREATE OR REPLACE TRIGGER secure_emp BEFORE


INSERT OR UPDATE OR DELETE ON employees BEGIN
IF (TO_CHAR(SYSDATE,'DY') IN ('SAT','SUN')) OR
(TO_CHAR(SYSDATE,'HH24')
NOT BETWEEN '08' AND '18') THEN
IF DELETING THEN RAISE_APPLICATION_ERROR(
-20502,'You may delete from EMPLOYEES table'||
'only during business hours.');
ELSIF INSERTING THEN RAISE_APPLICATION_ERROR(
-20500,'You may insert into EMPLOYEES table'||
'only during business hours.');
ELSIF UPDATING('SALARY') THEN
RAISE_APPLICATION_ERROR(-20503, 'You may '||
'update SALARY only during business hours.');
ELSE RAISE_APPLICATION_ERROR(-20504,'You may'||
' update EMPLOYEES table only during'||
' normal hours.');
END IF;
END IF;
END;
10-13

Copyright 2004, Oracle. Tous droits rservs.

CREATE OR REPLACE TRIGGER restrict_salary


BEFORE INSERT OR UPDATE OF salary ON employees
FOR EACH ROW
BEGIN
IF NOT (:NEW.job_id IN ('AD_PRES', 'AD_VP'))
AND :NEW.salary > 15000 THEN
RAISE_APPLICATION_ERROR (-20202,
'Employee cannot earn more than $15,000.');
END IF;
END;
/

10-14

Utiliser les qualificatifs OLD et NEW

Utiliser les qualificatifs OLD et NEW :


exemple de la table audit_emp
INSERT INTO employees
(employee_id, last_name, job_id, salary, ...)
VALUES (999, 'Temp emp', 'SA_REP', 6000,...);

CREATE OR REPLACE TRIGGER audit_emp_values


AFTER DELETE OR INSERT OR UPDATE ON employees
FOR EACH ROW
BEGIN
INSERT INTO audit_emp(user_name, time_stamp, id,
old_last_name, new_last_name, old_title,
new_title, old_salary, new_salary)
VALUES (USER, SYSDATE, :OLD.employee_id,
:OLD.last_name, :NEW.last_name, :OLD.job_id,
:NEW.job_id, :OLD.salary, :NEW.salary);
END;
/

10-15

Copyright 2004, Oracle. Tous droits rservs.

Copyright 2004, Oracle. Tous droits rservs.

UPDATE employees
SET salary = 7000, last_name = 'Smith'
WHERE employee_id = 999;
SELECT user_name, timestamp, ...
FROM audit_emp;

10-16

Copyright 2004, Oracle. Tous droits rservs.

Restreindre l'action d'un dclencheur


sur ligne : exemple
CREATE OR REPLACE TRIGGER derive_commission_pct
BEFORE INSERT OR UPDATE OF salary ON employees
FOR EACH ROW
WHEN (NEW.job_id = 'SA_REP')
BEGIN
IF INSERTING THEN
:NEW.commission_pct := 0;
ELSIF :OLD.commission_pct IS NULL THEN
:NEW.commission_pct := 0;
ELSE
:NEW.commission_pct := :OLD.commission_pct+0.05;
END IF;
END;
/

10-17

Copyright 2004, Oracle. Tous droits rservs.

Rcapitulatif du modle d'excution


des dclencheurs
1. Excuter tous les dclencheurs BEFORE
STATEMENT
2. Effectuer une boucle pour chaque ligne affecte :
a. Excuter tous les dclencheurs BEFORE ROW
b. Excuter l'instruction LMD et vrifier les contraintes
d'intgrit
c. Excuter tous les dclencheurs AFTER ROW

3. Excuter tous les dclencheurs AFTER STATEMENT


Remarque : La vrification d'intgrit peut tre diffre
jusqu' l'excution de l'opration COMMIT.

10-18

Dclencheurs INSTEAD OF

Implmenter une contrainte d'intgrit


avec un dclencheur
UPDATE employees SET department_id = 999
WHERE employee_id = 170;
-- Integrity constraint violation error

Application
INSERT INTO my_view
. . .;

CREATE OR REPLACE TRIGGER employee_dept_fk_trg


AFTER UPDATE OF department_id
ON employees FOR EACH ROW
BEGIN
INSERT INTO departments VALUES(:new.department_id,
'Dept '||:new.department_id, NULL, NULL);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
NULL; -- mask exception if department exists
END;
/

Dclencheur
INSTEAD OF

MY_VIEW

UPDATE employees SET department_id = 999


WHERE employee_id = 170;
-- Successful after trigger is fired
10-19

Copyright 2004, Oracle. Tous droits rservs.

Copyright 2004, Oracle. Tous droits rservs.

10-20

INSERT
TABLE1

UPDATE
TABLE2

Copyright 2004, Oracle. Tous droits rservs.

Crer un dclencheur INSTEAD OF


Excutez l'instruction INSERT dans la vue
EMP_DETAILS base sur les tables EMPLOYEES et
DEPARTMENTS :

Crer un dclencheur INSTEAD OF


Utilisez INSTEAD OF pour effectuer des oprations
LMD sur des vues complexes :
CREATE TABLE new_emps AS
SELECT employee_id,last_name,salary,department_id
FROM employees;

INSERT INTO emp_details


VALUES (9001,'ABBOTT',3000, 10, 'Administration');
1

2 INSERT dans NEW_EMPS

10-21

CREATE TABLE new_depts AS


SELECT d.department_id,d.department_name,
sum(e.salary) dept_sal
FROM employees e, departments d
WHERE e.department_id = d.department_id;

Opration INSERT
d'un dclencheur
INSTEAD OF dans
EMP_DETAILS
3 UPDATE NEW_DEPTS

CREATE VIEW emp_details AS


SELECT e.employee_id, e.last_name, e.salary,
e.department_id, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id
GROUP BY d.department_id,d.department_name;

Copyright 2004, Oracle. Tous droits rservs.

10-22

Copyright 2004, Oracle. Tous droits rservs.

Comparaison des dclencheurs de base


de donnes et des procdures stockes
CREATE OR REPLACE TRIGGER new_emp_dept
INSTEAD OF INSERT OR UPDATE OR DELETE ON
emp_details
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO new_emps
VALUES (:NEW.employee_id,
:NEW.last_name,
:NEW.salary,
:NEW.department_id);
UPDATE new_depts
SET dept_sal = dept_sal +
:NEW.salary
.

10-23

Copyright 2004, Oracle. Tous droits rservs.

Dclencheurs

Procdures

Dfinis via la commande CREATE Dfinies via la commande


TRIGGER.
CREATE PROCEDURE.
Le dictionnaire de donnes
contient le code source dans
USER_TRIGGERS.

Le dictionnaire de donnes
contient le code source dans
USER_SOURCE.

Appels implicitement par les


oprations LMD.

Appel explicite.

Les instructions COMMIT,


Les instructions COMMIT,
SAVEPOINT et ROLLBACK ne sont SAVEPOINT et ROLLBACK sont
pas autorises.
autorises.

10-24

Copyright 2004, Oracle. Tous droits rservs.

Comparaison des dclencheurs de base


de donnes et des triggers Oracle Forms

Grer les dclencheurs

INSERT INTO EMPLOYEES


. . .;

ALTER TRIGGER trigger_name DISABLE | ENABLE

Dclencheur CHECK_SAL

Table EMPLOYEES

Dsactiver ou ractiver un dclencheur de base


de donnes :

Dsactiver ou ractiver tous les dclencheurs


d'une table :
ALTER TABLE table_name DISABLE | ENABLE
ALL TRIGGERS

ligne
BEFORE
INSERT

10-25

Copyright 2004, Oracle. Tous droits rservs.

ALTER TRIGGER trigger_name COMPILE

10-26

Copyright 2004, Oracle. Tous droits rservs.

Supprimer des dclencheurs

Tester les dclencheurs

Pour supprimer un dclencheur de la base de


donnes, utilisez l'instruction DROP TRIGGER :

DROP TRIGGER trigger_name;

Exemple :
DROP TRIGGER secure_emp;

Remarque : Lorsqu'une table est supprime, tous ses


dclencheurs sont galement supprims.

10-27

Copyright 2004, Oracle. Tous droits rservs.

Recompiler un dclencheur pour une table :

10-28

Testez toutes les oprations sur les donnes qui


provoquent un dclenchement, ainsi que celles
qui n'en produisent pas.
Testez chaque cas de la clause WHEN.
Provoquez une excution directe du dclencheur
via une opration de base sur les donnes, et une
excution indirecte via une procdure.
Testez l'effet du dclencheur sur les autres
dclencheurs.
Testez l'effet des autres dclencheurs sur le
dclencheur.

Copyright 2004, Oracle. Tous droits rservs.

Synthse

Prsentation de l'exercice 10

Ce chapitre vous a permis d'apprendre :


crer des dclencheurs de base de donnes
appels par des oprations LMD
crer des dclencheurs sur instruction et sur ligne
utiliser les rgles d'activation des dclencheurs de
base de donnes
activer, dsactiver et grer les dclencheurs de
base de donnes
dvelopper une stratgie de test des dclencheurs
supprimer des dclencheurs de base de donnes

Cet exercice porte sur les points suivants :


Crer des dclencheurs sur ligne
Crer un dclencheur sur instruction
Appeler des procdures partir d'un dclencheur

10-29

Copyright 2004, Oracle. Tous droits rservs.

10-30

Copyright 2004, Oracle. Tous droits rservs.

Vous aimerez peut-être aussi