Le module spi fournit plusieurs exemples fonctionnels d'utilisation de l'interface de programmation du serveur (Server Programming Interface) (SPI) et des triggers. Bien que ces fonctions aient un intérêt certain, elles sont encore plus utiles en tant qu'exemples à modifier pour atteindre ses propres buts. Les fonctions sont suffisamment généralistes pour être utilisées avec une table quelconque, mais la création d'un trigger impose que les noms des tables et des champs soient précisés (comme cela est décrit ci-dessous).
Chaque groupe de fonctions décrit ci-dessous est fourni comme une extension installable séparément.
check_primary_key() et
check_foreign_key() sont utilisées pour vérifier les
contraintes de clé étrangère. (Cette fonctionnalité est dépassée depuis
longtemps par le mécanisme interne, mais le module conserve un rôle
d'exemple.) Ce module sera supprimée dans
PostgreSQL 20.)
refint requiert un
modèle d'utilisation sécurisée du
schéma et les types de données où l'opérateur d'égalité est
nommé =.
check_primary_key() vérifie la table de référence.
Pour l'utiliser, on crée un trigger AFTER INSERT OR UPDATE
qui utilise cette fonction sur une table référençant une autre table.
En arguments du trigger, on trouve : le nom de la colonne
de la table référençant qui forme la clé étrangère, le nom de la table
référencée et le nom de la colonne de la table référencée qui forme la
clé primaire/unique. Il peut y avoir plusieurs colonnes. Pour gérer
plusieurs clés étrangères, on crée un trigger pour chaque référence.
Les arguments de nom de la table et des colonnes
référencés à check_primary_key()
sont copiés tels quels dans les requêtes SQL générées en interne et, de ce
fait, doivent être entre guillemets doubles par l'utilisateur si nécessaire
dans la commande CREATE TRIGGER. Voir
Section 4.1.1 pour plus d'informations sur la
mise entre guillemets des identifiants SQL. Inversement, les arguments des
noms de colonne de la table référençante ne doivent pas
être entre guillemets doubles. Voir l'exemple suivant d'utilisation correcte
de check_primary_key() :
CREATE TRIGGER mytrigger
BEFORE INSERT OR UPDATE ON referencing_table
FOR EACH ROW EXECUTE PROCEDURE
check_primary_key (
'column A', 'column B', -- colonnes de la table référençante
'myschema."referenced table"', -- table référencée
'"column A"', '"column B"' -- colonnes de la table référencée
);
check_foreign_key() vérifie la table référencée.
Pour l'utiliser, on crée un trigger AFTER DELETE OR UPDATE
qui utilise cette fonction sur une table référencée par d'autres tables.
En arguments du trigger, on trouve : le nombre de tables référençant pour
lesquelles la fonction réalise la vérification, l'action à exécuter si une clé
de référence est trouvée (cascade -- pour supprimer
une ligne qui référence, restrict -- pour annuler la
transaction si des clés de référence existent, setnull
-- pour initialiser les champs des clés référençant à NULL), les noms
des colonnes de la table surveillées par le trigger, colonnes qui
forment la clé primaire/unique, puis le nom de la table référençant et les noms des
colonnes (répétés pour autant de tables référençant que cela est précisé par
le premier argument). Les colonnes de clé
primaire/unique doivent être marquées NOT NULL et posséder un index
d'unicité.
Notez que si ces triggers sont exécutés à partir d'un autre trigger
BEFORE, ils peuvent échouer de façon inattendue. Par
exemple, si un utilisateur insère row1 et que le trigger
BEFORE insère row2 et appelle un trigger avec la fonction
check_foreign_key(), la fonction
check_foreign_key() ne verra pas la ligne row1 et
échouera.
Le nom de la table et colonne référençante en arguments
de check_foreign_key() sont copiés tels quels dans
les requêtes SQL générées en interne et doivent de ce fait être mises entre
guillemets doubles par l'utilisateur si nécessaire dans la commande
CREATE TRIGGER. Voir
Section 4.1.1 pour plus d'informations sur la mise
entre guillemets des identifiants SQL. À l'inverse, le nom de colonne
référencée en argument ne doit pas être mis entre
guillemets doubles. Voir l'exemple suivant d'utilisation correcte de
check_foreign_key() :
CREATE TRIGGER mytrigger
BEFORE DELETE OR UPDATE ON referenced_table
FOR EACH ROW EXECUTE PROCEDURE
check_foreign_key (
1, -- nombre de tables référençantes
'cascade', -- action
'column A', 'column B', -- colonnes référencées
'myschema."referencing table"', -- table référençante
'"column A"', '"column B"' -- colonnes de la table référençante
);
Il y a des exemples dans refint.example.
autoinc() est un trigger qui stocke la prochaine valeur
d'une séquence dans un champ de type integer. Cela recouvre quelque peu la
fonctionnalité interne de la colonne « serial », mais ce n'est pas
strictement identique. Le trigger remplacera la valeur du champ seulement si
cette valeur est initialement à zéro ou NULL (après l'action de l'instruction
SQL qui a inséré ou modifié la ligne). De plus, si la prochaine valeur de la
séquence vaut zéro, nextval() sera appelée une deuxième
fois pour obtenir une valeur différente de zéro.
Pour l'utiliser, on crée un trigger BEFORE INSERT (ou
en option BEFORE INSERT OR UPDATE) qui utilise cette
fonction. Le trigger accepte deux arguments : le nom de la
colonne de type integer à modifier et le nom de la séquence qui fournit
les valeurs. (En fait, plusieurs paires de noms peuvent être indiquées pour
actualiser plusieurs colonnes.)
Un exemple est fourni dans autoinc.example.
insert_username() est un trigger qui stocke le
nom de l'utilisateur courant dans un champ texte. C'est utile pour
savoir quel est le dernier utilisateur à avoir modifié une ligne particulière d'une
table.
Pour l'utiliser, on crée un trigger BEFORE INSERT et/ou
UPDATE qui utilise cette fonction. Le trigger prend
pour seul argument le nom de la colonne texte à modifier.
Un exemple est fourni dans insert_username.example.
moddatetime() est un trigger qui stocke la date et
l'heure de la dernière modification dans un champ de type
timestamp. C'est utile pour savoir quand a eu lieu la
dernière modification sur une ligne particulière d'une table.
Pour l'utiliser, on crée un trigger BEFORE UPDATE qui
utilise cette fonction. Le trigger prend pour seul argument le
nom de la colonne de type à modifier.
La colonne doit être de type timestamp ou timestamp with
time zone.
Un exemple est fourni dans moddatetime.example.