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_keepplan
或SPI_saveplan
保存更长的时间。
参数
const char *
command
命令字符串
int
nargs
输入参数的个数($1
, $2
等等)
Oid *
argtypes
一个指针,指向包含参数数据类型的OID数组
返回值
SPI_prepare
返回一个指向一个SPIPlan
的非空指针, 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 获取更多关于预备语句的行为的信息。
这个函数应该只从一个已连接的过程中调用。
SPIPlanPtr
声明为一个指针,指向spi.h
中的一个不透明的结构类型。 尝试直接访问它的内容是不明智的,因为那样会使得你的代码在未来的 PostgreSQL修订版本中更容易破裂。
名字SPIPlanPtr
是历史用法,因为数据结构不再需要包含一个执行规划。