CodeGym /Cours /SQL SELF /Types de triggers dans PostgreSQL : BEFORE, AFTER, INSTEA...

Types de triggers dans PostgreSQL : BEFORE, AFTER, INSTEAD OF

SQL SELF
Niveau 57 , Leçon 1
Disponible

Les triggers dans PostgreSQL se divisent en trois grandes catégories :

  1. BEFORE — s’exécutent avant l’opération principale (genre avant un INSERT, UPDATE ou DELETE). Tu peux t’en servir pour empêcher l’opération ou modifier les données avant qu’elles soient enregistrées.

  2. AFTER — s’exécutent après que l’opération principale soit terminée. Ce type sert souvent à logger, créer des enregistrements liés ou faire des actions qui dépendent du succès de l’opération.

  3. INSTEAD OF — s’exécutent à la place de l’opération réelle. Utilisés uniquement pour les vues. Par exemple, si un utilisateur essaie d’insérer des données dans une vue, tu peux gérer ça avec un trigger INSTEAD OF.

Trigger BEFORE

Les triggers BEFORE se lancent avant que PostgreSQL fasse l’opération principale. Ils sont utiles si tu veux vérifier ou modifier les données juste avant qu’elles soient enregistrées. Imagine ça comme le contrôle des bagages avant de monter dans l’avion : si le bagage ne va pas, tu peux le modifier ou carrément le bloquer.

Voici un exemple de validation avant insertion.
Disons qu’on a une table students où on stocke les infos des étudiants. On veut s’assurer que l’âge d’un étudiant ne dépasse pas 100 ans (peu probable, mais bon).

On crée la table :

CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    age INT NOT NULL
);

On crée la fonction pour le trigger :

CREATE OR REPLACE FUNCTION validate_age()
RETURNS TRIGGER AS $$
BEGIN
    IF NEW.age > 100 THEN
        RAISE EXCEPTION 'L’âge de l’étudiant ne peut pas dépasser 100 ans !';
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

On crée le trigger :

CREATE TRIGGER before_insert_students
BEFORE INSERT ON students
FOR EACH ROW
EXECUTE FUNCTION validate_age();

Maintenant, si tu essaies d’insérer un étudiant avec plus de 100 ans, PostgreSQL va te sortir une erreur :

INSERT INTO students (name, age) VALUES ('Ivan Ivanov', 120);
-- Erreur : L’âge de l’étudiant ne peut pas dépasser 100 ans !

Voilà pour la vérif !

Trigger AFTER

Les triggers AFTER se lancent après que l’opération principale soit terminée avec succès. Ils sont pratiques pour faire des actions qui dépendent du résultat de l’opération. Genre logger ou créer des enregistrements liés.

Scénario : on a une table students et on veut enregistrer tous les changements dans une table de logs séparée.

On crée la table de logs :

CREATE TABLE students_log (
    id SERIAL PRIMARY KEY,
    student_id INT,
    operation TEXT,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

On crée la fonction pour le trigger :

CREATE OR REPLACE FUNCTION log_student_changes()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO students_log (student_id, operation)
    VALUES (NEW.id, TG_OP);  -- TG_OP contient le type d’opération : INSERT, UPDATE ou DELETE
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

On crée le trigger :

CREATE TRIGGER after_insert_students
AFTER INSERT ON students
FOR EACH ROW
EXECUTE FUNCTION log_student_changes();

Maintenant, quand tu ajoutes un nouvel étudiant, PostgreSQL enregistre direct l’opération dans le log :

INSERT INTO students (name, age) VALUES ('Anna Ling', 22);

SELECT * FROM students_log;
-- Résultat :
-- id | student_id | operation |        timestamp
--  1 |          1 | INSERT    | 2023-11-15 12:00:00

Trigger INSTEAD OF

Les triggers INSTEAD OF s’activent à la place de l’opération. C’est le seul type de trigger que tu peux utiliser avec les vues (views). Ils te donnent de la flexibilité pour gérer des opérations qu’on ne peut pas faire direct sur une vue.

Scénario : on a deux tables courses et teachers. On va créer une vue qui les combine, et écrire un trigger pour gérer les insertions via cette vue.

On crée les tables :

CREATE TABLE courses (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    teacher_id INT NOT NULL
);

CREATE TABLE teachers (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL
);

On crée la vue :

CREATE VIEW course_details AS
SELECT 
    courses.id AS course_id,
    courses.name AS course_name,
    teachers.name AS teacher_name
FROM courses
JOIN teachers ON courses.teacher_id = teachers.id;

Problème : on ne peut pas insérer des données dans la vue comme ça, vu qu’elle agrège des données de deux tables. Solution : on utilise un trigger INSTEAD OF.

On crée la fonction pour le trigger :

CREATE OR REPLACE FUNCTION insert_course_details()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO teachers (name) VALUES (NEW.teacher_name) RETURNING id INTO NEW.teacher_id;
    INSERT INTO courses (name, teacher_id) VALUES (NEW.course_name, NEW.teacher_id);
    RETURN NULL;  -- Les données ne sont pas stockées dans la vue
END;
$$ LANGUAGE plpgsql;

On crée le trigger :

CREATE TRIGGER instead_of_insert_course_details
INSTEAD OF INSERT ON course_details
FOR EACH ROW
EXECUTE FUNCTION insert_course_details();

Maintenant tu peux insérer des données direct dans la vue :

INSERT INTO course_details (course_name, teacher_name)
VALUES ('Mathématiques', 'Alex Ming');

SELECT * FROM courses;
-- Résultat :
-- id | name           | teacher_id
--  1 | Mathématiques  | 1

SELECT * FROM teachers;
-- Résultat :
-- id | name
--  1 | Alex Ming

Comparaison des types de triggers

Type de trigger Quand il s’exécute Utilisation principale
BEFORE Avant l’opération Validation, préparation des données
AFTER Après le succès de l’opération Logging, mise à jour des données liées
INSTEAD OF À la place de l’opération Gestion des opérations sur les vues

Particularités et limites

BEFORE triggers peuvent modifier les données avant l’opération. Par exemple, tu peux formater automatiquement les noms (genre tout en majuscules).

AFTER triggers ne peuvent pas modifier les données, vu que l’opération est déjà faite. Ils servent juste pour les actions qui suivent.

INSTEAD OF triggers ne s’appliquent qu’aux vues. Ils permettent de gérer une logique complexe d’insertion/modification sur plusieurs tables liées.

Voilà, c’est tout pour aujourd’hui ! Si BEFORE, AFTER et INSTEAD OF te semblent compliqués, t’inquiète. Le principal, c’est de retenir leur principe de base et quand les utiliser. Essaie de faire quelques exemples toi-même pour bien piger le truc.

Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION