Триггеры
Триггером в СУБД ЛИНТЕР называется хранимая процедура, которая вызывается на выполнение ядром СУБД автоматически при наступлении в БД события, на которое настроен триггер.
События, на которое может быть настроен триггер, делятся на события обработки данных и системные события.
В качестве события на обработку данных для триггера может выступать модификация (INSERT,
DELETE или UPDATE)
некоторой таблицы. В качестве системного события может быть событие регистрации пользователя.
Триггер может вызываться один раз на весь SQL-оператор
или на каждую операцию, выполняемую с записью таблицы. Триггеры различаются по времени срабатывания:
до выполнения операции с записью (BEFORE),
после выполнения операции (AFTER) и
вместо выполнения операции (INSTEAD OF).
Тело триггера представляет собой исходный текст на процедурном языке, то есть оно может включать декларации, исполняемые операторы и блок обработки исключений. В теле триггера разрешены любые операторы, в том числе, исполнение SQL-запросов, вызов хранимых процедур и т.д.
Триггеры типа INSTEAD OF применимы только к базовым таблицам и не применимы к представлениям.
В теле триггера, вызываемого на каждую строку (FOR EACH ROW) доступны
специальные переменные с префиксом по умолчанию OLD и NEW,
содержащие старое и новое значение строки.
Обе эти переменные – структуры (то есть с точки зрения языка хранимых
процедур – курсорные переменные), включающие
столбцы тех же имен и типов, что и обрабатываемая триггером таблица.
В зависимости от вида триггера эти переменные определяются следующим образом:
-
в триггере на
INSERTдоступна только переменнаяNEW; она содержит все значения, которые должны быть занесены в новую строку (если триггерBEFORE), или которые уже занесены (если триггерAFTER); при этом в триггереBEFOREдопустимо присвоить полям переменнойNEWновые значения, переопределив, таким образом, исходное поведениеINSERT; -
в триггере на
UPDATEпеременнаяNEWсодержит значение, которое должно содержаться в строке после обновления (если триггерBEFORE), или которое уже там содержится (если триггерAFTER); при этом в триггереUPDATEдопустимо присвоить полям переменнойNEWновые значения, переопределив, таким образом, исходное поведениеUPDATE; переменнаяOLDвсегда содержит все значения, которые были в строке до обновления; -
в триггере на
DELETEдоступна только переменнаяOLD; она содержит все значения удаляемой строки.
Кроме изменения значений переменной NEW, триггер BEFORE … FOR EACH ROW
также может повлиять на ход выполнения SQL-запроса путем запрета операции. Для этого триггер
должен вернуть логическое значение FALSE или завершиться с исключением.
В такой ситуации конкретная строка, обработанная триггером, пропускается
(не вставляется, не обновляется или не удаляется). Все остальные строки продолжают
обрабатываться. Таким образом, в результате действия триггеров может оказаться,
что часть строк, которые должны быть обработаны SQL-запросом, из этой обработки
будут исключены. В этом случае количество реально обработанных строк можно
получить с помощью соответствующих вызовов СУБД ЛИНТЕР.
СУБД ЛИНТЕР позволяет завершить и откатить весь SQL-оператор из триггера, вернув пользователю заданный код завершения.
С помощью триггеров можно снабдить СУБД такими возможностями, как альтернативный аудит, основанный на значениях данных, комплексный контроль безопасности и сложные правила целостности. Например, можно создать триггер, который будет позволять модифицировать некоторую таблицу лишь в заданный период времени.
Примечание
Хотя триггеры БД позволяют определять и вводить в действие правила целостности, они не эквивалентны этим правилам, а дополняют и/или расширяют их. Например, триггер, определенный для введения в действие правила целостности, не проверяет данные, уже загруженные в таблицу. Поэтому рекомендуется использовать триггеры вместо ограничений целостности только тогда, когда ограничение целостности не может быть реализовано подходящим правилом целостности.
Для поддержки триггеров должны существовать системные таблицы $$$TRIG
и $$$PROC (создаются при выполнении SQL-скрипта systab.sql).