2012-05-23 25 views
6

Mam SQL Server 2008 wiele-do-wielu tabeli relacji (Assets) z dwóch kolumn:MERGE Naruszenie klucz podstawowy

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

w moim projekcie, muszę wziąć wiersze z tej tabeli, a wstawiaj je okresowo do replikowanej bazy danych. Tak więc mam dwie bazy danych, które są dokładnie takie same (w tym ograniczenia).

Aby "skopiować" z jednej bazy danych do drugiej, używam instrukcji MERGE z tabelą tymczasową. Wstawić do 50 rekordów do tabeli temp, a następnie scalić temp tabeli z tabelą Assets mam kopiowane w sposób następujący:

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); 

Działa to doskonale, w przeważającej części. Jednak raz na jakiś czas, pojawia się błąd:

Violation of PRIMARY KEY constraint 'PK_Assets'. Cannot insert duplicate key in object 'dbo.Assets'. The duplicate key value is (dc5e3082-e2eb-4bdf-a640-94e0f59411ed, 22). The statement has been terminated.

Kiedy sprawdzić w tabeli Assets, taki zapis nie istnieje ... więc jestem zdezorientowany jak bym być wstawienie duplikat klucza.

Masz pojęcie, co się tutaj dzieje?

UPDATE

Podczas badania, działa skutecznie 6 razy wkładania 300 wierszy. W siódmej próbie zawsze daje ten sam błąd, co powyżej. Co więcej, gdy samemu się to stanie, działa dobrze. Mój test jest wtedy w stanie kontynuować i wstawić pozostałe wiersze bez błędów.

+0

Instrukcja łączenia jest znana z błędów. Może uderzyłeś jednego. Proszę opublikować plan wykonania. – usr

Odpowiedz

12

Musisz dodać HOLDLOCK na swoim oświadczeniu MERGE. Wypróbuj następujące:

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

Pozwala to uniknąć sytuacji wyścigu, w którym się znajdujesz. Zobacz więcej info here

EDIT

Na podstawie aktualizacji, tylko inne, co mogę myśleć o to, że tabela temp może mieć duplikat rekordu w nim. Czy możesz dokładnie sprawdzić?

+0

Dzięki za szybką odpowiedź. Prawdopodobnie uratowałeś mnie (i innych) niektórych bólów głowy w przyszłości, ale niestety to nie rozwiązało mojego problemu. Zobacz zaktualizowane pytanie. – Justin

+2

Masz 100% poprawności. Miałem duplikat w moim tymczasowym stole. Zgadnij, porady HOLDLOCK to tylko bonus! – Justin

Powiązane problemy