10

Assets2 つの列を持つ SQL Server 2008 多対多関係テーブル ( ) があります。

AssetId (PK, FK, uniqueidentifier, not null)
AssetCategoryId (PK, FK, int, not null)

私のプロジェクトでは、このテーブルから行を取得し、レプリケートされたデータベースに定期的に挿入する必要があります。したがって、まったく同じ (制約が含まれる) 2 つのデータベースがあります。

あるデータベースから別のデータベースに「コピー」するために、一時テーブルで MERGE ステートメントを使用します。一時テーブルに最大 50 個のレコードを挿入し、次のように一時テーブルをAssetsコピー先のテーブルとマージします。

CREATE TABLE #Assets (AssetId UniqueIdentifier, AssetCategoryId Int);
INSERT INTO #Assets (AssetId, AssetCategoryId) VALUES ('ed05bac3-7a92-46aa-8822-2d882b137597', 44), ('dc5e3082-e2eb-4bdf-a640-94e0f59411ed', 22) ... ;

MERGE INTO Assets WITH (HOLDLOCK) AS Target 
USING #Assets AS Source 
ON Target.AssetId = Source.AssetId AND Target.AssetCategoryId = Source.AssetCategoryId 
WHEN MATCHED THEN
UPDATE SET ...
WHEN NOT MATCHED BY Target THEN 
INSERT (AssetId,AssetCategoryId) VALUES (Source.AssetId,Source.AssetCategoryId);

ほとんどの場合、これはうまく機能します。ただし、時々、次のエラーが表示されます。

PRIMARY KEY 制約 'PK_Assets' に違反しています。オブジェクト 'dbo.Assets' に重複するキーを挿入できません。重複キーの値は (dc5e3082-e2eb-4bdf-a640-94e0f59411ed, 22) です。ステートメントは終了されました。

テーブルをチェックインすると、Assetsそのようなレコードは存在しません...そのため、重複キーを挿入する方法がわかりません。

ここで何が起こっているのか分かりますか?

アップデート

テストすると、6 回正常に実行され、300 行が挿入されました。7 回目の試行では、常に上記と同じエラーが発生します。さらに、私INSERT (dc5e3082-e2eb-4bdf-a640-94e0f59411ed, 22)はそれ自体でうまく機能します。その後、テストを続行して残りの行をエラーなしで挿入できます。

4

1 に答える 1

18

ステートメントに a を追加する必要がありHOLDLOCKます。MERGE次のことを試してください。

MERGE INTO Assets WITH (HOLDLOCK) AS Target
...

これにより、実行中の競合状態が回避されます。詳細はこちら

編集

あなたの更新に基づいて、他に考えられる唯一のことは、一時テーブルに重複したレコードが含まれている可能性があることです。再確認できますか?

于 2012-05-23T16:50:54.487 に答える