|
Программирование >> Построение запросов sql
или UPDATE для таблицы, для которой создан триггер. Переменная NEW не используется при удалении, т. к. новое значение не создается, а наоборот -происходит удаление. Переменная NEW является контекстной переменной только для чтения в триггерах, которые срабатывают после наступления событий (фаза триггера - AFTER). Контекстные переменные OLD и NEW могут использоваться в триггерах для нескольких событий. Но при этом могут возникнуть ситуации, когда для одного события, на которое реагирует триггер, контекстная переменная может использоваться, а для другого - нет. В этом случае ссылка на NEW.столбец в контексте удаления или на OLD.столбец в контексте добавления ошибкой не является - просто будет возвращено NULL-значение. Рассмотрим пример создания триггера, контролирующего вставку строк в таблицу Request. Допустим, существует такое граничение, что каждый исполнитель может быть назначен на выполнение не более 5 ремонтных заявок в год. При попытке зарегистировать для исполнителя лишнюю ремонтную заявку должно выдаваться сообщение. Скрипт создания триггера для решения данной задачи будет выглядеть следующим образом: /*подключение к БД */ CONNECT c:\sqllab.fdb USER SYSDBA PASSWORD masterkey; SET TERM !! ; -- определение нового разделителя /* определение триггера*/ CREATE TRIGGER Num Request FOR Request ACTIVE BEFORE INSERT POSITION 0 DECLARE ExecKod SMALLINT; DECLARE God SMALLINT; DECLARE NumRows SMALLINT; BEGIN SELECT ExecutorCD, EXTRACT(YEAR FROM IncomingDate), COUNT(*) FROM Request GROUP BY 1,2 INTO :ExecKod, :God, :NumRows DO BEGIN IF (ExecKod = New.ExecutorCD AND God = EXTRACT(YEAR FROM NEW.IncomingDate) AND NumRows>=5) /* генерация исключительной ситуации, если для исполнителя в указанном году уже зарегистировано 5 заявок*/ THEN Exception Ins Restrict; END !! --конец оператора CREATE TRIGGER SET TERM ; !! /*установка стандартного разделителя */ Созданный триггер NumRequest при попытке назначить исполнителю на выполнение более 5 заявок в год вызывает исключение InsRestrict, определенное при создании учебной базы данных, и предотвращает вставку строки в таблицу Request. В триггерах для нескольких событий с целью поддержания условных переходов между событиями используются такие логические контекстные переменные, как UPDATING, INSERTING, DELETING типа BOOLEAN. Они используются для задания определенных действий в зависимости от типа события DML, доступны в качестве предикатов в условных структурах, выполняющих операции изменения состояния данных, например, в теле триггера в следующем виде: IF (INSERTING OR DELETING) THEN NEW.ID = GEN ID(G GENERATOR 1, 1); Рассмотрим пример триггера для нескольких событий. Пусть требуется в некоторой таблице Journal фиксировать имена пользователей, которые добавляют, обновляют или удаляют данные в таблице NachislSumma, идентификатор факта начисления(NachislFactCD), признак типа события (INS для вставки, EDIT для обновления и DEL для удаления), а также дату и время совершения операции. Скрипт для создания такого триггера с именем UsrAction будет выглядеть следующим образом: /* подключение к БД */ CONNECT c:\sqllab.fdb USER SYSDBA PASSWORD masterkey; /* создание таблицы Journal */ CREATE TABLE Journal (Usr Name VARCHAR(20), Nach ID INTEGER, DML Event VARCHAR(4), Time Date TIMESTAMP); SET TERM !! ; /установка нового разделителя*/ /* определение триггера */ CREATE TRIGGER Usr Action FOR NachislSumma ACTIVE AFTER INSERT OR UPDATE OR DELETE AS DECLARE VARIABLE Nach INTEGER; DECLARE VARIABLE Event VARCHAR(4); BEGIN IF (DELETING) THEN BEGIN Nach = OLD.NachislFactCD; Event = DEL; END ELSE BEGIN Nach = NEW.NachislFactCD; IF (UPDATING) THEN Event = EDIT; ELSE Event = INS; /* вставка строки в таблицу Journal */ INSERT INTO Journal VALUES (USER, :Nach, :Event, CURRENT TIMESTAMP); END!! /*конец оператора CREATE TRIGGER */ SET TERM ; !! /*установка стандартного разделителя */. Чтобы проверить действие созданного триггера UsrAction, от имени пользователя SYSDBA выполним последовательно три следующих запроса: INSERT INTO NachislSumma VALUES (51 ,005488,1,63,1,2002); DELETE FROM NachislSumma WHERE NachislFactCD=1; UPDATE NachislSumma SET GazServiceCD=2 WHERE NachislFactCD=40;. Данные, помещенные в таблицу Journal и полученные в результате выполнения следующего запроса: SELECT * FROM Journal; , представлены на рис. 6.10.
Рис. 6.10. Данные таблицы Journal Описание всех имеющихся в БД триггеров (как системных, так и пользовательских) хранится в системной таблице RDB$TRIGGERS. При использовании утилиты IBExpert все пользовательские триггеры отображаются в окне инспектора объектов БД. 6.3.1.2. Примеры поддержания ссылочной целостности Рассмотрим примеры поддержания целостности БД с помощью триггеров. Пусть необходимо написать SQL сценарий по созданию триггера, предотвращающего вставку NULL значений в поля внешних ключей AccountCD, ExecutorCD и FailureCD таблицы Request. Если значения, вводимые в поля перечисленных внешних ключей, не содержат NULL, то необходимо вставить в поле первичного ключа RequestCD очередное значение, полученное с помощью генератора. При попытке вставить NULL значение должен сработать триггер и выдать сообщение об исключительной ситуации, т. е.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |