44.6. PL/Perl 触发器

PL/Perl 可用于编写触发功能。在触发功能中,哈希参考$_TD包含有关当前触发事件的信息。 $_TD是全局变量,每次调用触发器时都会获得一个单独的局部值。 $_TD哈希引用的字段为:

  • $_TD->{new}{foo}

    • NEWfoo的值
  • $_TD->{old}{foo}

    • OLDfoo的值
  • $_TD->{name}

    • 被调用的触发器的名称
  • $_TD->{event}

    • 触发事件:INSERTUPDATEDELETETRUNCATEUNKNOWN
  • $_TD->{when}

    • 调用触发器时:BEFOREAFTERINSTEAD OFUNKNOWN
  • $_TD->{level}

    • 触发等级:ROWSTATEMENTUNKNOWN
  • $_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";    # skip INSERT/UPDATE command
    } elsif ($_TD->{new}{v} ne "immortal") {
        $_TD->{new}{v} .= "(modified by trigger)";
        return "MODIFY";  # modify row and execute INSERT/UPDATE command
    } else {
        return;           # execute INSERT/UPDATE command
    }
$$ LANGUAGE plperl;

CREATE TRIGGER test_valid_id_trig
    BEFORE INSERT OR UPDATE ON test
    FOR EACH ROW EXECUTE PROCEDURE valid_id();