web-dev-qa-db-ja.com

Access / SQL(書き込み競合)でレコードの問題を編集する

使用したSQL DBを新しいサーバーに移行した後に問題が発生しました。 Access(フォームまたはテーブル)でレコードを編集しようとすると、次のように表示されます:WRITE CONFLICT: This record has been changed by another user since you started editing it...

これには明らかな理由はありますか。サーバーを使用している人は他にいません。テーブルのトリガーを無効にしました。レコードがないレコードは大丈夫ですが、NULLがある行はそうではないため、NULLと関係があることがわかりました。インデックスと関係があるのでしょうか?関係がある場合は、AccessからINSERT INTOを使用して1つずつアップロードするのではなく、最近BULKアップロードを毎日開始しました。

30
aSystemOverload

考えられる問題:

1同時編集

理由としては、問題のレコードが編集中のフォームで開かれていることが考えられます。編集セッション中にプログラムでレコードを変更し、フォームを閉じようとすると(したがって、レコードを保存しようとすると)、アクセスは、レコードが他の誰かによって変更されたと言います。

プログラムでレコードを変更する前にフォームを保存します。
形式:

'This saves the form's current record
Me.Dirty = False

'Now, make changes to the record programmatically

2主キーまたはタイムスタンプがありません

SQL-Serverテーブルにプライマリキーとタイムスタンプ列があることを確認してください。

タイムスタンプ列は、Accessが最後に選択されてからレコードが編集されたかどうかを判断するのに役立ちます。タイムスタンプが利用できない場合、アクセスはすべてのフィールドを検査することによりこれを行います。タイムスタンプ列がない場合、これはヌルエントリではうまく機能しない可能性があります(3 Null bits issueを参照)。

タイムスタンプには、実際には時刻ではなく行のバージョン番号が格納されます。

タイムスタンプ列を追加した後、アクセス時にテーブルリンクを更新することを忘れないでください。そうしないと、Accessはそれを表示しません。 (注:MicrosoftのアップサイジングWizardは、AccessテーブルをSQL-Serverテーブルに変換するときにタイムスタンプ列を作成します。)


3 Nullビットの発行

@ AlbertD.Kallalによると、これは KB2807 で説明されているnullビットの問題である可能性があります。ビットフィールドを使用している場合は、デフォルト値を0に設定し、以前に入力したNULLを0で置き換えます。私は通常、ブールフィールドにBIT DEFAULT 0 NOT NULLを使用します。これは、ブールの概念に最も近いためです。

KB記事では、*。mdbの代わりに* .adpを使用するように記述されています。ただし、 MicrosoftはAccess 2013でAccess Data Projects(ADP)のサポートを終了しました

この問題は、元のポスターと同じでした。フォームを使用せずに直接編集する場合でも。問題はビットフィールドにあります。フィールドがNullの場合、レコードにアクセスするとNullが0に変換され、次に2番目の変更である変更を行います。したがって、2つの変更が競合します。私はオリヴィエの提案に従いました:

「テーブルに主キーとtimestamp列があることを確認してください。」

そしてそれは問題を解決しました。

12
BratPAQ

MS SQL Sever 2000(およびそれ以前)にリンクした場合、MS Access 2003(およびそれ以前)でも同様の状況が見られました。私の場合、問題はMS SQL Serverデータベーステーブルのビットフィールドであることがわかりました。ビットフィールドはnull値を許可しません。 MS Access 2003のデータベースウィンドウを介してリンクされたテーブルにレコードを追加すると、ビットフィールドをTrueまたはFalseに設定しない限りエラーが返されます。修正するには、MS SQL Serverデータテーブルを変更して、ビットフィールドのデフォルトを0値または1に設定しました。それが完了したら、MS Accessを介してリンクテーブルにデータを追加/編集できました。

3
Spring

Jet/Accessブール値とSQL Serverビットフィールドの競合が原因で問題が見つかりました。

ここで落とし穴#4で説明 https://blogs.office.com/2012/02/17/five-common-pitfalls-when-upgrading-access-to-sql-server/

すべてのビットフィールドをNOT NULLに変更し、デフォルト(私の場合はゼロ)を提供するSQLスクリプトを作成しました。

これをSQL Server Management Studioで実行し、結果を新しいクエリウィンドウに貼り付けて実行します。これをカーソルに入れて実行する価値はほとんどありません。

SELECT
    'UPDATE [' + o.name + '] SET [' + c.name + '] = ISNULL([' + c.name + '], 0);' + 
    'ALTER TABLE [' + o.name + '] ALTER COLUMN [' + c.name + '] BIT NOT NULL;' + 
    'ALTER TABLE [' + o.name + '] ADD  CONSTRAINT [DF_' + o.name + '_' + c.name + '] DEFAULT ((0)) FOR [' + c.name + ']'
FROM
    sys.columns c
INNER JOIN sys.objects o
ON  o.object_id = c.object_id
WHERE
    c.system_type_id = 104
    AND o.is_ms_shipped = 0;
2
user607237

これはMicrosoftのバグです

この問題を回避するには、次のいずれかの方法を使用します。

  • マルチテーブルビューに基づくフォームを更新する「現象」に記載されているエラーメッセージが最初に発生した場合、[競合の書き込み]ダイアログボックスで[クリップボードにコピー]または[変更をドロップ]をクリックする必要があります。 「現象」に記載されているエラーメッセージの繰り返し発生を回避するには
    セクション、編集する前にフォームのレコードセットを更新する必要があります
    同じレコード。メモAccess 2003またはAccess 2002でフォームを更新するには、[レコード]メニューの[更新]をクリックします。 Access 2007でフォームを更新するには、[ホーム]タブの[レコード]グループで[すべて更新]をクリックします。

  • リンクされたサブフォームでメインフォームを使用する「現象」に記載されているエラーメッセージの繰り返し発生を回避するには、メインフォームを使用できます。
    リンクされたサブフォームは、関連するテーブルにデータを入力します。入力できます
    マルチテーブルビューに基づくフォームを使用せずに、1つの場所から両方のテーブルに記録します。リンクされたサブフォームでメインフォームを作成するには、次の手順を実行します。

    マルチテーブルビューで使用される関連(子)テーブルに基づく新しいフォームを作成します。フォームに必須フィールドを含めます。フォームを保存してから、フォームを閉じます。マルチテーブルビューで使用されるプライマリテーブルに基づく新しいフォームを作成します。に必須フィールドを含めます
    形。データベースウィンドウで、手順2で保存したフォームをメインフォームに追加します。

    これにより、サブフォームが作成されます。サブフォームのLink Child FieldsプロパティとLink Master Fieldsプロパティを、設定されているフィールドの名前に設定します。
    テーブルのリンクに使用。

Microsoftサポート から取られた回避策のメソッド

1
Hip Hip Array

上記の両方の原因を経験しました:現在フォームにバインドされているテーブルのデータを直接変更し、SQL Serverの「ビット」型フィールドにデフォルト値が「0」(ゼロ)に設定されていない。

後者の問題を回避できる唯一の方法は、ビットフィールドにデフォルト値のゼロを追加し、更新クエリを実行してすべての現在の値をゼロに設定することです。

前者のエラーを回避するために、私は独創的でなければなりませんでした。時々、VBAステートメントの順序を変更し、RefreshまたはRequeryを別の場所に移動して、エラーメッセージを防ぐことができます。ただし、ほとんどの場合、私が行うことは、直接テーブル更新を呼び出すサブルーチン内の文字列変数をDIMすることです。更新プログラムを呼び出す前に、このString変数をバインドされたフォームの背後のRecordsourceの値に設定し、その時点で使用されている正確なSQLステートメントをキャプチャします。次に、フォームのRecordsourceを空の文字列( "")に設定して、データから切断します。次に、データの更新を実行します。次に、フォームのRecordsourceをString変数に保存された値に戻し、バインディングを再確立し、テーブル内の新しい値を取得できるようにします。このフォーム内に1つ以上のサブフォームが含まれている場合、「リンク」フィールドはRecordsourceと同様の方法で処理する必要があります。 Recordsourceを空の文字列に設定すると、現在バインドされていないフィールドに#Nameが表示される場合があります。私がしているのは、Recordsourceが空のときに、可能な限り最高レベル(詳細セクション、サブフォームなど)でVisibleプロパティをFalseに設定し、ユーザーから#Name値を非表示にすることです。 Recordsourceを空の文字列に設定することは、コーディングの変更が見つからない場合の解決策です。しかし、私の設計スキルが不足しており、問題を完全に回避する方法があるかどうか疑問に思っています。

エラーメッセージへの対処に関する最後の考え:テーブルテーブルのデータを直接更新するルーチンを呼び出す代わりに、フォームにバインドコントロールを追加し、データを更新することで、フォームを介してデータを更新する方法を見つけますこれにより、フォームデータとテーブルデータが同期しなくなります。

1
KWells

リンクテーブルを使用している場合は、これらを更新したことを確認し、他の操作を行う前に再試行してください。

私はそれらを更新したと思っていましたが、誰かがフォーム検証とSQLテーブルを150文字を許可するように更新しましたが、リンクテーブルを更新しなかったため、アクセスは50文字しか許可されていませんでした-ブーム書き込みの競合

これがシナリオにとって最も適切なエラーかどうかはわかりませんが、興味深い問題のほとんどは、Microsoftソフトウェアで適切にフラグが立てられることはありません!

0
greeny129

私は、MS SQLテーブルに複数回リンクされたMS Accessテーブルでこの問題に対処しました。元のポスターの応答は非常に役に立ち、実際に私の問題の多くの原因でした。

また、フィールド名にスペースを含むビットフィールドを誤って追加したときに、この問題に遭遇しました...ええ....

Alter table tablename add [fieldname] bit default 0を実行しました。見つけた解決策は、そのフィールドを削除し、名前にスペースを入れないことでした。

0
Ben Reisner

かなり「重負荷」のスプリットフォームで、非常にひどい書き込み競合の問題(Acc2013 32ビット、SQL Srv2017 expr)がありました。私にとって-最後に-書き込み競合の問題を単純に解決するソリューションでした

AcSplitFormDatasheetを読み取り専用に設定します!!! (とにかく読み取り/書き込みが行われた理由がわからないのですが、フォールトで設定する必要があります...)

それを見つけるのに一週間かかった。

0

この問題を克服するために。同じ行の別のフィールドを変更するVBAを作成しました。そこで、フォームを閉じようとすると内容に1を追加する別のフィールドを作成しました。これで問題は解決しました。

0
Stuart

私はこの問題を抱えており、既存のテーブルに新しいビットフィールドを追加することによって引き起こされることに気付きました。新しいフィールドを削除すると、すべてが正常に機能するようになりました。

0
Alicia

私はこの回避策を使用していますが、それは私のために働いています:フロントエンド:MS Accessバックエンド:Mysql

特定のフィールドの更新前イベントで:

Private Sub tbl_comuna_id_comuna_BeforeUpdate(Cancel As Integer)

If Me.tbl_comuna_id_comuna.OldValue = Me.tbl_comuna_id_comuna.Value Then
Cancel = True
Undo
End If
End Sub
0
pperez