2009-06-24 6 views
0

フィールドが古い値と新しい値を示すフォームに変更されるたびに、データベースにエントリを追加する必要があります。特定のフォームフィールドの変更を監査する最も良い方法は何ですか?

あなたはこれについてどうやって行きますか?

ます...

  1. は、すべてのフィールドのための隠しフィールドを追加し、neccessary場合、監査エントリを追加し提出の新しい値にそれを比較するだろう??

  2. 投稿に挿入するデータを選択し、各プロパティを比較し、監査エントリを挿入します。

  3. 他のアイデア?

乾杯。

+0

これをASP-Classic、PHP、およびASP.NETとタグ付けしました。どちらですか? –

+0

もJavascriptでタグ付けされていますが、これは本当に悪い考えです。このようなことにクライアントサイドを使用しないでください。 –

+0

クラシックASPのサーバー側のJavaScript。 – Schotime

答えて

0

まず、フォームを文字列にシリアル化して とし、最新の文字列である と比較して、何か変わったかどうか確認してください。 2つの文字列が何もしていないならば。あなたが使用している場合

FORM_NAME [ 'first_nameの'] .... FORM_NAME [ 'LAST_NAME'] ....

iは[]で指定されたフォーム内のすべての要素が似ているものとPHPを使用すると、array_diff_assocを使ってどのような変更ができるかを確認できます。

あなたが必要とするのは、毎回DB形式で最新の書式配列を保存し、シリアル化して文字列として保存するだけです。

0

データベースで更新トリガーを使用して、比較と監査を行うことができます。 (私は便利なコードサンプルを持っていません - ごめんなさい)。

+0

ええ、私たちは何とかしていますが、この場合は適用できません。 – Schotime

+0

他の制限はありますか?ストアドプロシージャを使用できますか?私はオプション2、ストアドプロシージャ(あなたのアプリをシンプルに保つだろう)内に行くことができる場合 – Antony

+0

あなたはspのことができますが、値を変更したユーザーを知る必要があります。 – Schotime

0

あなたはどのデータベースを使用しているのかは分かりません。現在の値を取得し比較し、データベースに格納するプロシージャを作成してみることができます。私は思うようにこれを提案します。これは、データベース側ではなく、フロントエンドで行う比較のほうがはるかです。

編集:ちょっと、あなたがOracleを使用している場合、手続きを書くのは簡単です。 :)

0

あなたはPostgresのか、テーブルの上にUPDATEがポイント1について

を実行されるたびにトリガすることができ、あなたが簡単にあなたのことのためにそれを行うための関数を書くことができた機能を持っている他のデータベースを使用している場合は、誰かが簡単に独自のPOSTステートメントを作成できるように、フォームに「隠しフィールド」を含めることは間違いなく良い考えです。

ポイント2については、これは簡単に機能し、関数を書くことができない場合は私が使用するものです。彼らが提出されていることは非更新行

  • ストアフォームデータとDBデータの両方から有効
  • 選択情報であることを

    1. 検証:たいと思います

      あなたはこのような何かを行います2つのインスタンス$db_dataのための配列、および$form_data

    2. に機能array_diff_assoc

      を使用して違いをゲット

      $ differences = array_diff_assoc($ db_data、$ form_data);

    フォームとdb配列の両方に同じキーが必要であることに注意してください。

  • 1

    これをアプリ層に残しておきたい場合は、ロギングを行うためにフィールドごとのプロパティを持つモデルレイヤーを使用することをお勧めします。すべてのデータアクセスは、このデータモデルを通って行き、機能を追加するためのフックを与えます。

    activerecord基づい例(のVBScript):

    class cSomeEntity 
         public db ' link to a db wrapper 
         private id, dirty, loaded ' varous flags 
    
         private sub class_initialize 
         dirty = false 
         loaded = false 
         end sub 
    
         private sub class_terminate 
         if dirty then 
          db.execute("update some_table set some_field=? where id=?", array(p_some_field, id)) 
         end if 
         end sub 
    
         public sub load_by_id(value) 
         dim rs 
         set rs = db.fetch_rs("select id, some_field from some_table where id=?", array(id)) 
         id = rs("id") 
         p_some_field = rs("some_field")   
         loaded = true 
         end sub 
    
         private p_some_field 
         public property get some_field 
         some_field = p_some_field 
         end property 
    
         public property let some_field(value) 
         if not loaded then err.raise 1, , "Entity not yet initialized, call .load_by_id() first!" 
         if value <> p_some_field then 
          dirty = true 
          make_log_entry("some_value", p_some_field, value)   
          p_some_field = value  
         end if 
         end property 
    
         private sub make_log_entry(field, old_value, new_value) 
         db.execute("insert into audit_log (table, field, old_value, new_value) values (?, ?, ?, ?)", _ 
          array("some_table", field, old_value, new_value))  
         end sub 
        end class 
    

    これはビット肥大化に見えるかもしれないが、それは、トリガーベースのアプローチよりも柔軟です。たとえば、範囲チェックなどを簡単に実装できます。

    第2に、複数のエンティティクラスを記述する必要がある場合、デリゲートクラスに多くの機能をプッシュし、コードテンプレートを使用してgetter &セッターのプロパティを書き込むことができます。

    関連する問題