PostgreSQL 事件触发器

  创建触发器的步骤分两步,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

你可能感兴趣的:(PostgreSQL,基础)