Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 如何在postgresql的INSERT触发器中更新具有update触发器的表_Database_Postgresql_Triggers_Sql Update_Database Trigger - Fatal编程技术网

Database 如何在postgresql的INSERT触发器中更新具有update触发器的表

Database 如何在postgresql的INSERT触发器中更新具有update触发器的表,database,postgresql,triggers,sql-update,database-trigger,Database,Postgresql,Triggers,Sql Update,Database Trigger,我有一个表mytable和列myorder,我在其中存储记录的顺序。我需要一个行为,插入一个具有现有myorder值的新记录将使所有具有更大myorder值的记录增加1。当使用现有myorder值更新行时,应该有相同的行为 我做了一个BEFORE INSERT或UPDATE触发器,在这里我更新了这些值,但它给了我一个错误 错误:当前命令触发的操作已修改了要更新的元组 似乎它是以不受控制的顺序递归地为每个更新的行触发触发器。INSERT或UPDATE之后将不起作用,因为它将违反该列上的unique

我有一个表mytable和列myorder,我在其中存储记录的顺序。我需要一个行为,插入一个具有现有myorder值的新记录将使所有具有更大myorder值的记录增加1。当使用现有myorder值更新行时,应该有相同的行为

我做了一个BEFORE INSERT或UPDATE触发器,在这里我更新了这些值,但它给了我一个错误

错误:当前命令触发的操作已修改了要更新的元组

似乎它是以不受控制的顺序递归地为每个更新的行触发触发器。INSERT或UPDATE之后将不起作用,因为它将违反该列上的unique约束或以无限循环结束。 有没有有效的方法来实施这种行为?这是我的密码:

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');

那么,插入后的预期输出应该是1,'一',2,'四',3,'二',4,'三'?这种重新排序应该在更新ing时也起作用?如果在更新过程中旧的myorder值会留下一个间隙,这是一个问题吗?我能想到的一个解决方案是只更新触发器中的下一个myorder&让它通过表进行级联。类似于UPDATE mytable SET myorder=myorder+1,其中myorder=SELECT MINmyorder FROM mytable WHERE myorder>=NEW.myorder-它的性能不会很好。当insert触发器通过传递参数调用UPDATE时,也许有一种方法可以忽略UPDATE触发器?转移身份似乎是一项常见的任务,但我找不到一个简单而优雅的解决方案。