【PostgreSQL-9.6.3】事件触发器

当预定的事件发生时,事件触发器就会被触发。由于事件触发器设计的权限比较大,所以只有超级用户才能创建和修改触发器。

1. 事件触发器支持的事件分三类:ddl_command_start, ddl_command_end 和 sql_drop。

(1)ddl_command_start:在DDL开始前触发;

(2)ddl_command_end:在DDl结束后触发;

(3)sql_drop:删除一个数据库对象前被触发,其中删除的数据库对象详细信息,可以通过pg_event_trigger_dropped_objects()函数记录下来。

pg_event_trigger_dropped_objects()函数返回的结果集

列名称列类型列描述
classidOid对象所在目录的Oid
objjdOid数据库对象的Oid
objsubidint32数据库对象的子对象 (如:列)
object_typetext数据库对象的类型
schema_nametext数据库对象的模式名
object_nametext数据库对象的名称
object_identifytext数据库对象的标识符

 

 

 

 

 

 

 

 

 

2. 各种DDL操作会触发的事件列表:

 

命令标记ddl_command_startddl_command_endsql_drop
ALTER AGGREGATEXX
ALTER COLLATIONXX
ALTER CONVERSIONXX
ALTER DOMAINXX
ALTER EXTENSIONXX
ALTER FOREIGN DATA WRAPPERXX
ALTER FOREIGN TABLEXXX
ALTER FUNCTIONXX
ALTER LANGUAGEXX
ALTER OPERATORXX
ALTER OPERATOR CLASSXX
ALTER OPERATOR FAMILYXX
ALTER SCHEMAXX
ALTER SEQUENCEXX
ALTER SERVERXX
ALTER TABLEXXX
ALTER TEXT SEARCH CONFIGURATIONXX
ALTER TEXT SEARCH DICTIONARYXX
ALTER TEXT SEARCH PARSERXX
ALTER TEXT SEARCH TEMPLATEXX
ALTER TRIGGERXX
ALTER TYPEXX
ALTER USER MAPPINGXX
ALTER VIEWXX
CREATE AGGREGATEXX
CREATE CASTXX
CREATE COLLATIONXX
CREATE CONVERSIONXX
CREATE DOMAINXX
CREATE EXTENSIONXX
CREATE FOREIGN DATA WRAPPERXX
CREATE FOREIGN TABLEXX
CREATE FUNCTIONXX
CREATE INDEXXX
CREATE LANGUAGEXX
CREATE OPERATORXX
CREATE OPERATOR CLASSXX
CREATE OPERATOR FAMILYXX
CREATE RULEXX
CREATE SCHEMAXX
CREATE SEQUENCEXX
CREATE SERVERXX
CREATE TABLEXX
CREATE TABLE ASXX
CREATE TEXT SEARCH CONFIGURATIONXX
CREATE TEXT SEARCH DICTIONARYXX
CREATE TEXT SEARCH PARSERXX
CREATE TEXT SEARCH TEMPLATEXX
CREATE TRIGGERXX
CREATE TYPEXX
CREATE USER MAPPINGXX
CREATE VIEWXX
DROP AGGREGATEXXX
DROP CASTXXX
DROP COLLATIONXXX
DROP CONVERSIONXXX
DROP DOMAINXXX
DROP EXTENSIONXXX
DROP FOREIGN DATA WRAPPERXXX
DROP FOREIGN TABLEXXX
DROP FUNCTIONXXX
DROP INDEXXXX
DROP LANGUAGEXXX
DROP OPERATORXXX
DROP OPERATOR CLASSXXX
DROP OPERATOR FAMILYXXX
DROP OWNEDXXX
DROP RULEXXX
DROP SCHEMAXXX
DROP SEQUENCEXXX
DROP SERVERXXX
DROP TABLEXXX
DROP TEXT SEARCH CONFIGURATIONXXX
DROP TEXT SEARCH DICTIONARYXXX
DROP TEXT SEARCH PARSERXXX
DROP TEXT SEARCH TEMPLATEXXX
DROP TRIGGERXXX
DROP TYPEXXX
DROP USER MAPPINGXXX
DROP VIEWXXX
SELECT INTOXX

3.  创建事件触发器的语法

CREATE EVENT TRIGGER name

ON EVENT

[ WHEN filter_variable IN ( filter_value [ , … ]) [ AND … ] ]

EXECUTE PROCEDURE function_name ()

4. 事件触发器示例

(1)禁止所有DDL操作

--创建触发器函数
create or replace function abort_any_command()
returns event_trigger
language plpgsql
as $$
begin
raise exception 'command % is disabled ',tg_tag;
end;
$$;

--
创建触发器 create event trigger abort_ddl on ddl_command_start execute procedure abort_any_command();
--
测试触发器 test=# drop table emp; ERROR: command DROP TABLE is disabled CONTEXT: PL/pgSQL function abort_any_command() line 3 at RAISE test=# create table emp01 (x int); ERROR: command CREATE TABLE is disabled CONTEXT: PL/pgSQL function abort_any_command() line 3 at RAISE
test
=# truncate table emp; --注意:truncate是在普通触发器中触发,在事件触发器中不会触发。 TRUNCATE TABLE

--恢复DDL正常操作
test=# alter event trigger abort_ddl disable;
ALTER EVENT TRIGGER

(2)审计记录所有drop操作

--创建审计记录表
create table log_drop_objects(
op_time         timestamp, --操作执行时间
ddl_tag         text,  --执行的ddl操作
classid         Oid,
objid           Oid,
objsubid        OID,
object_type     text,
schema_name     text,
object_name     text,
object_identify text
);

--创建触发器函数
create function event_trigger_log_drops()
returns event_trigger language plpgsql as $$
declare
obj record;
begin
insert into log_drop_objects select now(),tg_tag,classid,objid,objsubid,
object_type,schema_name,object_name,
object_identity from pg_event_trigger_dropped_objects();
end
$$;

--创建触发器
create event trigger event_trigger_log_drops
on sql_drop
execute procedure event_trigger_log_drops();

--测试触发器
test=# alter table emp drop column salary;
ALTER TABLE
test=# 
test=# select ddl_tag,object_type,object_name,object_identity from log_drop_objects;
   ddl_tag   | object_type  | object_name |  object_identity  
-------------+--------------+-------------+-------------------
 ALTER TABLE | table column |             | public.emp.salary
(1 row)

test=# 
test=# drop table emp;
DROP TABLE
test=# 
test=# select ddl_tag,object_type,object_name,object_identity from log_drop_objects;
   ddl_tag   | object_type  |     object_name      |        object_identity        
-------------+--------------+----------------------+-------------------------------
 ALTER TABLE | table column |                      | public.emp.salary
 DROP TABLE  | table        | emp                  | public.emp
 DROP TABLE  | type         | emp                  | public.emp
 DROP TABLE  | type         | _emp                 | public.emp[]
 DROP TABLE  | toast table  | pg_toast_16461       | pg_toast.pg_toast_16461
 DROP TABLE  | index        | pg_toast_16461_index | pg_toast.pg_toast_16461_index
 DROP TABLE  | type         | pg_toast_16461       | pg_toast.pg_toast_16461
 DROP TABLE  | trigger      |                      | emp_audit on public.emp
(8 rows)

 5. 修改事件触发器

ALTER EVENT TRIGGER name DISABLE
ALTER EVENT TRIGGER name ENABLE [ REPLICA | ALWAYS ]
ALTER EVENT TRIGGER name OWNER TO new_owner
ALTER EVENT TRIGGER name RENAME TO new_name

 

The End!

2017-08-20

    原文作者:PostgreSQL
    原文地址: https://www.cnblogs.com/NextAction/p/7397601.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞