44.6. PL/Tcl 中的触发器函数#
触发器函数可以用 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在
CREATE TRIGGER语句中给出的函数参数的 Tcl 列表。这些参数还可作为$1...$在函数正文中访问。n
触发器函数的返回值可以是字符串OK或SKIP,或列名/值对列表。如果返回值是OK,触发触发器的操作(INSERT/UPDATE/DELETE)将正常进行。SKIP告诉触发器管理器静默地禁止此行的操作。如果返回列表,它告诉 PL/Tcl 向触发器管理器返回修改后的行;修改后的行的内容由列表中的列名和值指定。列表中未提及的任何列都将设为空值。返回修改后的行仅对行级BEFORE``INSERT或UPDATE触发器有意义,对于这些触发器,将插入修改后的行而不是$NEW中给出的行;或对于行级INSTEAD OF``INSERT或UPDATE触发器,其中返回的行用作INSERT RETURNING或UPDATE RETURNING子句的源数据。在行级BEFORE``DELETE或INSTEAD OF``DELETE触发器中,返回修改后的行与返回OK的效果相同,即操作继续进行。触发器返回值将被所有其他类型的触发器忽略。
提示
可以使用array getTcl 命令从修改后的元组的数组表示形式创建结果列表。
下面是一个小示例触发器函数,它强制表中的整数值来跟踪对行执行的更新次数。对于新插入的行,该值初始化为 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');请注意,触发器函数本身不知道列名;这是从触发器参数中提供的。这使得触发器函数可以与不同的表一起重复使用。
