Создание триггеров для поддержания каскадных воздействий
В рассматриваемом варианте БД соединения дочерних и родительских таблиц (соответственно RASHOD и TOVARY, POKUPATELI) являются "жесткими". Напомним, что при реализации ссылочной целостности на уровне PRIMARY KEY - FOREIGN KEY нельзя изменять значение поля связи как в дочерней таблице, так и в родительской таблице, если для данного значения первичного ключа существуют дочерние записи.
Дпя избранной структуры данных
CREATE TABLE POKUPATELI(
POKUP VARCHAR(20) NOT NULL COLLATE PXW_CYRL,
GOROD VARCHAR(12) COLLATE PXW_CYRL,
ADRES VARCHAR(20) COLLATE PXW_CYRL,
PRIMARY KEY(POKUP)
) ;
CREATE TABLE TOVARY(
TOVAR VARCHAR(20) NOT NULL COLLATE PXW_CYRL,
ED_IZM VARCHAR(IO) NOT NULL COLLATE PXW_CYRL,
ZENA INTEGER NOT NULL,
PRIMARY KEY(TOVAR)
) ;
CREATE TABLE RASHOD(
N_RASH INTEGER NOT NULL,
DAT_RASH DATE NOT NULL,
KOLVO INTEGER NOT NULL,
TOVAR VARCHAR(20) NOT NULL COLLATE PXW_CYRL,
POKUP VARCHAR(20) COLLATE PXW_CYRL,
PRIMARY KEY(N_RASH),
FOREIGN KEY(POKUP) REFERENCES POKUPATELI,
FOREIGN KEY(TOVAR) REFERENCES TOVARY
) ;
жирным отмечены ограничения по внешнему ключу. Таким образом, если в таблице TOVARY для какого-либо товара существует расход в таблице RASHOD, изменение названия товара в таблице TOVARY будет блокировано. При попытке изменить в таблице TOVAR значение наименования товара с "Сахар" на "Сахар кусковой" (рис. 17 9) будет возбуждено исключение из-за нарушения жестких ограничений целостности (рис. 17.10)
Можно увидеть, что жесткие ограничения целостности будут нам мешать в дальнейшем, когда возникнет необходимость изменять название товара или покупателя Если мы не будем менять названия товаров и покупателей, жесткие ограничения целостности можно оставить, однако будем считать, что потребность в подобных изменениях все-таки может возникнуть
Поэтому вместо жестких ограничений целостности нам необходимо реализовать возможность каскадных воздействий - таких, что:
• при изменении значения столбца TOVAR в таблице TOVARY эти изменения должны быть отражены в дочерних записях в таблице RASHOD (если такие есть для изменяемой записи в таблице TOVARY),
• при удалении записи в таблице TOVARY должны быть удалены дочерние записи в таблице RASHOD, если они есть
Для достижения этой цели нужно удалить не устраивающие нас ограничения целостности между таблицами TOVARY и RASHOD и затем определить в БД триггеры, реализующие каскадные воздействия
Для удаления внешнего ключа FOREIGN KEY(TOVAR) REFERENCES TOVARY необходимо удалить ограничение ссылочной целостности, определяемое этим ключом Однако в явном виде ограничение не было определено, например
CONSTRAINTS TOV_RASH FOREIGN KEY(TOVAR) REFERENCES TOVARY
где TOV_RASH есть имя ограничения Поэтому необходимо установить системное имя, присвоенное InterBase данному ограничению внешнего ключа Это системное имя, INTEG_32, можно увидеть в сообщении, выдаваемом при возбуждении исключения по нарушению жесткой ссылочной целостности (см выше) Следует убедиться, что INTEG_32 действительно есть ограничение целостности, которое следует удалить Для этой цели необходимо воспользоваться утилитой SQL Ex plorer, найдя для таблицы RASHOD узел Refrential Constraint's (рис 17.11)
Искомое нами ограничение имеет имя INTEG.32 Удалим его Для этого запустим WISQL, соединимся с БД и выполним оператор
ALTER TABLE RASHOD
DROP CONSTRAINT INTEG_32;
Затем создадим триггеры, реализующие каскадное изменение в таблице RASHOD при изменении названия товара в таблице TOVARY
CREATE TRIGGER BU_TOVARY FOR TOVARY
ACTIVE
BEFORE UPDATE
AS
BEGIN
IF (OLD.TOVAR 0 NEW.TOVAR) THEN
UPDATE RASHOD
SET TOVAR = NEW.TOVAR
WHERE TOVAR = OLD.TOVAR;
END
и каскадное удаление дочерних записей в таблице RASHOD при удалении родительской записи в таблице TOVARY:
CREATE TRIGGER AD_TOVARY FOR TOVARY
ACTIVE
AFTER DELETE
AS
BEGIN
DELETE FROM RASHOD
WHERE RASHOD.TOVAR =TOVARY.TOVAR;
END
Теперь, при изменении наименования товара в таблице TOVARY произойдут каскадные изменения наименования товара в дочерних записях таблицы RASHOD (рис 17 12 и 17 13)