我有一个表mytable
,其中包含myorder
列,其中我存储了记录顺序。我需要一种行为,其中插入具有现有myorder
值的新记录会将所有具有更大myorder
的记录增加1.当更新具有现有myorder
值的行时,应该具有相同的行为
我已经在BEFORE INSERT OR UPDATE
触发器中更新了这些值,但它给了我一个错误
ERROR: tuple to be updated was already modified by an operation triggered by the current command
似乎它以不受控制的顺序递归触发每个更新行的触发器。 AFTER INSERT OR UPDATE
无效,因为它会违反该列的唯一约束或最终无限循环。
有没有一种有效的方法来实现这种行为?这是我的代码:
CREATE TABLE mytable (
myorder INTEGER NOT NULL,
myotherstuff TEXT,
CONSTRAINT unq_myorder UNIQUE (myorder) DEFERRABLE INITIALLY DEFERRED
);
CREATE OR REPLACE FUNCTION reorder_records ()
RETURNS TRIGGER
LANGUAGE 'plpgsql'
AS $function$
DECLARE
reorder BOOLEAN := TRUE;
BEGIN
RAISE NOTICE 'fired on %', NEW.myorder;
reorder := EXISTS(SELECT 1 FROM mytable WHERE myorder = NEW.myorder);
IF reorder THEN
UPDATE
mytable
SET
myorder = myorder + 1
WHERE
myorder >= NEW.myorder;
END IF;
RETURN NEW;
END;
$function$;
CREATE TRIGGER trg_reorder
BEFORE INSERT OR UPDATE
ON mytable
FOR EACH ROW
EXECUTE PROCEDURE bak.reorder_records();
INSERT INTO mytable (myorder, myotherstuff) VALUES
(1, 'one')
,(2, 'two')
,(3, 'three');
--THIS ONE FAILS!!!
INSERT INTO mytable (myorder, myotherstuff) VALUES
(2, 'four');