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
的非空指针,它是一个表示已准备好语句的不透明 struct。出错时,将返回 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
中一个不透明 struct 类型的指针。尝试直接访问其内容是明智的,因为这使您的代码在 PostgreSQL 的未来版本中很容易发生中断。
名称 SPIPlanPtr
是有些历史性的,因为数据结构不再必定包含执行计划。