pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
为了补充 第 36 章 中讨论的触发器机制, PostgreSQL 还提供了事件触发器。与仅附着于单个表并且 只捕获 DML 事件的常规触发器不同,事件触发器在某个特定数据库中是全局的, 并且能够捕获 DDL 事件。
与常规触发器类似,事件触发器可以用任何支持事件触发器的过程语言编写,也可以 用 C 编写,但不能用纯 SQL 编写。
只要与事件触发器关联的事件在其定义所在数据库中发生,事件触发器就会被触发。 目前仅支持以下事件: ddl_command_start、 ddl_command_end 和 sql_drop。 未来版本可能会增加对更多事件的支持。
ddl_command_start 事件发生在 CREATE、ALTER 或 DROP 命令即将执行之前。在事件触发器触发之前,不会检查受影响对象究竟存在还是不存在。 但有一个例外:对于以共享对象 — 数据库、角色和表空间 — 为目标的 DDL 命令或者针对事件触发器本身的命令,不会发生该事件。事件触发器机制 不支持这些对象类型。 ddl_command_start 也会在 SELECT INTO 命令即将执行之前发生,因为它等价于 CREATE TABLE AS。
ddl_command_end 事件发生在上述同一组命令执行之后。
对于任何删除数据库对象的操作,sql_drop 事件都发生在 ddl_command_end 事件触发器之前。要列出已删除的对象,可在 sql_drop 事件触发器代码中使用 集合返回函数 pg_event_trigger_dropped_objects()(见 第 9.28 节)。注意,触发器是在这些对象已经从 系统目录中删除之后执行的,因此已无法再查找它们。
事件触发器(与其他函数一样)不能在已中止的事务中执行。因此,如果 DDL 命令因 错误而失败,任何关联的 ddl_command_end 触发器都不会执行。 反之,如果 ddl_command_start 触发器因错误而失败,后续事 件触发器都不会触发,也不会尝试执行该命令本身。类似地,如果 ddl_command_end 触发器因错误而失败,DDL 语句的效果将被回 滚,就像包含该语句的事务在任何其他情况下中止时那样。
有关事件触发器机制所支持命令的完整列表,参见 第 37.2 节。
事件触发器通过命令 CREATE EVENT TRIGGER 创建。 为了创建事件触发器,必须先创建一个返回类型为 event_trigger 的特殊函数。 该函数不需要(也不能)返回值;这个返回类型仅用于表明该函数要作为事件触发器 被调用。
如果为某个特定事件定义了多个事件触发器,它们将按触发器名称的字母顺序触发。
触发器定义也可以指定一个 WHEN 条件,这样,例如, ddl_command_start 触发器就可以只针对用户希望拦截的特定命 令触发。这类触发器的一个常见用途是限制用户可执行的 DDL 操作范围。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。