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
在某种程度上是历史性的,因为数据结构不再必然包含执行计划。
如果您发现文档中的任何内容不正确、与您使用特定功能的体验不符或需要进一步澄清,请使用此表格报告文档问题。