· количество триггеров в связке будет равно мощности множества tables’ – создается по одному триггеру для каждой таблицы;
· на основе анализа множества operations’ определяются наборы триггерных событий.
Проиллюстрируем вышесказанное следующим примером. Пусть имеются две взаимосвязанные таблицы: coaches (вагоны пассажирского поезда) и seats (посадочные места). Вагон характеризуется типом coach_type (купейный, плацкартный и т. п.), посадочное место – номером seat_number. Имеется требование: номер места в купейном вагоне не может быть больше 36. Формальный описатель этого требования следующий:
(5.8)
Множество tables включает два элемента: seats и coaches.
Данное требование является требованием к состоянию, поэтому множество операций у него следующее:
operations = {ins(seats), upd(seats), del(seats), ins(coaches), upd(coaches), del(coaches)}.
В результате выполнения некоторых операций из множества operations требование (5.8) может нарушиться:
· при добавлении и обновлении записей таблицы seats может появиться номер места больше 36, само же место – отнесено к купейному вагону;
· при обновлении таблицы coaches тип вагона может быть изменен на купейный в тот момент, когда в вагоне уже зарегистрированы места с номерами более 36.
Операции del(seats), ins(coaches) и del(coaches) не вызовут нарушений.
Таким образом:
operations’ = {ins(seats), upd(seats), upd(coaches)},
tables’ = {seats, coaches}.
Поскольку множество tables’ содержит два элемента, для реализации требования (5.8) необходимо создать триггерную связку из двух триггеров, по одному для каждой таблицы:
· триггер tr_seat_num будет реагировать на выполнение операций ins(seats) и upd(seats);
· триггер tr_coach_seat_num будет реагировать на выполнение операции upd(coach).
Что касается тел триггеров, то они будут идентичными. Самое простое, что можно сделать, - это отменить действие активизирующего оператора, если его запуск привел к нарушению условия требования.
Описатель (5.8) может быть переписан следующим образом:
(5.9)
Понимать это следует так: невозможно, чтобы результат выборки не был пустым.
Выражение легко «переводится» на Transact-SQL, ему соответствует запрос:
select * from coaches, seats
where coach_type = 'Купе'
and seat_number > 36
and coaches.id_coach = seats.id_coach
Операция проверки на неравенство пустому множеству реализуется в Transact-SQL с помощью квантора существования exists. Самое сложное здесь – это правильно «перевести» операцию логического отрицания. Для этого важно понять смысл ее использования в выражении (5.9). Смысл таков: если результат выборки стал непустым, триггер должен уничтожить некорректные изменения в связанной таблице. Самый простой способ сделать это – вернуть данные в исходное состояние, бывшее до выполнения активизирующего оператора, т. е. отменить транзакцию. «Переводя» все сказанное на Transact-SQL практически дословно, получаем:
if exists (select * from coaches, seats
where coach_type = 'Купе'
and seat_number > 36
and coaches.id_coach = seats.id_coach)
rollback tran
Данный скрипт и будет телом триггеров tr_seat_num и tr_coach_seat_num. Полные скрипты реализации триггеров будут выглядеть следующим образом:
create trigger tr_seat_num
on seats
for insert, update
as
if exists (select * from coaches, seats
where coach_type = 'Купе'
and seat_number > 36
and coaches.id_coach = seats.id_coach)
rollback tran
create trigger tr_coach_seat_num
on coaches
for update
as
if exists (select * from coaches, seats
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.