记录ddl操作

(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操作。

猜你喜欢

转载自www.cnblogs.com/5sdba-notes/p/12940949.html
今日推荐