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 Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|