[英]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 row
和after 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.