Les triggers

Plans d'exécution stockés

Aperçu des transactions autonomes

CBO : les plans d'exécution selon la volumétrie cible

Reprise de données : exemples simples

Clés primaires et étrangères : mettre en place ses contraintes d'intégrité

L'instruction MERGE ou l'insertion choisie

DBlink : interroger une base distante

Pourquoi mon index n'est pas utilisé ?

Les index bitmap

Les bind variables pour les requêtes courantes

Injection et traitements de masse

Créer un index de fonction

Vidage de cache

Utilisation de rownum et rowid

Les exceptions SQL oracle

Des lignes aux colonnes, un PIVOT suffit pour la 11g ; DECODE en attendant

Migration de modèles avec vues et synonymes

La clause WITH à la rescousse des sous requêtes

Comparer l'exécution d'une requête avec 2 index différents

La table DUAL pour développer

Tablespaces, datafiles et filesystem, comprendre le stockage

Modifier des paramètres, arrêter et redémarrer une base oracle.

Comprendre à quoi sert le listener et test avec tnsping

Interaction shell Unix / sqlplus Oracle

Gérer l'auto-increment sous Oracle

Le dictionnaire de données : premiers pas

Les LOB pour contourner les limites de LONG

Hint oracle et choix du plan d'exécution

Les types SQL et les types PL

Migration des LOB dans un tablespace dédié

SQL générant du SQL

Industrialisation des scripts SQL

CREATE OR REPLACE ... oui mais pour les tables ?

Les vues

Migration des index dans un tablespace dédié

Les colonnes virtuelles en 11g

Monter des données dans le cache Oracle

Index

La jointure : sélection sur plusieurs tables

XML et Oracle

Les statistiques Oracle

Import avec les contraintes : ordonner les insert

Les tables partitionnées

Fonction Oracle à partir d'une procédure java

Exporter la structure d'une base

Améliorer les performances d'une vue

Les index B-tree

Les triggers

Les triggers permettent d'exécuter du code lors d'un évènement particulier. La traduction littéral est déclencheur.


Le trigger sera exécuté dans la même transaction que l'ordre sur lequel il déclenche (en cas de rollback ou commit, le traitement sera annulé ou validé au même titre que l'ordre lui-même).


Trigger FOR EACH ROW


Exemple de création d'un trigger :

Création simple d'un trigger insérant une nouvelle ligne dans une table de log à chaque création de commande :

create or replace trigger TR_LOG_INS_CMD as
BEFORE INSERT ON COMMANDE
FOR EACH ROW
BEGIN
insert into T_LOG (evt_date, evt_label) values (systimestamp, 'Nouvelle commande créée');
END;
/



Exemple d'utilisation du mot clé :old
create or replace trigger TR_LOG_DEL_CMD as
BEFORE DELETE ON COMMANDE
FOR EACH ROW
BEGIN
insert into T_LOG (evt_date, evt_label) values (systimestamp, 'commande ' || :old.cmd_id || ' supprimée');
END;
/


create or replace trigger TR_LOG_UPDT_CMD as
BEFORE UPDATE ON COMMANDE
FOR EACH ROW
BEGIN
insert into T_LOG (evt_date, evt_label) values (systimestamp, 'commande ' || :old.cmd_id || ' mise à jour, la nouvelle date de livraison est : ' || :new.liv_date);
END;
/


Cependant, il est possible de ne déclencher que sur la colonne qui nous intéresse :

create or replace trigger TR_LOG_UPDT_CMD as
BEFORE UPDATE OF LIV_DATE ON COMMANDE
FOR EACH ROW
BEGIN
insert into T_LOG (evt_date, evt_label) values (systimestamp, 'commande ' || :old.cmd_id || ' mise à jour, la nouvelle date de livraison est : ' || :new.liv_date);
END;
/


Le trigger AFTER ... FOR EACH ROW effectuera la même chose mais une fois seulement que les valeurs aient été modifiées

Trigger globaux


Les précédents triggers se déclenchaient et effectuaient le traitement pour chaque tuple de la table concernée.
Or, il existe la possibilité de ne déclencher qu'en début ou fin de transaction sur la table entière (respectivement BEFORE et AFTER). Celà peut être particulièrement utile lorsque nous effectuons un calcul persistent sur les données ; par exemple, dans la table statistique, nous stockons la somme des commandes en cours (date_liv est nulle). Il est alors inutile d'effectuer le calcul plusieurs fois dans une même transaction car seul le dernier résultat sera réellement en base.

create or replace trigger TR_STAT_CMD_DEL as
AFTER INSERT or DELETE or UPDATE of date_liv ON COMMANDE
BEGIN
update statistique set nb_cmd = select count(*) from commande where date_liv is null;
END;
/



Ainsi lors de la suppression de 6 commandes (dans la même transaction), le trigger n'exécutera le code qu'une fois en fin de traitement.


Trigger INSTEAD

Lorsque des vues sont créées à destination de l'utilisateur, il est possible d'implémenter un trigger offrant à l'utilisateur un contournement à la mise à jour des données d'une vue. Dans ce cas, le trigger INSTEAD est tout à fait adapté. L'utilisateur effectuera ainsi une requête INSERT (ou UPDATE ou DELETE) sur un objet de type vue, mais derrière, le code sera adapté afin que la vue devienne complètement transparente et se manipule comme une table.



Mutating table

Le trigger déclenche du code PL ; ainsi n'importe quel code PL valide peut être exécuté par un trigger (appel de fonctions, de procédures, gestion d'exceptions, ...).
Attention cependant car un ordre DDL peut être déclenché par un trigger qui lui-même peut manipuler dans un autre trigger. On se retrouve alors dans le cas d'une "mutation" de table :
ORA-04091: table ma_table is mutating, trigger/function may not see it

Dans ce cas, l'astuce consiste à coupler un trigger de type ON EACH ROW, un trigger de type AFTER et une table temporaire. Si l'intégrité n'est pas en jeu, les transactions autonomes peuvent également résoudre le problème.

Les triggers sur évènements systèmes (DATABASE)

Il est possible de créer des triggers sur des évènements autres que traitant les données tels que les évènements système :
CREATE OR REPLACE TRIGGER TR_LOG
AFTER LOGON ON DATABASE
CALL ma_procédure_init_user;
/


Les évènements concernés sont :
AFTER STARTUP
BEFORE SHUTDOWN
AFTER LOGON
BEFORE LOGOFF
AFTER DB_ROLE_CHANGE
AFTER SUSPEND
AFTER SERVERERROR


Exemple de trigger de gestion d'erreur (erreur d'authentification notamment) :

create or replace trigger TR_BAD_PWD
AFTER SERVERERROR on DATABASE
BEGIN
IF (IS_SERVERERROR(1017)) THEN
insert into T_LOG (evt_date, evt_label) values (systimestamp, 'une erreur d''authentification est survenue' );
END IF;
END;
/



Les triggers sur évènements DDL


L'ensemble de ces évènements DDL peuvent être associés à des trigger BEFORE ou AFTER :
ALTER
ANALYZE
ASSOCIATE
AUDIT
COMMENT
CREATE
DDL
DISASSOCI
DROP
GRANT
NOAUDIT
RENAME
REVOKE
TRUNCATE





Opération sur les triggers

Tout comme les fonctions ou procédures, un trigger peut se retrouver avec un statut invalide ; il faut alors le recompiler :
ALTER TRIGGER monTriggger COMPILE;

Il est également possible de désactiver un trigger (afin qu'il ne déclanche plus, mais reste présent en base) :
ALTER TRIGGER monTriggger DISABLE;
que l'on réactive en faisant :
ALTER TRIGGER monTriggger ENABLE;

Informations sur les triggers

Les vues du dictionnaire concernées sont :
- ALL_TRIGGERS
- USER_TRIGGERS
- DBA_TRIGGERS




Voir les articles se référents à celui-ci :
- Aperçu des transactions autonomes
- Gérer l'auto-increment sous Oracle
- Les vues  

[ ... ] Lire la suite

Retour à l'index des articles


Catégories