SPI_execute
执行声明的 SQL 命令获取 count 行。如果 read_only 为 true ,命令必须是只读的,因此可以略微降低一些执行的开销。
这个函数只能在已连接的过程中调用。
如果 count 是零,则在命令适合的所有行上执行。如果 count 大于 0 ,那么命令执行的行数将被限制(很像一个 LIMIT 子句)。比如,
SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);
将只允许最多 5 行插入表中。
你可以在一个字符串里传递多个命令。SPI_execute
返回最后执行的命令的结果。count 的限制独立地应用于每一个命令,但是不会应用于规则生成的隐藏命令。
如果 read_only 是 false ,SPI_execute
递增命令计数器并且在执行字符串里的每个命令之前计算一个新的快照。如果当前事务的隔离级别是 SERIALIZABLE ,这个快照实际上并不改变,但是在 READ COMMITTED 模式里,这个快照更新允许每个命令看到其它会话的事务提交的结果。这样实际上是为了修改数据库的命令有一致的行为。
如果 read_only 是 true ,SPI_execute
并不更新快照或者命令计数器,并且它指允许简单的 SELECT 命令出现在命令字符串里。这个命令使用为周围的查询建立起来的快照执行。这个执行模式比读/写模式执行得略微块些,因为它消除了每个命令的一些开销。并且它还允许制作真正的稳定函数:因为随后的执行都将使用同一个快照,结果里不会有改变。
通常,在同一个使用 SPI 的函数里混杂只读和读写命令是不明智的;那样可能导致非常混乱的行为,因为只读的查询不能看到任何读写的查询做的数据库更新。
(最后)一条命令执行返回的结果的实际行数会放在全局的变量 SPI_processed 里。如果函数的返回值是 SPI_OK_SELECT, SPI_OK_INSERT_RETURNING, SPI_OK_DELETE_RETURNING, SPI_OK_UPDATE_RETURNING ,那么你可以使用全局指针 SPITupleTable *SPI_tuptable 访问结果行。一些实用命令(比如 EXPLAIN)还返回行集合,并且 SPI_tuptable 也将在这种情况下包含结果。
结构 SPITupleTable 是这样定义的:
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 调用者使用的。
SPI_finish
释放所有在当前过程中分配的 SPITupleTable 。如果你已经处理完特定的结果表,那么可以更早地释放它,方法是调用 SPI_freetuptable
如果命令执行成功,那么返回下列值之一(非负数):
如果执行了一个 SELECT 但不是 SELECT INTO
如果执行了一条 SELECT INTO
如果执行了一条 INSERT
如果执行了一条 DELETE
如果执行了一条 UPDATE
如果执行了一条 INSERT RETURNING
如果执行了一条 DELETE RETURNING
如果执行了一条 UPDATE RETURNING
如果执行了一条实用命令(比如 CREATE TABLE)
发生错误时,返回下列负数值之一:
如果 command 是 NULL 或 count 小于 0
如果企图进行 COPY TO stdout 或 COPY FROM stdin
如果企图进行 DECLARE, CLOSE, FETCH
如果企图调用任何事务操纵命令(BEGIN, COMMIT, ROLLBACK, SAVEPOINT, PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED 或它们的变种)
命令类型未知(不应该发生)
如果从一个未连接的过程中调用