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