SE EXISTE e Instrução MERGE

0

Pergunta

Eu tenho dados que fluem em uma tabela a partir de várias outras tabelas permite dizer: Table_A Então eu tenho uma Série de procedimento armazenado que usa os dados da tabela A associá-la com a Tabela B.

No entanto, algo que não parece ser o certo. Se eu truncar e carregar os dados, funciona bem, mas se eu não truncar e de carga, e apenas buscar a consulta por eachh hora eu recebo a mensagem de erro dizendo:

Msg 8672, Nível De 16, Estado 1, Procedimento Merge_Table_A, Linha 4 [Lote Linha De Partida 0] A instrução MERGE tentou ATUALIZAR ou EXCLUIR a mesma linha mais de uma vez. Isso acontece quando uma linha de destino corresponde a mais de uma linha de origem. Uma instrução MERGE não ATUALIZAR/EXCLUIR mesma linha da tabela de destino várias vezes. Refinar a cláusula ON para garantir uma linha de destino corresponde a, no máximo, uma linha de origem, ou utilize a cláusula GROUP BY para agrupar as linhas de origem.

Como eu posso superar isto?

Eu quero ser capaz de incrementalmente carregar os dados e não truncar carrega, mas ao mesmo tempo tem um procedimento armazenado que atualiza ou insere ou não se importa se a linha já existe.

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

Melhor resposta

1

Parece que você tem linhas duplicadas na sua tabela de destino que são carregados a partir de suas execuções anteriores.

Nota: a Correspondência de uma impressão em Série não considera as linhas inseridas (mesmo duplicado) durante a execução da Série em si.

Abaixo está o meu repro exemplo, com uma amostra de dados:

Tabela1: dados Iniciais

enter image description here

Tabela2: Taget tabela

enter image description here

Instrução Merge:

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;

Quando a Série é executado, ele insere todos os dados sem erros.

enter image description here

Novos dados em tb1:

enter image description here

Quando eu executar a instrução Merge, ele me dá o mesmo erro que o seu.

enter image description here

Como uma solução utilizando uma das opções abaixo,

  1. Adicionar condições adicionais se possível na cláusula ON para identificar com exclusividade os dados.

  2. Remover as duplicatas de origem e mesclar os dados em tb2 como abaixo.

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

Dados mesclados em tb2 com êxito.

enter image description here

2021-12-02 12:52:40

Em outros idiomas

Esta página está em outros idiomas

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