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 这个名字多少带有历史色彩,因为该数据结构已不再 必然包含执行计划。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。