SPI_prepare

Name

SPI_prepare -- 准备一个规划但不立即执行它

Synopsis

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

描述

SPI_prepare为声明的命令创建和返回一个预备语句但是不执行查询。 该预备语句稍后可以使用SPI_execute_plan重复的执行。

如果相同或者类似的查询要多次重复执行,那么通常只进行一次解析分析应该是更好些, 并且此外可能有利于为该命令重复使用一个执行规划。SPI_prepare 把一个命令字符串转换成一个封装解析分析的结果的预备语句。 如果发现为每个执行生成一个自定义规划没什么帮助, 那么该预备语句也为缓存一个执行规划提供位置。

可以把预编写的查询通用化,方法是在那些普通查询里是常量的地方书写参数 ($1, $2等等)。参数的数值随后在调用SPI_execute_plan 的时候声明。这样就允许已准备的查询在远比没有参数时广泛得多的场合下使用。

SPI_prepare返回的语句只能在当前过程调用中使用, 因为SPI_finish释放为这样一个语句分配的内存。不过, 一个语句可以用函数SPI_keepplanSPI_saveplan 保存更长的时间。

参数

const char * command

命令字符串

int nargs

输入参数的个数($1, $2等等)

Oid * argtypes

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

返回值

SPI_prepare返回一个指向一个SPIPlan的非空指针, 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 获取更多关于预备语句的行为的信息。

这个函数应该只从一个已连接的过程中调用。

SPIPlanPtr声明为一个指针,指向spi.h中的一个不透明的结构类型。 尝试直接访问它的内容是不明智的,因为那样会使得你的代码在未来的 PostgreSQL修订版本中更容易破裂。

名字SPIPlanPtr是历史用法,因为数据结构不再需要包含一个执行规划。