PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

SPI_prepare

SPI_prepare — 准备一条语句,但还不执行它

Synopsis

SPIPlanPtr SPI_prepare(const char * command, int nargs, Oid * argtypes)

描述

SPI_prepare 为指定的命令创建并返回一个 预备好的语句,但不执行该命令。 预备好的语句之后可以用 SPI_execute_plan 反复执行。

当要重复执行相同或相似的命令时,只做一次解析分析通常是有利的, 而且复用该命令的一个执行计划可能进一步有利。 SPI_prepare 把一个命令字符串转换成一个 封装了解析分析结果的预备语句。 如果发现为每次执行生成定制计划没有帮助, 预备语句还提供了一个缓存执行计划的位置。

可以通过在普通命令中写常量的位置写参数 ( $1、 $2 等)来把预备好的命令泛化。 参数的实际值随后在 SPI_execute_plan 被调用时指定。 这使得预备好的命令能够被用在比无参数时更宽泛的 场景中。

SPI_prepare 返回的语句只能在当前 C 函数 调用中使用, 因为 SPI_finish 会释放为这样的语句分配的 内存。 但可以使用 SPI_keepplan 或 SPI_saveplan 函数把语句保存得更久。

参数

const char * command

命令字符串

int nargs

输入参数的数量 ( $1、 $2 等)

Oid * argtypes

指向一个包含参数数据类型的 OID 的数组的指针

返回值

SPI_prepare 返回一个指向 SPIPlan(一个表示预备语句的不透明结构)的非空 指针。 出错时会返回 NULL,并且 SPI_result 会被设为 SPI_execute 使用的相同错误代码之一, 只是当 command 为 NULL,或 nargs 小于 0,或 nargs 大于 0 且 argtypes 为 NULL 时,它被设为 SPI_ERROR_ARGUMENT。

注意

如果没有定义参数,将在第一次使用 SPI_execute_plan 时创建一个通用计划, 并且把它用于所有后续执行。 如果有参数, SPI_execute_plan 的最初几次使用会生成 针对所提供参数值定制的计划。 在对同一个预备语句使用了足够多次之后, SPI_execute_plan 会构建一个通用计划, 如果它比定制计划贵不了太多,就会开始使用通用计划而不是每次 重新规划。 如果这种默认行为不合适,您可以通过把 CURSOR_OPT_GENERIC_PLAN 或 CURSOR_OPT_CUSTOM_PLAN 标志传给 SPI_prepare_cursor 来改变它, 分别强制使用通用或定制计划。

虽然预备语句的主要目的是避免对语句的重复解析分析和规划, 但每当语句中使用的数据库对象自上次使用预备语句以来经历了 定义性(DDL)更改, PostgreSQL 就会强制在使用它之前 重新分析和重新规划该语句。 此外,如果 search_path 的值在两次使用之间发生了 变化,语句将使用新的 search_path 重新解析。 (后一种行为是 PostgreSQL 9.3 新增的。) 关于预备语句行为的更多信息见 PREPARE。

这个函数应当只从已连接的 C 函数中调用。

SPIPlanPtr 在 spi.h 中被声明为指向一个不透明结构类型的 指针。 试图直接访问其内容是不明智的, 因为那会让您的代码在 PostgreSQL 的未来修订中更容易 失效。

SPIPlanPtr 这个名字有些历史遗留意味, 因为该数据结构已不再必然包含一个执行计划。