触发器函数可以使用 PL/Tcl 编写。PostgreSQL 要求要作为触发器调用的函数必须声明为无参数且返回类型为 trigger
的函数。
来自触发器管理器的信息通过以下变量传递给函数体
$TG_name
来自 CREATE TRIGGER
语句的触发器名称。
$TG_relid
导致触发器函数被调用的表的OID(对象标识符)。
$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
操作为空。该数组以列名为索引。为 null 的列不会出现在数组中。这对于语句级触发器没有设置。
$OLD
一个关联数组,包含 UPDATE
或 DELETE
操作的旧表行的值,或者 INSERT
操作为空。该数组以列名为索引。为 null 的列不会出现在数组中。这对于语句级触发器没有设置。
$args
一个 Tcl 列表,包含在 CREATE TRIGGER
语句中给出的函数参数。这些参数也可以在函数体中访问为 $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
的效果相同,即操作继续进行。对于所有其他类型的触发器,触发器返回值将被忽略。
可以使用 array get
Tcl 命令从修改后的元组的数组表示中创建结果列表。
以下是一个简单的示例触发器函数,它强制表中的整数值跟踪对行的更新次数。对于插入的新行,该值为 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');
请注意,触发器函数本身不知道列名;这是从触发器参数中提供的。这使得触发器函数可以在不同的表中重复使用。
如果您在文档中发现任何不正确的内容、与您对特定功能的体验不符或需要进一步说明,请使用 此表格 报告文档问题。