Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Функции и процедуры внутри PostgreSQL
functions_plpgsql

Функции и процедуры внутри PostgreSQL

SQL, PL/pgSQL, изменчивость, динамические команды и права владельца

Открыть лабораториюv1.1.0Запускается локально из публичного репозитория

Функции и процедуры внутри PostgreSQL

PostgreSQL умеет хранить не только данные, но и выполняемый код. Функция получает аргументы, возвращает значение или набор строк и может использоваться в SELECT. Процедура вызывается отдельной командой CALL и предназначена для последовательности действий.

Серверный код полезен, когда правило должно быть доступно всем клиентам базы. Но он не обязан заменять код приложения: начинайте с самого простого решения.

SQL-функция

Если нужен один запрос, достаточно языка SQL:

CREATE FUNCTION marketplace.order_total(p_order_id bigint) RETURNS numeric LANGUAGE sql STABLE PARALLEL SAFE AS $function$ SELECT coalesce(sum(quantity * unit_price), 0) FROM marketplace.order_items WHERE order_id = p_order_id $function$;

Функция принимает номер заказа и возвращает сумму позиций. Её можно вызвать:

SELECT marketplace.order_total(101);

PL/pgSQL — процедурный язык PostgreSQL. Он добавляет переменные, условия, циклы и обработку ожидаемых ошибок. Он нужен для нескольких связанных команд, а не просто потому, что функция находится в базе.

Построчный цикл часто можно заменить одной операцией над набором строк. Такая SQL-команда обычно короче и даёт планировщику больше свободы.

Как часто может меняться результат

Свойство изменчивости (volatility) — обещание функции планировщику:

  • VOLATILE — результат может измениться при каждом вызове; это значение по умолчанию;
  • STABLE — внутри одной SQL-команды одинаковые аргументы дают согласованный результат; функция может читать таблицы;
  • IMMUTABLE — результат навсегда зависит только от аргументов и не зависит от таблиц, времени, настроек или языка окружения.

Функция суммы заказа читает таблицу, поэтому она STABLE, но не IMMUTABLE. Слишком сильная метка — не ускорение, а ложь. Планировщик может заранее вычислить такую функцию и сохранить устаревший результат в подготовленном плане или индексе.

Динамический SQL

Иногда текст команды строится во время выполнения. Это называется динамическим SQL. Значения передавайте отдельно через USING, а имя таблицы форматируйте как идентификатор через %I:

EXECUTE format('SELECT count(*) FROM %I WHERE org_id = $1', p_table) INTO result USING p_org_id;

$1 безопасно получает значение организации. Имя таблицы нельзя передать как обычное значение, поэтому его нужно сначала проверить по разрешённому списку, а затем корректно заключить в кавычки через %I. Склеивать непроверенный ввод с SQL-командой нельзя.

Функция с правами владельца

Обычно функция работает с правами вызывающей роли. SECURITY DEFINER меняет это: функция выполняется с правами владельца. Так можно дать приложению узкую операцию без прямого доступа к таблице, но ошибка создаст повышение привилегий.

Безопасная функция такого типа требует:

  • владельца, который не используется приложением для входа;
  • явно заданного search_path только с доверенными схемами;
  • полных имён объектов вида marketplace.orders;
  • отозванного у PUBLIC права EXECUTE;
  • выдачи выполнения только нужной роли;
  • запрета непроверенных имён в динамическом SQL.

Иначе злоумышленник может создать объект с подходящим именем в доступной схеме, а привилегированная функция случайно обратится к нему.

Функция или процедура

Функция участвует в выражении и вызывается через SELECT. Процедура вызывается через CALL. В некоторых контекстах процедура может управлять транзакциями, но на это действуют ограничения.

Не выбирайте процедуру только из-за длины кода. Выбор определяется способом вызова, возвращаемым результатом и необходимостью управления транзакцией.

Практика

В лаборатории 16 вы создадите функцию расчёта суммы и узкую функцию SECURITY DEFINER, а затем проверите доступ от имени роли приложения.

Подробнее: CREATE FUNCTION, язык PL/pgSQL.

Проверьте свои знания

Вопросы ещё не добавлены

Вопросы для этой подтемы ещё не добавлены.

Далее: Триггеры: автоматическая реакция на изменения