40.2. Структура PL/pgSQL#
40.2. Структура PL/pgSQL #
Функции, написанные на языке PL/pgSQL, определяются на сервере путем выполнения команд CREATE FUNCTION. Обычно такая команда выглядит, скажем, так:
CREATE FUNCTION somefunc(integer, text) RETURNS integer
AS 'function body text
'
LANGUAGE plpgsql;
Тело функции представляет собой просто строковый литерал, что касается CREATE FUNCTION
. Часто полезно использовать кавычки доллара (см. Раздел 4.1.2.4) для написания тела функции, вместо обычного синтаксиса с апострофами. Без использования кавычек доллара, любые апострофы или обратные косые черты в теле функции должны быть экранированы удвоением. Почти все примеры в этой главе используют литералы с кавычками доллара для своих тел функций.
PL/pgSQL - это язык с блочной структурой. Полный текст тела функции должен быть блоком. Блок определяется следующим образом:
[ <<label
>> ] [ DECLAREdeclarations
] BEGINstatements
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
(см. Раздел 40.5.5). Внешний блок помечен именем функции, что означает, что параметры и специальные переменные могут быть полными именами функции.
Важно не путать использование команды BEGIN
/END
для группировки операторов в PL/pgSQL с аналогичными командами SQL для управления транзакциями. BEGIN
/END
в PL/pgSQL используются только для группировки, они не начинают и не завершают транзакцию. См. раздел Раздел 40.8 для получения информации о управлении транзакциями в PL/pgSQL. Кроме того, блок, содержащий предложение EXCEPTION
, фактически формирует подтранзакцию, которая может быть отменена без влияния на внешнюю транзакцию. Дополнительную информацию об этом см. в разделе Раздел 40.6.8.