觸發函數可以使用 PL/Tcl 編寫。PostgreSQL 要求作為觸發呼叫的函數必須宣告為不帶參數且傳回類型為 trigger
的函數。
觸發管理器的資訊會透過以下變數傳遞至函數主體
$TG_name
來自 CREATE TRIGGER
陳述式的觸發名稱。
$TG_relid
導致觸發函數被呼叫的表格的物件 ID。
$TG_table_name
導致觸發函數被呼叫的表格名稱。
$TG_table_schema
導致觸發函數被呼叫的表格的綱要。
$TG_relatts
表格欄位名稱的 Tcl 清單,以空白清單元素作為前綴。因此,使用 Tcl 的 lsearch
命令在清單中查詢欄位名稱會傳回元素的編號,從第一個欄位開始編號為 1,與 PostgreSQL 中慣用方式相同。(空白清單元素也會出現在已刪除欄位的位置,以便屬性編號對於其右側的欄位是正確的。)
$TG_when
字串 BEFORE
、AFTER
或 INSTEAD OF
,取決於觸發事件的類型。
$TG_level
字串 ROW
或 STATEMENT
,取決於觸發事件的類型。
$TG_op
字串 INSERT
、UPDATE
、DELETE
或 TRUNCATE
,取決於觸發事件的類型。
$NEW
一個關聯陣列,包含 INSERT
或 UPDATE
動作的新表格列的值,對於 DELETE
則為空。該陣列以欄位名稱作為索引。空值欄位不會出現在陣列中。這不適用於陳述式層級觸發。
$OLD
一個關聯陣列,包含 UPDATE
或 DELETE
動作的舊表格列的值,對於 INSERT
則為空。該陣列以欄位名稱作為索引。空值欄位不會出現在陣列中。這不適用於陳述式層級觸發。
$args
一個 Tcl 清單,包含 CREATE TRIGGER
陳述式中給定的函數引數。這些引數也可以在函數主體中作為 $1
... $
存取。n
觸發函數的回傳值可以是字串 OK
或 SKIP
,或是一個欄位名稱/數值配對的列表。如果回傳值是 OK
,觸發觸發器的操作(INSERT
/UPDATE
/DELETE
)會照常進行。SKIP
會告訴觸發器管理器靜默地抑制此列的操作。如果回傳一個列表,它會告訴 PL/Tcl 將修改後的列回傳給觸發器管理器;修改後的列的內容由列表中的欄位名稱和數值指定。列表中沒有提到的任何欄位都會設定為 null。回傳修改後的列只對 row-level BEFORE
INSERT
或 UPDATE
觸發器有意義,修改後的列將被插入,而不是 $NEW
中給出的列;或對 row-level INSTEAD OF
INSERT
或 UPDATE
觸發器有意義,其中回傳的列被用作 INSERT RETURNING
或 UPDATE RETURNING
子句的來源資料。在 row-level BEFORE
DELETE
或 INSTEAD OF
DELETE
觸發器中,回傳修改後的列具有與回傳 OK
相同的效果,也就是操作會繼續進行。對於所有其他類型的觸發器,觸發器的回傳值會被忽略。
結果列表可以使用 Tcl 指令 array get
從修改後的元組的陣列表示中建立。
這是一個小的觸發函數範例,它強制表格中的一個整數值來追蹤對列執行的更新次數。對於插入的新列,該值初始化為 0,然後在每次更新操作時遞增。
CREATE FUNCTION trigfunc_modcount() RETURNS trigger AS $$ switch $TG_op { INSERT { set NEW($1) 0 } UPDATE { set NEW($1) $OLD($1) incr NEW($1) } default { return OK } } return [array get NEW] $$ LANGUAGE pltcl; CREATE TABLE mytab (num integer, description text, modcnt integer); CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab FOR EACH ROW EXECUTE FUNCTION trigfunc_modcount('modcnt');
請注意,觸發函數本身不知道欄位名稱;那是從觸發器引數提供的。這使得觸發函數可以與不同的表格重複使用。
如果您在文件中看到任何不正確、與特定功能的經驗不符或需要進一步澄清的內容,請使用此表單來報告文件問題。