Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Create trigger ai_rasxod1 for rasxod




ACTIVE AFTER INSERT POSITION 1 AS

BEGIN

UPDATE TOVARY

SET COUNT_TOV = COUNT_TOV-NEW.KOLVO

WHERE KOD_TOVAR = NEW.KOD_TOVAR;

END

 

Триггер, отрабатывающий перед удалением записи в таблице RASXOD, выглядит следующим образом:

CREATE TRIGGER BD_RASXOD1 FOR RASXOD

ACTIVE BEFORE DELETE POSITION 0 AS

BEGIN

UPDATE TOVARY

SET COUNT_TOV= COUNT_TOV+RASXOD.KOLVO

WHERE KOD_TOVAR = RASXOD.KOD_TOVAR;

END

 

Триггер, отрабатывающий после обновления данных в таблице RASXOD (а точнее при изменении количества купленного товара)

CREATE TRIGGER AU_RASXOD1 FOR RASXOD

ACTIVE AFTER UPDATE POSITION 1 AS

BEGIN

IF ((OLD.KOLVO <> NEW.KOLVO) AND

(OLD.KOD_TOVAR = NEW.KOD_TOVAR)) THEN

UPDATE TOVARY

SET COUNT_TOV= COUNT_TOV+OLD.KOLVO-NEW.KOLVO

WHERE KOD_TOVAR = OLD.KOD_TOVAR;

END;

 

Остается еще один не рассмотренный случай – изменение кода купленного товара KOD_TOVAR в строке таблицы RASXOD [7] должно повлечь перерасчет значений количества товаров на складе COUNT_TOV в таблице TOVARY.

CREATE TRIGGER AU_RASXOD0 FOR RASXOD

ACTIVE AFTER UPDATE POSITION 0 AS

DECLARE VARIABLE OldKod INTEGER;

BEGIN

IF (OLD.KOD_TOVAR <> NEW.KOD_TOVAR) THEN

BEGIN OldKod = NULL;

SELECT KOD_TOVAR FROM TOVARY

WHERE KOD_TOVAR = OLD.KOD_TOVAR

INTO:OldKod;

IF (OldKod IS NOT NULL) THEN

BEGIN

UPDATE TOVARY

SET COUNT_TOV= COUNT_TOV+OLD.KOLVO

WHERE KOD_TOVAR = OLD.KOD_TOVAR;

UPDATE TOVARY

SET COUNT_TOV= COUNT_TOV-NEW.KOLVO

WHERE KOD_TOVAR = NEW.KOD_TOVAR;

END

END

END

 

Комментарий к триггерам обновления:

§ Вообще-то можно было бы написать один триггер обновления, подходящим образом объединив их содержание. Но раз уж их два, то возникает вопрос об их взаимоотношениях:

· После события обновления таблицы RASXOD (FOR RASXOD AFTER UPDATE) отработают оба триггера.

· Порядок, в котором они отработают, задан предложением POSITION n. Правда, в нашем случае этот порядок не важен.

· Однако важно, чтобы только один из них внес изменения в таблицу TOVARY, поэтому в теле использованы альтернативные IF-условия.

§ В триггере AU_RASXOD0 используется еще одно (внутреннее) IF-условие и связанный с ним оператор SELECT.

Это IF-условие связано со спецификой триггеров – в отличие от обычных процедур триггер вызывается не оператором процедуры, а неявно по соответствующему событию, что достаточно необычно для традиционного процедурного программирования. Поэтому программирование триггеров требует специального внимания – дабы не допустить действий, просто лишних, а тем более искажающих результат или ведущих к порочному кругу (Deadlock).

В нашем случае, если в таблице «Товары» изменится значение поля KOD_TOVAR, то в дочерней таблице «Расход» будет выполнено каскадное обновление согласно объявленному ограничению ссылочной целостности. Это обновление инициирует запуск всех UPDATE-триггеров таблицы RASXOD... для каждой обновляемой её строки... Легко видеть, что такой косвенный вызов не должен повлечь перерасчета количества товаров на складе в таблице «Товары»... а он, если не предпринять специальных усилий, произойдет и даст неправильный результат...

SELECT-оператор и последующее IF-условие позволяют проверить, имеется ли OLD.KOD_TOVAR в таблице TOVARY... отсутствовать он может только в случае косвенного вызова триггера AU_RASXOD0, инициированного тем самым каскадным обновлением. Возможно, это не самое лучшее решение проблемы, но какой-то вариант решения.

Каждая таблица имеет первичный ключ - целочисленное поле. Значения такого поля для различных записей должны быть разными по определению. Поскольку это поле не имеет содержательного смысла и используется только для связи между таблицами, то заполнение этого поля (проверку уникальности его значения) можно поручить серверу базы данных. Для этого удобно использовать генераторы.

Генератор - это переменная, значение которой хранится в БД, поэтому оно не теряется при завершении работы программы и восстанавливается при повторном ее запуске. Создается генератор посредством оператора

CREATE GENERATOR TOVARY_KOD;

Инициализация генератора производится оператором

SET GENERATOR TOVARY_KOD TO 100;

Соответствующие операторы для таблиц POKUPATELI и RASXOD выглядят следующим образом:

CREATE GENERATOR POKUPATELI_KOD;

SET GENERATOR POKUPATELI_KOD TO 100;

CREATE GENERATOR RASXOD_KOD;

SET GENERATOR RASXOD_KOD TO 100;

Далее необходимо определить хранимые процедуры, изменяющие на 1 значения этих переменных.

Поделиться:





Читайте также:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...