Dans cette section, nous suivons la convention Tcl habituelle pour l'utilisation des points d'interrogation, plutôt que les crochets, pour indiquer un élément optionnel dans un synopsis de syntaxe. Les commandes suivantes sont disponibles pour accéder à la base de données depuis le corps d'une fonction PL/Tcl :
spi_exec
?-count n
? ?-array name
? command
?loop-body
?
Exécute une commande SQL donnée en tant que chaîne. Une erreur dans la
commande lève une erreur. Sinon, la valeur de retour de
spi_exec
est le nombre de lignes intéressées dans
le processus (sélection, insertion, mise à jour ou suppression) par la
commande ou zéro si la commande est une instruction utilitaire. De plus,
si la commande est une instruction SELECT
, les valeurs des
données sélectionnées sont placées dans des variables Tcl décrites
ci-dessous.
La valeur optionnelle -count
indique à
spi_exec
d'arrêter une fois que
n
lignes ont été récupérées, tout comme si la
requête incluait une clause LIMIT
. Si
n
vaut zéro, la requête est exécutée jusqu'à
sa fin, tout comme si -count
était omis.
Si la commande est une instruction SELECT
, les
valeurs des colonnes de résultat sont placées dans les variables Tcl
nommées d'après les colonnes. Si l'option -array
est donnée, les valeurs de colonnes sont stockées à la place dans les
éléments d'un tableau associatif nommé, les noms des colonnes étant
utilisés comme index du tableau. De plus, le numéro de ligne courant
dans le résultat (en commençant par zéro) est enregistré dans
l'élément de tableau nommé « .tupno
»,
sauf si ce nom est utilisé comme nom de colonne dans le résultat.
Si la commande est une instruction SELECT
et
qu'aucun script loop-body
n'est donné,
alors seule la première ligne de résultats est stockée dans des
variables Tcl ou des éléments de tableau ; les lignes suivantes
sont ignorées. Aucun stockage n'intervient si la requête ne renvoie
pas de ligne (ce cas est détectable avec le résultat de la fonction
spi_exec
). Par exemple :
spi_exec "SELECT count(*) AS cnt FROM pg_proc"
initialisera la variable Tcl $cnt
avec le nombre de
lignes dans le catalogue système pg_proc
.
Si l'argument loop-body
optionnel est donné, il existe un
morceau de script Tcl qui est exécuté une fois pour chaque ligne du
résultat de la requête (loop-body
est ignoré si la
commande donnée n'est pas un SELECT
). Les valeurs des
colonnes de la ligne actuelle sont stockées dans des variables Tcl avant
chaque itération. Par exemple :
spi_exec -array C "SELECT * FROM pg_class" { elog DEBUG "have table $C(relname)" }
affichera un message de trace pour chaque ligne de pg_class
.
Cette fonctionnalité travaille de façon similaire aux autres
constructions de boucles de Tcl ; en particulier,
continue
et break
fonctionnent de la même façon
à l'intérieur de loop-body
.
Si une colonne d'un résultat de la requête est NULL, la variable cible est « dés-initialisée » plutôt qu'initialisée.
spi_prepare
query
typelist
Prépare et sauvegarde un plan de requête pour une exécution future. Le plan sauvegardé sera conservé pour la durée de la session actuelle.
La requête peut utiliser des paramètres, c'est-à-dire des emplacements
pour des valeurs à fournir lorsque le plan sera réellement exécuté. Dans
la chaîne de requête, faites référence aux paramètres avec les symboles
$1
...
$
. Si la requête utilise
les paramètres, les noms des types de paramètre doivent être donnés dans
une liste Tcl (écrivez une liste vide pour
n
typelist
si aucun paramètre n'est utilisé).
La valeur de retour de spi_prepare
est
l'identifiant de la requête à utiliser dans les appels suivants à
spi_execp
. Voir spi_execp
pour
un exemple.
spi_execp
?-count n
? ?-array name
? ?-nulls string
? queryid
?value-list
? ?loop-body
?
Exécute une requête préparée précédemment avec spi_prepare
.
queryid
est l'identifiant renvoyé par
spi_prepare
. Si la requête fait référence à des
paramètres, une liste de valeurs (value-list
)
doit être fournie. C'est une liste Tcl des valeurs réelles des
paramètres. La liste doit être de la même longueur que la liste de types
de paramètres donnée précédemment lors de l'appel à
spi_prepare
. Oubliez-la si la requête n'a pas de
paramètres.
La valeur optionnelle pour -nulls
est une chaîne d'espaces
et de caractères 'n'
indiquant à
spi_execp
les paramètres nuls. Si indiqué, elle doit
avoir exactement la même longueur que
value-list
. Si elle est omise, toutes les
valeurs de paramètres sont non NULL.
Sauf si la requête et ses paramètres sont spécifiés,
spi_execp
fonctionne de la même façon que
spi_exec
. Les options -count
,
-array
et loop-body
sont
identiques. Du coup, la valeur du résultat l'est aussi.
Voici un exemple d'une fonction PL/Tcl utilisant un plan préparé :
CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ if {![ info exists GD(plan) ]} { # prépare le plan sauvegardé au premier appel set GD(plan) [ spi_prepare \ "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ [ list int4 int4 ] ] } spi_execp -count 1 $GD(plan) [ list $1 $2 ] return $cnt $$ LANGUAGE pltcl;
Nous avons besoin des antislashs à l'intérieur de la chaîne de la
requête passée à spi_prepare
pour s'assurer que les
marqueurs $
sont passés
au travers de n
spi_prepare
sans transformation et ne sont
pas remplacés avec la substitution de variables de Tcl.
subtransaction
command
Le script Tcl contenu dans command
est
exécuté à l'intérieur d'une sous-transaction SQL. Si le script renvoie
une erreur, la sous-transaction entière est annulée avant de renvoyer
une erreur au code Tcl appelant. Voir Section 44.9 pour plus de détails et un exemple.
quote
string
Double toutes les occurrences de guillemet simple et d'antislash
dans la chaîne donnée. Ceci peut être utilisé pour mettre entre
guillemets des chaînes de façon sûr et pour qu'elles puissent être
insérées dans des commandes SQL passées à spi_exec
ou spi_prepare
. Par exemple, pensez à une
chaîne de commande SQL comme :
"SELECT '$val' AS ret"
où la variable Tcl val
contient actuellement le mot
doesn't
. Ceci finirait avec la chaîne de
commande :
SELECT 'doesn't' AS ret
qui va causer une erreur d'analyse lors de
spi_exec
ou de
spi_prepare
. Pour fonctionner correctement, la
commande soumise devrait contenir :
SELECT 'doesn''t' AS ret
qui peut-être créé avec PL/Tcl en utilisant :
"SELECT '[ quote $val ]' AS ret"
Un avantage de spi_execp
est que vous n'avez pas à
mettre entre guillemets des valeurs de paramètres comme ceux-ci car les
paramètres ne sont jamais analysés comme faisant partie de la chaîne de
la commande SQL.
elog
level
msg
Émet une trace ou un message d'erreur. Les niveaux possibles sont
DEBUG
, LOG
, INFO
,
NOTICE
, WARNING
, ERROR
et
FATAL
. ERROR
élève
une condition d'erreur ; si elle n'est pas récupérée par le code
Tcl, l'erreur est propagée à la requête appelante, causant l'annulation
de la transaction ou sous-transaction en cours. Ceci est en fait
identique à la commande error
. FATAL
annule la transaction et fait que la session courante s'arrête (il
n'existe probablement aucune raison d'utiliser ce niveau d'erreur dans
les fonctions PL/Tcl mais il est fourni pour que tous les messages
soient tout de même disponibles). Les autres niveaux génèrent seulement
des messages de niveaux de priorité différent. Le fait que les
messages d'un niveau de priorité particulier sont reportés au client,
écrit dans les journaux du serveur ou les deux à la fois, est contrôlé
par les variables de configuration log_min_messages
et client_min_messages. Voir le Chapitre 20 et Section 44.8
pour plus d'informations.