触发器函数可以用 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。返回修改后的行仅对于行级 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');
请注意,触发器函数本身不知道列名;该列名是从触发器参数提供的。这使得触发器函数可以重用于不同的表。
如果您在文档中发现任何不正确、与特定功能不符或需要进一步澄清的内容,请使用此表单报告文档问题。