Oracle 审计 table 使用触发器

Oracle Audit table using trigger

我需要在 Oracle 11g 中创建一个触发器来审计 table。我有一个 table 有 16 列需要审计。

对于 table 中的每个新插入,我需要在审计 table 中为插入的每一列添加一个条目,即在这种情况下,将在审计 table 中插入 16 行.

对于每次更新,假设我更新了第 1 列和第 2 列,那么它会在审计中创建两条记录,其中包含旧值和新值。审计结构 table 将是:

 id        
 mod_col_name 
 OLD VALUE 
 NEW VALUE  
 upd_time 
 mod_user_id

我的做法:

create or replace trigger my_trigger
after update or insert on temp12
for each row
declare

  TYPE tab_col_nt IS table of varchar2(30);

  v_tab_col_nt tab_col_nt;

begin

    v_tab_col_nt := tab_col_nt('id','name','salary'); --in example i have given only 3 column name

    for r in v_tab_col_nt.first..v_tab_col_nt.last

    loop

        if updating(v_tab_col_nt(r)) then

            insert into audit_table values (
                id_seq.nextval, v_tab_col_nt(r), :old.v_tab_col_nt(r),
                :new.v_tab_col_nt(r), sysdate, user
             ); --here :old & :new syntex is not working
        end if;

        if inserting then
            insert into audit_table values (
               id_seq.nextval, v_tab_col_nt(r), null, 
               :new.v_tab_col_nt(r), sysdate, user);
        end if;

    end loop;
end;

我的顾虑:

  1. 这里 :old.v_tab_col_nt(r), :new.v_tab_col_nt(r) 不工作

  2. 如何跟踪用户登录 GUI 的用户 ID(dot net 是前端)。

我想动态写入这个触发器。

:old.v_tab_col_nt(r):new.v_tab_col_nt(r) 不起作用的原因是因为 :old:new 仅供新旧参考(呃!...) table 中受影响的列中的值,而不是触发器内声明的用户定义类型。

您实际查找的值是::old.<name of column1>,或:new.<name of column1>

因此,根据您的要求,您的触发器必须如下所示:

create or replace trigger my_trigger
after insert or update on temp12
for each row
referencing old as old new as new
begin

    /*When-Insert block. 1 record for each column in audit*/
    if (INSERTING) then -- 
        insert into audit_table values (id_seq.nextval, '<name of column1>', :old.<name of column1>, :new.<name of column1>, sysdate, user);
        insert into audit_table values (id_seq.nextval, '<name of column2>', :old.<name of column2>, :new.<name of column2>, sysdate, user);
        insert into audit_table values (id_seq.nextval, '<name of column3>', :old.<name of column3>, :new.<name of column3>, sysdate, user);
         .
         . --(same for every column)
         .
        insert into audit_table values (id_seq.nextval, '<name of column16>', :old.<name of column16>, :new.<name of column16>, sysdate, user);
    end if;
    /*end of When-Insert block*/

    /*When-Update block. A new record in audit just for the updated column(s) */
    if (UPDATING ( '<name of column1>' )) then --col 1
        insert into audit_table values (id_seq.nextval, '<name of column1>', :old.<name of column1>, :new.<name of column1>, sysdate, user);
    end if;
    if (UPDATING ( '<name of column2>' )) then --col 2
        insert into audit_table values (id_seq.nextval, '<name of column2>', :old.<name of column2>, :new.<name of column2>, sysdate, user);
    end if;
    if (UPDATING ( '<name of column3>' )) then --col 3
        insert into audit_table values (id_seq.nextval, '<name of column3>', :old.<name of column3>, :new.<name of column3>, sysdate, user);
    end if;
     . 
     . --(same for every column)
     .
    if (UPDATING ( '<name of column16>' )) then --col 16
        insert into audit_table values (id_seq.nextval, '<name of column16>', :old.<name of column16>, :new.<name of column16>, sysdate, user);
    end if;
    /*end of When-Update block*/

end;

现在关于跟踪登录用户进入您的应用程序有两个注意事项:

  1. 如果您的整个应用程序在数据库级别实现了所有用户, 这是每个登录个人的 ORACLE 用户,如果是这样,则 每个 PL/SQL 块或执行的 DDL 中的保留字 "USER",将 每次都检索该用户名。

  2. 另一方面,如果您的应用程序决定管理用户 他们自己的,通过创建自定义用户控件,那么该值必须 通过参数传递(在命名的 PL/SQL 块的情况下)或 在每个 table 中包含一个 (NOT NULL) 列(至少每个 table 你想监视用户 activity),所以每个 INSERT 语句都是 强制发送该信息,您可以在里面使用 :new.<name of user monitor column> 阅读它 您的触发器代码,或者您可以使用

IF (:new.< name of user monitor column > is null) then raise_application_error(-20001, 'User must be specified'). END IF;

愿原力与你同在