【问题标题】:PSQL: Purpose of Trigger FunctionPSQL:触发函数的目的
【发布时间】:2013-02-12 23:52:52
【问题描述】:

触发功能与“常规”功能有何不同?创建触发器是否绝对必要?

例如,在这种情况下:

-- Trigger function
CREATE FUNCTION update_record_trigger_function() RETURNS trigger
LANGUAGE plpgsql
AS $update_record_trigger_function$
BEGIN
  PERFORM update_record(NEW.oid); -- helper function ... 
  RETURN NEW;
END
$update_record_trigger_function$;

-- Trigger for updating latest clicks for posts
CREATE TRIGGER update_latest_record
AFTER INSERT OR UPDATE ON record
FOR EACH ROW
EXECUTE PROCEDURE update_record_trigger_function();

这样做会不会更简单(或者可以做到):

-- Trigger for updating latest clicks for posts
CREATE TRIGGER update_latest_record
AFTER INSERT OR UPDATE ON record
FOR EACH ROW
PERFORM update_record(NEW.oid); -- syntactically not right but along this idea

我找不到任何包含“跳过触发功能”示例的文档或解释触发功能对于触发器的特殊性和必要性的文档?

【问题讨论】:

    标签: postgresql-9.1 psql


    【解决方案1】:

    PostgreSQL 将“触发器函数”从触发器定义中分离出来的原因有很多:

    • 触发器函数可以编写为通用函数,可以作用于许多不同的表,因此您可以将相同的触发器函数作为触发器添加到许多不同的表中。这样便于维护。

    • 触发器函数可以采用参数,使它们能够适应特定列名或应用它们的表的其他特征。这使得编写通用的、可重用的触发器函数变得切实可行,否则您将无法这样做,因此您通常不需要在多个地方重复代码。请参阅 EXECUTE ... USINGformat 函数及其 %L%I 格式说明符。

    • PostgreSQL 非常努力,不在乎你的函数是用什么编程语言编写的。它们可以是 PL/PgSQL、Python、Perl、C 或 MyWackyPluginLanguage。如果不将触发器函数与触发器定义分开,这将更难实现。

    PostgreSQL 不支持您描述的速记,尽管其他一些数据库系统提供的东西与您所展示的非常相似。您本质上希望能够将触发器函数定义为内联表达式。这不受支持。从来没有迫切需要它,所以没有人实施它。

    如果将来添加这样的功能 - 我不知道有任何计划这样做 - 可能会使用 PL/PgSQL DO 块来完成,该块在上下文中被解释为触发器,例如 (不合法的语法):

    CREATE TRIGGER update_latest_record
    AFTER INSERT OR UPDATE ON record
    FOR EACH ROW DO $$ PERFORM update_record(NEW.oid); RETURN NEW; $$;
    

    这样解析器就不需要理解 PL/PgSQL 结构,我们只需要教它理解 FOR EACH ROW DO [string literal body of function] 作为FOR EACH ROW EXECUTE PROCEDURE proc_name(args) 的替代方案,然后调用 PL/PgSQL 子系统来处理触发器文字。

    实际上,Pg 可能只是生成一个普通的触发器函数并从触发器中添加对它的引用,因此如果触发器被删除,它就会被删除,这使它成为一个方便的宏,就像SERIAL 是一个方便的宏带有DEFAULT nextval(...)INTEGER 字段和带有SERIAL 字段的表所拥有的SEQUENCE。特别是,pg_dump 可能会输出它,就好像你定义了一个单独的触发器函数和触发器,而不是使用简写。

    老实说,我怀疑这样的东西会不会被添加,但如果你能提供足够令人信服的用例,你可能如果你真的很幸运,有人会对它感兴趣。如果您愿意为实现该功能所需的时间提供资金支持,那么您很可能只会通过这样的提议(“允许将 DO 块用作触发程序”)获得任何结果。

    【讨论】:

    • 感谢您的深入解答!
    • 这个功能好像在规划中。它列在 PostgreSQL Todo 上(请参阅“允许创建内联触发器”),早在 2012 年就有相当长的 discussion on it
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 2021-06-15
    • 1970-01-01
    • 2020-11-26
    相关资源
    最近更新 更多