44.6. PL/Tcl 中的触发功能

触发功能可以用 PL/Tcl 编写。 PostgreSQL 要求必须将被称为触发器的函数声明为不带参数且返回类型为trigger的函数。

来自触发器 Management 器的信息通过以下变量传递到函数主体:

触发函数的返回值可以是字符串OKSKIP之一,也可以是列名/值对的列表。如果返回值为OK,则触发触发器的操作(INSERT/UPDATE/DELETE)将正常进行。 SKIP告诉触发器 Management 器静默禁止该行的操作。如果返回一个列表,它告诉 PL/Tcl 将修改后的行返回给触发器 Management 器;修改后的行的内容由列表中的列名和值指定。列表中未提及的任何列均设置为 null。返回修改后的行仅对行级BEFORE INSERTUPDATE触发器有意义,将为其插入修改后的行,而不是$NEW中给出的行;或用于行级INSTEAD OF INSERTUPDATE触发器,其中返回的行用作INSERT RETURNINGUPDATE RETURNING子句的源数据。在行级BEFORE DELETEINSTEAD 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 FUNCTION trigfunc_modcount('modcnt');

请注意,触发函数本身不知道列名。由触发器参数提供。这使触发器功能可以在不同的表中重复使用。

上一章 首页 下一章