我有一个表tbl有一个dirty: boolean列。在事务处理期间,对于某些行,此标志设置为true。然后,我有以下触发器:

create function tbl_process() returns trigger as
$$ begin
    -- first, do something for all rows with dirty flag set to true
    ...

    -- then, reset the dirty flag
    update tbl set dirty = false where dirty = true;

    return null;
end $$ language plpgsql;

create trigger tbl_process after update on tbl for each statement execute procedure tbl_process();

这里的问题是第二个查询(update tbl set dirty = false where dirty = true)递归地调用触发器。一直这样直到堆栈溢出。
有办法避免吗?还有,为什么我们会遇到递归呢?在第一次迭代中,我们将所有行标记为dirty = false,因此在第二次迭代中,不应该有dirty = true
我正在使用PostgreSQL 9.6。

最佳答案

在函数体的开头添加下面的语句

IF pg_trigger_depth() <> 1 THEN
        RETURN NEW;
    END IF;

喜欢
create function tbl_process() returns trigger as
$$ begin
    IF pg_trigger_depth() <> 1 THEN
        RETURN NEW;
    END IF;
    update tbl set dirty = false where dirty = true;

    return null;
end $$ language plpgsql;

关于sql - 如何避免在此FOR EACH STATEMENT触发器中进行无限递归?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48702802/

10-09 22:15