Les déclencheurs (Triggers) avec Oracle

Transcription

Les déclencheurs (Triggers) avec Oracle
Les déclencheurs (Triggers)
avec Oracle
1) Introduction
2) Événements déclenchant
3) Mécanisme général
4) Privilèges systèmes
5) Syntaxe
6) Nom du déclencheur
7) Option BEFORE ou AFTER
8) Déclencheur LMD
9) Déclencheur LDD
10) Déclencheur d'instance
11) Gestion des déclencheurs
12) Nouveautés 11g
E.Porcq : Cours BDD
IUT CAEN : Département Informatique
Année universitaire 2013-2014
Sources :
SQL Pour Oracle 3è édition de Christian Soutou
Les triggers d’Oracle de J. Akoka & I. Wattiau
http://sheikyerbouti.developpez.com/pl_sql/?page=Chap6
Les déclencheurs (Triggers)
avec Oracle
1) Introduction
Les déclencheurs (triggers) sont des programmes associés à des objets dont
l'exécution est lancée automatiquement (déclenchée) lors d'une mise à jour ceuxci.
Ils se programment en PL/SQL; on peut aussi utiliser les langages C, C++, Java
etc ... pour créer des déclencheurs.
Ils permettent de
Programmer des règles de gestion qui n'ont pu être mises en places par des
contraintes au niveau des tables (contraintes multitables ...)
Déporter des contraintes au niveau serveur pour alléger le client
Programmer l'intégrité référentielle et la réplication dans les architectures
distribuées avec l'utilisation de liens de données (database links).
Les déclencheurs
existent depuis la version 6 d'Oracle.
sont compilables depuis la version 7.3
Permettent la mise à jour de vues multitables depuis la version 8 (instead of)
Les déclencheurs (Triggers)
avec Oracle
2) Événements déclenchant
Les événements déclencheurs peuvent être
Une instruction insert, update ou delete sur une table ou une vue.
On parle de déclencheurs LMD
Une instruction create, alter ou drop sur un objet (table, index,
séquence, etc...) On parle de déclencheurs LDD
Le démarrage ou l'arrêt de la base (startup ou shutdown), une erreur
spécifique (no_data_found, dup_val_on_index, etc...), une connexion
ou une déconnexion d'un utilisateur. On parle de déclencheurs
d'instances
Les déclencheurs (Triggers)
avec Oracle
3) Mécanisme général
Une fois codé puis compilé, le déclencheur est stocké dans la base
En cas d'événement approprié, si le déclencheur est actif, il s'exécute
Le bloc PL/SQL qui constitue le trigger peut être exécuté avant ou après
la vérification des contraintes d'intégrité
Il peut être exécuté pour chaque ligne affectée par l'ordre LMD ou bien
une seule fois pour la commande
Un déclencheur s'exécute dans le cadre d'une transaction. Il ne peut
donc pas contenir d'instruction commit ou rollback ou toute instruction
générant une fin de transaction implicite (ordre LDD)
Les déclencheurs (Triggers)
avec Oracle
4) Privilèges systèmes
Pour créer des déclencheurs, il faut disposer des privilèges systèmes
CREATE TRIGGER (présent avec le rôle RESOURCE)
CREATE ANY TRIGGER (pour ceux des autres schémas)
ADMINISTER DATABSE TRIGGER (pour les déclencheurs d'instances)
5) Syntaxe
La syntaxe de création du déclencheur commence par :
●
CREATE [OR REPLACE] TRIGGER [<schéma>].<nom du déclencheur>
Les déclencheurs (Triggers)
avec Oracle
6) Nom du déclencheur
doit être unique dans un même schéma
peut être le nom d'un autre objet (table, vue, procédure) mais à éviter
Ex : CREATE TRIGGER trigInsertCoureur
7) Option before ou after
Elle précise le moment de l'exécution du déclencheur (avant ou après
l'opération).
Les triggers after sont plus efficaces que les before parce qu'ils ne
nécessitent pas une double lecture des données.
Avec l’option before, le déclencheur s’exécute avant une éventuelle contrainte
d’intégrité portant sur la même table et/ou colonne.
Avec l’option after, le déclencheur s’exécutera peut être après une éventuelle
contrainte d’intégrité portant sur la même table et/ou colonne.
Ex : CREATE TRIGGER trigInsertCoureur before insert ...
Les déclencheurs (Triggers)
avec Oracle
8) Déclencheur LMD
Ils sont lancés par une opération insert ou update ou delete
Le même déclencheur peut s'activer par les trois opérations
Pour update, on peut spécifier une liste de colonnes. Dans ce cas, le trigger
ne se déclenchera que si l'instruction update porte sur l'une au moins des
colonnes précisée dans la liste.
Ex : CREATE TRIGGER trigInsertCoureur before insert or
delete on tdf_coureur
8-1) Déclencheur global ou ligne
un déclencheur ligne (row trigger) est exécuté pour chaque ligne concernée
par l'opération LMD. On le distingue par la directive " for each row ".
un déclencheur global ou d'état (statement trigger) ou d'instruction ne
s'exécute qu'une fois par instruction LMD
Ex : CREATE TRIGGER trigInsertCoureur before insert or
update on tdf_coureur for each row
Les déclencheurs (Triggers)
avec Oracle
8-2) Déclencheur ligne
avec ce type de déclencheur, on peut avoir accès (suivant l'opération LMD) à
l'ancienne et/ou à la nouvelle donnée affectant la table.
pour un insert, toutes les colonnes de la ligne insérée sont accessibles.
Elles se nomment :new.<nom de la colonne>
pour un delete, toutes les colonnes de la ligne supprimée sont accessibles.
Elles se nomment :old.<nom de la colonne>
pour un update, toutes les colonnes de la ligne supprimée et insérées sont
accessibles. Elles se nomment :new.<nom de la colonne> :old.<nom de la
colonne>
il est possible de restreindre l'exécution du déclencheur avec la clause when.
Si l'expression when n'est pas vérifiée le déclencheur ne s'exécute pas.
Ex CREATE TRIGGER trigInsertCoureur before insert or update on
tdf_coureur for each row when (new.code_tdf = 'FRA')
La clause referencing peut permettre de renommer new et old
Ex CREATE TRIGGER trigInsertCoureur before insert or update on
tdf_coureur for each row referencing NEW as nouveau
Les déclencheurs (Triggers)
avec Oracle
8-2) Déclencheur ligne (suite)
Lorsque le même déclencheur peut être exécuté à partir d'opérations LMD
différentes, il est possible de tester dans le programme l'événement
déclencheur avec les prédicats inserting, updating[('<colonne>')],
deleting.
Exemple de déclencheur ligne
create or replace trigger SONDAGE_TRIG1
AFTER insert on SONDAGE
for each row
begin
dbms_output.put_line('début SONDAGE_TRIG1');
insert into sondage_copie values
(
:new.num,:new.date_naissance,
:new.reponse1, :new.reponse2,:new.val
);
dbms_output.put_line('fin SONDAGE_TRIG1');
end;
Les déclencheurs (Triggers)
avec Oracle
8-3) Table en mutation
Un déclencheur ligne ne peut pas modifier la table concernée (appelée aussi
table mutante) par l'instruction (insert, update ou delete) qui a déclenché
ce trigger
Il peut éventuellement lire la table dans le cas d'un déclenchement par un
insert de type before
8-4) Déclencheur d'état
Ils n'ont pas accès aux valeurs mises à jours (:new et :old) par l'opération
puisqu'ils se déclenchent une seule fois même si la requête LMD met à jour
plusieurs lignes.
Ils présentent l'avantage de pouvoir effectuer des manipulations sur la table
qui a déclenché le trigger.
Les déclencheurs (Triggers)
avec Oracle
8-5) Déclencheur Instead of
il permet de mettre à jour une vue multitable ce qui n'est pas toujours
possible avec une requête LMD standard. En effet la mise à jour n'est possible
dans une vue que
si une table est protégée par clé
si on effectue la mise à jour uniquement dans cette table
(voir exemple page suivante)
il utilise la clause for each row (implicite)
il n'utilise pas la les options before et after
il ne permet pas de préciser le nom d'une colonne pour un update
il ne permet pas non plus d'utiliser la clause when
Les déclencheurs (Triggers)
avec Oracle
8-5) Déclencheur Instead of (suite)
création d'une vue modifiable (v_article_fournisseur1)
drop view v_article_fournisseur1;
create view v_article_fournisseur1 as
select fo.fo_nom, ar.fo_numero,ar_numeroar_nom,ar_poids,ar_couleur,
ar_stock,ar_pa,ar_pv from cdi_article ar
join cdi_fournisseur fo on ar.fo_numero = fo.fo_numero;
drop view v_article_fournisseur2;
create view v_article_fournisseur2 as
select fo.fo_nom, fo.fo_numero,ar_numero,ar_nom,ar_poids,ar_couleur,
ar_stock,ar_pa,ar_pv from cdi_article ar
join cdi_fournisseur fo on ar.fo_numero = fo.fo_numero;
Les déclencheurs (Triggers)
avec Oracle
8-5) Déclencheur Instead of (suite)
insertion dans une vue modifiable (v_article_fournisseur1)
insert into v_article_fournisseur1 (fo_numero,ar_numero,
ar_nom,ar_poids,ar_couleur,ar_stock,ar_pa,ar_pv)
values ('F06','A85','GOMME','25','BLANC',20,1,2);
insert into v_article_fournisseur2 (fo_numero,ar_numero,
ar_nom,ar_poids,ar_couleur,ar_stock,ar_pa,ar_pv)
values ('F06','A86','GOMME','25','BLANC',20,1,2);
ORA-01779: impossible de modifier une colonne correspondant à une table non
protégée par clé
select * from user_updatable_columns where lower(table_name) like
'v_article_fournisseur%' and column_name like '%NUMERO%';
OWNER
CDI
CDI
CDI
CDI
TABLE_NAME
V_ARTICLE_FOURNISSEUR1
V_ARTICLE_FOURNISSEUR1
V_ARTICLE_FOURNISSEUR2
V_ARTICLE_FOURNISSEUR2
COLUMN_NAME
FO_NUMERO
AR_NUMERO
FO_NUMERO
AR_NUMERO
UPDATABLE
YES
YES
NO
YES
INSERTABLE
YES
YES
NO
YES
DELETABLE
YES
YES
NO
YES
Les déclencheurs (Triggers)
avec Oracle
8-5) Déclencheur Instead of (suite)
insertion dans une vue modifiable (v_article_fournisseur1)
create or replace trigger art_four_trig1 instead of insert on
v_article_fournisseur1
declare
vNbFour int := 0; vNbArt int := 0;
begin
select count(*) into vNbFour from cdi_fournisseur where fo_numero=:new.fo_numero;
select count(*) into vNbArt from cdi_article where ar_numero = :new.ar_numero;
if vnbart<>0 and vnbfour<>0 then
raise_application_error (-20001,'l''article et le fournisseur existent déjà');
elsif vnbart=0 then
insert into cdi_article (fo_numero,ar_numero,ar_nom,ar_poids,ar_couleur,
ar_stock,ar_pa,ar_pv) values (:new.fo_numero,:new.ar_numero,:new.ar_nom,
:new.ar_poids,:new.ar_couleur,:new.ar_stock,:new.ar_pa,:new.ar_pv);
else
insert into cdi_fournisseur (fo_numero,fo_nom) values (:new.fo_numero,null);
end if;
dbms_output.put_line('v_article_fournisseur1 terminé');
end;
Les déclencheurs (Triggers)
avec Oracle
9) Déclencheur LDD
Ils réagissent aux modifications de la structure de la base de données
Ils sont sensibles aux options before et after
la directive database précise que le déclencheur peut s'exécuter à partir d'un
événement provoqué par n'importe quel schéma
la directive schema précise que le déclencheur peut s'exécuter à partir d'un
événement provoqué par le schéma lui même
Les ordres LDD pouvant provoquer l'exécution du déclencheur sont : alter,
comment, create, drop, grant, rename, revoke
Ex :
create trigger majTDF before drop on iut123.schema
begin
if to_char(sysdate,'DAY') = 'DIMANCHE' then
raise_application_error
(-20001,'pas de destruction le dimanche') ;
end if ;
end ;
Les déclencheurs (Triggers)
avec Oracle
10) Déclencheur d'instance
Des événements systèmes peuvent provoquer le déclenchement d'un code
PL/SQL
Des événements comme logon, startup, serverrror, suspend
utilisent l'option after
Des événements comme LOGOFF, SHUTDOWN utilisent l'option before
Des événements comme AFTER STARUP et BEFORE SHUTDOWN s'appliquent
avec des déclencheurs de type DATABASE
Ex :
create or replace
trigger deconnexion before LOGOFF on DATABASE
begin
insert into trace values (user,sysdate);
end;
Les déclencheurs (Triggers)
avec Oracle
11) Gestion des déclencheurs
Voici la liste des opérations de gestion des déclencheurs
ALTER TRIGGER <nom du déclencheur> COMPILE
ALTER TRIGGER <nom du déclencheur> DISABLE
ALTER TRIGGER <nom du déclencheur> ENABLE
ALTER TRIGGER <nom table> ENABLE ALL TRIGGERS
DROP TRIGGER <nom du déclencheur>
12) Nouveautés 11g
Il est possible de créer des déclencheurs directement inactifs (disable)
Il est possible de choisir l'ordre d'exécution des déclencheurs d'un même
événement (utilisation de la directive follows)
Il est possible de créer des déclencheurs composés de plusieurs blocs
sensibles à des événements différents. Cela peut permettre de résoudre le
problème des tables mutantes.

Documents pareils