↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0
历史版本PostgreSQL 8.2 已于 2011 年 12 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

SPI_execute

SPI_execute — 执行一个命令

大纲

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

描述

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_finish 会释放当前过程调用期间分配的全部 SPITupleTable。如果某个结果表已经不再需要,也 可以提前调用 SPI_freetuptable 释放它。

参数

const char * command

包含待执行命令的字符串

bool read_only

true 表示只读执行

long count

要处理或返回的最大行数

返回值

如果命令执行成功,则返回下列(非负)值之一:

SPI_OK_SELECT

执行了 SELECT(但不是 SELECT INTO)

SPI_OK_SELINTO

执行了 SELECT INTO

SPI_OK_INSERT

执行了 INSERT

SPI_OK_DELETE

执行了 DELETE

SPI_OK_UPDATE

执行了 UPDATE

SPI_OK_INSERT_RETURNING

执行了 INSERT RETURNING

SPI_OK_DELETE_RETURNING

执行了 DELETE RETURNING

SPI_OK_UPDATE_RETURNING

执行了 UPDATE RETURNING

SPI_OK_UTILITY

执行了工具命令(例如 CREATE TABLE)

出错时,返回下列负值之一:

SPI_ERROR_ARGUMENT

如果command为NULL或 count小于 0

SPI_ERROR_COPY

尝试执行了 COPY TO stdout 或 COPY FROM stdin

SPI_ERROR_CURSOR

试图执行DECLARE、CLOSE或FETCH命令

SPI_ERROR_TRANSACTION

尝试执行了事务控制命令(BEGIN、 COMMIT、ROLLBACK、 SAVEPOINT、 PREPARE TRANSACTION、 COMMIT PREPARED、 ROLLBACK PREPARED 及其各种变体)

SPI_ERROR_OPUNKNOWN

命令类型未知(理论上不应发生)

SPI_ERROR_UNCONNECTED

如果从未连接的过程中调用

注解

函数 SPI_execute、SPI_exec、 SPI_execute_plan 和 SPI_execp 都会更改 SPI_processed 和 SPI_tuptable(只更改指针,而不更改结构体内容)。如果 需要在后续调用之后继续访问 SPI_execute 或相关函数 的结果表,请把这两个全局变量保存到过程局部变量中。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。