簡體   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