Доступ к базе данных из PL/Tcl
Эта страница переведена при помощи нейросети GigaChat.
Этот раздел оформлен в соответствии с обычной конвенцией Tcl, используя вопросительные знаки вместо скобок для обозначения необязательного элемента в синтаксическом обзоре. Следующие команды доступны для доступа к базе данных из тела функции PL/Tcl:
spi_exec ?-count n? ?-array name? command? loop-body?
Выполняет команду SQL, заданную строкой. Ошибка в команде вызывает ошибку. В противном случае возвращаемое значение spi_exec
– это количество строк, обработанных (выбранных, вставленных, обновленных или удаленных) командой, или ноль, если команда является служебным оператором. Кроме того, если команда является оператором SELECT
, значения выбранных столбцов помещаются в переменные Tcl, как описано ниже.
Необязательное значение -count
указывает spi_exec
прекратить выполнение после получения n
строк, так же, как если бы запрос включал предложение LIMIT
. Если n
равен нулю, запрос выполняется до завершения, то же самое происходит при пропуске -count
.
Если команда является оператором SELECT
, значения столбцов результата помещаются в переменные Tcl с именами, соответствующими столбцам. Если указан параметр -array
, значения столбцов вместо этого сохраняются в элементы ассоциативного массива с именами столбцов, используемыми в качестве индексов массива. Кроме того, текущий номер строки в результате (считая от нуля) сохраняется в элемент массива с именем .tupno
, если это имя не используется в качестве имени столбца в результате.
Если команда является оператором SELECT
и сценарий loop-body
не предоставлен, то только первая строка результатов сохраняется в переменных или элементах массива Tcl, оставшиеся строки, если они есть, игнорируются. Никакое сохранение не происходит, если запрос не возвращает никаких строк. Этот случай можно обнаружить, проверив результат выполнения команды spi_exec
. Например:
spi_exec "SELECT count(*) AS cnt FROM pg_proc"
Установит переменную Tcl $cnt
равную количеству строк в системном каталоге pg_proc
.
Если передается необязательный аргумент loop-body
, заданный в нем блок скрипта Tcl будет выполняться для каждой строки результата запроса. Аргумент loop-body
игнорируется, если целевая команда — не SELECT
. Значения столбцов текущей строки сохраняются в переменные Tcl или элементы массива перед каждым повторением. Например:
spi_exec -array C "SELECT * FROM pg_class" {
elog DEBUG "have table $C(relname)"
}
Будет выводить сообщение журнала для каждой строки pg_class
. Эта функция работает аналогично другим конструкциям цикла Tcl, в частности, continue
и break
работают обычным образом внутри тела цикла.
Если какой-либо столбец результата запроса имеет значение NULL
, целевая переменная для него будет «неустановленной», а не установлена.
spi_prepare query typelist
*
Подготавливает и сохраняет план запроса для последующего выполнения. Сохраненный план будет сохраняться до конца текущего сеанса.
Запрос может использовать параметры, то есть заполнители для значений, которые будут предоставлены всякий раз при фактическом выполнении плана. В строке запроса ссылайтесь на параметры с помощью символов $1 ... $n
. Если запрос использует параметры, имена типов параметров должны быть даны в виде списка Tcl. Напишите пустой список для typelist
, если параметры не используются.
Возвращаемое значение из spi_prepare
– это идентификатор запроса, который будет использоваться в последующих вызовах к spi_execp
. См. spi_execp
для примера.
spi_execp ?-count n? ?-array name? ?-nulls string? queryid ?value-list? ?loop-body?
Выполняет запрос, предварительно подготовленный с использованием spi_prepare
. queryid
– это идентификатор, возвращаемый spi_prepare
. Если запрос ссылается на параметры, необходимо предоставить value-list
. Это список Tcl фактических значений для параметров. Список должен иметь ту же длину, что и ранее предоставленный список типов параметров spi_prepare
. Пропустите value-list
, если у запроса нет параметров.
Необязательное значение для -nulls
– это строка пробелов и символов 'n'
, указывающая spi_execp
, какие из параметров являются пустыми значениями. Если указано, оно должно быть точно такой же длины, что и value-list
. Если он не указан, все значения параметров не равны нулю.
За исключением способа, которым задается запрос и его параметры, spi_execp
работает точно так же, как spi_exec
. Параметры -count
, -array
и loop-body
одинаковы, и то же самое касается возвращаемого значения.
Вот пример функции PL/Tcl с использованием подготовленного плана:
CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$
if {![ info exists GD(plan) ]} {
# prepare the saved plan on the first call
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
, чтобы убедиться, что маркеры $n
будут переданы в spi_prepare
без изменений, а не заменены подстановкой переменной Tcl.
subtransaction
command
Сценарий Tcl, содержащийся в command
, выполняется внутри подоперации SQL. Если сценарий возвращает ошибку, вся эта подоперация откатывается перед возвратом ошибки обратно в окружающий код Tcl. См. раздел «Явные подтранзакции в PL/Tcl» для получения дополнительных сведений и примера.
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, ошибка распространяется к вызывающему запросу, вызывая прерывание текущей транзакции или подоперации. По сути то же самое делает команда error
языка Tcl. FATAL
прерывает транзакцию и приводит к завершению текущего сеанса. Вероятно, нет веских причин использовать этот уровень ошибок в функциях PL/Tcl, но он предоставляется для полноты картины. Другие уровни генерируют только сообщения различных уровней приоритета. Контроль за тем, передаются ли сообщения определенного приоритета клиенту, записываются в журнал сервера или и то, и другое, осуществляется с помощью переменных конфигурации log_min_messages и client_min_messages. См. раздел «Конфигурация сервера» и раздел «Обработка ошибок в PL/Tcl» для получения дополнительной информации.