PostgreSQL 事件触发器行为总览
只要与一个事件触发器相关的事件在事件触发器所在的数据库中发生, 该事件触发器就会被引发。当前支持的事件是 ddl_command_start
、ddl_command_end
、 table_rewrite
和sql_drop
。未来的发行版 中可能会增加对更多事件的支持。
ddl_command_start
事件就在CREATE
、 ALTER
、DROP
、SECURITY LABEL
、 COMMENT
、GRANT
或者
REVOKE
命令的执行之前发生。在事件触发器引发前不会做受影响对象是否存在的检查。 不过,一个例外是,这个事件不会为目标是共享对象 — 数据库、角色 以及表空间 — 的 DDL 命令发生,也不会为目标是事件触发器的 DDL 命令发生。事件触发器机制不支持这些对象类型。 ddl_command_start
也会在SELECT INTO
命令的执行之前发生,因为这等价于
CREATE TABLE AS
。
ddl_command_end
事件就在同一组命令的执行之后发生。为了 得到发生的DDL操作的更多细节,可以从 ddl_command_end
事件触发器代码中使用集合返回函数 pg_event_trigger_ddl_commands()
(见 第 9.29 节)。注意该触发器是在那些动作 已经发生之后(但是在事务提交前)引发,并且因此系统目录会被读作已更改。
sql_drop
事件为任何删除数据库对象的操作在 ddl_command_end
事件触发器之前发生。要列出已经被删除的 对象,可以从sql_drop
事件触发器代码中使用集合返回函数 pg_event_trigger_dropped_objects()
见 第 9.29 节)。注意该触发器是在对象已经 从系统目录删除以后执行,因此不能再查看它们。
table_rewrite
事件在表被命令ALTER TABLE
和 ALTER TYPE
的某些动作重写之前发生。虽然其他控制语句(例如 CLUSTER
和VACUUM
)也可以用来重 写表,但是它们不会触发table_rewrite
事件。
不能在一个中止的事务中执行事件触发器(其他函数也一样)。因此,如果一个 DDL 命令出现错误失败,将不会执行任何相关的 ddl_command_end
触发器。反过来,如果一个 ddl_command_start
触发器出现错误失败,将不会引发进一步的 事件触发器,并且不会尝试执行该命令本身。类似地,如果一个 ddl_command_end
触发器出现错误失败,DDL
命令的效果将被 回滚,就像其他包含事务中止的情况中那样。
第 39.2 节中有事件触发器机制所支持的完整 命令列表。
事件触发器通过命令CREATE EVENT TRIGGER创建。为了 创建一个事件触发器,你必须首先创建一个有特殊返回类型 event_trigger
的函数。这个函数不一定需要返回一个值, 该返回类型仅仅是作为一种信号表示该函数要被作为一个事件触发器调用。
如果对于一个特定的事件定义了多于一个事件触发器,它们将按照触发器名称 的字母表顺序被引发。
一个触发器定义也可以指定一个WHEN
条件,这样事件触 发器(例如ddl_command_start
触发器)就可以只对用户 希望介入的特定命令触发。这类触发器的通常用法是用于限制用户可能执行的 DDL 操作的范围。