2

私が使用している既存のアプリケーションがあり、顧客が監査ログに必要なテーブル構造を定義しています。次の列があります。

storeNo 
timeChanged
user 
tableChanged 
fieldChanged 
BeforeValue 
AfterValue

通常、userChanged値とtimeChanged値を提供する単純な監査列が各テーブルにあります。これらのテーブルに書き込むアプリケーションはJavaアプリケーションであり、呼び出しはOracleデータベース上のjdbcを介して行われます。私が持っている質問は、前/後の値を取得するための最良の方法は何ですか。オブジェクトを比較して、このテーブルにデータを入力するためにどのような変更が加えられたかを確認するのは嫌です。これは効率的ではありません。1回の更新で複数の列が変更された場合、この新しいテーブルには複数のエントリが含まれます。または、オラクルでこれを行う方法はありますか?変更だけでなく変更された値を追跡するために、過去に他の人は何をしましたか?

4

4 に答える 4

10

これは伝統的にOracleトリガーの目的です。挿入または更新のたびに、「前後」のデータにアクセスできるストアド プロシージャがトリガーされます。このストアド プロシージャは、古い値を監査テーブルに記録するなど、好きなように処理できます。アプリケーションに対して透過的です。

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

于 2009-11-09T22:34:38.257 に答える
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. これにはかなりのオーバーヘッドがあります。10個のフィールドに触れる1回の更新で、10個の挿入ステートメントが生成されます。
  2. 異なるデータ型を処理する必要がある場合、BeforeValue列とAfterValue列は問題になります。CLOBはもちろん、日付やタイムスタンプも興味深いものになります。
  3. ある時点でのレコードの状態を再構築することは困難です。レコードの最も古いバージョンから始めて、その後の変更を段階的に適用する必要があります。
  4. このアプローチがINSERTおよびDELETEステートメントをどのように処理するかはすぐにはわかりません。

現在、顧客の根本的な要件が少数の機密性の高い列(EMPLOYEES.SALARY、CREDIT_CARDS.LIMITなど)への変更を監視することである場合、これらの異議は問題になりません。ただし、要件がすべてのテーブルへの変更を監視することである場合、「全体「レコード」アプローチの方が優れています。DMLの影響を受ける行ごとに1つの監査レコードを挿入するだけです。

于 2009-11-10T14:11:41.837 に答える
2

Oracle 10g 以降を使用している場合は、組み込みの監査機能を使用できます。ライセンスにかなりのお金を払ったので、それを使用することもできます。

詳細については、http://www.oracle.com/technology/pub/articles/10gdba/week10_10gdba.htmlを参照してください。

于 2009-11-10T15:17:48.613 に答える
0

トリガーについても同じです。

アプリケーションレベルでそれを行う必要がある場合、次の手順を実行しないとどうなるかわかりません。

  1. トランザクションを開始します
  2. 変更するレコードの更新を選択
  3. 変更するフィールドごとに、レコードから古い値を取得し、プログラムロジックから新しい値を取得します
  4. 変更するフィールドごとに、監査レコードを書き込みます
  5. レコードを更新する
  6. トランザクションを終了します

これがたくさんある場合は、一般的なレベルで、またはテーブルごとに個別の関数で、比較を行うための更新レコード関数を作成すると思います。

于 2009-11-09T23:08:04.733 に答える