SPI_prepare — prépare une instruction sans l'exécuter tout de suite
SPIPlanStr SPI_prepare(const char *command
, intnargs
, Oid *argtypes
)
SPI_prepare
crée et retourne une requête préparée
pour la commande spécifiée mais ne lance pas la commande.
La requête préparée peut être appelée plusieurs fois en utilisant
SPI_execute_plan
.
Lorsque la même commande ou une commande semblable doit être lancée à
plusieurs reprises, il est généralement avantageux de réaliser une
analyse du plan d'exécution une fois et de ré-utiliser le plan
d'exécution pour la commande.
SPI_prepare
convertit une chaîne de commande en une
requête préparée qui encapsule le résultat de l'analyse du plan. La
requête préparée fournit aussi une place pour mettre en cache un plan
d'exécution s'il s'avère que la génération d'un plan personnalisé pour
chaque exécution n'est pas utile.
Une commande préparée peut être généralisée en utilisant les paramètres
($1
, $2
, etc.) en lieu et place de ce qui serait des
constantes dans une commande normale. Les valeurs actuelles des paramètres
sont alors spécifiées lorsque SPI_executeplan
est appelée.
Ceci permet à la commande préparée d'être utilisée sur une plage plus grande
de situations que cela ne serait possible sans paramètres.
La requête renvoyée par SPI_prepare
ne peut être utilisé
que dans l'invocation courante de la procédure puisque
SPI_finish
libère la mémoire allouée pour la requête.
Mais l'instruction peut être sauvegardée plus longtemps par l'utilisation des
fonctions SPI_keepplan
ou SPI_saveplan
.
const char * command
chaîne contenant la commande à planifier
int nargs
nombre de paramètres d'entrée ($1
, $2
, etc.)
Oid * argtypes
pointeur vers un tableau contenant les OID des types de données des paramètres
SPI_prepare
retourne un pointeur non nul vers un
plan d'exécution. En cas d'erreur, NULL
sera retourné
et SPI_result
sera positionnée à un des mêmes codes
d'erreur utilisés par SPI_execute
sauf qu'il
est positionné à SPI_ERROR_ARGUMENT
si
command
est NULL
ou si
nargs
est inférieur à 0 ou si nargs
est
supérieur à 0 et typesargs
est NULL
.
Si aucun paramètre n'est défini, un plan générique sera créé lors de la
première utilisation de SPI_execute_plan
, et utilisé
aussi pour toutes les exécutions suivantes. Si des paramètres sont fournis,
les premières utilisations de SPI_execute_plan
génèreront
des plans personnalisés qui sont spécifiques aux valeurs fournies pour les
paramètres. Après suffisamment d'utilisation de la même requête préparée,
SPI_execute_plan
construira un plan générique et, si
ce n'est pas beaucoup plus coûteux que les plans personnalisés, cette fonction
commencera à utiliser le plan générique au lieu de re-planifier à chaque fois.
Si le comportement par défaut n'est pas tenable, vous pouvez le modifier en
passant le drapeau CURSOR_OPT_GENERIC_PLAN
ou
CURSOR_OPT_CUSTOM_PLAN
à
SPI_prepare_cursor
pour forcer l'utilisation,
respectivement, de plans génériques ou personnalisés.
Bien que le but principal d'une requête préparée est déviter les étapes
d'analyser et de planification d'une requête,
PostgreSQL forcera l'analyse et la planification
de la requête avant de l'utiliser quand les objets de la base utilisés
dans la requête ont subi des changements de définition (à partir de
requêtes DDL) depuis la dernière utilisation de la requête préparée. De
plus, si la valeur de search_path change d'une
exécution à une autre, la requête sera de nouveau planifiée en utilisant
le nouveau search_path
(ce dernier comportement est une
nouveauté de la version 9.3 de PostgreSQL). Voir
PREPARE pour plus d'informations sur le comportement
des requêtes préparées.
Cette fonction doit seulement être appelée à partir d'une procédure connectée.
SPIPlanPtr
est déclaré comme un pointeur vers un type de
structure opaque dans spi.h
. Il est déconseillé d'essayer
d'accéder à son contenu directement car cela rend votre code plus fragile aux
futures versions de PostgreSQL.
Le nom SPIPlanPtr
est historique principalement car la structure
des données ne contient plus nécessairement un plan d'exécution.