Триггеры – это активные элементы базы данных, которые срабатывают по условию, определенному программистом. Триггеры позволяют проверять не только ограничения, но и другие условия, не связанные с ошибками ввода или изменения данных. Триггеры предусмотрены в стандарте SQL 3.
Триггеры отличаются от рассмотренных ранее ограничений следующими свойствами:
· триггеры применяются при наступлении событий, определяемых программистом;
· триггер проверяет условие, записанное в программе триггера;
· при выполнении условия СУБД предпринимает действия, которое состоит либо в предотвращении события, либо в отмене результата выполнения события.
Условие срабатывания триггера записываются в пункте WHEN описания триггера. При этом события, вызвавшие срабатывание, могут относиться к отдельному столбцу или к множеству столбцов таблицы.
Событием, вызывающим срабатывание триггера, может быть вставка, обновление или удаление элементов определенного отношения. Для спецификации события в описании используются соответствующие ключевые слова UPDATE OF, INSERT, DELETE.
В ответ на событие в триггере предусмотрено действие, которое СУБД может выполнять до наступления события, вместо события или после наступления события. Порядок выполнения действий определяется соответствующими ключевыми словами BEFOR, INSTEAD OF или AFTER.
Действие, выполняемое в ответ на событие, может быть описано как одним SQL оператором, так и любым их числом.
Действие может выполняться для каждого изменяемого кортежа или один раз для всех кортежей. Триггер уровня строки, который выполняется для каждого кортежа, включает ключевые слова FOR EACH ROW. Триггер уровня оператора не имеет ключевых слов FOR EACH ROW и выполняется один раз для всей таблицы.
В триггере уровня строки действие может относиться к старым или к новым кортежам, которые были введены, удалены или изменены в результате произошедшего события. Для идентификации этих кортежей им присваиваются имена в предложении REFERENCING с помощью ключевых слов OLD AS или NEW AS. При вставке кортежей не используются ключевое слово OLD AS, а при удалении кортежей не используются ключевое слово NEW AS.
В триггере уровня оператора можно ссылаться только на множество новых и множество старых кортежей. Для идентификации множества новых и множества старых кортежей в предложении REFERENCING используются ключевые слова OLD_TABLE AS и NEW_TABLE AS.
В качестве примера создадим триггер уровня строки, который при любом действии с таблицей Producers следует записать в таблицу аудита пользователя, время и имя триггера.
CREATE OR REPLACE TRIGGER ProducersTrigger
AFTER INSERT OR DELETE OR UPDATE ON Producers
DECLARE
BEGIN
INSERT INTO SYSTEM.ProducrsAudit(users,time,VID_TRG)
VALUES (user, sysdate, 'OPER_TRIGGER');
END ProducersTrigger;
Предварительно должна быть создана таблица аудита:
CREATE TABLE ProducersAudit(
users VARCHAR2(20),
time DATE,
VID_TRG VARCHAR2(20));
Следующий триггер уровня оператора. При любом действии с таблицей Theatres следует записать в таблицу аудита пользователя, дату и имя триггера.
CREATE TRIGGER TheatresTrigger
AFTER INSERT OR DELETE OR UPDATE ON Theatres
FOR EACH ROW
DECLARE
BEGIN
INSERT INTO SYSTEM. TheatresAudit(users, time, VID_TRG)
VALUES (user, sysdate, 'ROW_TRIGGER');
END TheatresTrigger;
Следующий триггер уровня строки предназначен для обеспечения ссылочной целостности. При удалении строки из таблицы Producers, на которую имеется ссылка из таблицы Performances,должна быть удалена соответствующая строка из таблицы Performances.
CREATE OR REPLACE TRIGGER DelProducers
AFTER DELETE ON Producers
FOR EACH ROW
DECLARE
BEGIN
DELETE FROM system.Performances WHERE producerC#=:old.cert# ;
END DelProducers;
Триггер может использовать предикаты типа IF INSERTING THEN, IF UPDATING THEN и IF DELETING THEN, которые позволяют проверять условие вставки, обновления и удаления кортежей.
Для выполнения аудита создайте таблицу для отслеживания действий пользователя над таблицей актеров:
CREATE TABLE ActorsAudit(
userID VARCHAR2(15),
adate DATE,
operation VARCHAR2(20),
hist VARCHAR2(50)
);
Следующий триггер выполняет аудит событий вставки, обновления и удаления кортежей в таблице Actors:
CREATE OR REPLACE TRIGGER ActorsAudit
AFTER INSERT OR UPDATE OR DELETE ON Actors
FOR EACH ROW
DECLARE
type VARCHAR2(10);
BEGIN
IF INSERTING THEN type:='INSERT';END IF;
IF UPDATING THEN type:='UPDATE';END IF;
IF DELETING THEN type:='DELETE';END IF;
INSERT INTO ActorsAudit VALUES(USER,SYSDATE,type, 'oldName:'||:old.name||'newName:'||:new.name);
END ActorsAudit;
Триггер уровня строки с условием WHEN и с псевдозаписями при вводе нового картежа в таблицу Producers проверяет атрибут networth и вводит этот кортеж в новую таблицу RichProducers новый кортеж:
CREATE TRIGGER WhenTrigger
AFTER INSERT OR DELETE OR UPDATE OF networth ON Producers
FOR EACH ROW
WHEN (new.networth > 1 000 000)
DECLARE
BEGIN
INSERT INTO SYSTEM.RichProducers (name,address, cert#,networth)VALUES (:new.name,:new.address, :new.cert#,:new.networth);