Давно меня мучает один неразрешенный вопрос, связанный с обеспечением бизнес-логики приложения. Прошу извинение за большой пост, но для наглядности привожу пример.
Есть две таблицы - справочник товаров и движение товаров:
Код: Выделить всё
CREATE TABLE GOODS - Справочник товаров
ID INTEGER - код товара
RES NUMERIC(18,4) - остаток товара
CREATE TABLE DETAL - Движение товара:
GDS INTEGER - товар
MODE SMALLINT - признак (-1 расход, 1 приход)
CNT NUMERIC(18,4) - количество
Код: Выделить всё
Первый вариант - Только триггеры:
CREATE TRIGGER DETAL_AI FOR DETAL
ACTIVE AFTER INSERT POSITION 0
AS
BEGIN
UPDATE GOODS
SET RES = RES + NEW.CNT * NEW.MODE
WHERE ID = NEW.GDS;
END
CREATE TRIGGER DETAL_AU FOR DETAL
ACTIVE AFTER UPDATE POSITION 0
AS
BEGIN
UPDATE GOODS
SET RES = RES - OLD.CNT * OLD.MODE
WHERE ID = OLD.GDS;
UPDATE GOODS
SET RES = RES + NEW.CNT * NEW.MODE
WHERE ID = NEW.GDS;
END
CREATE TRIGGER DETAL_AD FOR DETAL
ACTIVE AFTER DELETE POSITION 0
AS
BEGIN
UPDATE GOODS
SET RES = RES - OLD.CNT * OLD.MODE
WHERE ID = OLD.GDS;
END
Код: Выделить всё
Второй вариант - триггеры с процедурой:
CREATE PROCEDURE SET_GDS_RES(
PGDS INTEGER,
PCNT NUMERIC(18,4))
AS
BEGIN
UPDATE GOODS
SET RES = RES + PCNT
WHERE ID = PGDS;
END
CREATE TRIGGER DETAL_AI FOR DETAL
ACTIVE AFTER INSERT POSITION 0
AS
BEGIN
EXECUTE PROCEDURE SET_GDS_RES(NEW.GDS, NEW.CNT * NEW.MODE);
END
CREATE TRIGGER DETAL_AU FOR DETAL
ACTIVE AFTER UPDATE POSITION 0
AS
BEGIN
EXECUTE PROCEDURE SET_GDS_RES(OLD.GDS, 0-OLD.CNT * OLD.MODE);
EXECUTE PROCEDURE SET_GDS_RES(NEW.GDS, NEW.CNT * NEW.MODE);
END
CREATE TRIGGER DETAL_AD FOR DETAL
ACTIVE AFTER DELETE POSITION 0
AS
BEGIN
EXECUTE PROCEDURE SET_GDS_RES(OLD.GDS, 0-OLD.CNT * OLD.MODE);
END