## SPI\_准备 SPI_prepare — 准备一个语句,但还没有执行它 ## 概要 ``` SPIPlanPtr SPI_prepare(const char * command, int nargs, Oid * argtypes) ``` ## 描述 `SPI_prepare`为指定的命令创建并返回一个准备好的语句,但不执行该命令。准备好的语句稍后可以使用重复执行`SPI_execute_plan`. 当要重复执行相同或相似的命令时,通常只执行一次解析分析是有利的,并且可能更有利于重复使用该命令的执行计划。`SPI_prepare`将命令字符串转换为封装解析分析结果的预处理语句。如果发现为每个执行生成自定义计划没有帮助,prepared statement 还提供了缓存执行计划的地方。 一个准备好的命令可以通过写参数来泛化(`1美元`,`2美元`等)代替普通命令中的常量。然后指定参数的实际值`SPI_execute_plan`叫做。与没有参数的情况相比,这允许在更广泛的情况下使用准备好的命令。 返回的语句`SPI_prepare`只能在 C 函数的当前调用中使用,因为`SPI_完成`释放为此类语句分配的内存。但是使用函数可以将语句保存更长时间`SPI_keepplan`或者`SPI_saveplan`. ## 论据 `常量字符 * *`命令`*` 命令字符串 `整数 *`纳尔格斯`*` 输入参数的数量(`1美元`,`2美元`, 等等。) `好* *`参数类型`*` 指向包含参数数据类型的 OID 的数组的指针 ## 返回值 `SPI_prepare`返回一个非空指针`SPI计划`,这是一个不透明的结构,表示准备好的语句。出错时,`空值`将被退回,并且`SPI_结果`将设置为使用的相同错误代码之一`SPI_执行`, 除了它设置为`SPI_ERROR_ARGUMENT`如果*`命令`*是`空值`, 或者如果*`纳尔格斯`*小于 0,或者如果*`纳尔格斯`*大于 0 并且*`参数类型`*是`空值`. ## 笔记 如果没有定义参数,则在第一次使用时会创建一个通用计划`SPI_execute_plan`, 并用于所有后续执行。如果有参数,前几次使用`SPI_execute_plan`will generate custom plans that are specific to the supplied parameter values. After enough uses of the same prepared statement,`SPI_execute_plan`will build a generic plan, and if that is not too much more expensive than the custom plans, it will start using the generic plan instead of re-planning each time. If this default behavior is unsuitable, you can alter it by passing the`CURSOR_OPT_GENERIC_PLAN`or`CURSOR_OPT_CUSTOM_PLAN`flag to`SPI_prepare_cursor`, to force use of generic or custom plans respectively. Although the main point of a prepared statement is to avoid repeated parse analysis and planning of the statement, PostgreSQL will force re-analysis and re-planning of the statement before using it whenever database objects used in the statement have undergone definitional (DDL) changes since the previous use of the prepared statement. Also, if the value of[search_path](runtime-config-client.html#GUC-SEARCH-PATH)changes from one use to the next, the statement will be re-parsed using the new`search_path`. (This latter behavior is new as of PostgreSQL 9.3.) See[PREPARE](sql-prepare.html)for more information about the behavior of prepared statements. This function should only be called from a connected C function. `SPIPlanPtr`is declared as a pointer to an opaque struct type in`spi.h`. It is unwise to try to access its contents directly, as that makes your code much more likely to break in future revisions of PostgreSQL. The name`SPIPlanPtr`is somewhat historical, since the data structure no longer necessarily contains an execution plan.