2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4

SPI_prepare

SPI_prepare — 准备一个语句,暂不执行

概要

SPIPlanPtr SPI_prepare(const char * command, int nargs, Oid * argtypes)

描述

SPI_prepare 会为指定的命令创建并返回一个预备语句,但不会执行该命令。该预备语句之后可以使用 SPI_execute_plan 进行重复执行。

当需要重复执行相同或相似的命令时,通常的好处是只进行一次解析分析,并且可能进一步的好处是为命令重用执行计划。 SPI_prepare 将命令字符串转换为一个预备语句,该语句封装了解析分析的结果。该预备语句还为缓存执行计划提供了一个位置,如果发现为每次执行生成定制计划没有帮助的话。

可以通过在普通命令中的常量位置写入参数($1$2 等)来泛化预备命令。参数的实际值随后在调用 SPI_execute_plan 时指定。这使得预备命令可以用于比没有参数时更广泛的场景。

SPI_prepare 返回的语句只能在当前 C 函数的调用中使用,因为 SPI_finish 会释放为此类语句分配的内存。但可以使用 SPI_keepplanSPI_saveplan 函数将该语句保存更长时间。

参数

const char * command

command string

int nargs

输入参数的数量($1$2 等)

Oid * argtypes

指向一个数组的指针,其中包含OID参数的数据类型

返回值

SPI_prepare 返回一个非空指针,指向 SPIPlan,这是一个表示预备语句的不透明结构。发生错误时,将返回 NULL,并且 SPI_result 将被设置为与 SPI_execute 使用的错误代码相同的错误代码之一,但如果 commandNULL,或者 nargs 小于 0,或者 nargs 大于 0 且 argtypesNULL,则其将被设置为 SPI_ERROR_ARGUMENT

注释

如果没有定义参数,将在第一次使用 SPI_execute_plan 时创建一个通用计划,并用于所有后续执行。如果存在参数,第一次使用 SPI_execute_plan 将生成特定于提供的参数值的定制计划。在使用相同的预备语句足够多次后,SPI_execute_plan 将构建一个通用计划,如果通用计划的开销不会比定制计划高太多,它将开始使用通用计划而不是每次都重新规划。如果默认行为不适用,您可以通过将 CURSOR_OPT_GENERIC_PLANCURSOR_OPT_CUSTOM_PLAN 标志传递给 SPI_prepare_cursor 来改变它,分别强制使用通用计划或定制计划。

尽管预备语句的主要作用是避免对语句进行重复的解析分析和规划,但当语句中使用的数据库对象在上次使用预备语句后经历了定义(DDL)更改时,PostgreSQL 会强制对语句进行重新分析和重新规划。此外,如果 search_path 的值在使用之间发生变化,该语句将使用新的 search_path 进行重新解析。(此后者的行为是 PostgreSQL 9.3 及以后的新特性。)有关预备语句行为的更多信息,请参阅 PREPARE

此函数只能从已连接的 C 函数中调用。

SPIPlanPtrspi.h 中被声明为指向不透明结构类型的指针。尝试直接访问其内容是不明智的,因为这会使您的代码在 PostgreSQL 的未来版本中更容易出现问题。

名称 SPIPlanPtr 具有一定的历史性,因为该数据结构不再一定包含执行计划。

提交更正

如果您在文档中发现任何不正确之处、与您对特定功能的体验不符之处或需要进一步澄清之处,请使用 此表单 报告文档问题。