Программирование >>  Построение запросов sql 

1 ... 80 81 82 [ 83 ] 84 85 86 ... 101


или 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.

USR NAME

NACH ID

DML EVENT

TIME DATE

SYSDBA

04.06.2007 23:00

SYSDBA

04.06.2007 23:01

SYSDBA

EDIT

04.06.2007 23:03

Рис. 6.10. Данные таблицы Journal

Описание всех имеющихся в БД триггеров (как системных, так и пользовательских) хранится в системной таблице RDB$TRIGGERS. При использовании утилиты IBExpert все пользовательские триггеры отображаются в окне инспектора объектов БД.

6.3.1.2. Примеры поддержания ссылочной целостности

Рассмотрим примеры поддержания целостности БД с помощью триггеров.

Пусть необходимо написать SQL сценарий по созданию триггера, предотвращающего вставку NULL значений в поля внешних ключей AccountCD, ExecutorCD и FailureCD таблицы Request. Если значения, вводимые в поля перечисленных внешних ключей, не содержат NULL, то необходимо вставить в поле первичного ключа RequestCD очередное значение, полученное с помощью генератора. При попытке вставить NULL значение должен сработать триггер и выдать сообщение об исключительной ситуации, т. е.



1 ... 80 81 82 [ 83 ] 84 85 86 ... 101

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика