大纲
SPI_exec(query,tcount)
输入
- char *
query 包含查询计划的字符串
- int
tcount 要返回的最大元组数
输出
- int
→ SPI_ERROR_UNCONNECTED从未连接的过程中调用时→ SPI_ERROR_ARGUMENTquery 为 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 query 为 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_processed 给出)。tupdesc 是一个元组描述符,可以传给处理元组的 SPI 函数。tuptabcxt、alloced 和 free 是内部字段,不供
SPI 调用者使用。
注意
函数 SPI_exec、SPI_execp 和
SPI_prepare 都会更改 SPI_processed 和
SPI_tuptable(只更改指针,而不更改结构体内容)。如果需要在后续调用之后继续访问某次 SPI_exec 或
SPI_execp 的结果,请把这两个全局变量保存到过程局部变量中。
SPI_finish 会释放当前过程调用期间分配的全部
SPITupleTable。如果某个结果表已经不再需要,也可以提前调用
SPI_freetuptable 释放它。