postgresql触发可能的无限循环?

vltsax25  于 2023-06-29  发布在  PostgreSQL
关注(0)|答案(2)|浏览(175)

我有一个有3个字段的表

id, name , value

我想添加第4列calcValuecalcValue的计算基于整个表中的value字段,在一行中更改它会导致所有其他行的更改。
我想写一个触发器,每当表中有insert, delete or update时更新calcValue
我担心的是触发器本身将有一个Update命令。它会再次调用此触发器吗?我会被无限循环卡住吗?
更好地描述它:

CREATE TRIGGER x
  AFTER INSERT OR UPDATE OR DELETE
  ON a
  FOR EACH ROW
  EXECUTE PROCEDURE dosomething();

以及:

CREATE OR REPLACE FUNCTION dosomething()
  RETURNS trigger AS
$BODY$

begin 
        code + calculation of result...
                for row in 
                             QUERY
                Loop
             Update a set calValue=result where id=...
                end loop;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE

dosomething()中的a的更新是否会导致触发器x的另一次调用?如果是这样,有没有一种方法来处理它,使它不会卡在无限循环?
我的目标是在a的每个更新/插入/删除操作中执行一次dosomething()。我不希望因为触发器中的更新a而再次调用dosomething()

**编辑:**因为我在触发器中更新了一个不同的列,所以我可以这样做:

CREATE TRIGGER x
    BEFORE UPDATE OF value ON a
    FOR EACH ROW
    EXECUTE PROCEDURE dosomething();

这应该解决了我的问题,因为触发器更新calcValue,而tigger没有在value列上设置调用。然而,我仍然想知道我最初的问题是否有答案...假设触发器将更新同一列。

xfb7svmp

xfb7svmp1#

另一种方法是添加when子句,沿着所示:

CREATE TRIGGER x
AFTER INSERT OR UPDATE OR DELETE
ON a
FOR EACH ROW
WHEN NEW IS NULL OR OLD IS NULL OR NEW.value <> OLD.value
EXECUTE PROCEDURE dosomething();

它只会在value字段发生更改时执行触发器。因此,当在触发器内部更新calcValue时,不会再次调用触发器,从而防止无限“循环”。

6g8kf2rb

6g8kf2rb2#

您可以使用pg_trigger_depth()来防止这种情况,只要它符合更广泛的触发器生态系统(现在和未来)。

CREATE TRIGGER my_trigger
AFTER INSERT ON my_tbl
FOR EACH ROW
WHEN (pg_trigger_depth() < 1)
EXECUTE PROCEDURE my_trigger_func();

参见https://dba.stackexchange.com/questions/163142/is-pg-trigger-depth-bad-to-use-for-preventing-trigger-cascading-recursion

相关问题