【问题标题】:Using triggers in Postgres在 Postgres 中使用触发器
【发布时间】:2021-02-21 08:48:41
【问题描述】:

我在 Postgres DB 中有两个表 A 和 B。

每当我在表 A 中插入一个或多个新行时,我想将这些更新添加到表 B。如果表 B 为空,则表 A 中插入的所有新闻行也将添加到表 B。但是,当新行插入到表A中,如果表B中已经有数据,我想在将表A的新行插入表B之前删除表B中的所有数据。

所以基本上每次在A表中插入新行时,相应的行也应该添加到表B中,但每次插入表B之前都要执行删除操作,这样表B中就没有旧行了。表B旨在仅保存表 A 中新添加的行。

以下是我使用触发器的 Postgres 脚本。

    CREATE TRIGGER test_one AFTER INSERT ON A
    FOR EACH ROW EXECUTE PROCEDURE addRows();

    CREATE OR REPLACE FUNCTION addRows() RETURNS TRIGGER AS $remove_table$
       BEGIN
          DELETE from B;
          INSERT INTO B(std_id, name) VALUES (new.col1, new.col2);
          RETURN NEW;
       END;
    $remove_table$ LANGUAGE plpgsql;

这个触发器函数完成了这项工作,但表 A 中的所有新添加的行都没有被保留。我最终在表 B 中只有一行是表 A 中新插入数据的最后一行。再次强调,如果我在表 A 中插入 10 行新行,则表 B 预计将添加 10 行。但是,表 B 中只添加了第 10 行,这不是我们想要的结果。

谁能帮我弄明白怎么回事?

【问题讨论】:

    标签: postgresql triggers


    【解决方案1】:

    从 Postgres 10 开始,支持伪表,通过这些伪表可以在FOR EACH STATEMENT 触发器中访问插入的集合。

    更改您的函数以从此类伪表中执行INSERT ... SELECT ...

    CREATE
     OR REPLACE FUNCTION addrows
                         ()
                         RETURNS TRIGGER
    AS
    $$
    BEGIN
      DELETE FROM b;
      
      INSERT INTO b
                  (std_id,
                   name)
                  SELECT col1,
                         col2
                         FROM inserted;
      RETURN NULL;
    END;
    $$
    LANGUAGE plpgsql;
    

    并且在创建触发器时,将其设为FOR EACH STATEMENT 触发器并添加对伪表的引用。

    CREATE TRIGGER test_one
                   AFTER INSERT ON a
                   REFERENCING NEW TABLE AS inserted
                   FOR EACH STATEMENT
                   EXECUTE PROCEDURE addrows();
    

    db<>fiddle

    【讨论】:

    • 谢谢@sticky bit。为我工作!
    【解决方案2】:

    触发器的问题在于它会针对您插入的每一行触发,而不是针对每个“集合”行触发。例如,对于一批 10 次插入,触发器将触发 10 次,始终删除 B 中的所有数据,留下 1 行 - 最后插入。

    为什么要创建这个额外的表并重复数据?您能否在表 A 中存储插入日期/时间或“插入批号”并从中查询或在其上创建视图?

    【讨论】:

    • 谢谢您,先生。我意识到为什么表 B 中只有一行。另外,我理解你的建议。有太多要解释的问题,所以我缩短了上下文。是的,存在数据重复,但根据我的问题,它可以达到目的,所以没关系。无论如何,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多