E N D
Три́ггер • Это хранимая процедура особого типа, которую пользователь не вызывает непосредственно, а исполнение которой обусловлено наступлением определенного события (действием) — по сути добавлением INSERT или удалением DELETE строки в заданной таблице, или модификации UPDATE данных в определенном столбце заданной таблицы реляционной базы данных. Триггеры применяются для обеспечения целостности данных и реализации сложной бизнес-логики. Триггер запускается сервером автоматически при попытке изменения данных в таблице, с которой он связан. Все производимые им модификации данных рассматриваются как выполняемые в транзакции, в которой выполнено действие, вызвавшее срабатывание триггера. Соответственно, в случае обнаружения ошибки или нарушения целостности данных может произойти откат этой транзакции.
Синтаксис команды для создания триггера • CREATE [OR REPLACE] TRIGGER имя_триггера • BEFORE | AFTER активизирующее_событие ON ссылка_на_таблицу • FOR EACH ROW [WHEN условие_срабатывания] --------------------- --- тело_триггера -------------
Пример • CREATE TABLE ADT ( • USAL VARCHAR2(50), • TISP DATE )
CREATE OR REPLACE TRIGGER testTrg AFTER INSERT OR DELETE OR UPDATE ON customers DECLARE BEGIN INSERT INTO MILLER.ADT(USAL, TISP) VALUES(USER, SYSDATE); END testTrg;
Словарь данных USER_TRIGGERS • SELECT TRIGGER_NAME, TRIGGER_TYPE, TABLE_NAME, TRIGGERING_EVENT • FROM USER_TRIGGERS • WHERE TRIGGER_NAME = 'testTrg'
Если есть необходимость на некоторое время прекратить вызов определенного вами триггера, но не удалять его тело полностью, примените команду: • ALTER TRIGGER TESTTRG DISABLE
Удаление триггера • Триггер удаляется с помощью оператора DROP TRIGGER, вот таким образом: • DROP TRIGGER TESTTRG
Порядок активации триггеров • Выполняется операторный триггер BEFORE (при его наличии) • Для каждой строки, на которую воздействует оператор: • Выполняется строковый триггер BEFORE (при его наличии). • Выполняется собственно оператор. • Выполняется строковый триггер AFTER (при его наличии). • Выполняется операторный триггер AFTER (при его наличии).
Изменение значений атрибутов в триггере • Строковый триггер срабатывает один раз для каждой строки. При этом внутри триггера можно обращаться к строке обрабатываемой в данный момент времени. Делать это можно, применяя псевдозаписи: :old и :new.
Пример CREATE OR REPLACE TRIGGER INSIDTRG BEFORE INSERT ON TSTTRIG FOR EACH ROW DECLARE BEGIN SELECT TRG.NEXTVAL INTO :NEW.ID FROM DUAL; END INSIDTRG;
Использование условия в триггере CREATE OR REPLACE TRIGGER WHENTRG BEFORE INSERT OR UPDATE OF COST ON TSTTRIG FOR EACH ROW WHEN (new.COST > 10000) DECLARE BEGIN UPDATE TSTSV SET TSTSV.ITOG = :new.COST + :old.COST WHERE TSTSV.CONS = :old.ID; END WHENTRG;
Обратите внимание • Обратите внимание на наличие строки OF COST ON TSTTRIG - здесь определяется поле, на которое устанавливаем условие триггера и собственно само условие WHEN (new.COST > 10000) - обратите внимание, что псевдозапись new записана как - new, а не :new
Полезные предикаты • В триггерах БД Oracle возможно применение логических операторов - так называемых предикатов. Они имеют следующие определения INSERTING, UPDATING, DELETING. Это некие внутренние переменные среды Oracle, которые в зависимости от воздействующего на таблицу оператора DML принимают одно из значений TRUE или FALSE.
Пример использования CREATE OR REPLACE TRIGGER AUDT_TSTTRIG BEFORE INSERT OR UPDATE OR DELETE ON TSTTRIG FOR EACH ROW DECLARE TIP VARCHAR2(10); BEGIN IF INSERTING THEN TIP := 'INSERT'; ELSIF UPDATING THEN TIP := 'UPDATE'; ELSIF DELETING THEN TIP := 'DELETE'; END IF; INSERT INTO MYAUDIT(MYAUDIT.POLZ, MYAUDIT.VIZM, MYAUDIT.OPER, MYAUDIT.NZAP, MYAUDIT.HIST) VALUES (USER, SYSDATE, TIP, :new.ID, 'Old Name: '||:old.NM||' New Name: '||:new.NM); END AUDT_TSTTRIG;
Системные триггеры • CREATE OR REPLACE TRIGGER [схема.]имя_триггера • {BEFORE | AFTER} • {список_событий_DDL | список_событий_базы_данных} ON {DATABASE | [схема.]SCHEMA} конструкция_REFERENCING [условие_WHEN] тело триггера;
Пример • CREATE OR REPLACE TRIGGER FIXUSERIN AFTER LOGON ON DATABASE • BEGIN • INSERT INTO SYSTEM.AUDTBASE(NZAP, POLZ, TMIN, OPER) VALUES(1, USER, SYSDATE, 'UserIsLog(off)'); • END FIXUSERIN;