|
Программирование >> Построение запросов sql
триггер должен запускаться при каждой вставке строки в таблицу Request. Ниже приведен текст SQL сценария, реализующего поставленную задачу. /*подключение к БД */ CONNECT c:\sqllab.fdb USER SYSDBA PASSWORD masterkey; /* создание сообщения об исключительной ситуации*/ CREATE EXCEPTION E Request Error insert null value into Request ; /* создание генератора*/ CREATE GENERATOR Request GEN; /*установка начального значения генератора*/ SET GENERATOR Request GEN TO 24; SET TERM !! ; -- определение нового разделителя CREATE TRIGGER Request INSERT FOR Request BEFORE INSERT AS /* конец заголовка и начало тела триггера*/ BEGIN /* проверка значений вставляемой строки в таблицу Request; при этом переменная NEW представляет собой ссылку на вставляемое значение в указанное поле внешнего ключа таблицы Request */ IF ((NEW.AccountCD IS NULL) OR (NEW.ExecutorCD IS NULL) OR (NEW.FailureCD IS NULL)) THEN /* генерация исключительной ситуации, если значения полей AccountCD, ExecutorCD или FailureCD содержат NULL значения*/ EXCEPTION E Request; ELSE /* присвоение полю первичного ключа таблицы Request очередного значения генератора RequestGEN */ NEW.RequestCD = GEN ID(Request GEN, 1); END !! --конец оператора CREATE TRIGGER SET TERM ; !! /*установка стандартного разделителя */ COMMIT; -- фиксация текущей транзакции Следует обратить внимание на способ присвоения полю RequestCD (первичный ключ таблицы Request) очередного значения: контекстная переменная NEW используется в качестве имени таблицы (Request), в которую вставляется строка. В данном случае нельзя вставлять внутри тела триггера значение первичного ключа в таблицу Request с помощью запроса INSERT (т.к. этот триггер создан именно для события INSERT таблицы Request, то он фактически будет пытаться вызвать сам себя). Таким образом, вставка очередной строки в таблицу Request должна производиться запросом INSERT без указания значения первичного ключа, которое будет генерироваться автоматически, например в следующим виде: INSERT INTO Request (AccountCD, ExecutorCD, FailureCD, IncomingDate, ExecutionDate, Executed) VALUES (005488, 3, 1, 28.12.2005, 01.02.2006, 0);. При выполнении данного запроса срабатывает триггер Request INSERT, т. к. он создан для таблицы Request, активный и имеет реакцию на тип события INSERT. Так как вставляемая строка не содержит NULL значения, то запрос будет выполнен успешно. Если же будет произведена попытка вставки NULL-значений в поля внешних ключей таблицы Request, то сгенерируется исключительная ситуация E Request, будет выдано сообщение Error insert null value into Request и вставки не произойдет. Рассмотрим еще один пример. Пусть необходимо создать условие ссылочной целостности с помощью триггера, который бы запрещал удаление и изменение значения первичного ключа StreetCD в таблице Street при наличии ссылающихся на него внешних ключей в таблице Abonent. Ниже приведен текст SQL сценария, реализующего поставленную задачу. CONNECT c:\sqllab.fdb USER SYSDBA PASSWORD masterkey; SET TERM !! ; CREATE TRIGGER Str DELETE FOR Street BEFORE DELETE OR UPDATE DECLARE VARIABLE NumRows INTEGER; BEGIN SELECT COUNT(*) FROM Abonent WHERE Abonent.StreetCD = OLD.StreetCD INTO :NumRows; IF (NumRows > 0) THEN BEGIN IF (DELETING) THEN EXCEPTION Del Restrict; IF (UPDATING) THEN EXCEPTION Upd Restrict; END END!! SET TERM ; !!. Созданный триггер с именем Str DELETE выполняется перед удалением или обновлением строки в таблице Street. С помощью агрегатной функции COUNT(*) подсчитывается количество строк в таблице Abonent, которые имеют внешние ключи, ссылающиеся на удаляемый или обновляемый первичный ключ таблицы Street. Если количество строк не равно нулю, то анализируется вид события DML. Если это удаление записи, то возникает определенная при создании учебной базы данных исключительная ситуация Del Restrict, прерывающая выполнение тела триггера, и удалить первичный ключ из таблицы Street, который имеет ссылающийся на него внешний ключ, становится невозможно. Если это обновление записи, то возникает исключительная ситуация UpdRestrict, прерывающая выполнение тела триггера, и обновить первичный ключ из таблицы Street, который имеет ссылающийся на него внешний ключ, становится невозможно. Таким образом, созданный триггер реализует правило ссылочной целостности, которое запрещает удаление и обновление первичного ключа родительской таблицы, если имеются ссылающиеся на него внешние ключи дочерней таблицы. 6.3.1.3. Модификация и удаление триггера Триггер представляет собой весьма полезное средство, но в то же время триггеры необходимо очень тщательно отлаживать, так как неправильно написанные триггеры могут привести к серьезным проблемам. При неправильной логике работы триггеров можно легко уничтожить нужные данные и даже целую базу данных. Часто возникает необходимость модифицировать ранее созданный триггер DML. Причинами этого могут быть: - исправление ошибок, допущенных в процессе разработки триггера и нарушающих правильную логику работы системы; - изменение функциональности уже созданного триггера; - временное отключение триггера, полезное при разработке и отладке. Производить модификацию триггера можно в тексте SQL сценария или путем выполнения отдельного запроса на модификацию в SQL-редакторе IBExpert. Для изменения определения созданного триггера DML необходимо использовать запросы ALTER TRIGGER, CREATE OR ALTER TRIGGER или RECREATE TRIGGER, которые имеют следующий формат: { ALTER TRIGGER имя триггера { CREATE OR ALTER RECREATE } TRIGGER имя триггера FOR { базовая таблица представление } } [ACTIVE INACTIVE] [{ BEFORE AFTER } <событие1> [OR <событие2> [OR <событие3>] ] [ [POSITION приоритет триггера[ [AS <тело триггера>] [разделитель]. Изменения триггера могут быть следующих трех видов: - только заголовка; - только тела; - заголовка и тела. Если требуется изменить только заголовок триггера, то можно использовать запрос ALTER TRIGGER. Данный запрос требует хотя бы одного изменяемого атрибута после имени триггера. Любой атрибут заголовка, опущенный в этом запросе, остается неизменным. Если изменяется индикатор фазы, то событие также должно быть указано. Как следует из приведенного выше синтаксиса, запрос ALTER TRIGGER не может связать триггер с другой таблицей, отличной от заданной ранее при создании триггера.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |