On this page
43.6. PL/Tcl 中的触发过程
触发过程可以用 PL/Tcl 编写。 PostgreSQL 要求将被称为触发器的过程必须声明为不带参数且返回类型为trigger
的函数。
来自触发器 Management 器的信息将通过以下变量传递到过程主体:
$TG_name
CREATE TRIGGER
语句中的触发器的名称。
$TG_relid
- 导致触发过程被调用的表的对象 ID。
$TG_table_name
- 导致触发过程被调用的表的名称。
$TG_table_schema
- 导致触发过程被调用的表的模式。
$TG_relatts
- 表列名称的 Tcl 列表,以空列表元素为前缀。因此,使用 Tcl 的
lsearch
命令在列表中查找列名将返回第一列的元素编号(从 1 开始),这与在 PostgreSQL 中通常对列进行编号的方式相同。 (空列表元素也会出现在已删除列的位置,因此属性编号对于右边的列是正确的.)
- 表列名称的 Tcl 列表,以空列表元素为前缀。因此,使用 Tcl 的
$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
的形式访问。
- Tcl
触发过程的返回值可以是字符串OK
或SKIP
之一,也可以是列名/值对的列表。如果返回值为OK
,则触发触发器的操作(INSERT
/UPDATE
/DELETE
)将正常进行。 SKIP
告诉触发器 Management 器静默禁止该行的操作。如果返回一个列表,它告诉 PL/Tcl 将修改后的行返回给触发器 Management 器;修改后的行的内容由列表中的列名和值指定。列表中未提及的任何列均设置为 null。返回修改后的行仅对行级BEFORE
INSERT
或UPDATE
触发器有意义,对于这些触发器,将插入修改后的行,而不是$NEW
中给出的行;或用于行级INSTEAD OF
INSERT
或UPDATE
触发器,其中返回的行用作INSERT RETURNING
或UPDATE RETURNING
子句的源数据。在行级BEFORE
DELETE
或INSTEAD OF
DELETE
触发器中,返回修改后的行与返回OK
具有相同的效果,即操作 continue 进行。对于所有其他类型的触发器,将忽略触发器返回值。
Tip
结果列表可以使用array get
Tcl 命令从修改后的 Tuples 的数组表示中得出。
这是一个小示例触发过程,该过程强制在表中强制使用整数值来跟踪对行执行的更新次数。对于插入的新行,该值初始化为 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 PROCEDURE trigfunc_modcount('modcnt');
请注意,触发过程本身并不知道列名。由触发器参数提供。这使触发过程可以在不同的表中重复使用。