38.6. Procédures pour déclencheurs en PL/Tcl

Les procédures pour déclencheurs peuvent être écrites en PL/Tcl. PostgreSQL requiert qu'une procédure, devant être appelée en tant que déclencheur, doit être déclarée comme une fonction sans arguments et retourner une valeur de type trigger.

L'information du gestionnaire de déclencheur est passée au corps de la procédure avec les variables suivantes :

$TG_name

Nom du déclencheur provenant de l'instruction CREATE TRIGGER.

$TG_relid

L'identifiant objet de la table qui est à la cause du lancement du déclencheur.

$TG_relatts

Une liste Tcl des noms des colonnes de la table, préfixée avec un élément de liste vide. Donc, rechercher un nom de colonne dans la liste avec la commande lsearch de Tcl renvoie le numéro de l'élément, en commençant à 1 pour la première colonne, de la même façon que les colonnes sont numérotées personnellement avec PostgreSQL.

$TG_when

La chaîne BEFORE ou AFTER suivant le type d'appel du déclencheur.

$TG_level

La chaîne ROW ou STATEMENT suivant le type d'appel du déclencheur.

$TG_op

La chaîne INSERT, UPDATE ou DELETE suivant le type d'appel du déclencheur.

$NEW

Un tableau associatif contenant les valeurs de la nouvelle ligne de la table pour les actions INSERT ou UPDATE ou vide pour DELETE. Le tableau est indexé par nom de colonne. Les colonnes nulles n'apparaissent pas dans le tableau.

$OLD

Un tableau associatif contenant les valeurs de l'ancienne ligne de la table pour les actions UPDATE or DELETE ou vide pour INSERT. Le tableau est indexé par nom de colonne. Les colonnes nulles n'apparaissent pas dans le tableau.

$args

Une liste Tcl des arguments de la procédure ainsi que l'instruction CREATE TRIGGER. Ces arguments sont aussi accessibles par $1 ... $n dans le corps de la procédure.

Le code de retour d'une procédure déclencheur peut être faite avec une des chaînes OK ou SKIP ou une liste renvoyée par la commande Tcl array get. Si la valeur de retour est OK, l'opération (INSERT/UPDATE/DELETE) qui a lancé le déclencheur continuera normalement. SKIP indique au gestionnaire de déclencheurs de supprimer silencieusement l'opération pour cette ligne. Si une liste est renvoyée, elle indique à PL/Tcl de renvoyer la ligne modifiée au gestionnaire de déclencheurs qui l'insérera au lieu de celle données par $NEW (ceci fonctionne seulement pour INSERT et UPDATE). Inutile de dire que tout ceci est vraiment significatif lorsque le déclencheur est BEFORE et FOR EACH ROW ; sinon le code de retour est ignoré.

Voici un petit exemple de procédure déclencheur qui force une valeur entière dans une table pour garder trace du nombre de mises à jour réalisées sur la ligne. Pour les nouvelles lignes insérées, la valeur est initialisée à 0 puis incrémentée à chaque opération de mise à jour.

CREATE FUNCTION trigfunc_modcount() RETURNS trigger AS '
    switch $TG_op {
        INSERT {
            set NEW($1) 0
        }
        UPDATE {
            set NEW($1) $OLD($1)
            incr NEW($1)
        }
        default {
            return OK
        }
    }
    return [array get NEW]
' LANGUAGE pltcl;

CREATE TABLE mytab (num integer, description text, modcnt integer);

CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
    FOR EACH ROW EXECUTE PROCEDURE trigfunc_modcount('modcnt');

Notez que la procédure déclencheur elle-même ne connaît pas le nom de la colonne ; c'est fourni avec les arguments du déclencheur. Ceci permet à la procédure déclencheur d'être ré-utilisée avec différentes tables.