Postgresql

如果操作是由帶有 UPDATE CASCADE 的 FK 約束引起的,FOR EACH STATEMENT 觸發器將多久執行一次?

  • May 26, 2015

我知道FOR EACH STATEMENT當我執行一個UPDATE t ....

現在,當t用 定義時FOREIGN KEY ... REFERENCES a ... ON UPDATE CASCADE,我更新了 N 行a,這會導致觸發器被呼叫一次還是 N 次?

換句話說,對由 FK 約束級聯的表所做的更改更像是單個s UPDATE,還是更像是一系列UPDATEs?

外鍵約束目前是通過特殊的內部觸發器實現的。他們都在執行***FOR EACH ROW***。

請注意,這些是可以更改的實現細節,所以不要依賴它。但是在過去的幾個主要版本中,基礎沒有改變,因此不太可能發生重大變化。

我用一個簡單的 FK 約束從tblto執行了一個快速測試tbltypeFOR EACH ROW在我對 pg 9.4 的測試中,使用四個簡單的內部觸發器實現了一個簡單的 FK 。

以下是有關如何調查的簡要說明:

SELECT oid  -- 74791
FROM   pg_constraint
WHERE  conrelid = 'tbl'::regclass
AND    contype = 'f';

SELECT objid, classid::regclass  -- 74792,74793,74794,74795 / 'pg_trigger'
FROM   pg_depend
WHERE  refobjid = 74791
AND   deptype = 'i'

SELECT tgrelid::regclass, tgname, tgfoid, **tgtype** FROM pg_trigger
WHERE  oid IN (74792,74793,74794,74795) ORDER BY tgfoid;

'tbl'    ;'RI_ConstraintTrigger_c_74794';1644;**5**
'tbl'    ;'RI_ConstraintTrigger_c_74795';1645;**17**
'tbltype';'RI_ConstraintTrigger_a_74792';1654;**9**
'tbltype';'RI_ConstraintTrigger_a_74793';1655;**17**

SELECT oid, proname FROM pg_proc
WHERE oid IN (1654,1655,1644,1645);

1644;'RI_FKey_check_ins'
1645;'RI_FKey_check_upd'
1654;'RI_FKey_noaction_del'
1655;'RI_FKey_noaction_upd'

兩個內部“無動作”觸發器在tbltype.

兩個內部“檢查”觸發器tbl

它們都在執行***FOR EACH ROW,如 中的奇數所示tgtype*。

Postgres 的 2 個字節tgtype smallint表示int16C 原始碼中的最低有效位編碼TRIGGER_TYPE_ROW. 詳細解釋在這裡:

您可以使用一對相同的觸發器輕鬆測試這一點,您只需更改FOR ROW/ STATEMENT

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