zoukankan      html  css  js  c++  java
  • data object audit

    客户提出了一个需求。想对一个表做audit。 本来这是非常简单的一个case,因为oracle自带的 audit功能就可以非常方便的实现。  实现的方式如下:

    BEGIN
    	DBMS_FGA.ADD_POLICY(
    	object_schema => 'SCOTT',
    	object_name => 'TEST',
    	policy_name => 'chk3',
    	statement_types => 'insert,update,delete');
    END;
    

    这种方式激活的是FGA(fine granulate audit),可以对一个表进行非常精细的审计,审计结果存在 dba_fga_audit_trail这个表中。表结构如下:

    SQL> desc dba_fga_audit_trail
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     SESSION_ID                                NOT NULL NUMBER
     TIMESTAMP                                          DATE
     DB_USER                                            VARCHAR2(30)
     OS_USER                                            VARCHAR2(255)
     USERHOST                                           VARCHAR2(128)
     CLIENT_ID                                          VARCHAR2(64)
     ECONTEXT_ID                                        VARCHAR2(64)
     EXT_NAME                                           VARCHAR2(4000)
     OBJECT_SCHEMA                                      VARCHAR2(30)
     OBJECT_NAME                                        VARCHAR2(128)
     POLICY_NAME                                        VARCHAR2(30)
     SCN                                                NUMBER
     SQL_TEXT                                           NVARCHAR2(2000)
     SQL_BIND                                           NVARCHAR2(2000)
     COMMENT$TEXT                                       VARCHAR2(4000)
     STATEMENT_TYPE                                     VARCHAR2(7)
     EXTENDED_TIMESTAMP                                 TIMESTAMP(6) WITH TIME ZONE
     PROXY_SESSIONID                                    NUMBER
     GLOBAL_UID                                         VARCHAR2(32)
     INSTANCE_NUMBER                                    NUMBER
     OS_PROCESS                                         VARCHAR2(16)
     TRANSACTIONID                                      RAW(8)
     STATEMENTID                                        NUMBER
     ENTRYID                                            NUMBER
     DBID                                               NUMBER
    

    可以看到这里收集到的auditi信息其实已经非常丰富了。但是客户的需求里多了一条,需要client 机器上 client进程的pid。 但是现在的dba_fga_audit_trial这个表中并没有client pid这一列。所以我们需要自己获得。同时我们需要创建一个新的表来存放 audit 结果。

    具体过程是先创建 temp_audit表:

    SQL> desc temp_audit
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     TIMESTAMP                                          DATE
     DB_USER                                            VARCHAR2(30)
     OS_USER                                            VARCHAR2(30)
     USERHOST                                           VARCHAR2(30)
     CLIENTPID                                          VARCHAR2(10)
     OBJECT_SCHEMA                                      VARCHAR2(30)
     OBJECT_NAME                                        VARCHAR2(128)
     POLICY_NAME                                        VARCHAR2(30)
     SQL_TEXT                                           NVARCHAR2(2000)
     OS_PROCESS                                         VARCHAR2(16)

    这个先创建的用来存放audit 结果的表里面有一条clientpid是需要自己写SQL去查询的,其它的都可以直接从dba_fga_audit_trial中获得。 我们要考虑的是,怎么让目标表在发生变化的时候会把audit信息写入这个表。很显然,trigger是一个好办法。我们创建一个trigger在目标表上,当目标表被DML语句操作的时候,trigger就去读取dba_fga_audit_trial并且通过一系列SQL来写temp_audit这个表。

    我们首先写一个procedure 该procedure会读取dba_fga_audit_trial这个表并且通过一系列SQL得到client pid然后写入temp_audit。 然后我们再写一个trigger来调用这个procedure

    create or replace procedure pump_audit_CITOSADMIN
    as 
      cursor audit_cur is select * from dba_fga_audit_trail where OBJECT_SCHEMA='CITOSADMIN' and OBJECT_NAME='BERTH_APPLICATION' order by TIMESTAMP ;
      v_clientpid varchar2(12);
      v_my_audit_count number;
      v_count number;
    begin 
      select count(*) into v_my_audit_count from temp_audit where OBJECT_SCHEMA='CITOSADMIN' and OBJECT_NAME='BERTH_APPLICATION' ;
      v_count :=1;
      
      for record_name in audit_cur loop
        if v_count <= v_my_audit_count  
        then v_count := v_count+1;
        else     
          select b.process into v_clientpid from v$process a, v$session b where a.addr = b.paddr and a.spid=record_name.OS_PROCESS;
          insert into temp_audit(TIMESTAMP,DB_USER,OS_USER,USERHOST,CLIENTPID,OBJECT_SCHEMA,OBJECT_NAME,POLICY_NAME,SQL_TEXT,OS_PROCESS) values(record_name.TIMESTAMP,record_name.DB_USER,record_name.OS_USER,record_name.USERHOST,v_clientpid,record_name.OBJECT_SCHEMA,record_name.OBJECT_NAME,record_name.POLICY_NAME,record_name.SQL_TEXT,record_name.OS_PROCESS); 
        end if;
      end loop;
    end;
    

      

    create or replace trigger audit_obj_CITOSADMIN
      after insert or update or delete on CITOSADMIN.BERTH_APPLICATION
    begin
      pump_audit_CITOSADMIN;
    end;
  • 相关阅读:
    MVC各部分技术体现
    SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
    my SQL Workbench创建数据库
    哪些素质很重要,却是读书学不来
    给程序员最好的18个忠告!
    互联网协议入门(二)
    互联网协议入门(一)
    div+css命名规范大全
    javascript中this的用法
    XHTML 相对路径与绝对路径
  • 原文地址:https://www.cnblogs.com/kramer/p/3471225.html
Copyright © 2011-2022 走看看