SPI_prepare#
SPI_prepare
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
, за исключением того, что оно будет установлено в SPI_ERROR_ARGUMENT
, если command
равно NULL
, или если nargs
меньше 0, или если nargs
больше 0 и argtypes
равно NULL
.
Примечания
Если параметры не определены, будет создан общий план при первом использовании функции SPI_execute_plan
и будет использоваться для всех последующих выполнений. Если есть параметры, первые несколько использований функции SPI_execute_plan
будут генерировать индивидуальные планы, специфичные для предоставленных значений параметров. После достаточного количества использований того же подготовленного оператора, функция SPI_execute_plan
создаст общий план, и если он не намного дороже индивидуальных планов, она начнет использовать общий план вместо повторного планирования каждый раз. Если это поведение по умолчанию не подходит, вы можете изменить его, передав флаг CURSOR_OPT_GENERIC_PLAN
или CURSOR_OPT_CUSTOM_PLAN
в функцию SPI_prepare_cursor
, чтобы принудительно использовать общие или индивидуальные планы соответственно.
Хотя основная цель подготовленного оператора - избежать повторного анализа и планирования оператора, Tantor BE будет принудительно выполнять повторный анализ и планирование оператора перед его использованием, если объекты базы данных, используемые в операторе, были изменены с момента предыдущего использования подготовленного оператора. Кроме того, если значение search_path изменяется от одного использования к другому, оператор будет повторно разбираться с использованием нового значения search_path
. (Это последнее поведение появилось в PostgreSQL 9.3). См. PREPARE для получения дополнительной информации о поведении подготовленных операторов.
Эта функция должна вызываться только из подключенной C-функции.
SPIPlanPtr
объявляется как указатель на непрозрачный структурный тип в
spi.h
. Не рекомендуется пытаться напрямую обращаться к его содержимому,
так как это может привести к большей вероятности поломки вашего кода
в будущих версиях Tantor BE.
Имя SPIPlanPtr
отчасти историческое, поскольку структура данных больше не обязательно содержит план выполнения.