• ベストアンサー

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

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

noname#182251
noname#182251

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

  • ベストアンサー
  • 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

  • access2000でデータの変更の内容がわかるようにしたいのですが。

    ACCESS初心者です。 ACCESS2000でフォームで既存レコードのどこかを更新したら、 (1)変更する前のデータをテーブル?で保存していきたい。(変更されたデータの過去分のデータをどんどん残していく。上書きはしない)&表示できれば尚うれしい。 (2)データを更新した日時も(1)と同じテーブルに書き込みたい。(こちらも(1)同様表示できれば尚うれしい)のです。 この作業はアクセスでできる?!と思っているのですが、 どなたかご教授頂ける方、よろしくお願いします。

  • アクセス作成について

     アクセスについて質問します。  フォームで入力する場合で、例えばテーブルのレコードを100までとし、101を超えた場合またレコード1にデータを入力することは可能でしょうか。 テーブル フィールド1 フィールド2  1       6  2       8   .      .   .      . 100       55 フィールド1は固定し、フィールド2にデータを入力していき101番目にデータを入力する時はまた1行目の6を上書きしてデータを更新していくようなことは可能でしょうか。(もちろんフィールド1、フィールド2を別テーブルとしクエリーを活用することでもok) アクセス初心者です。よろしくおねがいします。

  • Accessレコードの追加や変更が出来ません。

    テーブルのレコードにデータを入力したいのですが、試すと『テーブル'発注一覧'にリレーションシップが設定されたレコードが必要なので、レコードの追加や変更を行うことはできません』という表示がされ、入力も保存も出来ません。どうしたらよいか、ご存知でしたら教えていただけますでしょうか。すみませんが宜しくお願いいたします。

  • ACCESS2000 更新クエリで文字を追加・変更したい

    ACCESS2000のマクロでCSVファイルをインポートし、Excelに出力しています。 そこで途中に更新クエリを使い、文字の追加・変更を行いたいのですが何故かうまくいきません。。。 【テーブルA】 フィールド/受注番号(910004292) 【テーブルB】 フィールド/出荷番号(910005232)/製造番号(910005451) 【テーブルC】 フィールド/受注番号(910005232)/製造番号(910005451)/納期(1021) 受注、出荷、製造の各フィールドは先頭に"0"を追加したいです。 910004292→0910004292 納期は2009/10/21となるように、現在の西暦(できれば自動)/と3桁目にスラッシュを入れて、yyyy/mm/dd形式にしたいです。 更新クエリで フィールド:受注番号 テーブル:テーブルA レコードの更新:"0"&[受注番号] と入力してやるとうまくいきました。 同じように横のフィールドに フィールド:受注番号 受注番号 ・・・ テーブル:テーブルA テーブルB ・・・ レコードの更新:"0"&[受注番号] "0"&[受注番号] ・・・ と各テーブルの全てのフィールドを入力して更新すると、 レコードに物凄い数の"0"が追加されてしまいます。 例:0000000000000000910004292 何度も繰り返しているようなのですが、なぜなんでしょうか? 更新クエリを別々に作ればそれぞれうまくいきました。 ひとつのクエリに複数のテーブルのフィールドを入れると駄目です。 また、納期について1021→2009/10/21にうまく変更する方法はありますでしょうか? 分かりにくくて申し訳ありませんが宜しくお願いいたします。

  • Accessの参照整合性について

    アクセスでリレーションシップをはると参照整合性にチェックするボックスがありますよね。 以下の選択の組み合わせが考えられると思うのですが、 1.参照整合性にチェックしない場合 2.参照整合性のみチェックした場合 3.参照整合性と連鎖更新にチェックした場合 4.参照整合性と連鎖更新と連鎖削除にチェックした場合 一(マスタ)対多のリレーションを張ったとき、以下のように理解しています。 2.のとき マスタにあるものしか登録できない。また、マスタは他のテーブルにリレーションを張っている場合、削除も編集もできない。 3.のとき マスタにあるものしか登録できない。またマスタで更新をかけると、他のテーブルのレコードも更新がかかる。また、マスタは他のテーブルにリレーションを張っている場合、削除はできない。 4.のとき マスタにあるものしか登録できない。またマスタで更新、削除を行なうと他のテーブルのレコードも更新、削除がかかる。 では1.のときってリレーションシップは張れるのですが、何の意味があるのでしょうか?

  • Accessのリレーションシップ

    Access初心者です。 Access2010でデータベースを作っていて、行き詰ってしまいました。 テーブル1にフィールドABCDEFがあって、Aに主キーが付いています。(Aはテキスト型でフィールドサイズ10です。) テーブル2にはフィールドAGHがあり、Aに主キーが付いてます。(Aはテーブル1と同じです。) テーブル3にも同じくフィールドAIJがあり、Aに主キーが付いています。(Aはテーブル1と同じです。) テーブル1のフィールドAを主テーブルとし、テーブル2・3のフィールドAにリレーションを組んでいます。 この時のリレーションシップで参照整合性と連鎖更新と連鎖削除にチェックを入れ、種類が一対一になりました。 その後、テーブル1でレコードを追加しようとすると、「テーブル'2'にリレーションシップが設定されたレコードが必要なので、レコードの追加や変更を行うことができません。」と出ます。 これを解決する方法はどうするのか、お教えお願いします。 分かりにくい説明ですいません。

  • Accessの更新クエリについて質問です。

    よろしくお願いします。 集計したクエリを元に更新クエリを実行すると、更新できません。 やりたい作業としては、売上データテーブルのレコード数を得意先ごとにカウントして、得意先マスタテーブルのレコード件数フィールドを更新する作業です。 追加クエリで一度テーブルに追加してから、テーブル同士で更新も考えたんですが、レコード数が多いためにDBのサイズが爆発的に増えて廃案になりました。 何か良い方法があれば教えてください。

  • アクセス2000でクエリーで更新できない

    アクセス2000で簡単なプログラムを作成中なのですが、2つのテーブルをリレーションで繋いでそれぞれ必要項目を抽出するクエリーを作成しました。 このクエリーをフォームに使って空欄のエリアにデータを 入力しようとしたら次のメッセージとなりました。 「このレコードセットは更新できません。」となってしまいます。根本的なミスのような気がしますが、気が焦っていて思いつきません。どこの設定を見れば良いか、どなたかご教示ください。 よろしくお願いします。

  • Accessリレーションシップについて

    お世話になります。 Access2010 普段はクエリにて、いくつかのテーブルやクエリを紐づけているのですが リレーションシップの設定は今までやったことがありません。 ネットで調べて、 ・「参照整合性」にチェックを入れることにより、1対多の多側で1側に存在  しないIDで登録しようとするとエラーになる。   →間違ったデータが入力されるのを防ぐ。 ・多側でリレーションシップが設定されているフィールドに値を入力しない  ことは可能。但し、当該フィールドの「値要求」プロパティを"はい"に  した場合は、入力しないとエラーになる。 ・「フィールドの連鎖更新」にチェックを入れると、1側で変更したものが  多側でも自動的に変更される。 ・「レコードの連鎖削除」にチェックを入れると、1側で削除した場合、  多側で該当するデータをもつレコードが自動的に削除される。 上記については実際に試してみて動きを確認しました。 ※上記の認識違いや、もっと大事なことがあればご指摘、ご教示頂けると  幸いです。 今までは、こっちのテーブルで削除したらこっちのテーブルでも削除 みたいなことをやってたので、便利だとは思うのですが。。 以下のテーブルでリレーションシップの設定を行ったとします。 売上テーブル  ID 商品 担当者コード  1 AAAAA  3  2 BBBBB  1  3 AAAAA  1  4 CCCCC  2  5 CCCCC  3 担当者テーブル 担当者コード 担当者名  1     担当者A  2     担当者B  3     担当者C 売上テーブルの担当者コードと、担当者テーブルの 担当者コードでリレーションの設定を行い、「参照整合性」及び 「レコードの連鎖削除」にチェックを入れたとします。 例えばフォーム上にリストボックスを設置し ID 商品 担当者名 を表示し、リストボックス上で選択されたレコードを、削除ボタンを 押したら、そのレコードが削除されるプログラムを作成します。 ※選択されたレコードのIDを取得し削除クエリで削除。 リストボックスでID:5のレコードを選択し、削除ボタンを押した場合 売上テーブルのID:5のレコードを削除しても、担当者テーブルから 担当者コード:3のレコードは削除されない・・という認識でよろしい でしょうか。 ※要するに、1対多の多側で削除されても1側には影響無し。 同様にリストボックスでID:5のレコードを選択し、削除ボタンを押したときに 担当者コード:3を取得し、まずは担当者テーブルで担当者コード:3の レコードを削除すると、併せて売上テーブルのID:1及びID:5が削除 される。 要するに、上記のケースで「レコードの連鎖削除」の設定を行うと 本来削除すべきID:5以外のレコード(ID:1)まで削除されてしまう ことになる?? ※そもそも例がちょっと悪かったかもしれません。。 何が言いたいかというと、「フィールドの連鎖更新」「レコードの 連鎖削除」は、よーく考えて設定しないと意図しないところまで 更新されたり削除されてしまうのかなと。。なので、設定することに よって、プログラムの作りも変わってきてしまうことになるので しょうか。 理解不足で質問自体もモヤモヤしたものになってしまいましたが、 ご教示のほど、宜しくお願い致します。

  • 紙の報告書をACCESSに移行するにあたり(過去の作業報告を簡単に引用して入力したい)

    ACCESS初心者です 周期的に作業を行う先が複数あり、作業結果を毎回紙の報告書に記載しています。 データが1年以上入力されれば、記録作業の簡略化や将来の作業計画も立てやすくなるだろうとACCESSに移行したいのです。 ほとんどの作業が過去に行ったものと同じ作業(周期は現場により1週間だったり1年だったりいろいろ) 作業の内容は紙の報告書では10行とってあります。 たいていは2~3行(箇所)で間に合うのですが。 このような事をACCESSに移行したいと思い 1.取引先(作業先)テーブル 2.作業内容テーブル を作成しました 二つをリレーションでつなげようと思うのですが、作業内容テーブルの作り方をどうしたものかと思案しています。 1つは 1レコードに作業1~作業10(前述の紙の報告書の行数)とすれば、次回の作業報告は前回記録の1レコードをコピーすれば簡単にでき、極端に言えば日付の書き換えだけで終える事が可能と思いました。 2つは 1レコードに1作業 ただしこの場合前回の記録を参考にしようとした場合、1レコードだったり、4レコードだったりと作業内容が作業先によって異なることからコピーして日付だけ書き換えというのが面倒になります。 しかし、作業明細をつけて請求書等を作成しようとした場合この方がデータの取り回しが簡単かなとも思います テーブルとリレーション作成の初歩的なことでの悩みですので、私の考える以外の方法以外でも何かヒントになることをご存じの方がおられましたら、アドバイスをお願いします。