MERGE Нарушение ограничения PRIMARY KEY

У меня есть таблица отношений «многие-ко-многим» SQL Server 2008 ( Assets ) с двумя столбцами:

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

В моем проекте мне нужно взять строки из этой таблицы и периодически вставлять их в реплицированную базу данных. Итак, у меня есть две базы данных, которые в точности одинаковы (включая ограничения).

Чтобы «скопировать» из одной базы данных в другую, я использую оператор MERGE с временной таблицей. Я вставляю до 50 записей в временную таблицу, затем объединяю таблицу temp с таблицей 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) сам по себе, он отлично работает. Затем мой тест можно продолжить и вставить оставшиеся строки без ошибок.

Solutions Collecting From Web of "MERGE Нарушение ограничения PRIMARY KEY"

Вам нужно добавить HOLDLOCK в свой оператор HOLDLOCK . Попробуйте следующее:

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

Это позволяет избежать состояния гонки, в которое вы работаете. Подробнее см. Здесь

РЕДАКТИРОВАТЬ

Исходя из вашего обновления, единственное, что я могу придумать, это то, что в вашей таблице temp может быть дубликат записи. Можете ли вы дважды проверить?