sql - 如何避免在此 FOR EACH STATEMENT 触发器中无限递归?

标签 sql postgresql recursion

我有一个表 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/

相关文章:

macos - Postgres 数据库没有角色

java - 如何在java中的递归函数中创建数组

mysql - 在数据库中存储登录详细信息

c# - 如何让 linq 准确地生成我想要的 sql?

mysql - 如何在不知道元素id的情况下删除元素,只需在数据库中排序

mysql - 永不删除的关系数据库模式设计

postgresql - ts_vector 之间的交点

sql - JSON_MODIFY 删除数组对象

java - 在Java中递归地替换链表中的字符串

javascript - 生成 JavaScript 数组的排列