簡體   English   中英

Postgresql:僅在數據發生變化時,僅在更新FOR FOR NOACH STATEMENT時運行觸發器

[英]Postgresql: run trigger AFTER update FOR EACH STATEMENT ONLY if data changed

在Postgresql中,我可以有兩種觸發器:FOR EACH ROW和FOR EACH STATEMENT。 如果我執行FOR EACH ROW觸發器,我可以添加類似OLD.* != NEW.*的WHERE子句OLD.* != NEW.*所以只有在實際發生了某些變化時它才會觸發。 有沒有辦法用STATEMENT級觸發器做類似的事情? 我知道我不能做同樣的事情,因為OLD和NEW都不可用,但我想也許可能有辦法檢查我的函數本身等中改變的行數。

用法案例:我正在使用postgresql NOTIFY系統在數據發生變化時通知我的應用程序。 理想情況下,每次更改一個或多個記錄時,應用程序都會收到一條通知,如果數據保持不變(即使運行了UPDATE),也不會得到通知。 對於每個語句的基本AFTER UPDATE觸發器,每次更新語句運行時我都會收到通知 - 即使它實際上沒有更改任何內容。

您應該創建兩個觸發器: before update for each row after update for each statement before update for each rowafter update for each statement

第一個觸發器檢查表是否正在更新,如果是,則設置標志。

第二個觸發器檢查標志並在設置時執行notify

您可以使用自定義配置參數作為標志(例如flags.the_table )。 解決方案簡單而安全,因為參數在當前會話中是本地的。

create or replace function before_each_row_on_the_table()
returns trigger language plpgsql
as $$
begin
    if new <> old then
        set flags.the_table to 'on';
    end if;
    return new;
end $$;

create or replace function after_each_statement_on_the_table()
returns trigger language plpgsql
as $$
begin
    if (select current_setting('flags.the_table')) = 'on' then
        notify your_channel, 'the_table was updated';
        set flags.the_table to 'off';
    end if;
    return null;
exception
    when undefined_object then
        -- occurs when flags.the_table was not defined
        return null;
end $$;

create trigger before_each_row_on_the_table
before update on the_table
for each row execute procedure before_each_row_on_the_table();

create trigger after_each_statement_on_the_table
after update on the_table
for each statement execute procedure after_each_statement_on_the_table();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM