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
来更改它,以分别强制使用通用计划或自定义计划。
虽然准备语句的主要目的是避免重复解析分析和规划语句,但 PostgreSQL 将在每次使用语句的数据库对象发生定义 (DDL) 更改后,强制在使用准备语句之前重新分析和重新规划该语句。此外,如果 search_path 的值从一次使用到另一次使用发生更改,则将使用新的 search_path
重新解析该语句。(这种后一种行为是自 PostgreSQL 9.3 开始的新行为。)有关准备语句行为的更多信息,请参见 PREPARE。
此函数只能从连接的 C 函数调用。
SPIPlanPtr
在 spi.h
中声明为指向不透明结构体类型的指针。尝试直接访问其内容是不明智的,因为这会使您的代码更有可能在 PostgreSQL 的未来版本中出现错误。
名称 SPIPlanPtr
有点历史意义,因为数据结构不再一定包含执行计划。
如果您在文档中发现任何不正确的内容,与您对特定功能的体验不符,或者需要进一步说明,请使用 此表格 报告文档问题。