44.2. Структура PL/pgSQL
Функции, написанные на PL/pgSQL, определяются на сервере командами CREATE FUNCTION. Такая команда обычно выглядит, например, так:
CREATE FUNCTION somefunc(integer, text) RETURNS integer
AS 'тело функции
'
LANGUAGE plpgsql;
Если рассматривать CREATE FUNCTION
, тело функции представляет собой просто текстовую строку. Часто для написания тела функции удобнее заключать эту строку в доллары (см. Подраздел 4.1.2.4), а не в обычные апострофы. Если не применять заключение в доллары, все апострофы или обратные косые черты в теле функции придётся экранировать, дублируя их. Почти во всех примерах в этой главе тело функций заключается в доллары.
PL/pgSQL это блочно-структурированный язык. Текст тела функции должен быть блоком. Структура блока:
[ <<метка
>> ] [ DECLAREобъявления
] BEGINоператоры
END [метка
];
Каждое объявление и каждый оператор в блоке должны завершаться символом «;» (точка с запятой). Блок, вложенный в другой блок, должен иметь точку с запятой после END
, как показано выше. Однако финальный END
, завершающий тело функции, не требует точки с запятой.
Подсказка
Распространённой ошибкой является добавление точки с запятой сразу после BEGIN
. Это неправильно и приведёт к синтаксической ошибке.
Метка
требуется только тогда, когда нужно идентифицировать блок в операторе EXIT
, или дополнить имена переменных, объявленных в этом блоке. Если метка указана после END
, то она должна совпадать с меткой в начале блока.
Ключевые слова не чувствительны к регистру символов. Как и в обычных SQL-командах, идентификаторы неявно преобразуются к нижнему регистру, если они не взяты в двойные кавычки.
Комментарии в PL/pgSQL коде работают так же, как и в обычном SQL. Двойное тире (--
) начинает комментарий, который завершается в конце строки. Блочный комментарий начинается с /*
и завершается */
. Блочные комментарии могут быть вложенными.
Любой оператор в выполняемой секции блока может быть вложенным блоком. Вложенные блоки используются для логической группировки нескольких операторов или локализации области действия переменных для группы операторов. Во время выполнения вложенного блока переменные, объявленные в нём, скрывают переменные внешних блоков с такими же именами. Чтобы получить доступ к внешним переменным, нужно дополнить их имена меткой блока. Например:
CREATE FUNCTION somefunc() RETURNS integer AS $$ << outerblock >> DECLARE quantity integer := 30; BEGIN RAISE NOTICE 'Сейчас quantity = %', quantity; -- Выводится 30 quantity := 50; -- -- Вложенный блок -- DECLARE quantity integer := 80; BEGIN RAISE NOTICE 'Сейчас quantity = %', quantity; -- Выводится 80 RAISE NOTICE 'Во внешнем блоке quantity = %', outerblock.quantity; -- Выводится 50 END; RAISE NOTICE 'Сейчас quantity = %', quantity; -- Выводится 50 RETURN quantity; END; $$ LANGUAGE plpgsql;
Примечание
Существует скрытый «внешний блок», окружающий тело каждой функции на PL/pgSQL. Этот блок содержит объявления параметров функции (если они есть), а также некоторые специальные переменные, такие как FOUND
(см. Подраздел 44.5.5). Этот блок имеет метку, совпадающую с именем функции, таким образом, параметры и специальные переменные могут быть дополнены именем функции.
Важно не путать использование BEGIN
/END
для группировки операторов в PL/pgSQL с одноимёнными SQL-командами для управления транзакциями. BEGIN
/END
в PL/pgSQL служат только для группировки предложений; они не начинают и не заканчивают транзакции. Управление транзакциями в PL/pgSQL описывается в Разделе 44.8. Кроме того, блок с предложением EXCEPTION
по сути создаёт вложенную транзакцию, которую можно отменить, не затрагивая внешнюю транзакцию. Подробнее это описано в Подразделе 44.6.8.