(1)创建日志表:
create table SYS.AUDIT_DDL_OBJ ( opr_time DATE, session_id NUMBER, os_user VARCHAR2(200), ip_address VARCHAR2(200), terminal VARCHAR2(200), host VARCHAR2(200), user_name VARCHAR2(30), ddl_type VARCHAR2(30), ddl_sql CLOB, object_type VARCHAR2(18), owner VARCHAR2(30), object_name VARCHAR2(128), module VARCHAR2(128) );
(2)创建触发器:
CREATE OR REPLACE TRIGGER SYS.DDL_AUDIT_TRIGGER AFTER DDL ON DATABASE /* ||名称:DDL事件审计触发器 ||说明: */ DECLARE PRAGMA AUTONOMOUS_TRANSACTION; SESSION_ID_VAR NUMBER; /* 会话ID */ OS_USER_VAR VARCHAR2(200); /* 终端OS用户 */ IP_ADDRESS_VAR VARCHAR2(200); /* 终端IP */ TERMINAL_VAR VARCHAR2(200); /* 终端 */ HOST_VAR VARCHAR2(200); /* 终端主机名 */ N NUMBER; /* SQL列表长度 */ SQL_TEXT ORA_NAME_LIST_T; /* SQL_TEXT 列表 */ --DDL_SQL_VAR VARCHAR2(2000); /* DDL语句 */ DDL_SQL_VAR CLOB; VERRTEXT1 VARCHAR2(2000); VERRTEXT2 VARCHAR2(2000); MODULE VARCHAR2(100); /* 终端类型 */ BEGIN /* 获取操作用户信息 */ SELECT SYS_CONTEXT('USERENV', 'SESSIONID'), SYS_CONTEXT('USERENV', 'OS_USER'), SYS_CONTEXT('USERENV', 'IP_ADDRESS'), SYS_CONTEXT('USERENV', 'TERMINAL'), SYS_CONTEXT('USERENV', 'HOST'), SYS_CONTEXT('USERENV', 'MODULE') INTO SESSION_ID_VAR, OS_USER_VAR, IP_ADDRESS_VAR, TERMINAL_VAR, HOST_VAR, MODULE FROM DUAL; /* IP_Address_Var为空时,记录的是Oracle使用SYS用户的内部操作, 如AWR/ASH的更新、全局临时表的创建或情况等,不需要记录 */ --IF IP_Address_Var IS NULL THEN -- RETURN; --END IF; /* 获取DDL SQL语句 */ N := ORA_SQL_TXT(SQL_TEXT); FOR I IN 1 .. N LOOP DDL_SQL_VAR := DDL_SQL_VAR || SQL_TEXT(I); END LOOP; --暂时把截取长度去掉,如果只截取部分DDL保存,把下面这行注释去掉 --DDL_SQL_VAR := SUBSTR(DDL_SQL_VAR, 1, 4000); /* 记录登陆审计信息 */ INSERT INTO SYS.AUDIT_DDL_OBJ (OPR_TIME, /* 操作时间 */ SESSION_ID, /* 会话ID */ OS_USER, /* 终端OS用户 */ IP_ADDRESS, /* 终端IP地址 */ TERMINAL, /* 终端 */ HOST, /* 终端主机名 */ USER_NAME, /* ORACLE 用户名*/ DDL_TYPE, /* DDL操作类型 */ DDL_SQL, /* DDL语句 */ OBJECT_TYPE, /* 操作对象类型 */ OWNER, /* 对象拥有者 */ OBJECT_NAME, /* 对象名称 */ MODULE /* 终端类型 */) VALUES (SYSDATE, SESSION_ID_VAR, OS_USER_VAR, IP_ADDRESS_VAR, TERMINAL_VAR, HOST_VAR, ORA_LOGIN_USER, ORA_SYSEVENT, DDL_SQL_VAR, ORA_DICT_OBJ_TYPE, ORA_DICT_OBJ_OWNER, ORA_DICT_OBJ_NAME, MODULE); COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; --DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE); --DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_STACK); --获取错误信息 VERRTEXT1:=DBMS_UTILITY.FORMAT_ERROR_BACKTRACE; VERRTEXT2:=DBMS_UTILITY.FORMAT_ERROR_STACK; --插入日志表 INSERT INTO AUDIT_DDL_OBJ_LOG(OPTIME,LOGIN_USER,DDL_TYPE,OBJECT_TYPE,OWNER,OBJECT_NAME,ERRTEXT1,ERRTEXT2) VALUES (SYSDATE,ORA_LOGIN_USER,ORA_SYSEVENT,ORA_DICT_OBJ_TYPE,ORA_DICT_OBJ_OWNER,ORA_DICT_OBJ_NAME,VERRTEXT1,VERRTEXT2); COMMIT; END DDL_AUDIT_TRIGGER;
可以记录所有ddl操作。