40.2. Структура PL/pgSQL#

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>> ]
[ 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 (см. Раздел 40.5.5). Внешний блок помечен именем функции, что означает, что параметры и специальные переменные могут быть полными именами функции.

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