Меню
Главная
Авторизация/Регистрация
 
Главная arrow Информатика arrow Базы данных

Создание и использование триггеров

Триггером называют процедуру, которая хранится на сервере в откомпилированном виде и выполняется автоматически при наступлении события добавления, редактирования или удаления записи независимо от желания клиента. Принудительно запустить триггер из приложения клиента нельзя. Триггеру нельзя передать входные параметры и получить от него выходные параметры.

Триггер всегда работает с текущей записью и реализует конкретное действие.

Триггеры могут выполняться до наступления события (параметр BEFORE) или после наступления события (параметр AFTER).

Триггеры различают по направлению действия:

  • INSERT — на добавление записи;
  • UPDATE — на редактирование записи;
  • DELETE — на удаление записи.

Триггер создается для конкретной таблицы и принадлежит ей. Если таблица имеет несколько триггеров одного направления действия, то время их срабатывания определяется в первую очередь параметрами BEFORE и AFTER, а при одинаковом значении параметра наступления события — параметром POSITION с указанием номера (порядка) срабатывания триггера.

При работе с триггерами следует иметь в виду, что:

  • • при откате транзакций откатываются все изменения, сделанные триггерами;
  • • легко реализуются каскадные изменения и каскадные удаления в дочерних таблицах;
  • • изменения, внесенные в тело триггера, автоматически работают для каждого приложения клиента, т. е. нет необходимости сделанные изменения доводить до каждого пользователя.

Создание триггера производится по правилам создания хранимых процедур, хотя имеются некоторые особенности.

Создание триггера

Для создания триггера используется оператор CREATE TRIGGER.

Формат оператора

CREATE TRIGGER <имя триггера> FOR <имя таблицы>

[ ACTIVE | INACTIVE ]

[ BEFORE|AFTER]

[ INSERT | UPDATE DELETE ]

[ POSITION <номер> ]

AS

<тело триггера>

Назначение опций:

ACTIVE — триггер активен, т. е. при обращении к указанной таблице выполняется процедура, записанная в стеле триггерам

INACTIVE — триггер пассивен, т. е. триггер создан и хранится на сервере, но при обращении к указанной таблице стело триггера> не выполняется;

BEFORE — определяет время срабатывания до наступления события;

AFTER — определяет время срабатывания после наступления события;

INSERT — определяет для триггера событие добавления записи в таблицу;

UPDATE — определяет для триггера событие редактирования записи в таблице;

DELETE — определяет для триггера событие удаления записи из таблицы;

POSITION — определяет номер (позицию) срабатывания триггера внутри определенного события срабатывания (BEFORE или AFTER).

Для описания процедуры стело триггера> используются те же операторы и конструкции, которые используются при создании хранимой процедуры. В заголовке триггера определяют его активность, событие срабатывания, действие, на которое он реагирует, и, при необходимости, позицию срабатывания триггера.

При написании стела триггера> дополнительно можно использовать ключевые слова OLD (до события) и NEW (после события) с последующим указанием имени поля.

Так как в удаленной базе данных все изменения в таблицах (добавление, редактирование и удаление записи) производятся в выборках (в оперативной памяти), то, например, при изменении значения поля можно обратиться как к старому (до изменения) значению поля — ОЬО.симя поля>, так и к новому (после изменения) значению поля — NEW-симя полях Если в указанное поле изменение не вносилось, то ОЬО.симя поля> будет равно NEW.chmb полях

Пример 6.10. Создание триггера.

CREATE TRIGGER T_COMPCODE FOR COMPOSERS

ACTIVE BEFORE INSERT POSITION 0

AS

begin

new.code_composer=gen_id(g_composers, 1); if(COMPOSERS.data born is not null) then begin

new.actuallyage = (CAST('NOW' AS DATE)-COMPOSERS.data_born)/365; if(COMPOSERS.data day is not null) then COM POSERS.age =(COMPOSERS.data_day-COMPOSERS. data born) /365; else new.age=null; end

else begin new.age=null; new.actually_age=null; end end

Триггер срабатывает до наступления события добавления новой записи и вычисляет возраст композитора. Вычисленный возраст записывает в поле «actually_age».

Изменение триггера

Для изменения триггера используется команда ALTER TRIGGER, имеющая аналогичный формат и аналогичный принцип работы, что и команда ALTER PROCEDURE для изменения тела хранимой процедуры.

Формат команды

ALTER TRIGGER <имя триггера> FOR <имя таблицы> [ ACTIVE I INACTIVE

BEFORE I AFTER

INSERT I UPDATE DELETE

[ POSITION <номєр> 1

AS

<тело триггера>

После выполнения оператора ALTER TRIGGER старое определение триггера заменяется новым определением. Старое определение триггера восстановить нельзя.

Пример 6.11. Редактирование триггера.

ALTER TRIGGER T_COMPCODE FOR COMPOSERS ACTIVE BEFORE INSERT POSITION 5 AS

begin

new.code_composer=gen_id(g_composers, 1); if(COMPOSERS.data_born is not null) then begin

new.actually_age = (CAST('NOW' AS DATE)-COMPOSERS.data_born)/365; if(COM POSERS.dataday is not null) then COM POSERS.age =

(COMPOSERS.data_day-COMPOSERS.data born) /365; else new.age=null; end

else begin new.age=null; new.actually_age=null; end end

В триггер, созданный в примере 6.10, внесено изменение: задана новая позиция (POSITION) срабатывания триггера — 5.

Удаление триггера

Для удаления триггера используют команду

DROP TRIGGER <имя триггера>

Пример 6.12. Удаление триггера.

DROP TRIGGER T_COMPCODE

Восстановить удаленный триггер нельзя.

Использование триггера в каскадных воздействиях

Как отмечалось выше, предусмотрено два вида каскадных воздействий: каскадное изменение и каскадное удаление. Поэтому для каждой родительской таблицы надо предусмотреть два триггера: один — для каскадного изменения, второй — для каскадного удаления. При этом условия ссылочной целостности должны быть удалены.

Пример 6.13. Каскадное удаление записей.

При удалении фамилии из родительской таблицы ГАМ необходимо удалить соответствующие фамилии (по ключам фами-

лии) во всех дочерних таблицах (в примере таблицы AUTHOR и BOOK).

CREATE TRIGGER DEL FAM FOR FAM ACTIVE

AFTER DELETE AS

BEGIN

DELETE FROM AUTHOR

WHERE FAM.KEYFAM = AUTHOR. KEYFAM; DELETE FROM BOOK

WHERE FAM.KEY FAM = BOOK.KEY FAM;

END

Пример 6.14. Каскадное редактирование записей.

При изменении значения ключевого поля (KEY FAM) в родительской таблице FAM необходимо изменить соответствующие значения внешних ключей во всех дочерних таблицах (в примере таблицы AUTHOR и BOOK).

CREATE TRIGGER UPD FAM FOR FAM ACTIVE

BEFORE UPDATE AS

BEGIN

IF (OLD.KEYFAM <> NEW.KEY FAM) THEN BEGIN

UPDATE AUTHOR SET KEY FAM = NEW.KEY FAM

WHERE KEY FAM - OLD.KEY FAM; UPDATE BOOK SET KEYFAM - N EW. KEYFAM

WHERE KEY FAM = OLD.KEY FAM;

END

END

Особенности использования каскадных воздействий:

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

Обеспечение достоверности данных с помощью триггера

Так как одна таблица может иметь несколько триггеров на одно событие (добавление, редактирование или удаление записи), то имеется возможность обеспечить достоверность вводимых в таблицу данных. Для создания триггера по обеспечению достоверности данных дополнительно используют операторы и ключевые слова.

а. Обеспечение уникальности значения поля

Как правило, для этих целей используют генератор. Работу с генераторами см. п. 6.3. Предварительно создается генератор, а затем имя генератора указывают в теле триггера.

Пример 6.15. Заполнение поля первичного ключа.

Написать триггер по добавлению уникального значения первичного ключа KEYFAM. Генератор GFAM уже создан.

CREATE TRIGGER К РАМ FOR FAM

ACTIVE

BEFORE INSERT

BEGIN

N EW. KEYFAM = GEN_ID(G_FAM, 1);

END

Пример 6.16. Заполнение информационного поля.

CREATE TRIGGER TCOMPDATE FOR COMPOSERS

ACTIVE BEFORE UPDATE POSITION 0

as

begin

if(COMPOSERS.data born is not null) then begin

new.actually_age = (CAST('NOW' AS

DATE)-COMPOSERS.data_born)/365; if(COMPOSERS.data day is not null) then COM POSERS.age =

(COM POSERS.data_day-COMPOSERS.data_born)/365; else new.age=null; end

else begin new.age=null; new.actually_age=null; end

end

В данном примере вычисляется возраст человека и заполняется поле actually age.

Ведение журнала аудита с помощью триггера

В удаленных базах данных особый интерес представляет ведение журнала изменений таблиц базы данных с целью определения источника недостоверных данных. При ведении журнала изменений в специальной таблице фиксируется:

  • • выполненное действие над таблицей;
  • • новое значение поля;
  • • старое значение поля;
  • • дата внесения изменения;
  • • фамилия, имя и отчество пользователя (USER NAME);
  • • номер (имя) рабочей станции.

Пример 6.17. Автоматическое заполнение журнала аудита.

CREATE TRIGGER AFTJNS_DOGS FOR DOGS ACTIVE AFTER INSERT POSITION 0 AS begin

insert into log (act, table_name,record_id) values('INSERT','DOGS',DOGS. ID); end

CREATE TRIGGER AFT_UPD_DOGS FOR DOGS ACTIVE AFTER UPDATE POSITION 0 AS begin

insert into log (act,table_name,record_id) values(’UPDATE’,'DOGS’,DOGS.ID); end

CREATE TRIGGER AFT DEL DOGS FOR DOGS ACTIVE AFTER DELETE POSITION 0 AS

begin

insert into log (act,table_name,record_id) values(’DELETE','DOGS’,DOGS.ID); end

В этом примере для таблицы DOGS созданы три триггера (по одному на каждое событие INSERT, UPDATE и DELETE). Каждый из триггеров добавляет в таблицу аудита log одну строку, которая содержит поля «выполненное действие», «имя таблицы» и «номер записи». При желании количество полей в таблице аудита можно увеличить.

 
Если Вы заметили ошибку в тексте выделите слово и нажмите Shift + Enter
< Пред   СОДЕРЖАНИЕ   След >
 

Популярные страницы