Ordre d'Exécution des Triggers

Comprendre la séquence et les variables spéciales

1 Séquence d'Exécution Complète

🎬 Déroulement lorsqu'une requête arrive

1️⃣ BEFORE STATEMENT

Une seule fois

Tous les triggers FOR EACH STATEMENT de type BEFORE

→ Exécutés dans l'ordre alphabétique s'il y en a plusieurs

🔄 Pour CHAQUE enregistrement concerné :

2️⃣ BEFORE ROW
Par ligne

Tous les triggers FOR EACH ROW de type BEFORE

Important: Peut modifier NEW avant l'enregistrement
3️⃣ MODIFICATION EFFECTIVE

L'enregistrement est verrouillé et le changement effectué dans la table

💾 INSERT / UPDATE / DELETE réellement exécuté
4️⃣ AFTER ROW
Par ligne

Tous les triggers FOR EACH ROW de type AFTER

⚠️ Les données sont déjà enregistrées, impossible de les modifier

5️⃣ AFTER STATEMENT

Une seule fois

Tous les triggers FOR EACH STATEMENT de type AFTER

→ Exécutés dans l'ordre alphabétique s'il y en a plusieurs

📊 Exemple: UPDATE de 3 employés

🔷 BEFORE STATEMENT (1 fois)
▪️ BEFORE ROW employé #1
✓ Modification employé #1
▪️ AFTER ROW employé #1
▪️ BEFORE ROW employé #2
✓ Modification employé #2
▪️ AFTER ROW employé #2
▪️ BEFORE ROW employé #3
✓ Modification employé #3
▪️ AFTER ROW employé #3
🔷 AFTER STATEMENT (1 fois)

2 Variables OLD et NEW

Opération OLD NEW Modification possible ?
INSERT ❌ NULL ✅ Nouvelles valeurs BEFORE: Oui (modifier NEW)
UPDATE ✅ Anciennes valeurs ✅ Nouvelles valeurs BEFORE: Oui (modifier NEW)
DELETE ✅ Valeurs supprimées ❌ NULL Non (OLD en lecture seule)
STATEMENT ❌ NULL ❌ NULL Non applicable

📝 Exemple BEFORE INSERT

CREATE FUNCTION maj_date_creation()
RETURNS TRIGGER AS $$
BEGIN
    -- Modifier NEW avant insertion
    NEW.date_creation := CURRENT_DATE;
    NEW.user_creation := CURRENT_USER;
    RETURN NEW; -- Important !
END;
$$ LANGUAGE plpgsql;

📝 Exemple AFTER UPDATE

CREATE FUNCTION log_changement()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO audit_log VALUES (
        OLD.emp_no,
        OLD.emp_salaire,
        NEW.emp_salaire,
        CURRENT_TIMESTAMP
    );
    RETURN NULL; -- Pas important pour AFTER
END;
$$ LANGUAGE plpgsql;

3 Variables Spéciales dans les Triggers

TG_NAME

Nom du trigger actuellement exécuté

Type: TEXT

TG_WHEN

Moment du déclenchement

Valeurs: BEFORE / AFTER / INSTEAD OF

TG_LEVEL

Niveau du trigger

Valeurs: ROW / STATEMENT

TG_OP

Type d'opération

Valeurs: INSERT / UPDATE / DELETE

TG_TABLE_NAME

Nom de la table concernée

Type: TEXT

TG_TABLE_SCHEMA

Schéma de la table

Type: TEXT

💡 Exemple d'utilisation

CREATE FUNCTION universal_trigger() RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'INSERT' THEN
        RAISE NOTICE 'Insertion dans %', TG_TABLE_NAME;
        RETURN NEW;
    ELSIF TG_OP = 'UPDATE' THEN
        RAISE NOTICE 'Mise à jour de % dans %', OLD.emp_no, TG_TABLE_NAME;
        RETURN NEW;
    ELSIF TG_OP = 'DELETE' THEN
        RAISE NOTICE 'Suppression de % dans %', OLD.emp_no, TG_TABLE_NAME;
        RETURN OLD;
    END IF;
END;
$$ LANGUAGE plpgsql;
-- Un seul trigger pour 3 événements !
CREATE TRIGGER trg_audit
    AFTER INSERT OR UPDATE OR DELETE ON exe_employe
    FOR EACH ROW
    EXECUTE FUNCTION universal_trigger();

4 Valeurs à Retourner

Type de Trigger Valeur à retourner Effet
BEFORE ROW (INSERT/UPDATE) NEW L'opération continue avec NEW (éventuellement modifié)
BEFORE ROW (INSERT/UPDATE) NULL ⚠️ L'opération est ANNULÉE pour cette ligne !
BEFORE ROW (DELETE) OLD L'opération continue
BEFORE ROW (DELETE) NULL ⚠️ Le DELETE est ANNULÉ pour cette ligne !
AFTER ROW NULL ou n'importe quoi La valeur est ignorée (données déjà enregistrées)
STATEMENT (BEFORE/AFTER) NULL Toujours NULL (pas de OLD/NEW)

⚠️ Attention !

  • • Retourner NULL dans un BEFORE ROW = annuler l'opération
  • • Dans un AFTER, la valeur retournée n'a aucun effet (mais doit être non-NULL pour ne pas générer d'erreur)
  • • Pour modifier les données, il faut un BEFORE ROW et retourner NEW modifié

🎮 Exercice Interactif: Ordre d'Exécution

Vous avez les triggers suivants sur la table exe_employe:

• trg_audit_statement AFTER INSERT STATEMENT
• trg_before_insert BEFORE INSERT ROW
• trg_validate BEFORE INSERT STATEMENT
• trg_log AFTER INSERT ROW

Question: Dans quel ordre seront-ils exécutés lors d'un INSERT de 2 employés ?

A) trg_validate (BEFORE STATEMENT)
B) trg_before_insert (BEFORE ROW) pour employé 1
C) INSERT réel employé 1
D) trg_log (AFTER ROW) pour employé 1
E) trg_before_insert (BEFORE ROW) pour employé 2
F) INSERT réel employé 2
G) trg_log (AFTER ROW) pour employé 2
H) trg_audit_statement (AFTER STATEMENT)
🏠 Retour au Hub Mukbang
Glisser pour continuer vers QCM Final PL/SQL
⬇️