• ベストアンサー

アクセスで変更ログを作成する

MS-Access2000です。データ保護のため、変更ログを取ろうかと考えています。一応以下のような手順を計画中ですが、他によい方法やアドバイス等あればご教授下さい 1.対象テーブルをコピーしてバックアップテーブルを作る 2.対象テーブルに「更新フラッグ」フィールド(boolean)を追加する 3.通常の操作(入力作業)で、レコードに対する変更が行われれば「更新フラッグ」をたてる 4.入力作業終了時に更新フラッグが立っているレコードは、IDでリレーションをとり、バックアップテーブルから当該レコードを「変更履歴テーブル」に(日時と共に)書き出す 5.バックアップテーブルと、対象テーブルの同期を取り、更新フラッグを倒す ざっとこんなかんじですが結構面倒で、何かもっと簡便な方法がないかと思考中です。

質問者が選んだベストアンサー

  • ベストアンサー
  • ShowMeHow
  • ベストアンサー率28% (1424/5027)
回答No.2

見当違いなことを言ってしまいました。 すみません。  また、トンチンカンなことを言っていたら申し訳ないのですが、、、 更新データに関しては、削除フラグ、削除タイムスタンプ、削除ユーザーID等の設定を行うだけにして、新規にレコードを作るというのも手です。  パフォーマンスに影響が出るほど更新が多いなら、時々バッチで別テーブルに移動させるということも考えても良いですが、 最適化を行わない限りパフォーマンス上は差はでないだろうし、頻繁に最適化を行うのはそれなりに怖いし、、、、

noname#182251
質問者

お礼

度々のご回答有り難うございます。バックアップテーブルを持たずに済む分、スペース的には有利でしょう。 削除フラグは削除そのものに使用しているので更新フラグでしょうか。 しかしこのフラグを立てるタイミングが難しそうです。更新前にフラグをたてて「保存し」新規レコードを作るわけですが、そのために「更新ボタン」的なものを作るのでしょうか?しかし「更新するつもりだったら隣のレコードだった」とかそのために「更新取り消しボタン」が必要なのか、もう少し考えてみます。ここら辺に関するアイデアがあればご教授下さい。

noname#182251
質問者

補足

バックアップテーブルを持たないと云うアイディアは大変参考になりました。しかし同じテーブルにおいてフラグで管理するのは、お礼にも書いたタイミングの問題も含め、難しいように思われます。別テーブルに、更新寸前(BeforePost)に書き出す方法で、一応「解決」いたしました。ご報告します。

すると、全ての回答が全文表示されます。

その他の回答 (3)

  • DexMachina
  • ベストアンサー率73% (1287/1744)
回答No.4

No.3です。 > ご提案いただいた1)~4)は入力用各種フォームに対するコーディングが大変で、 > メンテナンスはもっと大変に思われるのですが、違うのでしょうか? すみません、おっしゃるとおりです(汗) Delphi等、Access以外のものは知らないので、No.1の方への補足欄を見た際には その旨コメントするつもりだったのが、すっかり忘れていました。 アドバイスをするつもりが却って混乱を招いてしまったようで、申し訳ありません。

noname#182251
質問者

お礼

度々のご投稿有り難うございます。 >アドバイスをするつもりが却って混乱を招いてしまったようで、申し訳ありません。 そんなことはありません。充分役立ちました。ご回答いただいたことをきっかけにしばらく考えていたのですが、改善案が浮かびました。「BeforePost」イベントハンドラを使用するならば、このタイミングでポストされる前のレコードをログに書き出せば、バックアップテーブルもいらないし、対象データが更新されるごとに履歴も更新される、より望ましい形です。SQL文もより簡単なもので済みました。完成に近づいたようです。 今後もよろしくお願いします。

noname#182251
質問者

補足

下記のようなSQL文を実行することにより、「更新日時」も含めてログファイルに書き出すことができるようになりました。読みにくいSQL文と思いますが、参考のため添付します INSERT INTO NameListEditLog ( 更新日時 ) SELECT NameList.*, Now() AS d FROM NameList WHERE (((NameList.NameID)=282)); ログを利用して、どのように変更履歴を見たり、復元したりするかは、まだほとんどアイディアもない状態です。何かあればご教授下さい。よろしく

すると、全ての回答が全文表示されます。
  • DexMachina
  • ベストアンサー率73% (1287/1744)
回答No.3

「作業用の一時テーブルを作成して、ある一定条件のレコードを抽出して 編集作業を行った後、更新ボタンで一括更新」とはされていない、 ということでよろしいでしょうか。 (もしも上記のようにされているなら、No.2の方へのお礼で、タイミングを  問題にはされないように思ったので) ※上記のようにしないのは、マルチユーザーによるレコードの競合を、  Accessのレコードロック機能で解決するため、ということでしょうか。 ・・・上記の推測により、ご質問は「保存用テーブルのレコードを直接 編集する際」についてのものという前提で話を進めさせて戴きます。 (違っていましたらご容赦のほど・・・) 1)編集前のレコードを一時保存するテーブルを作成 2)レコード移動時イベントで、上記テーブルの全レコード(但し最大で  1件)を初期化 3)ダーティー時イベントにより、編集開始時に編集前のレコードを上記  テーブルに保存  (新規レコードは旧データがないので、何らかの仕様を考える必要あり)  ※この時点では、SQLやクエリで参照できるデータは編集前のものなので   旧データを取得するタイミングとしては問題ないはず 4)フォームの更新後イベントで、各フィールドの値を一時保存テーブルと  照合し、変更があったら一時保存テーブルのデータをバックアップ用  テーブルに追加  ※場合によっては、レコード移動時だけでなくここでも初期化を実行 ・・・以上です。 なお、照合については、RunCommand.SaveRecordなどで強制的にレコード を保存して、といった操作が必要かもしれません。 (上記の通り、レコードが編集中のままだとSQL上では確認できないので) ・・・根本的に「何かもっと簡便な方法がないかと」という趣旨には 添えていない気もしますが(汗)

noname#182251
質問者

補足

ご回答有り難うございます 私の質問が不充分なため、誤解を招いたことをお詫びします。最初に書くべき条件が脱落していました。 1.シングルユーザー 2.レコード数は高々数万 以上です。 質問で例としてあげた方式は「入力作業終了時」に更新フラグが立っているレコードをバックアップテーブルから変更履歴テーブルへ書き出します。SQLで処理できるので、速度に不満はありません。問題は更新フラグの立て方ですが、#1の補足にも書いたように、BeforePostで簡単にできることが判りました。 一方#2でご提案いただいた、「変更せずにフラグを立て、変更データは実は新規データ」という考え方も面白いと感じましたが、そちらでは「タイミングを問題」と認識している次第です。 で、ご提案いただいた1)~4)は入力用各種フォームに対するコーディングが大変で、メンテナンスはもっと大変に思われるのですが、違うのでしょうか?

すると、全ての回答が全文表示されます。
  • ShowMeHow
  • ベストアンサー率28% (1424/5027)
回答No.1

素人なので参考にもならないかもしれませんが、 テーブルのバックアップを取り、更新をすべてSQL処理にして、一意のタイムスタンプと共にSQL文を(ユーザーIDや端末名などと共に)書き出しておけば、バックアップ以降のどの時点へのロールバックも可能だと思います。 欲を言うならば、テーブルに更新タイムスタンプやユーザーID、端末名などのフィールドを入れておきたいところです。(これがあればSQL文の保存だけですみます。) まあ、アクセスで提供されているセキュリティが不十分なら、他のDBを使った方が簡単だと思いますが、、、

noname#182251
質問者

補足

ご回答有り難うございます。私の説明が不充分であったのか、ちょっと問題が誤解されているようです。 例えば住所録DBを考えます。 Aさんの電話番号が変更になった。それを修正したつもりが、隣のBさんを修正してしまった。Aさんの電話番号を元に戻したい。ただ誤りにいつ気付くか保証がないので、変更の記録をずっと残したいわけです。 ということで >更新をすべてSQL処理にして と云うわけには行きません。仮にそれが可能でも、手間がかかりすぎて現実的ではありません。 プロトタイプを作成中ですが私が使用しているDelphiで、ADO関係に「BeforePost」というイベントがあり、このイベントハンドラを使用して「更新フラッグ」と「更新日時」を書き込むようにすると、比較的簡単に目的を達することができそうです。 繰り返しますが、単なる「ロールバック」ではなく、有効な変更は残し、間違った変更を元に戻したいのです。

すると、全ての回答が全文表示されます。

関連するQ&A