使用触发器的MySQL递归更新
我的目标是在不允许用户删除任何行的情况下设计一个模式,为此,我为每个表设置了一个“非活动”列 问题是我有一个这样设计的表格列表使用触发器的MySQL递归更新,mysql,triggers,Mysql,Triggers,我的目标是在不允许用户删除任何行的情况下设计一个模式,为此,我为每个表设置了一个“非活动”列 问题是我有一个这样设计的表格列表 sales_offers (so) -> sales_offers_items (soi) -> sales_offers_items_requisites (soir) -> sales_offers_items_labor (soil) soir和soi
sales_offers (so) -> sales_offers_items (soi) -> sales_offers_items_requisites (soir)
-> sales_offers_items_labor (soil)
和soir
参考soil
带列soi
idparent
refenrencessoi
带列so
idparent
-销售优惠的标题so
-包含提供的项目soi
-包含构建上述项目所需的项目列表(soir
)soi
-包含每个车间的人工成本列表soil
soir
和soil
上都有触发器,它们对其父表soi
进行更新。此更新汇总了每个表中的值,并将其汇总到父表中,以便我可以使用这些汇总进行一些计算
我的问题是这个。当我设置so.inactive=1
时,我希望递归地设置soi.inactive=1;soir.inactive=1;土壤。非活性=1
据我所知,MySQL不允许您以这种方式设计触发器,以避免执行无限循环
我唯一的解决方案是使用另一个表进行聚合,类似于sales\u offers\u items\u totals
(soit
)
这个解决方案太耗时了,我尝试使用复合外键,如果我想停用每个子表,它可以工作,但是如果我只想停用子表的一行,我会得到一个约束错误
如果有人有比额外的聚合表更好的解决方案,我将不胜感激。演示:
所以,我是不活跃的
----: | -------:
11 | 1
111 | 0
soi|u id |不活动| so|u id
-----: | -------: | ----:
22 | 1 | 11
222 | 0 | 111
soir|U id |非活动| soi|U id
------: | -------: | -----:
33 | 1 | 22
333 | 0 | 222
soi|U id | so|id |不活动|不活动| soi|U id |不活动
-----: | ----: | -------: | -------: | ------: | -------:
22 | 11 | 1 | 1 | 33 | 1
222 | 111 | 0 | 0 | 333 | 0
dbfiddle嗨,Akina,谢谢你的回答。这一切都是我做的。问题在于soir在“value”列上有一个触发器,该触发器对soi.total_值进行更新。当我更新soi.inactive并启动触发器时,mysql表示我无法更新此表,因为它正在另一个触发器/函数中使用。
CREATE TABLE so (so_id INT PRIMARY KEY,
inactive boolean);
CREATE TABLE soi (soi_id INT PRIMARY KEY,
inactive boolean,
so_id INT,
FOREIGN KEY (so_id) REFERENCES so (so_id));
CREATE TABLE soir (soir_id INT PRIMARY KEY,
inactive boolean,
soi_id INT,
FOREIGN KEY (soi_id) REFERENCES soi (soi_id));
INSERT INTO so VALUES (11, 0), (111, 0);
INSERT INTO soi VALUES (22, 0, 11), (222, 0, 111);
INSERT INTO soir VALUES (33, 0, 22), (333, 0, 222);
CREATE TRIGGER tr_au_so
AFTER UPDATE
ON so
FOR EACH ROW
UPDATE soi SET inactive = NEW.inactive WHERE so_id = NEW.so_id;
CREATE TRIGGER tr_au_soi
AFTER UPDATE
ON soi
FOR EACH ROW
UPDATE soir SET inactive = NEW.inactive WHERE soi_id = NEW.soi_id;
SELECT * FROM so;
SELECT * FROM soi;
SELECT * FROM soir;
SELECT *
FROM so
JOIN soi USING (so_id)
JOIN soir USING (soi_id);
so_id | inactive
----: | -------:
11 | 0
111 | 0
soi_id | inactive | so_id
-----: | -------: | ----:
22 | 0 | 11
222 | 0 | 111
soir_id | inactive | soi_id
------: | -------: | -----:
33 | 0 | 22
333 | 0 | 222
soi_id | so_id | inactive | inactive | soir_id | inactive
-----: | ----: | -------: | -------: | ------: | -------:
22 | 11 | 0 | 0 | 33 | 0
222 | 111 | 0 | 0 | 333 | 0
UPDATE so SET inactive = 1 WHERE so_id = 11;
SELECT * FROM so;
SELECT * FROM soi;
SELECT * FROM soir;
SELECT *
FROM so
JOIN soi USING (so_id)
JOIN soir USING (soi_id);
so_id | inactive
----: | -------:
11 | 1
111 | 0
soi_id | inactive | so_id
-----: | -------: | ----:
22 | 1 | 11
222 | 0 | 111
soir_id | inactive | soi_id
------: | -------: | -----:
33 | 1 | 22
333 | 0 | 222
soi_id | so_id | inactive | inactive | soir_id | inactive
-----: | ----: | -------: | -------: | ------: | -------:
22 | 11 | 1 | 1 | 33 | 1
222 | 111 | 0 | 0 | 333 | 0