繁体   English   中英

在 Postgres 中使用触发器

[英]Using triggers in Postgres

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

每当我在表 AI 中插入一个或多个新行时,都想将这些更新添加到表 B。如果表 B 为空,则表 A 中插入的所有新闻行也将添加到表 B 中。但是,当在表 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;

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

任何人都可以帮助我了解问题所在吗?

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

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

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

从这样的伪表中更改您的 function 以执行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<>小提琴

暂无
暂无

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

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