Database 如何在postgresql的INSERT触发器中更新具有update触发器的表
我有一个表mytable和列myorder,我在其中存储记录的顺序。我需要一个行为,插入一个具有现有myorder值的新记录将使所有具有更大myorder值的记录增加1。当使用现有myorder值更新行时,应该有相同的行为 我做了一个BEFORE INSERT或UPDATE触发器,在这里我更新了这些值,但它给了我一个错误 错误:当前命令触发的操作已修改了要更新的元组 似乎它是以不受控制的顺序递归地为每个更新的行触发触发器。INSERT或UPDATE之后将不起作用,因为它将违反该列上的unique约束或以无限循环结束。 有没有有效的方法来实施这种行为?这是我的密码: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
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触发器?转移身份似乎是一项常见的任务,但我找不到一个简单而优雅的解决方案。