觸發器函式可以用 PL/Tcl 編寫。 PostgreSQL 要求要被用作觸發器呼叫的函式必須宣告為無引數且返回型別為 trigger
的函式。
來自觸發器管理器(trigger manager)的資訊透過以下變數傳遞給函式體:
$TG_name
CREATE TRIGGER
語句中觸發器的名稱。
$TG_relid
導致觸發器函式被呼叫的表的 OID(物件識別符號)。
$TG_table_name
導致觸發器函式被呼叫的表的名稱。
$TG_table_schema
導致觸發器函式被呼叫的表的模式(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
操作為空。陣列以列名作為索引。值為 NULL 的列不會出現在陣列中。此變數對於語句級觸發器不設定。
$OLD
一個關聯陣列,包含 UPDATE
或 DELETE
操作的舊行值,對於 INSERT
操作為空。陣列以列名作為索引。值為 NULL 的列不會出現在陣列中。此變數對於語句級觸發器不設定。
$args
CREATE TRIGGER
語句中給出的函式引數的 Tcl 列表。這些引數在函式體中也可以透過 $1
... $
訪問。n
觸發器函式的返回值可以是字串 OK
或 SKIP
,也可以是列名/值對的列表。如果返回值為 OK
,則觸發該觸發器的操作(INSERT
/UPDATE
/DELETE
)將正常進行。SKIP
會告知觸發器管理器靜默地阻止對該行的操作。如果返回的是一個列表,它會告訴 PL/Tcl 將一個修改後的行返回給觸發器管理器;修改後的行的內容由列表中的列名和值指定。列表中未提及的任何列都將設定為 NULL。返回一個修改後的行僅對行級 BEFORE
INSERT
或 UPDATE
觸發器有意義,在這種情況下,返回的修改後的行將替代 $NEW
中的行被插入;或者對於行級 INSTEAD OF
INSERT
或 UPDATE
觸發器,返回的行將用作 INSERT RETURNING
或 UPDATE RETURNING
子句的源資料。在行級 BEFORE
DELETE
或 INSTEAD OF
DELETE
觸發器中,返回修改後的行與返回 OK
的效果相同,即操作將繼續進行。對於所有其他型別的觸發器,將忽略觸發器返回值。
結果列表可以由 Tcl 命令 array get
從修改後的元組(tuple)的陣列表示形式生成。
這是一個小的示例觸發器函式,它強制一個表中的整數值來跟蹤對該行執行的更新次數。對於新插入的行,該值初始化為 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');
請注意,觸發器函式本身不知道列名;列名是從觸發器引數中提供的。這使得觸發器函式可以與不同的表重用。
如果您在文件中發現任何不正確之處、與您對特定功能的實際體驗不符之處或需要進一步澄清之處,請使用此表單來報告文件問題。