SQL, как и любой другой язык программирования, предоставляет функции и хранимые процедуры. В этой статье мы рассмотрим функции и хранимые процедуры в PostgreSQL, а также будут освещены следующие моменты:
- что такое функции и хранимые процедуры;
- разница между функциями и хранимыми процедурами;
- создание функций и хранимых процедур;
- применение функций и хранимых процедур в реальных примерах.
Функции и хранимые процедуры в SQL, как и в любом другом языке программирования, обеспечивают возможность повторного использования и гибкость. Функции и хранимые процедуры представляют собой блок кода или запросов, хранящихся в базе данных, которые можно использовать снова и снова. Вместо того чтобы писать одни и те же запросы, удобнее сгруппировать все запросы и сохранить их, чтобы можно было использовать их много раз. Что касается гибкости, то всякий раз, когда происходит изменение логики запросов, можно передавать новый параметр функциям и хранимым процедурам.
Между функциями и хранимыми процедурами в PostgreSQL есть несколько различий. Они показаны в таблице ниже.
Функции | Хранимые процедуры |
Функция имеет возвращаемый тип и возвращает значение | Хранимая процедура не имеет возвращаемого типа, но имеет выходные аргументы |
Использование DML (insert, update, delete) запросов внутри функции невозможно. В функциях разрешены только SELECT-запросы | Использование DML-запросов (insert, update, delete) возможно в хранимой процедуре. |
Функция не имеет выходных аргументов | Хранимая процедура имеет и входные, и выходные аргументы |
Вызов хранимой процедуры из функции невозможно | Использование или же управление транзакциями возможно в хранимой процедуре |
Вызов функции внутри SELECT запросов возможен |
Вызов хранимой процедуры из SELECT запросов невозможно |
Давайте рассмотрим создание функции в PostgreSQL. Следующий блок кода иллюстрирует, как создавать функцию.
Оператор:
create [or replace] function имя_функции
— создает или заменяет функцию, если она существует, с заданным именем и параметрами;returns return_type
— тип данных, который возвращает функция;- язык plpgsql — указывает на процедурное расширение PostgreSQL;
- внутри знака
$
является телом функции; declare
— показывает, как объявляются или инициализируются переменные;- блок кода
[begin — end]
— содержит всю логику функции; begin
— указывает на начало запросов;end
— указывает конец функции.
В следующем блоке кода показано создание простой функции, которая вычисляет стоимость самой дорогой покупки определенного пользователя.
Важно отметить:
Declare itemCost integer
— объявляем локальную переменную;SELECT max(cost) INTO itemCost
— как мы инициализируем переменную itemCost;RETURN itemCost
— возвращает значение функции.
Создание хранимой процедуры, как показано в блоке кода ниже, почти такое же, как создание функции с небольшим отличием — в ней нет return
. Остальное почти идентично.
В приведенном ниже блоке кода показано создание процедуры — transfer()
, которая принимает три параметра. Сразу после имени процедуры передаются аргументы с соответствующими типами данных — sourceAccountId
, destinationAccountId
, сумма. Процедура вычитает переданную сумму из одного account
и добавляет ее к другому account
.
Наконец, давайте применим все это на реальных примерах. Чтобы запустить весь код, который будет показан ниже, потребуется установить PostgreSQL (версия 13.2) на локальный компьютер или запустить PostgreSQL с помощью Docker-контейнера. Чтобы запустить PostgreSQL в Docker контейнере, необходимо запустить файл docker-compose.yaml
, указанный ниже.
Давайте создадим таблицы users
и purchases
и заполним их. Для простоты в таблице users
есть три столбца — id
, name
и profession
; таблица profession
состоит из четырех столбцов — id
, name
, cost
и user_id
.
После выполнения запросов мы можем проверить нашу базу данных
Допустим, мы хотим запросить имя пользователя и его самые дорогие покупки. Можно написать несколько сложных запросов, которые вернут желаемый результат, однако мы можем использовать нашу функцию, определенную выше.
Во-первых, нам нужно выполнить сам запрос для создания нашей функции.
Чтобы вызвать функцию — выполните следующую команду:
Чтобы в полной мере воспользоваться функциями, их можно использовать во многих случаях, например, во внутренних запросах select
. С функциями запросы становятся намного короче и точнее, это уменьшает шаблонный код и делает запросы лаконичными и простыми.
Как мы обсуждали ранее, хранимые процедуры немного отличаются от функций. Функции позволяют выполнять только Select-запросы, а хранимые процедуры позволяют выполнять Insert
, Update
, Delete
операции. Хранимые процедуры очень удобны при работе со случаями, когда необходимы операции insert
, update
или delete
.
Рассмотрим банковскую операцию — перевод. При выполнении какой-либо банковской операции деньги переводятся с одного счета на другой. Чтобы реализовать эту хранимую процедуру — transfer()
, давайте создадим таблицу accounts
и заполним ее.
После выполнения приведенных выше запросов мы получим следующий вывод.
Для вызова хранимой процедуры используется — call procedure_name()
.
Сделаем условно перевод денег – 500 единиц с account.id = 3
на account.id = 4
и проверим результат.
Заключение
В этой статье мы рассмотрели:
- что такое функции и хранимые процедуры, а также их разницу;
- создание функции и процедуры;
- применение функций и процедур на реальных примерах;
Материалы по теме
- 🐘 Руководство по SQL для начинающих. Часть 1: создание базы данных, таблиц и установка связей между таблицами
- 📜 Основные SQL-команды и запросы с примерами, которые должен знать каждый разработчик
- 🗄️ Лучшие стратегии по работе с РСУБД: индексы, транзакции и уровни изоляции
Комментарии