【发布时间】:2019-10-23 14:00:08
【问题描述】:
我有一个表,其中包含带有订单字段的项目,我用这些字段将它们绘制在树上。
CREATE TABLE items (
menuId INTEGER,
itemId INTEGER,
name VARCHAR,
order1 INTEGER,
order2 INTEGER,
order3 INTEGER,
order4 INTEGER,
);
主键是“menuId”和“itemId”。
“menuId”与“menus”表的外键。
对于每个菜单,我都有一个唯一的检查,例如对于 menu1,我不能有两个具有相同组合顺序的项目,但 menu2 可以。
我想创建一个在我插入或更新项目时触发的触发器,所以如果添加一个订单为 2 的新项目,订单 2 的项目更新为 3,订单 3 更新为 4,依此类推。现在我不在乎订单之间是否有空格,我会在稍后尝试解决这个问题。
触发器是这样的:
CREATE TRIGGER trg_items_menu_bibu
BEFORE INSERT OR UPDATE
ON items
FOR EACH ROW
EXECUTE PROCEDURE update_menu_order();
CREATE OR REPLACE FUNCTION update_menu_order()
RETURNS trigger AS
$BODY$
BEGIN
IF EXISTS (SELECT name
FROM items
WHERE order1 = NEW.order1
AND order2 = NEW.order2
AND order3 = NEW.order3
AND order4 = NEW.order4
AND menuId = NEW.menuId
AND itemId <> NEW.itemId) THEN
-- If exists an item for that menu with the same orders
IF (NEW.order4 <> 0) THEN
-- If it's an item in the sublevel4
UPDATE items SET order4 = order4 + 1
WHERE order1 = NEW.order1
AND order2 = NEW.order2
AND order3 = NEW.order3
AND order4 = NEW.order4
AND menuId = NEW.menuId
AND itemId <> NEW.itemId;
ELSEIF (NEW.order3 <> 0) THEN
-- If it's an item in the sublevel3
UPDATE items SET order3 = order3 + 1
WHERE order1 = NEW.order1
AND order2 = NEW.order2
AND order3 = NEW.order3
AND order4 = 0
AND menuId = NEW.menuId
AND itemId <> NEW.itemId;
ELSEIF (NEW.order2 <> 0) THEN
-- If it's an item in the sublevel2
UPDATE items SET order2 = order2 + 1
WHERE order1 = NEW.order1
AND order2 = NEW.order2
AND order3 = 0
AND order4 = 0
AND menuId = NEW.menuId
AND itemId <> NEW.itemId;
ELSE
-- If it's an item in the sublevel1
UPDATE items SET order1 = order1 + 1
WHERE order1 = NEW.order1
AND order2 = 0
AND order3 = 0
AND order4 = 0
AND menuId = NEW.menuId
AND itemId <> NEW.itemId;
END IF;
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;
如果我有这些物品:
menuId itemId name order1 order2 order3 order4
1 1 menu1 1 0 0 0
1 2 menu2 1 1 0 0
1 3 menu3 1 2 0 0
我尝试插入以下内容:
menuId itemId name order1 order2 order3 order4
1 4 menu4 1 1 0 0
触发器正确更新为:
menuId itemId name order1 order2 order3 order4
1 1 menu1 1 0 0 0
1 4 menu4 1 1 0 0
1 2 menu2 1 2 0 0
1 3 menu3 1 3 0 0
但如果我尝试更新:
1 3 menu3 1 1 0 0
我收到一条错误消息,指出要修改的一行已被修改。
我了解问题是触发器使menu2将order2更新为3,谁强制menu3将order2更新为4,但menu3已经被原始更新修改了。
我不知道我该如何解决这个问题,或者是否有可能。
【问题讨论】:
标签: sql postgresql triggers