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
command string
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
具有一定的历史性,因为该数据结构不再一定包含执行计划。
如果您在文档中发现任何不正确之处、与您对特定功能的体验不符之处或需要进一步澄清之处,请使用 此表单 报告文档问题。