数据库审计表

时间:2009-11-09 22:31:38

标签: java oracle audit

我有一个我正在使用的现有应用程序,并且客户已经为审计日志定义了他们想要的表结构。它包含以下列:

storeNo 
timeChanged
user 
tableChanged 
fieldChanged 
BeforeValue 
AfterValue

通常我在每个表上都有简单的审计列,提供userChanged和timeChanged值。将写入这些表的应用程序是一个Java应用程序,并且通过jdbc在oracle数据库上进行调用。我的问题是获得前/后值的最佳方法是什么。我讨厌比较对象以查看填充此表的更改,这不会有效。如果一个更新中有多个列发生更改,则此新表将包含多个条目。或者有没有办法在oracle中这样做?过去其他人做了什么来跟踪变化而不是改变价值观?

4 个答案:

答案 0 :(得分:10)

传统上这是oracle触发的内容。每次插入或更新都会触发一个存储过程,该存储过程可以访问“之前和之后”数据,您可以根据需要进行操作,例如将旧值记录到审计表中。它对应用程序是透明的。

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:59412348055

答案 1 :(得分:2)

“客户已经为审计日志定义了他们想要的表结构”

恐惧的话。

以下是如何实现这样的事情:

create or replace trigger emp_bur before insert on emp for each row
begin
    if :new.ename = :old.ename then
        insert_audit_record('EMP', 'ENAME', :old.ename, :new.ename);
    end if;
    if :new.sal = :old.sal then
        insert_audit_record('EMP', 'SAL', :old.sal, :new.sal);
    end if;
    if :new.deptno = :old.deptno then
        insert_audit_record('EMP', 'DEPTNO', :old.deptno, :new.deptno);
    end if;
end;
/

正如您所看到的,它涉及大量重复,但这很容易处理,使用在数据字典上构建的代码生成器。但是这种方法存在更严重的问题。

  1. 它有相当大的开销: 单个更新,触及十个 字段将生成十个插入 语句。
  2. BeforeValue和AfterValue 当我们这些列成为问题 必须处理不同的数据类型 - 甚至日期和时间戳也变成了 有趣的是,更不用说CLOB了。
  3. 很难重建国家 在某个时间点的记录。我们 需要从最早开始 版本的记录并申请 随后的变化逐渐增加。
  4. 目前还不是很明显 这种方法会处理INSERT 和DELETE语句。
  5. 现在,如果客户的基本要求是监控对少数敏感列的更改,那么这些异议都不是问题:EMPLOYEES.SALARY,CREDIT_CARDS.LIMIT等。但是如果要求监视每个表的更改, “整个记录”方法更好:只需为受DML影响的每一行插入一条审计记录。

答案 2 :(得分:2)

如果您使用Oracle 10g或更高版本,则可以使用内置审核功能。你为这个许可证支付了很多钱,也可以使用它。

http://www.oracle.com/technology/pub/articles/10gdba/week10_10gdba.html

了解详情

答案 3 :(得分:0)

我会同意触发器。

如果您必须在应用程序级别执行此操作,我不会看到如果不执行这些步骤将会如何:

  1. 开始交易
  2. 选择更新要更改的记录
  3. 对于要更改的每个字段,从记录中获取旧值以及从程序逻辑中获取新值
  4. 对于每个要更改的字段,写一条审核记录
  5. 更新记录
  6. 结束交易
  7. 如果有很多这样的话,我想我会创建一个更新记录函数来进行比较,无论是在通用级别还是每个表的单独函数。