web-dev-qa-db-ja.com

リンクされたAccessDB「レコードが別のユーザーによって変更されました」

私が作成したのではなく、MSSQL2000データベースにリンクされたマルチユーザーAccess 2000DBを維持しています。

データベースの設計は非常に貧弱なので、私に耐えなければなりません。

「Customer」フォームには「Customer_ID」フィールドがあり、デフォルトで次に利用可能な顧客IDを取得する必要がありますが、ユーザーはこの選択を既存の顧客IDで上書きするオプションがあります。

現在、Customer_IDフィールドはCustomerテーブルのPKではありません。それもユニークではありません。

顧客が2回電話をかけてジョブを送信すると、テーブルには2つのレコードが取得され、それぞれに同じ顧客情報と同じ顧客IDが含まれます。

ユーザーが新しいチケットを作成すると、Accessは次に利用可能な顧客IDをすばやく検索して入力します。ただし、レコードは保存されません。明らかに問題です。編集している2人のユーザーは、顧客IDを複製しないように、互いの作業を追跡する必要があります。

そこで、「新規レコード」ボタンを変更して、新しいチケットを作成した直後にチケットを保存するようにします。

問題は、変更をテストすると、「このレコードは、編集を開始してから別のユーザーによって変更されました」というメッセージが表示されることです。

DB上に他のユーザーは絶対にいません。 「他のユーザー」はおそらく私の強制保存でした。

何か案は?

15

SQL Server 2000のリンクテーブルを見てください。ビットデータ型を含むフィールドがありますか?ビットフィールドがある場合、Accessはリンクテーブルシナリオでこのエラーメッセージを表示しますデフォルト値はありません

あなたの場合は問題ではないかもしれませんが、Access 2007データベースで同じことを経験し、デフォルト値のないビットフィールドまで問題を追跡しました。

45
Istari

私は以前にこの動作を見たことがあり、これで修正されました。

テーブルにTimeStampフィールドを追加してみてください(このフィールドを追加して、リンクされたテーブルを更新するだけです。このフィールドにデータを入力する必要はありません)。

10
Birger

通常、発生するエラーは次の場合に発生します。

  1. フォーム内のレコードを編集していて、フォームがダーティである(つまり、編集が保存されていない)、

そして

  1. dAOまたはADOを使用してSQLを実行し、同じレコードを更新するコードを実行します。

Jetにとっては、2つの異なる編集操作であるため、これは2つの「ユーザー」です。基になるテーブルはSQLの更新によって更新されましたが、フォームバッファのデータは古くなっています。

通常の解決策は、SQL更新を実行する前に強制的に保存することです。

  If Me.Dirty Then
     Me.Dirty = False
  End If
  [run your SQL update here]

ただし、フォームを使用してレコードを編集している場合は、SQLを使用して更新を行うのではなく、フォーム内のすべての更新を行う必要があります。

独自のシーケンスを生成して説明する状況は、次の方法で実行する必要があります。

  1. ユーザーがNEWRECORDボタンを押します。

  2. 次のシーケンス値を計算し、それを変数に格納します。

  3. sQL INSERTを使用して、そのシーケンス値を含む新しいレコードを挿入します。

4a。フォームがテーブル内のすべてのレコードにバインドされている場合は、データ編集フォームを再クエリし([新しいレコード]ボタンがユーザーがデータを編集するフォーム上にあると想定)、ブックマークナビゲーションを使用して、シーケンス値が次の新しいレコードに移動します。手順2で変数に保存しました。

4b。フォームがnotすべてのレコードにバインドされている場合(適切に設計されたデータベースの場合はそうではないはずです)、フォームのレコードソースを変更して、新しいレコードのみをロードします。

もう1つの方法は、SQL INSERTと再クエリ(またはレコードソースのリセット)を回避し、既存のフォームに新しいレコードを追加し、シーケンスフィールドを新しい値に設定して、すぐにレコードを保存することです。

重要な点は、これがマルチユーザー環境で機能するためには、シーケンス値が割り当てられたらすぐにレコードを保存する必要があるということです。つまり、レコードを保存せずにそのままにしておくことはできません。同じシーケンス値を他のユーザーが利用できますが、これは災害を要求しているだけです。

7
David-W-Fenton

これは私がグーグルから出くわした古い質問なので、私は私の答えを提出します。

ODBCドライバーで、行のバージョン管理をオンにしてください。テーブルが既にAccessにある場合は、テーブルを削除してソーステーブルに再リンクする必要があります。

Accessはxminという列をテーブルに追加する必要があるため、行のバージョン管理が有効になっているかどうかを確認できるはずです。

5
vol7ron

ユーザーが新しいcustomer_idを独自の値でオーバーライドしたかどうかを追跡します。そうでない場合、アプリは保存する直前に重複をチェックし、再度自己インクリメントできるはずです。ユーザーはデフォルトを使用してもかまいません。たぶん、あなたが自動的に別の値を選択しなければならなかったことをユーザーに示す何らかの指標さえあります。

1
great_llama

私はこの投稿と他のいくつかの投稿を行ったり来たりして、この動作の解決策を見つけました。 MySQLデータベースにリンクされたMSAccessデータベースがあります。この問題は、MySQLphpmyadminの既存のBeforeUpdateトリガーが原因で発生しました。 phpmyadminでテーブルの構造に移動すると、画面の下部にトリガーが表示されます。

0

私たちの問題は、アクセスフロントエンドがint(yes/no)をmssqlビット(0/1)フィールドに保存しようとしていたことでした。 mssqlデータベースをintフィールドに変更することは、魅力のように機能しました。

0
Dilbert

このエラーは、SQL Serverテーブルにdatetime2列が含まれている場合にもスローされる可能性があります(私の場合、デフォルト値はsysdatetime()です)。データ型を日時のデフォルトのcurrent_timestampに戻すと、エラーが停止します。

0
Dead Red

このエラーを生成する別の状況に遭遇しました。 mysqlテーブルには、最初はデフォルト値「0000-00-00」であった2つの日付列がありました。その後、デフォルトのNULLに変更されましたが、多くの行が値「0000-00-00」を保持していました。エラーを停止するには、値を手動でNULLにリセットする必要がありました。

何がエラーを引き起こしているのかを理解するのに多くの時間がかかりました、HTH他の誰か。

0
koriander

私も同じ問題を抱えていました。 SpringMVCとHibernateを使用してテーブルを更新しようとしていました。私の場合、テーブルのバージョン列に1より大きい値(つまり3)が含まれていますが、更新クエリの更新情報のバージョン値は1でした。

0
Tejbir Singh