JEŚLI ISTNIEJE i operator korespondencji SERYJNEJ

0

Pytanie

Mam dane, pochodzące w jedną tabelę z kilku innych tabel, powiedzmy: Table_A Następnie mam zapisany proces scalania, który pobiera dane z tabeli A, łączy je z tabelą B.

Jednak coś chyba jest nie tak. Jeśli усекаю i pobierania danych, to działa dobrze, ale jeśli nie усекаю i nie zgrywam, ale po prostu mam zapytanie co godzinę, otrzymuję komunikat o błędzie, w którym czytamy:

Msg 8672, Poziom: 16, Stan: 1, Procedura Merge_Table_A, Wiersz 4 [Początkowa Linia Pakietu 0] Instrukcja MERGE kilka razy próbowałam ZAKTUALIZOWAĆ lub USUNĄĆ jeden i ten sam ciąg. Dzieje się tak, gdy docelowa linia pokrywa się z więcej niż jednej źródłowego. Instrukcja MERGE nie może AKTUALIZOWAĆ lub USUWAĆ jeden i ten sam wiersz w tabeli docelowej kilka razy. Sprawdź ofertę ON, aby upewnić się, że docelowa wiersz nie więcej niż jednej oryginalnej linii, lub użyj klauzula GROUP BY do grupy oryginalnych wierszy.

Jak mogę przezwyciężyć?

Chcę, żeby u mnie była możliwość stopniowo pobierać dane i nie obcięciu obciążenia, ale w tym samym czasie mieć zapisany proces, który aktualizuje, wstawia lub nie dba o to, czy istnieje już linia.

azure sql-merge sql-server
2021-11-24 01:52:34
1

Najlepsza odpowiedź

1

Chyba masz zduplikowane wiersze w tabeli docelowej, które zostały przesłane z poprzednich startów.

Uwaga.Zestawienie w połączeniu nie uwzględnia wstawione wiersze (nawet duplikaty) podczas wykonywania samego korespondencji seryjnej.

Oto mój przykład powtórki z przykładowych danych:

Tabela 1: dane Źródłowe

enter image description here

Tabela 2: Tabela Taget

enter image description here

Operator korespondencji seryjnej:

MERGE tb2 AS Target
USING tb1   AS Source
 ON Source.firstname = Target.firstname and 
    Source.lastname = Target.lastname 

-- For Inserts
WHEN NOT MATCHED BY Target THEN
INSERT (firstname, lastname, updated_date) 
VALUES (Source.firstname, Source.lastname, source.updated_date)

-- For Updates
WHEN MATCHED THEN UPDATE SET
   Target.updated_date      = Source.updated_date

-- For Deletes
WHEN NOT MATCHED BY Source THEN
DELETE;

Gdy wykonywane jest połączenie, to wstawia wszystkie dane bez żadnych błędów.

enter image description here

Nowe dane w tb1:

enter image description here

Gdy uruchamiam instrukcji Merge, to wyświetla mi się ten sam błąd, co i twoje.

enter image description here

Jako obejścia drodze, użyj jednej z następujących opcji

  1. Dodaj dodatkowe warunki, jeśli to możliwe, w ofercie ON, aby jednoznacznie zidentyfikować dane.

  2. Usuń duplikaty ze źródła i połączyć dane w tb2, jak pokazano poniżej.

     --temp table
     drop table if exists #tb1;
    
     select *  into #tb1 from (
         select *, row_number() over(partition by firstname, lastname order by firstname, lastname, updated_date desc) as rn from tb1) a
     where rn = 1 
    
     MERGE tb2 AS Target
     USING #tb1 AS Source
      ON Source.firstname = Target.firstname and 
         Source.lastname = Target.lastname 
    
     -- For Inserts
     WHEN NOT MATCHED BY Target THEN
     INSERT (firstname, lastname, updated_date) 
       VALUES (Source.firstname, Source.lastname, source.updated_date)
    
     -- For Updates
     WHEN MATCHED THEN UPDATE SET
        Target.updated_date     = Source.updated_date
    
     -- For Deletes
     WHEN NOT MATCHED BY Source THEN
       DELETE;
    

Dane pomyślnie połączone w tb2.

enter image description here

2021-12-02 12:52:40

W innych językach

Ta strona jest w innych językach

Русский
..................................................................................................................
Italiano
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................