42.6. PL/Perl 触发器
PL/Perl 可以用来书写触发器函数。在一个触发器函数中,散列引用$_TD
包含了当前触发事件的信息。$_TD
是一个全局变量, 它对于每次触发器调用都能够获取一个局部值。$_TD
散列引用的字段有:
$_TD->{new}{foo}
字段foo
的NEW
值
$_TD->{old}{foo}
字段foo
的OLD
值
$_TD->{name}
被调用的触发器的名字
$_TD->{event}
触发器事件:INSERT
, UPDATE
, DELETE
, TRUNCATE
, 或 UNKNOWN
$_TD->{when}
何时调用触发器:BEFORE
, AFTER
, INSTEAD OF
, 或 UNKNOWN
$_TD->{level}
触发器的级别: ROW
, STATEMENT
, 或 UNKNOWN
$_TD->{relid}
触发触发器的表的 OID
$_TD->{table_name}
触发触发器的表的名字
$_TD->{relname}
触发触发器的表的名字。已经废弃了,并且可能在将来的版本中移除。请使用$_TD->{table_name}。
$_TD->{table_schema}
触发触发器的表的模式名
$_TD->{argc}
触发器函数的参数个数
@{$_TD->{args}}
触发器函数的参数,如果$_TD->{argc}
为 0 则不存在。
行级别的触发器返回下列之一:
return;
执行该操作
"SKIP"
不执行该操作
"MODIFY"
表明NEW
行被触发器函数修改过
下面是一个触发器函数,演示了上面的一些东西。
CREATE TABLE test (
i int,
v varchar
);
CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$
if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) {
return "SKIP"; #跳过 INSERT/UPDATE 命令
} elsif ($_TD->{new}{v} ne "immortal") {
$_TD->{new}{v} .= "(modified by trigger)";
return "MODIFY"; #修改一行并且执行 INSERT/UPDATE 命令
} else {
return; # 执行 INSERT/UPDATE 命令
}
$$ LANGUAGE plperl;
CREATE TRIGGER test_valid_id_trig
BEFORE INSERT OR UPDATE ON test
FOR EACH ROW EXECUTE PROCEDURE valid_id();