37.1. 事件触发器行为综述

任何时候当事件触发器所在的数据库中发生与其相关的事件时,该事件触发器就会引发。当前,只支持ddl_command_startddl_command_endsql_drop事件。在未来的发布中可能会支持额外的事件。

ddl_command_start事件正好在一个CREATEALTERDROP命令执行之前发生。在事件触发器引发前,不会执行对受影响对象是否存在的检查。但是,作为一种特例,这种事件不会被目标为共享对象 — 数据库、角色和表空间 — 或者事件触发器本身的 DDL 命令而发生。事件触发器机制不支持这些对象类型。ddl_command_start也在SELECT INTO命令的执行之前发生,因为这等价于CREATE TABLE AS

ddl_command_end事件在同一组命令的执行之后发生。

sql_drop事件在用于任何删除数据库对象的操作的ddl_command_end事件触发器之前发生。要列出被删除的对象,在sql_drop事件触发器代码中使用集合返回函数pg_event_trigger_dropped_objects()(见Section 9.28)。注意该触发器是在那些对象已经从系统目录中删除后被执行,因此无法再查看它们。

事件触发器(和其他函数一样)不能在一个中断的事务中被执行。因而,如果一个 DDL 命令带着一个错误失败,任何相关的ddl_command_end触发器将不会被执行。相反,如果一个ddl_command_start触发器带着一个错误失败,不会有更多事件触发器将会引发,并且也不会继续执行该命令本身。相似地,如果一个ddl_command_end触发器带着一个错误失败,该 DDL 语句的效果将被回滚,就像在其他包含事务中止的情况中的表现一样。

受事件触发器机制支持的完整命令列表可参考Section 37.2

事件触发器使用CREATE EVENT TRIGGER命令创建。为了创建一个事件触发器,你必须首先创建一个具有特殊返回类型event_trigger的函数。这个函数不需要(并且不可以)返回一个值。该返回类型仅仅作为一个信号表示该函数是被作为一个事件触发器调用的。

如果为一个特定事件定义了多于一个事件触发器,它们将按照触发器名称的字母表顺序引发。

一个触发器定义也可以指定一个WHEN条件,这样一个ddl_command_start触发器能够只对用户希望干涉的特定命令而引发。这种触发器的一个常见用途是限制用户可能执行的 DDL 操作的范围。