Documentation PostgreSQL 7.4.29 | ||||
---|---|---|---|---|
Précédent | Arrière rapide | Chapitre 37. PL/pgSQL - SQL Procedural Language | Avance rapide | Suivant |
Toutes les expressions utilisées dans les instructions PL/pgSQL sont traitées par l'exécuteur SQL classique du serveur. Les expressions qui apparaissent contenir des constantes peuvent en fait nécessiter une évaluation pendant l'exécution (par exemple, 'now' pour le type timestamp) ainsi il est impossible pour l'analyseur syntaxique PL/pgSQL d'identifier les valeurs réelles des constantes autres que le mot clé NULL. Toutes les expressions sont évaluées de façon interne en exécutant une requête
SELECT expression
en utilisant le gestionnaire SPI. Pour l'évaluation, les occurrences des identifiants de variablesPL/pgSQL sont remplacées par des paramètres, et les valeurs réelles des variables sont passées à l'exécuteur dans le tableau des paramètres. Ceci permet au plan de requêtes pour le SELECT de n'être élaboré qu'une fois et réutilisé pour les évaluations postérieures.
L'évaluation faite par l'analyseur syntaxique principal de PostgreSQL a quelques effets de bord sur l'interprétation des valeurs constantes. Plus précisément, il y a une différence entre ce que font ces deux fonctions :
CREATE FUNCTION logfunc1(text) RETURNS timestamp AS ' DECLARE logtxt ALIAS FOR $1; BEGIN INSERT INTO logtable VALUES (logtxt, ''now''); RETURN ''now''; END; ' LANGUAGE plpgsql;
et
CREATE FUNCTION logfunc2(text) RETURNS timestamp AS ' DECLARE logtxt ALIAS FOR $1; curtime timestamp; BEGIN curtime := ''now''; INSERT INTO logtable VALUES (logtxt, curtime); RETURN curtime; END; ' LANGUAGE plpgsql;
Dans le cas de logfunc1
, l'analyseur syntaxique principal de
PostgreSQL sait, quand il élabore le plan pour l'
INSERT, que la chaîne 'now'
doit être interprétée comme un timestamp parce que la colonne cible
de logtable
est de ce type. Ainsi, il en fera une constante
à ce moment et cette valeur constante sera alors utilisée dans toutes les invocations
de logfunc1
pendant le temps que durera la session. Il va
sans dire que ce n'est pas ce que le programmeur voulait.
Dans le cas de logfunc2
, l'analyseur principal de
PostgreSQL ne sait pas quel type 'now'
doit devenir, et par conséquent, il renvoie une valeur de type text
contenant la chaîne now. Durant l'assignation consécutive de la
variable locale curtime, l'interpréteur
PL/pgSQL transtype cette chaîne en type
timestamp en appelant les fonctions text_out
et timestamp_in
pour la conversion.
Ainsi, l'horodateur est mis à jour à chaque exécution comme l'attend le programmeur.
La nature modifiable des variables record présente un problème lors de cette connexion. Quand les champs d'une variable record sont utilisés dans les expressions ou les instructions, les types de données des champs ne doivent pas changer entre les appels de deux expressions identiques, puisque l'expression sera planifiée en utilisant le type de données présent quand l'expression est atteinte pour la première fois. Gardez ceci à l'esprit quand vous écrivez des procédures déclencheurs qui gèrent des évènements pour plus d'une table (EXECUTE peut être utilisé pour contourner le problème si nécessaire).
Précédent | Sommaire | Suivant |
Déclarations | Niveau supérieur | Instructions de base |