CodeGym /Cours /SQL SELF /Trigger pour mettre à jour automatiquement le champ

Trigger pour mettre à jour automatiquement le champ last_modified lors de la modification d’un enregistrement

SQL SELF
Niveau 58 , Leçon 1
Disponible

Trigger pour mettre à jour automatiquement le champ last_modified lors de la modification d’un enregistrement

Imagine que tu développes une appli pour gérer des étudiants et des cours, et que tu as une table students. Dans cette table, il y a un champ last_modified qui doit se mettre à jour tout seul à chaque fois qu’on modifie les données d’un étudiant (genre, on change son nom ou son âge).

Au lieu de devoir écrire la mise à jour de last_modified à la main dans chaque requête SQL, on va créer un trigger qui va s’en occuper pour nous.

Structure de la table students

Pour commencer, créons la table students qu’on va utiliser dans l’exemple. Cette table contient les infos de base sur les étudiants :

CREATE TABLE students (
    student_id SERIAL PRIMARY KEY, -- Identifiant unique de l’étudiant
    name VARCHAR(100) NOT NULL,   -- Nom de l’étudiant
    age INT,                      -- Âge de l’étudiant
    last_modified TIMESTAMP NOT NULL DEFAULT NOW() -- Date de la dernière modif
);
  • Le champ last_modified est rempli avec la date/heure actuelle (NOW()) quand on crée l’enregistrement.
  • Ce champ va se mettre à jour automatiquement quand on modifie les données de l’étudiant.

On va remplir la table avec quelques données de test :

INSERT INTO students (name, age)
VALUES 
    ('Otto Lin', 20),
    ('Maria Chi', 22),
    ('Alex Song', 19);

Maintenant, les données dans la table ressemblent à ça :

student_id name age last_modified
1 Otto Lin 20 2023-10-15 12:00:00
2 Maria Chi 22 2023-10-15 12:00:00
3 Alex Song 19 2023-10-15 12:00:00

Création de la fonction pour mettre à jour last_modified

La fonction en PL/pgSQL va être utilisée par le trigger pour mettre à jour la valeur du champ last_modified. Elle sera appelée automatiquement avant la modification de l’enregistrement.

Créons la fonction update_last_modified :

CREATE OR REPLACE FUNCTION update_last_modified()
RETURNS TRIGGER AS $$
BEGIN
    -- On met à jour le champ last_modified avec la date/heure actuelle
    NEW.last_modified := NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;
  • NEW — c’est une variable spéciale qui contient les nouvelles données de l’enregistrement (après modif).
  • On met NEW.last_modified à NOW() (date et heure actuelles).
  • La fonction retourne la variable NEW modifiée, c’est nécessaire pour que le trigger marche bien.

Création du trigger

Maintenant, on va créer le trigger qui va appeler automatiquement la fonction update_last_modified à chaque update d’une ligne dans la table students.

CREATE TRIGGER set_last_modified
BEFORE UPDATE ON students
FOR EACH ROW
EXECUTE FUNCTION update_last_modified();

Ce qui se passe ici :

  • BEFORE UPDATE veut dire que le trigger se lance avant l’opération d’update.
  • FOR EACH ROW veut dire que le trigger s’exécute pour chaque ligne modifiée.
  • EXECUTE FUNCTION update_last_modified() indique qu’il faut appeler la fonction update_last_modified.

Tester le trigger

On va voir comment marche notre trigger. On sélectionne les données actuelles de la table students :

SELECT * FROM students;

Résultat :

student_id name age last_modified
1 Otto Lin 20 2023-10-15 12:00:00
2 Maria Chi 22 2023-10-15 12:00:00
3 Alex Song 19 2023-10-15 12:00:00

Maintenant, on va mettre à jour l’âge de l’étudiant avec student_id = 1 :

UPDATE students
SET age = 21
WHERE student_id = 1;

On re-sélectionne les données de la table :

SELECT * FROM students;

Résultat attendu :

student_id name age last_modified
1 Otto Lin 21 2023-10-15 14:00:00
2 Maria Chi 22 2023-10-15 12:00:00
3 Alex Song 19 2023-10-15 12:00:00

Regarde bien : le champ last_modified pour la ligne avec student_id = 1 a été mis à jour avec la nouvelle heure, alors que les autres lignes n’ont pas bougé.

Étendre la logique du trigger

Imaginons maintenant qu’on veut que le champ last_modified ne se mette à jour que si certains champs changent. Par exemple, si on change juste le nom ou l’âge de l’étudiant, le trigger doit se lancer, mais pas pour d’autres modifs.

Pour ça, on peut ajouter une condition avec l’opérateur WHEN dans la définition du trigger.

Créons un nouveau trigger avec une condition :

DROP TRIGGER IF EXISTS set_last_modified ON students;

CREATE TRIGGER set_last_modified
BEFORE UPDATE ON students
FOR EACH ROW
WHEN (OLD.name IS DISTINCT FROM NEW.name OR OLD.age IS DISTINCT FROM NEW.age)
EXECUTE FUNCTION update_last_modified();

Ici :

  • La condition WHEN vérifie si les anciennes valeurs (OLD) sont différentes des nouvelles (NEW) pour les colonnes name et age.
  • Si aucun de ces champs n’a changé, le trigger ne se lance pas.

On peut maintenant refaire des updates dans la table et tester la nouvelle logique.

Conseils pour utiliser les triggers

  1. N’abuse pas des triggers. C’est pratique, mais ça peut rendre la logique de la base de données plus compliquée et l’debug plus galère.
  2. Documente toujours ce que fait un trigger et dans quels cas il est utilisé.
  3. Utilise des conditions WHEN pour éviter que le trigger se lance pour rien.
  4. Souviens-toi que les triggers peuvent impacter les perfs de la base, surtout si la table est grosse.

Erreurs classiques avec les triggers

Mauvaise modification des données. Par exemple, t’as oublié de mettre à jour NEW et tu retournes les données originales sans changement.

Mauvaises conditions. Genre, t’as oublié d’ajouter la condition WHEN et le trigger se lance même quand il n’y a rien à changer.

Récursion. Si le trigger appelle une fonction qui rappelle le trigger, tu peux te retrouver avec une boucle infinie. PostgreSQL protège contre la récursion, mais vaut mieux éviter ce genre de trucs.

Cet exemple montre comment les triggers peuvent simplifier la mise à jour automatique des données. Dans les vrais projets, cette technique est souvent utilisée pour journaliser les changements, garder l’intégrité des données et automatiser les tâches chiantes.

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