SPI_prepare — 准备一条语句,但还不执行它
SPIPlanPtr SPI_prepare(const char *command, intnargs, 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 这个名字有些历史遗留意味,
因为该数据结构已不再必然包含一个执行计划。