SPI_exec

Name

SPI_exec --  创建一个执行规划 (分析器+规划器+优化器)并且执行一个查询.

Synopsis

SPI_exec(query, tcount)

输入

char *query

包含查询规划的字符串

int tcount

返回的最大记录数

输出

int

SPI_ERROR_UNCONNECTED 如果从一个未联接的过程调用,返回此值
SPI_ERROR_ARGUMENT 如果查询是 NULL 或者 tcount < 0 ,返回此值
SPI_ERROR_UNCONNECTED 如果过程未联接,返回此值.
SPI_ERROR_COPY 如果 COPY TO/FROM stdin(标准输入),返回此值.
SPI_ERROR_CURSOR 如果 DECLARE/CLOSE CURSOR,FETCH,返回此值
SPI_ERROR_TRANSACTION 如果 BEGIN/ABORT/END, 返回此值.
SPI_ERROR_OPUNKNOWN 如果查询类型未知(这种情况不应发生).

如果你的查询执行成功,那么将返回下列非负数值之一:

SPI_OK_UTILITY 如果执行了某些应用(例如 CREATE TABLE ...)
SPI_OK_SELECT 如果执行了 SELECT (但不是 SELECT ... INTO!)
SPI_OK_SELINTO 如果执行了 SELECT ... INTO
SPI_OK_INSERT 如果执行了 INSERT(或 INSERT ... SELECT)
SPI_OK_DELETE 如果执行了 DELETE
SPI_OK_UPDATE 如果执行了 UPDATE

描述

SPI_exec 创建一个执行规划(分析器+规划器+优化器)并且执行查询以获取 tcount 条记录.

用法

这个(函数)只能从一个已联接的过程中调用. 如果 tcount 是零则对查询扫描返回的所有记录都执行查询. 使用 tcount > 0 你可以限制查询执行的记录数(很象 LIMIT 子句).例如,

SPI_exec ("INSERT INTO tab SELECT * FROM tab", 5);

将允许最多 5 条记录插入表中.如果你的查询执行成功则返回一个非负数.

注意: 你可能在一个字符串里传递多个查询或一个查询字符串可能被 RULE (规则)重写. SPI_exec 返回最后一个执行的查询的结果.

最后一个被执行的查询的实际记录数放在全局变量 SPI_processed 里返回 (如果不是 SPI_OK_UTILITY). 如果返回 SPI_OK_SELECT,那么你可以使用全局指针 SPITupleTable *SPI_tuptable 访问结果集.

SPI_exec 可能返回下面的(本地)值:

SPI_ERROR_ARGUMENT 如果查询是 NULL (空)或 tcount < 0 ,返回此值.
SPI_ERROR_UNCONNECTED 如果过程没有联接,返回此值.
SPI_ERROR_COPY 如果是 COPY TO/FROM stdin(标准输入),返回此值.
SPI_ERROR_CURSOR 如果是 DECLARE/CLOSE CURSOR,FETCH,返回此值.
SPI_ERROR_TRANSACTION 如果 BEGIN/ABORT/END,返回此值.
SPI_ERROR_OPUNKNOWN 如果查询类型未知(不应发生这种情况),返回此值.

结构

如果返回 SPI_OK_SELECT, 那么你可疑用全局指针 SPITupleTable *SPI_tuptable 访问选出的元组.

结构 SPITupleTable 定义在 spi.h 里∶

   typedef struct
   {
       MemoryContext tuptabcxt;    /* 结果表的内存环境 */
       uint32      alloced;        /* 分配的 vals 的数目 */
       uint32      free;           /* 空余 vals 的数目 */
       TupleDesc   tupdesc;        /* 元组描述符 */
       HeapTuple  *vals;           /* 元组 */
   } SPITupleTable;

vals是一个指向元组的指针数组(有用的条目是 SPI_proceed 给出的). tupdesc是一个元组描述符,你可以把它传递给 SPI 函数处理元组. tuptabctxalloced,和 free都是内部字段,不是给 SPI 调用者使用的.

Note: 函数 SPI_execSPI_execpSPI_prepare 都修改 SPI_processed 和 SPI_tuptable(只是修改指针,而不是结构的内容). 如果你需要跨越稍后的调用访问 SPI_execSPI_execp 的结果,请把这两个全局变量保存到 局部过程变量中.

SPI_finish 释放所有在当前的过程中分配的 SPITupleTables.如果你已经完成处理,那么你可以提前释放一个特定的结果表, 方法是调用 SPI_freetuptable