【问题标题】:FOR EACH STATEMENT trigger exampleFOR EACH STATEMENT 触发器示例
【发布时间】:2014-08-03 07:40:00
【问题描述】:

我一直在查看documentation of postgresql triggers,但它似乎只显示了行级触发器的示例,但我找不到语句级触发器的示例。

特别是,不清楚如何在单个语句中迭代更新/插入的行,因为NEW 是针对单个记录的。

【问题讨论】:

    标签: postgresql plpgsql triggers


    【解决方案1】:

    OLDNEW 为 null 或未在语句级触发器中定义。 Per documentation:

    NEW

    数据类型RECORD;为行级触发器中的INSERT/UPDATE 操作保存新数据库行的变量。 这个变量是 null 在语句级触发器DELETE 操作中。

    OLD

    数据类型记录;为行级触发器中的UPDATE/DELETE 操作保存旧数据库行的变量。 此变量在语句级触发器中为空,对于INSERT 操作。

    我的大胆强调。

    在 Postgres 10 之前,这读起来略有不同,但效果大致相同:

    ...此变量在语句级触发器中未分配。 ...

    虽然这些记录变量对于语句级触发器仍然没有用处,但一个非常新的功能是:

    Postgres 10+ 中的转换表

    Postgres 10 引入了转换表。这些允许访问整个受影响的行集。 The manual:

    AFTER 触发器还可以利用转换表 来检查由触发语句更改的整个行集。 CREATE TRIGGER 命令将名称分配给一个或两个转换 表,然后函数可以引用这些名称,就好像它们 是只读的临时表。 Example 43.7 显示了一个示例。

    点击手册链接获取代码示例。

    示例语句级触发器没有转换表

    在转换表出现之前,这种情况就更少见了。一个有用的例子是在某些 DML 命令之后发送notifications
    这是我使用的基本版本:

    -- Generic trigger function, can be used for multiple triggers:
    CREATE OR REPLACE FUNCTION trg_notify_after()
      RETURNS trigger
      LANGUAGE plpgsql AS
    $func$
    BEGIN
       PERFORM pg_notify(TG_TABLE_NAME, TG_OP);
       RETURN NULL;
    END
    $func$;
    
    -- Trigger
    CREATE TRIGGER notify_after
    AFTER INSERT OR UPDATE OR DELETE ON my_tbl
    FOR EACH STATEMENT
    EXECUTE PROCEDURE trg_notify_after();

    对于 Postgres 11 或更高版本,请使用等效且不易混淆的语法:

    ...
    EXECUTE FUNCTION trg_notify_after();
    

    见:

    【讨论】:

    • 我希望语句触发器有一些 equivalentNEWOLD 用于多记录情况,以及一些迭代这些情况的方法..
    • 那真是太糟糕了,因为这意味着你只能在触发器中进行 RBAR 操作。
    • 如果没有受影响的行,似乎也会执行语句触发器。我不需要分析里面的数据,但是我想知道是否有任何记录更新。有什么办法吗?
    • @user1038334:您可以将查询封装在一个函数中并检查结果,而不是触发器。详情:stackoverflow.com/a/19393268/939860
    • @ErwinBrandstetter 我认为这在较新的版本中有所改变......我相信现在可以在语句级触发器中访问 NEW 和 OLD 表
    猜你喜欢
    • 1970-01-01
    • 2011-11-05
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 1970-01-01
    • 2013-01-07
    • 2013-08-28
    相关资源
    最近更新 更多