Postgresql

如何防止 PostgreSQL 觸發器被另一個觸發器觸發?

  • March 23, 2021

我在一張桌子上有 2 個觸發器;一個適用於 INSERT:

CREATE TRIGGER "get_user_name"
AFTER INSERT ON "field_data"
FOR EACH ROW EXECUTE PROCEDURE "add_info"();

這會更新表中的一些值。

還有一個用於更新(填​​寫歷史表):

CREATE TRIGGER "set_history"
BEFORE UPDATE ON "field_data"
FOR EACH ROW EXECUTE PROCEDURE "gener_history"();

問題是,當我在表中插入新行時,該過程"add_info"()會進行更新並因此觸發第二個觸發器,該觸發器以錯誤結束:

ERROR:  record "new" has no field "field1"

我怎樣才能避免這種情況?

(觸發器邏輯明顯錯誤。)

在Postgres 9.2或更高版本中,使用@Akash在觸發器本身的條件中已經pg_trigger_depth()提到的函式(而不是觸發器函式的主體),這樣觸發器函式就不是偶數了當從另一個觸發器呼叫時執行(包括它自己 - 所以也防止循環)。 這通常表現更好,更簡單,更乾淨:

CREATE TRIGGER set_history
BEFORE UPDATE ON field_data
FOR EACH ROW 
**WHEN (pg_trigger_depth() < 1)**
EXECUTE PROCEDURE gener_history();

在輸入觸發函式之前pg_trigger_depth() < 1計算表達式。所以它在第一次呼叫時評估為 0。當從另一個觸發器呼叫時,該值較高且不執行觸發器函式。

引用自:https://dba.stackexchange.com/questions/103402