如何更新postgresql中INSERT触发器中具有UPDATE触发器的表

时间:2017-01-27 14:04:25

标签: database postgresql triggers sql-update database-trigger

我有一个表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');

0 个答案:

没有答案