PostgreSQLLa base de données la plus sophistiquée au monde.

SPI_execute

SPI_execute — exécute une commande

Synopsis

int SPI_execute(const char * command, bool read_only, long count)

Description

SPI_exec lance la commande SQL spécifiée pour count lignes. Si read_only est true, la commande doit être en lecture seule et la surcharge de l'exécution est quelque peu réduite.

Cette fonction ne devrait être appelée qu'à partir d'une procédure connectée.

Si count vaut zéro, alors la commande est exécutée pour toutes les lignes auxquelles elle s'applique. Si count est plus grand que 0, alors le nombre de lignes pour lesquelles la commande sera exécutée est restreint (très semblable à une clause LIMIT). Par exemple :

SPI_execute("INSERT INTO foo SELECT * FROM bar", 5);

autorisera au plus cinq lignes à être insérées dans la table.

Vous pourriez passer plusieurs commandes dans une chaîne, mais ces commandes ne peuvent pas dépendre d'objets créés plus tôt dans la chaîne car toute la chaîne est analysée et planifiée avant le début de l'exécution. SPI_execute renvoie le résultat pour la dernière commande exécutée. La limite count s'applique à chaque commande séparément mais n'est pas appliquée aux commandes cachées par les règles.

Quand read_only vaut false, SPI_execute incrémente le compteur de la commande et calcule une nouvelle image avant d'exécuter chaque commande dans la chaîne. L'image n'est pas réellement modifiée si le niveau d'isolation de la transaction en cours est SERIALIZABLE mais, en mode READ COMMITTED, la mise à jour de l'image permet à chaque commande de voir les résultats des transactions nouvellement validées à partir des autres sessions. Ceci est essentiel pour un comportement cohérent quand les commandes modifient la base de données.

Quand read_only vaut true, SPI_execute ne met à jour ni l'image ni le compteur de commandes, et il autorise seulement les commandes SELECT dans la chaîne des commandes. Elles sont exécutées en utilisant l'image précédemment établie par la requête englobante. Ce mode d'exécution est un peu plus rapide que le mode lecture/écriture à cause de l'élimination de la surcharge par commande. Il autorise aussi directement la construction des fonctions stable  comme les exécutions successives utiliseront toutes la même image, il n'y aura aucune modification dans les résultats.

Il n'est généralement pas conseillé de mixer les commandes en lecture seule et les commandes en lecture/écriture à l'intérieur d'une seule fonction utilisant SPI ; ceci pourrait causer un comportement portant confusion car les requêtes en mode lecture seule devraient ne pas voir les résultats de toute mise à jour de la base de données effectuées par les requêtes en lecture/écriture.

Le nombre réel de lignes pour lesquelles la (dernière) commande a été lancée est retourné dans la variable globale SPI_processed. Si la valeur de retour de la fonction est SPI_OK_SELECT, SPI_OK_INSERT_RETURNING, SPI_OK_DELETE_RETURNING ou SPI_OK_UPDATE_RETURNING, alors vous pouvez utiliser le pointeur global SPITupleTable *SPI_tuptable pour accéder aux lignes de résultat. Quelques commandes (comme EXPLAIN) renvoient aussi des ensembles de lignes et SPI_tuptable contiendra aussi le résultat dans ces cas.

La structure SPITupleTable est définie comme suit :

typedef struct
{
    MemoryContext tuptabcxt;    /* contexte mémoire de la table de résultat */
    uint32      alloced;        /* nombre de valeurs allouées */
    uint32      free;           /* nombre de valeurs libres */
    TupleDesc   tupdesc;        /* descripteur de rangées */
    HeapTuple  *vals;           /* rangées */
} SPITupleTable;

vals est un tableau de pointeurs vers des lignes (le nombre d'entrées valables est donné par SPI_processed). tupdesc est un descripteur de ligne que vous pouvez passer aux fonctions SPI qui traitent des lignes. tuptabcxt, alloced et free sont des champs internes non conçus pour être utilisés par des routines SPI appelantes.

SPI_finish libère tous les SPITupleTables allouées pendant la procédure courante. Vous pouvez libérer une table de résultats donnée plus tôt, si vous en avez terminé avec elle, en appelant SPI_freetuptable.

Arguments

const char * command

chaîne contenant la commande à exécuter

bool read_only

true en cas d'exécution en lecture seule

long count

nombre maximum de lignes à traiter ou à retourner

Valeur de retour

Si l'exécution de la commande a réussi, alors l'une des valeurs (positives) suivantes sera renvoyée :

SPI_OK_SELECT

si un SELECT (mais pas SELECT INTO) a été lancé

SPI_OK_SELINTO

si un SELECT INTO a été lancé

SPI_OK_INSERT

si un INSERT a été lancé

SPI_OK_DELETE

si un DELETE a été lancé

SPI_OK_UPDATE

si un UPDATE a été lancé

SPI_OK_INSERT_RETURNING

si un INSERT RETURNING a été lancé

SPI_OK_DELETE_RETURNING

si un DELETE RETURNING a été lancé

SPI_OK_UPDATE_RETURNING

si un UPDATE RETURNING a été lancé

SPI_OK_UTILITY

si une commande utilitaire (c'est-à-dire CREATE TABLE) a été lancée

SPI_OK_REWRITTEN

si la commande a été réécrite dans un autre style de commande (c'est-à-dire que UPDATE devient un INSERT) par une règle.

Sur une erreur, l'une des valeurs négatives suivante est renvoyée :

SPI_ERROR_ARGUMENT

si command est NULL ou count est inférieur à 0

SPI_ERROR_COPY

si COPY TO stdout ou COPY FROM stdin ont été tentés

SPI_ERROR_TRANSACTION

Si une commande de manipulation de transaction a été tentée (BEGIN, COMMIT, ROLLBACK, SAVEPOINT, PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED ou toute variante de ces dernières)

SPI_ERROR_OPUNKNOWN

si le type de commande est inconnu (ce qui ne devrait pas arriver)

SPI_ERROR_UNCONNECTED

si appel à partir d'une procédure non connectée

Notes

Les fonctions SPI_execute, SPI_exec, SPI_execute_plan et SPI_execp changent à la fois SPI_processed et SPI_tuptable (juste le pointeur, pas le contenu de la structure). Sauvegardez ces deux variables globales dans des variables locales de procédures si vous voulez accéder à la table des résultats de SPI_execute ou d'une fonction relative sur plusieurs appels.