Функции на языке запросов (SQL)
Last updated
Last updated
SQL-функция выполняет произвольный набор команд на языке SQL, разделённых точкой с запятой, и возвращает результат последнего запроса в списке. Помимо запросов SELECT
, эти команды могут включать запросы, изменяющие данные (INSERT
, UPDATE
и DELETE
и MERGE
), а также другие SQL-команды.
В SQL-функциях нельзя использовать команды управления транзакциями, например COMMIT
, SAVEPOINT
, и некоторые вспомогательные команды, в частности VACUUM
.
Последней командой должна быть SELECT
или команда с предложением RETURNING
, возвращающая результат с типом возврата функции. В простом случае будет возвращена первая строка результата последнего запроса. Если последний запрос не вернёт ни одной строки, то будет возвращено значение NULL.
Функции можно разделить по типу возвращаемого значения:
Без возврата значений;
Возвращающие единственную запись базового типа, составного типа или типа record;
C выходными параметрами;
Возвращающие множество (SETOF) записей базового типа, составного типа или типа record;
Возвращающие таблицу (TABLE).
Далее рассмотрим все варианты SQL-функций. А подробный материал по функциям на языке SQL можно найти по .
К аргументам SQL-функции можно обращаться по именам или индексу.
Объявив аргумент с именем, это имя можно использовать в теле функции:
При обращении к аргументу по индексу используется запись вида $n
. Нумерация аргументов начинается с единицы: $1
обозначает первый аргумент, $2
- второй и т. д. Обращение по номеру будет работать, и когда аргументам назначены имена.
Если нужна SQL-функция, выполняющая действие, но не возвращающая полезное значение, можно объявить её как возвращающую тип void
.
Например, эта функция удаляет черновые записи клиентов из таблицы:
Простейшая возможная функция SQL не имеет аргументов и возвращает базовый тип. Такая функция возвращает таблицу с одним столбцом и одной строкой.
Например, функция ниже возвращает идентификатор типа smallint
:
Также возможно создать функцию, возвращающую составной тип. В таком случае функция возвращает таблицу из одной строки со столбцами для каждого атрибута составного типа.
Например, функция получения настроек SMTP-сервера будет возвращать одну строку типа template.settings:
Тогда в ответе получим:
Если составной тип не подходит в качестве типа возвращаемого значения, так как содержит избыточные столбцы, то можно объявить функцию, возвращающую тип record. Такие переменные не имеют предопределённой структуры. Количество и тип столбцов результата будет равно количеству полей последнего запроса в теле функции.
Например, функция получения настроек SMTP-сервера из предыдущего примера будет переписана следующим образом:
Важный момент: у функций, возвращающих запись, должен быть список определений столбцов - для этого, в запросе на получение результата функции задаются псевдонимы и типы колонок ответа.
Ответ функции будет иметь вид:
Альтернативный способ описать результаты функции - определить её с выходными параметрами. Например:
Но, основное преимущество выходных параметров в том, что они позволяют определять функции, возвращающие несколько столбцов. Например:
В ответ получим:
Можно объявить SQL-функцию как возвращающую множество. В этом случае будут возвращены все строки результата последнего запроса.
Когда SQL-функция объявляется как возвращающая SETOF
некий_тип
, конечный запрос функции выполняется до завершения и каждая строка выводится как элемент результирующего множества.
Это обычно используется, когда функция вызывается в предложении FROM
. В этом случае каждая строка, возвращаемая функцией, становится строкой таблицы, появляющейся в запросе.
Функция может возвращать множество простого типа, тогда в ответе будет таблица с одним столбцом.
В ответ получим:
Также возможно создать функцию, возвращающую множество составной тип. В таком случае функция возвращает таблицу с несколькими строками со столбцами для каждого атрибута составного типа.
В ответ получим:
Также возможно выдать несколько строк со столбцами, определяемыми выходными параметрами. Для этого необходимо указать функцию возвращающую SETOF record
.
Например, функция возвращающая список идентификаторов товаров и их стоимость:
В ответ получим таблицу:
Тип record
позволяет использовать динамическую структуру выходной таблицы.
Есть ещё один способ объявить функцию, возвращающую множества, - использовать синтаксис RETURNS TABLE(
столбцы
)
. Это равнозначно использованию одного или нескольких параметров OUT
с объявлением функции, возвращающей SETOF record
.
Например, предыдущий пример с товарами и их стоимостью можно переписать следующим образом:
Запись RETURNS TABLE
не позволяет явно указывать OUT
и INOUT
для параметров - все выходные столбцы необходимо записать в списке TABLE
.