创建触发器的步骤分两步,a. 创建触发器函数,b. 编写触发语句;创建事件触发器的步骤也是一样,分为两步。
1. 简介:
事件触发器为全局触发器,影响范围为指定的某个库,并且可以捕获 DDL 事件,而传统的触发器是基于表级别,并且只能捕获 DML 事件;事件触发器是Postgresql 9.3新增的功能。
2. 语法:
postgres=# \h create event trigger
Command: CREATE EVENT TRIGGER
Description: define a new event trigger
Syntax:
CREATE EVENT TRIGGER name
ON event
[ WHEN filter_variable IN (filter_value [,... ]) [ AND ... ] ]
EXECUTE PROCEDURE function_name()
name : 事件触发器的名称。
event : 目前只支持三种,ddl_command_start,ddl_command_end and sql_drop。
ddl_command_start : 在 CREATE,ALTER,DROP 或者 SELECT INTO 命令执行之前触发,例外的情况是: 这不会在共享对象上触发,例如 database,roles, tablespace。(SELECT INTO 也会有 CREATE 的动作 select * into tb100 from tb1,会创建tb100)
ddl_command_end: ddl_command_end 事件在以类似同样命令执行后触发。
sql_drop : sql_drop 事件在 ddl_command_end 触发之前触发,要查看删除的数据库对像,可以通过函数 pg_event_trigger_dropped_objects() 查看,当数据库对像在 catalog 表中被删除时,触发器被触发。
filter_variable: 过滤事件的变量名称.这将限制它所支持的事件的一个子集去触发该触发器.现在仅支持filter_variable值为TAG.
filter_value: drop table,alter table,drop function.. (参考: http://www.postgresql.org/docs/current/static/event-trigger-matrix.html)
3. 事件触发函数pg_event_trigger_dropped_objects():
pg_event_trigger_dropped_objects返回一个在sql_drop 事件中调用的命令删除的所有对象的列表。(注意该函数只能用在sql_drop事件中)
名字 | 类型 | 描述 |
---|---|---|
classid | Oid | 对象所在的目录的OID |
objid | Oid | 目录中对象的OID |
objsubid | int32 | 对象的sub-id(例如,字段的属性个数) |
object_type | text | 对象的类型 |
schema_name | text | 如果有,为对象所在模式的名字;否则为NULL。不用双引号。 |
object_name | text | 如果模式和名字的组合可以用来唯一的标识对象,那么就是对象的名字;否则为NULL。不用双引号,并且名字是从不模式限定的。 |
object_identity | text | 对象身份的文本表现,模式限定的。每个标识符在身份中出现时要在必要时引用。 |
4. 示例:
- pg_event_trigger_dropped_objects函数的演示:
CREATE FUNCTION test_event_trigger_for_drops() RETURNS event_trigger LANGUAGE plpgsql AS $$ DECLARE obj record;
BEGIN FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() LOOP RAISE NOTICE '% dropped object: % %.% %',tg_tag,obj.object_type,obj.schema_name,obj.object_name,obj.object_identity;
END LOOP;
END $$;
CREATE EVENT TRIGGER test_event_trigger_for_drops
ON sql_drop
EXECUTE PROCEDURE test_event_trigger_for_drops();
新建一个表,然后删除:
postgres=# create table tb10 (id integer);
CREATE TABLE postgres=# postgres=# drop table tb10;
NOTICE: DROP TABLE dropped object: table public.tb10 public.tb10 NOTICE: DROP TABLE dropped object: type public.tb10 public.tb10 NOTICE: DROP TABLE dropped object: type public._tb10 public.tb10[] DROP TABLE
新建一个function,然后删除:
postgres=# create function ff() returns void as $$ postgres$# begin postgres$# end postgres$# $$language plpgsql;
CREATE FUNCTION postgres=# postgres=# drop function ff();
NOTICE: tg_tag: DROP FUNCTION; object_type: function
NOTICE: DROP FUNCTION dropped object: function public.<NULL> public.ff() DROP FUNCTION
- filter_variable,filter_value 的演示:
在指定sql_drop的时候,事件触发器会拦截所有的drop操作,如果仅仅是需要拦截drop table操作的时候,就需要指定过滤条件。
-- 先删除刚刚之前创建的event trigger
postgres=# drop event trigger test_event_trigger_for_drops;
DROP EVENT TRIGGER postgres=#
CREATE EVENT TRIGGER test_event_trigger_for_drops
ON sql_drop WHEN TAG in('drop table')
EXECUTE PROCEDURE test_event_trigger_for_drops();
-- 新建表和function
postgres=# create table tb10(id integer);
CREATE TABLE postgres=# create function ff()returns void as $$ begin end $$language plpgsql;
CREATE FUNCTION -- 测试删除 postgres=# drop function ff();
DROP FUNCTION postgres=# postgres=# drop table tb10;
NOTICE: DROP TABLE dropped object: table public.tb10 public.tb10 NOTICE: DROP TABLE dropped object: type public.tb10 public.tb10 NOTICE: DROP TABLE dropped object: type public._tb10 public.tb10[] DROP TABLE
可以看到,只有drop table的时候被拦截了。
5. 查看所有触发器 \dy:
postgres=# \dy
List of event triggers
Name | Event | Owner | Enabled | Procedure | Tags ------------------------------+----------+----------+---------+------------------------------+------------ test_event_trigger_for_drops | sql_drop | postgres | enabled | test_event_trigger_for_drops | DROP TABLE trg_log_drop_command | sql_drop | postgres | enabled | fun_log_drop_command | (2 rows)
参考:
http://francs3.blog.163.com/blog/static/4057672720134210569584/
http://www.postgresql.org/docs/current/static/sql-createeventtrigger.html
http://www.postgresql.org/docs/current/static/event-triggers.html