В данном разделе мы придерживаемся принятого в Tcl соглашения об использовании знаков вопроса вместо квадратных скобок для обозначения необязательных элементов в описании синтаксиса. Для обращения к базе данных из тела функции PL/Tcl предусмотрены следующие команды:
spi_exec ?-count n? ?-array имя? команда ?тело-цикла?
Выполняет SQL-команду, переданную в виде строки. Ошибка в команде
приводит к возникновению ошибки. В противном случае возвращаемым значением spi_exec
является количество строк, обработанных (выбранных, добавленных, изменённых или
удалённых) командой, или ноль, если команда является вспомогательной
инструкцией. Кроме того, если команда является SELECT инструкцией, то
значения выбранных столбцов помещаются в переменные Tcl как
описано ниже.
Необязательный параметр -count указывает
spi_exec прекратить выполнение,
как только n будет получено указанное количество строк,
подобно тому, как если бы запрос содержал LIMIT предложение.
Если n равно нулю, запрос выполняется до
завершения, так же, как и в случае, когда параметр -count опущен.
Если команда является SELECT оператором, значения
результирующих столбцов помещаются в переменные Tcl, названные по именам столбцов.
Если -array указан параметр, то значения столбцов будут
вместо этого сохранены в элементах указанного ассоциативного массива, при этом
имена столбцов используются в качестве индексов массива. Кроме того, номер текущей строки
в результирующем наборе (начиная с нуля) сохраняется в элементе массива
с именем «.tupno», если только это имя не
используется как имя столбца в результатах запроса.
Если команда является SELECT инструкция, и тело-цикла
скрипт не указан, то в
переменные Tcl или элементы массива сохраняется только первая строка результатов; остальные строки, если они есть, игнорируются.
Сохранение не производится, если запрос не возвращает строк. (Этот случай можно
выявить, проверив результат выполнения команды spi_exec.)
Например:
spi_exec "SELECT count(*) AS cnt FROM pg_proc"
установит значение переменной Tcl $cnt количеству строк в
этом pg_proc системном каталоге.
Если указан необязательный тело-цикла аргумент, он представляет собой
фрагмент скрипта Tcl, который выполняется один раз для каждой строки в
результате запроса. (тело-цикла игнорируется, если заданная
команда не является SELECT.)
Значения столбцов текущей строки
сохраняются в переменные Tcl или элементы массива перед каждой итерацией.
Например:
spi_exec -array C "SELECT * FROM pg_class" {
elog DEBUG "have table $C(relname)"
}
выведет сообщение в лог для каждой строки из pg_class. Эта
функциональность работает аналогично другим циклическим конструкциям Tcl; в
частности, continue и break работают
обычным образом внутри тела цикла.
Если столбец результата запроса имеет значение null, то целевая переменная для него «unset» вместо присваивания значения.
spi_prepare запрос typelistПодготавливает и сохраняет план запроса для последующего выполнения. Этот сохранённый план будет храниться до завершения текущего сеанса.
Запрос может использовать параметры, то есть заполнители для
значений, передаваемых при фактическом выполнении плана.
В строке запроса ссылки на параметры обозначаются
символами $1 ... $.
Если запрос использует параметры, то названия типов параметров
должен быть указан в виде списка Tcl. (Укажите пустой список,
ntypelist если параметры не используются.)
Значение, возвращаемое функцией, spi_prepare представляет собой идентификатор запроса,
предназначенный для использования в последующих вызовах spi_execp. См.
spi_execp пример.
spi_execp ?-count n? ?-array имя? ?-nulls string? queryid ?value-list? ?тело-цикла?
Выполняет запрос, ранее подготовленный с помощью spi_prepare.
queryid — это идентификатор, возвращаемый функцией
spi_prepare. Если запрос ссылается на параметры,
необходимо передать value-list . Этот
представляет собой список Tcl с фактическими значениями параметров. Данный список должен быть
той же длины, что и список типов параметров, ранее переданный в
spi_prepare. Опустите это значение value-list
если в запросе отсутствуют параметры.
Необязательное значение для -nulls представляет собой строку из пробелов и
'n' символов, определяющих, spi_execp
какие из параметров имеют значения null. Если данный аргумент указан, он должен иметь ту же
самую длину, что и value-list. Если он
не задан, все значения параметров считаются отличными от null.
За исключением способа определения запроса и его параметров,
spi_execp работает точно так же, как spi_exec.
Параметры -count, -array, и
тело-цикла опции идентичны,
это же относится и к возвращаемому значению.
Ниже приведен пример функции на языке PL/Tcl, использующей подготовленный план:
CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$
if {![ info exists GD(plan) ]} {
# подготовить сохраненный план при первом вызове
set GD(plan) [ spi_prepare \
"SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \
[ list int4 int4 ] ]
}
spi_execp -count 1 $GD(plan) [ list $1 $2 ]
return $cnt
$$ LANGUAGE pltcl;
Внутри строки запроса, передаваемой в
spi_prepare , необходимы обратные косые черты, чтобы
$ маркеры были переданы
в nspi_prepare в исходном виде, а не заменены посредством
подстановки переменных Tcl.
подтранзакция команда
Tcl-скрипт, содержащийся в команда выполняется
внутри SQL-подтранзакции. Если скрипт возвращает
ошибки вся эта подтранзакция полностью откатывается перед возвратом
ошибки во внешний код Tcl.
См. Раздел 5.7.9 для получения подробных сведений и
примера.
quote string
Дублирует все вхождения символов одинарной кавычки и обратной косой черты
в заданной строке. Это может быть использовано для безопасного заключения в кавычки строк,
которые должны быть вставлены в SQL-команды, передаваемые
в spi_exec или
spi_prepare.
Например, рассмотрим строку SQL-команды вида:
"SELECT '$val' AS ret"
где переменная Tcl val на самом деле содержит
doesn't. Это приведет
к формированию итоговой командной строки следующего вида:
SELECT 'doesn't' AS ret
что вызовет ошибку синтаксического анализа в процессе
spi_exec или
spi_prepare.
Для корректной работы передаваемая команда должна иметь следующий вид:
SELECT 'doesn''t' AS ret
которую в PL/Tcl можно сформировать следующим образом:
"SELECT '[ quote $val ]' AS ret"
Одним из преимуществ spi_execp является отсутствие необходимости
заключать значения параметров в кавычки подобным образом, так как они никогда не
анализируются как часть строки SQL-команды.
elog level msg
Выводит сообщение в журнал или сообщение об ошибке. Допустимые уровни важности:
DEBUG, LOG, INFO,
NOTICE, WARNING, ERROR, и
FATAL. ERROR
генерирует состояние ошибки; если оно не будет перехвачено окружающим
кодом Tcl, ошибка передаётся выше в вызывающий запрос, что приводит к
отмене текущей транзакции или подтранзакции. Это
фактически эквивалентно команде Tcl error command.
FATAL прерывает транзакцию и приводит к завершению текущего
сеанса. (Вероятно, нет веских причин использовать
этот уровень ошибки в функциях PL/Tcl, но он предусмотрен для
полноты.) Другие уровни лишь генерируют сообщения различных
уровней приоритета.
То, будут ли сообщения определенного уровня важности передаваться клиенту,
записываться в журнал сервера или и то, и другое, определяется
log_min_messages и
client_min_messages конфигурационными
переменными. См. Глава 3.4
и Раздел 5.7.8
для получения дополнительной информации.