Функции, написанные на языке PL/pgSQL определяются на сервере посредством выполнения CREATE FUNCTION команд. Обычно такая команда выглядит, например, так:
CREATE FUNCTION somefunc(integer, text) RETURNS integer
AS 'текст тела функции'
LANGUAGE plpgsql;
С точки зрения команды CREATE
FUNCTION тело функции является обычным строковым литералом. Часто бывает полезно использовать экранирование долларами
(см. Раздел 2.1.1.2.4) для написания тела функции вместо обычного синтаксиса с одинарными кавычками. Без использования экранирования долларами любые одинарные кавычки или обратные косые черты в теле функции должны быть экранированы путем их удвоения. Почти во всех примерах в данной главе для записи тел функций используются константы с экранированием долларами.
PL/pgSQL является блочно-структурированным языком. Весь текст тела функции должен представлять собой блок. Структура блока:
[ <<label>> ] [ DECLAREобъявления] BEGINstatementsEND [label];
Каждое объявление и каждый оператор внутри блока завершаются точкой с запятой. Блок, вложенный в другой блок, должен иметь точку с запятой после END, как показано выше;
однако финальный оператор END который
завершает тело функции, не требует точки с запятой.
Распространенной ошибкой является использование точки с запятой сразу после
BEGIN. Это недопустимо и приведет к синтаксической ошибке.
A 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; -- Выводит 30
quantity := 50;
--
-- Создание подблока
--
DECLARE
quantity integer := 80;
BEGIN
RAISE NOTICE 'Quantity here is %', quantity; -- Выводит 80
RAISE NOTICE 'Outer quantity here is %', outerblock.quantity; -- Выводит 50
END;
RAISE NOTICE 'Quantity here is %', quantity; -- Выводит 50
RETURN quantity;
END;
$$ LANGUAGE plpgsql;
Фактически имеется скрытый «внешний блок» окружающий тело
любой PL/pgSQL функции. В данном блоке содержатся объявления параметров функции (если они есть), а также некоторые специальные переменные, такие как FOUND (см. раздел
Раздел 5.6.5.5). Внешний блок
помечается именем функции; это означает, что имена параметров и специальных
переменных могут быть квалифицированы именем функции.
Важно не путать использование
BEGIN/END для группировки операторов в
PL/pgSQL с одноименными командами SQL
для управления
транзакциями. PL/pgSQL BEGIN/END
служат только для группировки; они не начинают и не завершают транзакцию.
См. Раздел 5.6.8 информацию об управлении
транзакциями в PL/pgSQL.
Кроме того, блок, содержащий предложение EXCEPTION фактически формирует подтранзакцию, которую можно откатить без влияния на внешнюю транзакцию. Подробнее об этом см. в разделе Раздел 5.6.6.8.