繁体   English   中英

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

[英]How can I avoid infinite recursion in this FOR EACH STATEMENT trigger?

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

您可以在更新之前验证此字段的NEW值是否为true。 如果将其设置为false,则无需执行任何操作。

但是,为什么要处理设置了该字段的所有记录? 由于此触发器,因此只应存在此触发器,因为最后将其重置。 而且,如果您需要更新当前记录,则可以通过将NEW.dirty更新为false来正确地进行操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM