PostgreSQL中的事件触发器

版权声明:本文为博主原创之文章,未经博主允许谢绝转载。 https://blog.csdn.net/pg_hgdb/article/details/83413485

PostgreSQL也提供了事件触发器。和常规触发器(在一个表上并且只捕捉 DML 事件)不同,事件触发器对一个特定数据库来说是全局的,并且可以捕捉 DDL 事件。

只要与一个事件触发器相关的事件在事件触发器所在的数据库中发生, 该事件触发器就会被引发。当前支持的事件是 ddl_command_startddl_command_end table_rewritesql_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()。注意该触发器是在动作已经发生之后(但是在事务提交前)引发,因此系统目录会被读作已更改。

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

table_rewrite事件在表被命令ALTER TABLE和 ALTER TYPE的某些动作重写之前发生。虽然其他控制语句(例如 CLUSTER和VACUUM)也可以用来重写表,但是它们不会触发table_rewrite事件。

不能在一个中止的事务中执行事件触发器。因此,如果一个 DDL 命令出现错误失败,将不会执行任何相关的ddl_command_end触发器。相反,如果一个ddl_command_start触发器出现错误失败,将不会引发进一步的事件触发器,并且不会尝试执行该命令本身。类似地,如果一个ddl_command_end触发器出现错误失败,DDL 命令的效果将被回滚。

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

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

一个触发器定义也可以指定一个WHEN条件,这样事件触发器(例如ddl_command_start触发器)就可以只对用户希望介入的特定命令触发。这类触发器的通常用法是用于限制用户可能执行的 DDL 操作的范围。

By Kalath

猜你喜欢

转载自blog.csdn.net/pg_hgdb/article/details/83413485