系统事件触发器概述:
1、系统事件触发器可建立在模式上,也可以建立在整个数据库上。
2、当建立在模式(SCHEMA)上时,模式所指定用户的DDL操作和他们所导致的错误才激活触发器, 默认时为当前用户模式。
3、当建立在数据库(DATABASE)上时,数据库所有用户的DDL操作和他们所导致的错误以及数据库的启动和关闭均可激活触发器。
4、要在数据库之上建立触发器时,要求用户具有ADMINISTER DATABASE TRIGGER权限。
一、DDL触发器(DDL TRIGGER):
1、DDL触发器(trigger)是一个有名字的且存储在数据库中的PL/SQL块。是系统事件触发器的一种。
2、定义在模式或数据库上,由系统事件触发,这里介绍由DDL事件触发的触发器。
3、无需手动执行,只要触发事件发生,就自动会执行。一般用于数据库安全审计。
二、DDL事件包括:
CREATE,ALTER,DROP,TRUNCATE,RENAME,DDL等
三、触发器的定义(DDL trigger):
语法:
CREATE OR REPLACE TRIGGER [sachema.]trigger_name
{BEFORE|AFTER} {create|alter|drop|truncate|ddl }
ON { DATABASE | [schema.]SCHEMA }
[WHEN condition]
PL/SQL_block | CALL procedure_name;
说明:
or replace ----表示创建的触发器存在则替换
trigger_name ----表示触发器名字
after |before ----表示触发时机
create|alter|drop|truncate ----表示触发事件,可以并行出现,用OR连接
on database ----表示触发对象是数据库
on [schema.]SCHEMA ----表示触发对象是模式(schema)
四、触发器限制
1、如果有多个触发器被定义成为相同时间、相同事件触发,且最后定义的触发器是有效的,则最后定义的触发器被触发,
其他触发器不执行。
2、一个触发器可由多个不同的DDL事件触发。
3、触发器体内禁止使用COMMIT、ROLLBACK、SAVEPOINT语句,也禁止直接或间接地调用含有上述语句的存储过程.
4、时机与事件的关系说明:
事件 允许的时机 说明
CREATE BEFORE,AFTER 在执行CREATE语句创建数据库对象之前、之后触发
DROP BEFORE,AFTER 在执行DROP语句删除数据库对象之前、之后触发
ALTER BEFORE,AFTER 在执行ALTER语句更新数据库对象之前、之后触发
TRUNCATE BEFORE,AFTER 在执行TRUNCATE语句更新数据库对象之前、之后触发
DDL BEFORE,AFTER 在执行大多数DDL语句之前、之后触发
RENAME BEFORE,AFTER 执行RENAME语句更改数据库对象名称之前、之后触犯发
AUDIT/NOAUDIT BEFORE,AFTER 执行AUDIT或NOAUDIT进行审计或停止审计之前、之后触发
特殊事件,严格上来讲属于DCL事件,当然也是数据库事件
GTANT BEFORE,AFTER 在执行大多数GRANT语句之前、之后触发
REVOKE BEFORE,AFTER 在执行大多数REVOKE语句之前、之后触发
5、除DML语句的列属性外,其余事件属性值可通过调用ORACLE定义的事件属性函数来读取。
【1】 下面函数可直接使用
函数名称 数据类型 说 明
ora_sysevent VARCHAR2(20) 激活触发器的事件名称
ora_instance_num NUMBER 数据库实例编号
ora_database_name VARCHAR2(50) 数据库名称
ora_server_error(posi) NUMBER 错误信息栈中posi指定位置中的错误号
ora_login_user VARCHAR2(30) 登陆或注销的用户名称.与user函数相同。
ora_dict_obj_type VARCHAR2(20) DDL语句所操作的数据库对象类型
ora_dict_obj_name VARCHAR2(30) DDL语句所操作的数据库对象名称
ora_dict_obj_owner VARCHAR2(30) DDL语句所操作的数据库对象所有者名称
ora_client_ip_address VARCHAR2(30) 客户IP地址
【2】下面函数必须通过赋值给变量才能使用。
函数名称 数据类型 说 明
sysevent VARCHAR2(20) 激活触发器的事件名称
instance_num NUMBER 数据库实例编号
database_name VARCHAR2(50) 数据库名称
server_error(posi) NUMBER 错误信息栈中posi指定位置中的错误号
login_user VARCHAR2(30) 登陆或注销的用户名称.与user函数相同。
dictionary_obj_type VARCHAR2(20) DDL语句所操作的数据库对象类型
dictionary_obj_name VARCHAR2(30) DDL语句所操作的数据库对象名称
dictionary_obj_owner VARCHAR2(30) DDL语句所操作的数据库对象所有者名称
des_encrypted_password VARCHAR2(2) 正在创建或修改的经过DES算法加密的用户口令
五、触发器其它操作
1、删除触发器:
--触发器的创建者或具有DROP ANY TIRGGER系统权限的人才能删除触发器
DROP TIRGGER trigger_name;
2、改变触发器状态:
ALTER TRIGGER trigger_name DISABLE|ENABLE}
其中,DISABLE表示使触发器失效,ENABLE表示使触发器生效。
3、触发器错误查看:
show errors
4、查看触发器的相关信息
select * from user_triggers;
select * from dba_triggers;
六、触发器的使用:
触发器无需用户手动执行,它是通过事件来触发的,当触发的事件发生,触发器的内部动作就会自动执行。
七、实例应用
1、DDL触发器使用----审计HGX用户模式下的create操作:
说明:审计HGX模式下的create操作,当在hgx.schema上进行create时,将这些操作记录在审计表ddl_log中。
--创建审计表
create table ddl_log
(
username varchar2(20),
event varchar2(20),
obj_type varchar2(20),
obj_name varchar2(20),
time timestamp
);
--创建触发器
--set serverout on; 打开服务器输出。
create or replace trigger tri_audit_ddl_create
before create on hgx.schema
begin
insert into ddl_log(username,event,obj_type,obj_name,time)
values(ora_login_user,ora_sysevent,ora_dict_obj_type,ora_dict_obj_name,systimestamp);
end;
--另一种写法
create or replace trigger tri_audit_ddl_create
before create on schema
declare
v_username varchar2(20) := login_user;
v_event varchar2(20) := sysevent;
v_obj_type varchar2(20) := dictionary_obj_type;
v_obj_name varchar2(20) := dictionary_obj_name;
begin
insert into ddl_log(username,event,obj_type,obj_name,time)
values(v_username,v_event,v_obj_type,v_obj_name,systimestamp);
end;
--当在hgx.schema上执行create时:
SQL> create table tt4(id number);
SQL>select * from ddl_log;
USERNAME EVENT OBJ_TYPE OBJ_NAME TIME
----------- ----------- ---------- ----------- -------------------------
HGX CREATE TABLE TT1 08-FEB-13 12.12.49.030984 AM
HGX CREATE TABLE TT2 08-FEB-13 12.14.42.328301 AM
HGX CREATE TABLE TT3 08-FEB-13 12.20.07.000000 AM
HGX CREATE TABLE TT4 08-FEB-13 12.24.26.947588 AM
2、DDL触发器使用----审计HGX用户模式下的DDL操作:
说明:审计HGX模式下的DDL操作,当在hgx.schema上进行DDL时,将这些操作记录在审计表ddl_log中。
--创建审计表
create table ddl_log
(
username varchar2(20),
event varchar2(20),
obj_type varchar2(20),
obj_name varchar2(20),
time timestamp
);
--创建触发器
--set serverout on; 打开服务器输出。
create or replace trigger tri_audit_ddl_create
before DDL on hgx.schema
begin
insert into ddl_log(username,event,obj_type,obj_name,time)
values(ora_login_user,ora_sysevent,ora_dict_obj_type,ora_dict_obj_name,systimestamp);
end;
--另一种写法
create or replace trigger tri_audit_ddl_create
before ddl on schema
declare
v_username varchar2(20) := ora_login_user;
v_event varchar2(20) := ora_sysevent;
v_obj_type varchar2(20) := ora_dict_obj_type;
v_obj_name varchar2(20) := ora_dict_obj_name;
begin
insert into ddl_log(username,event,obj_type,obj_name,time)
values(v_username,v_event,v_obj_type,v_obj_name,systimestamp);
end;
--当在hgx.schema上执行DDL后:
SQL>select * from ddl_log;
USERNAME EVENT OBJ_TYPE OBJ_NAME TIME
---------- ---------- -------------------- ---------- ----------------------------------------
HGX CREATE TABLE TT1 08-FEB-13 12.12.49.030984 AM
HGX CREATE TABLE TT2 08-FEB-13 12.14.42.328301 AM
HGX CREATE TABLE TT3 08-FEB-13 12.20.07.000000 AM
HGX CREATE TABLE TT4 08-FEB-13 12.24.26.947588 AM
HGX CREATE TABLE TT4 08-FEB-13 12.44.40.021550 AM
HGX ALTER TABLE TT4 08-FEB-13 12.44.50.373093 AM
HGX TRUNCATE TABLE TT4 08-FEB-13 12.44.56.864417 AM
HGX GRANT OBJECT PRIVILEGE TT4 08-FEB-13 12.45.09.191057 AM
HGX REVOKE OBJECT PRIVILEGE TT4 08-FEB-13 12.45.17.188289 AM
HGX DROP TABLE TT4 08-FEB-13 12.45.27.043511 AM
3、DDL触发器使用----审计DB系统用户的DDL:
思路:
1、创建审计表
2、创建触发器
实操:
--创建审计表
create table db_ddl_log
(
username varchar2(20), --操作者
event varchar2(20), --DDL操作类型,即事件
obj_type varchar2(20), --DDL操纵的对象类型
obj_name varchar2(40), --DDL操纵的对象名称
time timestamp --操作时间
);
--创建触发器
--set serverout on; 打开服务器输出。
create or replace trigger tri_audit_ddl_for_db
before ddl on database
begin
insert into db_ddl_log(username,event,obj_type,obj_name,time)
values(ora_login_user,ora_sysevent,ora_dict_obj_type,ora_dict_obj_name,systimestamp);
end;
测试结果:
SQL>SELECT * FROM DB_DDL_LOG;
USERNAME EVENT OBJ_TYPE OBJ_NAME TIME
---------- --------- ----------- --------------------- ----------------------------
HGX CREATE TABLE TT3 08-FEB-13 01.00.56.567178 AM
HGX ALTER TABLE TT3 08-FEB-13 01.00.56.582508 AM
HGX DROP TRIGGER TT3 08-FEB-13 01.14.35.116345 AM
HGX CREATE TRIGGER TRI_UPDATE_EMP 08-FEB-13 01.14.41.361586 AM
HGX CREATE TRIGGER TRI_DELETE_EMP 08-FEB-13 01.14.58.581824 AM
HGX ALTER TABLE DDL_LOG 08-FEB-13 01.16.15.754579 AM
HGX ALTER TRIGGER TRI_AUDIT_DDL_CREATE 08-FEB-13 01.16.19.865638 AM
HGX ALTER TABLE STU 08-FEB-13 01.39.34.733717 AM
HGX ALTER INDEX STU_AGE_UN 08-FEB-13 01.39.34.866512 AM
HGX CREATE VIEW V_STUDENT 08-FEB-13 01.41.02.008012 AM
HGX CREATE INDEX SYS_C0020578 08-FEB-13 08.45.02.732791 AM
HGX CREATE SEQUENCE B 08-FEB-13 08.45.18.152964 AM
HGX CREATE SEQUENCE C_1 08-FEB-13 08.50.21.738607 AM
HGX DROP TABLE A_S 08-FEB-13 08.51.18.465478 AM
USERNAME EVENT OBJ_TYPE OBJ_NAME TIME
---------- --------- ----------- --------------------- ----------------------------
SYS CREATE TRIGGER TRI_AUDIT_LOGON 08-FEB-13 02.34.45.569313 PM
SYS CREATE TRIGGER TRI_AUDIT_LOGOFF 08-FEB-13 02.34.54.837699 PM
SYS TRUNCATE TABLE DB_LOGIN_LOG 08-FEB-13 04.18.35.732458 PM
SYS DROP TRIGGER TRI_AUDIT_LOGON 08-FEB-13 04.19.23.323373 PM
SYS DROP TRIGGER TRI_AUDIT_LOGOFF 08-FEB-13 04.19.34.058371 PM
SYS CREATE TRIGGER TRI_AUDIT_LOGON 08-FEB-13 04.20.57.853006 PM
SYS CREATE TRIGGER TRI_AUDIT_LOGON 08-FEB-13 04.23.12.096618 PM
SYS CREATE TRIGGER TRI_AUDIT_LOGOFF 08-FEB-13 04.23.22.443680 PM
SYS ALTER TABLE DB_DDL_LOG 08-FEB-13 04.52.20.268771 PM
--触发器的另一种写法:使用系统变量
create or replace trigger tri_audit_ddl_for_db
before ddl on database
declare
v_username varchar2(20) := login_user;
v_event varchar2(20) := sysevent;
v_obj_type varchar2(20) := dictionary_obj_type;
v_obj_name varchar2(40) := dictionary_obj_name;
begin
insert into db_ddl_log(username,event,obj_type,obj_name,time)
values(v_username,v_event,v_obj_type,v_obj_name,systimestamp);
end;