Attention lors de l’utilisation de type polymorphe…
# SELECT addition('un'::text, 'mot'::text);ERREUR: L'opérateur n'existe pas : text + textLIGNE 1 : SELECT $1+ $2^ASTUCE : Aucun opérateur correspond au nom donné et aux types d'arguments. Vous devez ajouter des conversions explicites de type.REQUÊTE : SELECT $1 + $2CONTEXTE : PL/pgSQL function "addition" line 4 at assignment
Fonctions trigger
Fonctions trigger :
introduction
Fonction stockée
Action déclenchée par INSERT (incluant
COPY), UPDATE, DELETE,
TRUNCATE
Mode par ligne ou par
instruction
Exécution d’une fonction
Fonctions trigger : variables
(1/5)
OLD :
type de données RECORD correspondant à la ligne avant
modification
valable pour un DELETE et un UPDATE
NEW :
type de données RECORD correspondant à la ligne après
modification
valable pour un INSERT et un UPDATE
Fonctions trigger : variables
(2/5)
Ces deux variables sont valables uniquement pour les triggers en
mode ligne
pour les triggers en mode instruction, la version 10 propose les
tables de transition
Accès aux champs par la notation pointée
NEW.champ1 pour accéder à la nouvelle valeur de
champ1
Fonctions trigger : variables
(3/5)
TG_NAME
nom du trigger qui a déclenché l’appel de la fonction
TG_WHEN
chaîne valant BEFORE, AFTER ou
INSTEAD OF suivant le type du trigger
TG_LEVEL
chaîne valant ROW ou STATEMENT suivant le
mode du trigger
TG_OP
chaîne valant INSERT, UPDATE,
DELETE, TRUNCATE suivant l’opération qui a
déclenché le trigger
Fonctions trigger : variables
(4/5)
TG_RELID
OID de la table qui a déclenché le trigger
TG_TABLE_NAME
nom de la table qui a déclenché le trigger
TG_TABLE_SCHEMA
nom du schéma contenant la table qui a déclenché le trigger
Fonctions trigger : variables
(5/5)
TG_NARGS
nombre d’arguments donnés à la fonction trigger
TG_ARGV
les arguments donnés à la fonction trigger (le tableau commence à
0)
Fonctions trigger : retour
Une fonction trigger a un type de retour spécial :
trigger
Trigger BEFORE FOR EACH ROW :
si retour NULL : annulation de l’opération, sans
erreur, la transaction continue
modification possible de NEW
BEFORE DELETE : NEW est NULL,
retourner OLD
BEFORE INSERT : OLD est NULL,
retourner NEW
Trigger AFTER :
valeur de retour ignorée (même NULL)
Trigger FOR EACH STATEMENT :
valeur de retour ignorée, renvoyer NULL
RAISE EXCEPTION toujours possible, interrompt la
transaction
Fonctions trigger : exemple -
1
Horodater une opération sur une ligne
CREATETABLE ma_table (id serial,-- un certain nombre de champs informatifsdate_ajout timestamp,date_modif timestamp);
FETCH [ direction { FROM | IN } ] curseur INTO cible
Récupère la prochaine ligne
FOUND indique si cette nouvelle ligne a été récupérée
Cible est
une variable RECORD
une variable ROW
un ensemble de variables séparées par des virgules
Curseurs : récupération des
données
direction du FETCH :
NEXT, PRIOR
FIRST, LAST
ABSOLUTE nombre, RELATIVE nombre
nombre
ALL
FORWARD, FORWARD nombre,
FORWARD ALL
BACKWARD, BACKWARD nombre,
BACKWARD ALL
Curseurs : modification des
données
Mise à jour d’une ligne d’un curseur :
UPDATE une_table SET...WHERECURRENTOF curseur;
Suppression d’une ligne d’un curseur :
DELETEFROM une_tableWHERECURRENTOF curseur;
Curseurs : fermeture d’un
curseur
Instruction SQL : CLOSE curseur
Ferme le curseur
Permet de récupérer de la mémoire
Permet aussi de réouvrir le curseur
Curseurs : renvoi d’un curseur
Fonction renvoyant une valeur de type refcursor
Permet donc de renvoyer plusieurs valeurs
Gestion des erreurs
Gestion des erreurs :
introduction
Sans exceptions :
toute erreur provoque un arrêt de la fonction
toute modification suite à une instruction SQL (INSERT,
UPDATE, DELETE) est annulée
d’où l’ajout d’une gestion personnalisée des erreurs avec le concept
des exceptions
Gestion des erreurs : une
exception
La fonction comporte un bloc supplémentaire,
EXCEPTION :
DECLARE-- déclaration des variables localesBEGIN-- instructions de la fonctionEXCEPTIONWHEN condition THEN-- instructions traitant cette erreurWHEN condition THEN-- autres instructions traitant cette autre erreur-- etc.END
Gestion des
erreurs : flot dans une fonction
L’exécution de la fonction commence après le BEGIN
Si aucune erreur ne survient, le bloc EXCEPTION est
ignoré
Si une erreur se produit
tout ce qui a été modifié dans la base dans le bloc est annulé
les variables gardent par contre leur état
l’exécution passe directement dans le bloc de gestion de
l’exception
Gestion des
erreurs : flot dans une exception
Recherche d’une condition satisfaisante
Si cette condition est trouvée
exécution des instructions correspondantes
Si aucune condition n’est compatible
sortie du bloc BEGIN/END comme si le bloc
d’exception n’existait pas
passage de l’exception au bloc BEGIN/END
contenant (après annulation de ce que ce bloc a modifié en base)
Dans un bloc d’exception, les instructions INSERT,
UPDATE, DELETE de la fonction ont été
annulées
Dans un bloc d’exception, les variables locales de la fonction ont
gardé leur ancienne valeur
Gestion des erreurs : codes
d’erreurs
SQLSTATE : code d’erreur
SQLERRM : message d’erreur
Par exemple :
Data Exception : division par zéro, overflow, argument
invalide pour certaines fonctions, etc.
Integrity Constraint Violation : unicité, CHECK, clé
étrangère, etc.
Syntax Error
PL/pgSQL Error : RAISE EXCEPTION, pas de
données, trop de lignes, etc.
Les erreurs sont contenues dans des classes d’erreurs plus
génériques, qui peuvent aussi être utilisées
Messages d’erreurs : RAISE - 1
Envoyer une trace dans les journaux applicatifs et/ou vers le client
RAISE niveau message
Niveau correspond au niveau d’importance du message
DEBUG, LOG, INFO,
NOTICE, WARNING, EXCEPTION
Message est la trace à enregistrer
Message dynamique… tout signe % est remplacé par la
valeur indiquée après le message
Champs DETAIL et HINT disponibles
Messages d’erreurs : RAISE - 2
Exemples :
RAISE WARNING 'valeur % interdite', valeur;
RAISE WARNING 'valeur % ambigue', valeurUSING HINT ='Controlez la valeur saisie en amont';
Messages d’erreurs :
configuration des logs
Deux paramètres importants pour les traces
log_min_messages
niveau minimum pour que la trace soit enregistrée dans les
journaux
client_min_messages
niveau minimum pour que la trace soit envoyée au client
Dans le cas d’un RAISE NOTICE message, il faut avoir
soit log_min_messages, soit
client_min_messages, soit les deux à la valeur
NOTICE au minimum.
Messages d’erreurs :
RAISE EXCEPTION - 1
Annule le bloc en cours d’exécution
RAISE EXCEPTION message
Sauf en cas de présence d’un bloc EXCEPTION gérant la
condition RAISE_EXCEPTION
message est la trace à enregistrer, et est dynamique… tout signe %
est remplacé par la valeur indiquée après le message
Messages d’erreurs :
RAISE EXCEPTION - 2
Exemple :
RAISE EXCEPTION'erreur interne';-- La chose à ne pas faire !
Flux des erreurs dans du code
PL
Les exceptions non traitées «remontent»
de bloc BEGIN/END imbriqués vers les blocs
parents (fonctions appelantes comprises)
jusqu’à ce que personne ne puisse les traiter
voir note pour démonstration
Flux des erreurs dans du
code PL - 2
Les erreurs remontent
Cette fois-ci, on rajoute un bloc PL pour intercepter l’erreur
Flux des erreurs dans du
code PL - 3
Cette fois-ci, on rajoute un bloc PL indépendant pour gérer le
second INSERT
Flux des erreurs dans du
code PL - 4
Illustrons maintenant la remontée d’erreurs
Nous avons deux blocs imbriqués
Une erreur non prévue va se produire dans le bloc intérieur
Abus des exceptions
Ne pas abuser des exceptions
les sous-transactions ne sont pas gratuites
Si saturation, paramétre SLRU dédié (v17)
Sécurité
Sécurité : droits
L’exécution de la routine dépend du droit EXECUTE
Par défaut, ce droit est donné à la création de la routine
au propriétaire de la routine
au groupe spécial PUBLIC
Sécurité : ajout
Ce droit peut être donné avec l’instruction SQL
GRANT :