PL/pgSQL
Тема дорожной карты · PostgreSQL
PL/pgSQL — встроенный процедурный язык PostgreSQL, расширяющий SQL управляющими структурами IF, LOOP, FOR и WHILE, объявлениями переменных, обработкой исключений и поддержкой курсоров, что позволяет реализовывать сложную серверную логику непосредственно в базе данных. Функции и процедуры, написанные на PL/pgSQL, выполняются целиком внутри серверного процесса PostgreSQL, устраняя задержки на сетевые обращения при многошаговых операциях и делая их незаменимыми для настройки производительности пакетной обработки или сложных бизнес-правил. PL/pgSQL является наиболее распространённым языком для написания триггеров PostgreSQL, поскольку функции триггеров должны возвращать тип TRIGGER и получать записи строк NEW и OLD через специальные переменные PL/pgSQL. Администраторы баз данных используют PL/pgSQL для реализации хранимых процедур, инкапсулирующих транзакционную логику, журналирование изменений и правила валидации данных непосредственно в PostgreSQL без зависимости от кода прикладного уровня. Понимание PL/pgSQL — фундаментальный навык в продвинутом администрировании баз данных PostgreSQL, позволяющий командам приближать вычисления к данным.
Как это работает
PL/pgSQL переносит логику в БД. PL/pgSQL — дефолтный процедурный язык; PL/Python, PL/V8, PL/Perl тоже есть. Функции возвращают скаляр, set-of или table-типы; триггеры срабатывают BEFORE/AFTER на INSERT/UPDATE/DELETE/TRUNCATE per ROW или per STATEMENT. Для чего: валидация данных, держащаяся независимо от приложения, audit trail, computed-колонки (generated columns проще в большинстве случаев), денормализация, синхронизируемая в БД.
Когда применять
Функции — для инвариантов, держащихся независимо от приложения (enforce constraint, нормализация). Триггеры — для audit-логирования или поддержки производных колонок. Избегайте тяжёлой бизнес-логики в stored procedures — Git, тесты, observability для DB-кода хуже чем для app; dev round-trip медленный. Generated columns — для простых производных; дешевле триггеров.
Типичные ошибки
Ловушки PL/pgSQL: цепочки триггеров (один зовёт функцию, та срабатывает триггер, который...); рекурсивные триггеры без base case (взрыв стека); триггеры, читающие извне транзакции (race condition); бизнес-логика наполовину в приложении, наполовину в БД (удачи новым инженерам). Закрепляйте функции в схеме, версионируйте как SQL-файлы.