2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4

42.6. PL/Tcl 中的觸發器函式 #

觸發器函式可以用 PL/Tcl 編寫。 PostgreSQL 要求要被用作觸發器呼叫的函式必須宣告為無引數且返回型別為 trigger 的函式。

來自觸發器管理器(trigger manager)的資訊透過以下變數傳遞給函式體:

$TG_name

CREATE TRIGGER 語句中觸發器的名稱。

$TG_relid

導致觸發器函式被呼叫的表的 OID(物件識別符號)。

$TG_table_name

導致觸發器函式被呼叫的表的名稱。

$TG_table_schema

導致觸發器函式被呼叫的表的模式(schema)名稱。

$TG_relatts

表的列名稱的 Tcl 列表,前面有一個空列表元素。因此,使用 Tcllsearch 命令在列表中查詢列名時,返回的元素編號從 1 開始,對於第一個列,與 PostgreSQL 中通常編號方式相同。(已被刪除的列的位置也會出現空列表元素,以確保其右側列的屬性編號正確。)

$TG_when

根據觸發器事件型別,字串為 BEFOREAFTERINSTEAD OF

$TG_level

根據觸發器事件型別,字串為 ROWSTATEMENT

$TG_op

根據觸發器事件型別,字串為 INSERTUPDATEDELETETRUNCATE

$NEW

一個關聯陣列,包含 INSERTUPDATE 操作的新行值,對於 DELETE 操作為空。陣列以列名作為索引。值為 NULL 的列不會出現在陣列中。此變數對於語句級觸發器不設定。

$OLD

一個關聯陣列,包含 UPDATEDELETE 操作的舊行值,對於 INSERT 操作為空。陣列以列名作為索引。值為 NULL 的列不會出現在陣列中。此變數對於語句級觸發器不設定。

$args

CREATE TRIGGER 語句中給出的函式引數的 Tcl 列表。這些引數在函式體中也可以透過 $1 ... $n 訪問。

觸發器函式的返回值可以是字串 OKSKIP,也可以是列名/值對的列表。如果返回值為 OK,則觸發該觸發器的操作(INSERT/UPDATE/DELETE)將正常進行。SKIP 會告知觸發器管理器靜默地阻止對該行的操作。如果返回的是一個列表,它會告訴 PL/Tcl 將一個修改後的行返回給觸發器管理器;修改後的行的內容由列表中的列名和值指定。列表中未提及的任何列都將設定為 NULL。返回一個修改後的行僅對行級 BEFORE INSERTUPDATE 觸發器有意義,在這種情況下,返回的修改後的行將替代 $NEW 中的行被插入;或者對於行級 INSTEAD OF INSERTUPDATE 觸發器,返回的行將用作 INSERT RETURNINGUPDATE RETURNING 子句的源資料。在行級 BEFORE DELETEINSTEAD 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');

請注意,觸發器函式本身不知道列名;列名是從觸發器引數中提供的。這使得觸發器函式可以與不同的表重用。

提交更正

如果您在文件中發現任何不正確之處、與您對特定功能的實際體驗不符之處或需要進一步澄清之處,請使用此表單來報告文件問題。