Перейти к основному содержимому

Структура PL/pgSQL

примечание

Эта страница переведена при помощи нейросети GigaChat.

Функции, написанные на PL/pgSQL, определяются на сервере путем выполнения команд CREATE FUNCTION. Такая команда обычно выглядит, например, так:

CREATE FUNCTION somefunc(integer, text) RETURNS integer
AS 'function body text'
LANGUAGE plpgsql;

Если рассматривать CREATE FUNCTION, тело функции представляет собой просто текстовую строку. Часто для написания тела функции удобнее заключать эту строку в доллары (см. Раздел «Строковые константы, заключенные в доллары»), а не в обычные апострофы. Без использования доллара любые одиночные кавычки или обратные косые черты в теле функции должны быть экранированы путем их удвоения. Почти все примеры в этом разделе используют литералы с долларами для своих тел функций.

PL/pgSQL – это блочно-структурированный язык. Полный текст тела функции должен быть блоком. Блок определяется следующим образом:

[ <<label>> ]
[ DECLARE
declarations ]
BEGIN
statements
END [ label ];

Каждое объявление и каждое предложение внутри блока должно заканчиваться точкой с запятой. Блок, который появляется внутри другого блока, должен иметь точку с запятой после END, как показано выше; однако последняя END , которая завершает тело функции, не требует точки с запятой.

Совет

Распространенной ошибкой является написание точки с запятой сразу после BEGIN. Это неправильно и приведет к синтаксической ошибке.

label необходим только в том случае, если нужно идентифицировать блок для использования в операторе EXIT или чтобы уточнить имена переменных, объявленных в этом блоке. Если метка указана после END, она должна соответствовать метке в начале блока.

Все ключевые слова нечувствительны к регистру. Идентификаторы неявно преобразуются в нижний регистр, если они не заключены в двойные кавычки, так же как и в обычных командах SQL.

Комментарии работают так же в коде PL /pgSQL, как и в обычном SQL. Двойной дефис (--) начинает комментарий, который продолжается до конца строки. /* начинается блок комментариев, который продолжается до соответствующей записи */. Блоки комментариев вложены.

Любое утверждение в разделе операторов блока может быть подблоком. Подблоки могут использоваться для логической группировки или локализации переменных в небольшую группу утверждений. Переменные, объявленные в подблоке, маскируют любые одноименные переменные внешних блоков на время действия подблока; но все равно можно получить доступ к внешним переменным, если квалифицировать их имена с помощью метки их блока. Например:

CREATE FUNCTION somefunc() RETURNS integer AS $$
<< outerblock >>
DECLARE
quantity integer := 30;
BEGIN
RAISE NOTICE 'Quantity here is %', quantity; -- Prints 30
quantity := 50;
--
-- Create a subblock
--
DECLARE
quantity integer := 80;
BEGIN
RAISE NOTICE 'Quantity here is %', quantity; -- Prints 80
RAISE NOTICE 'Outer quantity here is %', outerblock.quantity; -- Prints 50
END;

RAISE NOTICE 'Quantity here is %', quantity; -- Prints 50

RETURN quantity;
END;
$$ LANGUAGE plpgsql;
Примечание

На самом деле существует скрытый «внешний блок», окружающий тело любой функции PL/pgSQL. Этот блок предоставляет объявления параметров функции (если таковые имеются), а также некоторые специальные переменные, такие как FOUND (см. раздел «Получение статуса результата»). Внешний блок помечен именем функции, что означает, что параметры и специальные переменные могут быть квалифицированы с помощью имени функции.

Важно не путать использование BEGIN/END для группировки операторов в PL/pgSQL с аналогичными командами SQL для управления транзакциями. BEGIN/END PL/pgSQL предназначены только для группировки; они не начинают и не завершают транзакцию. См. раздел «Управление транзакциями» для получения информации об управлении транзакциями в PL/pgSQL. Кроме того, блок, содержащий предложение EXCEPTION, фактически образует подтранзакцию, которую можно откатить без влияния на внешнюю транзакцию. Для получения дополнительной информации см. раздел «Захват ошибок».