PSQL:触发函数的目的

Ji *_*Mun 2 postgresql-9.1 psql

触发函数与“常规”函数有何不同?创建触发器是绝对必要的吗?

例如,在这种情况下:

-- 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();
Run Code Online (Sandbox Code Playgroud)

这不是更简单吗(或者是否可以这样做):

-- 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
Run Code Online (Sandbox Code Playgroud)

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

Cra*_*ger 5

PostgreSQL 将“触发函数”与触发器定义分开的原因有很多:

  • 触发器函数可以编写为可以在许多不同表上工作的通用函数,因此您可以将相同的触发器函数作为触发器添加到许多不同的表中。这简化了维护工作。

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

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

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

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

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

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

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

老实说,我怀疑是否会添加这样的东西,但如果您能够提供足够令人信服的用例,如果您真的很幸运,那么您可能会对它感兴趣。最有可能的是,如果您愿意在实现该功能所需的时间内提供资金来支持该提案(“允许将 DO 块用作触发程序”),那么您很可能会取得任何进展。

  • 看来这个功能正在规划中。它列在 [PostgreSQL Todo](https://wiki.postgresql.org/wiki/Todo) 上(请参阅“允许创建内联触发器”),并且有一个相当长的[讨论](http://postgresql .nabble.com/Triggers-with-DO-功能性-td5492468.html)早在 2012 年。 (3认同)