У меня есть таблица, в которой есть элементы с полями заказов, которые я использую для рисования их на дереве.
CREATE TABLE items (
menuId INTEGER,
itemId INTEGER,
name VARCHAR,
order1 INTEGER,
order2 INTEGER,
order3 INTEGER,
order4 INTEGER,
);
Первичный ключ - это 'menuId' и 'itemId'.
Foreignключ '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 update order2 до 3, который заставил menu3 обновить order2 до 4, но menu3 уже было изменено при первоначальном обновлении.
Что я делаюне знаю, как я могу решить эту проблему или если это вообще возможно.