none
Comparação e atualizaçao de conteudo tabelas SQL RRS feed

  • Pergunta

  • Olá a todos,

    Gostaria de saber se alguém pode me ajudar na seguinte questão...

    imagine o seguinte cenário, tenho duas tabelas idênticas em termos de estrutura,  uma temporária e outra onde se guarda os dados reais no banco de dados, eu gostaria de saber se existe algum comando no SQL em que eu possa comparar as duas tabelas em termos de conteúdo, apontar uma como origem e a outra como destino, e que este comando ATUALIZE somente os dados diferentes da tabela de destino com os dados da origem. Dei uma pesquisada e encontrei o MERGE que esta disponível a partir do SQL Server 2008, porém ele não faz exatamente isso que eu preciso.

    Desde de já agradeço. Obrigado.

    terça-feira, 1 de setembro de 2015 04:21

Respostas

  • Olá Junior Galvao,

    O Merge não me atende por que nele eu precisaria setar quais colunas que deverão ser atualizadas no registro em que o usuário alterou, e para saber quais colunas atualizar eu precisaria comparar as mesmas uma a uma para identificar o que esta diferente entre tabela temporária e tabela de dados reais.

    Funciona assim: Eu tenho uma tabela de ordem de serviço e nesta tabela existem varias colunas ( umas 40 colunas mais ou menos.. ), o usuário utilizando o sistema ( um ERP no caso ) pode inserir, alterar e excluir ordens de serviço desta tabela. No momento da ATUALIZAÇÃO é criada uma tabela temporária com o registro que o usuário esta alterando.. o usuário altera o mesmo da forma que ele quer e quando ele finaliza alteração o sistema posiciona no registro da tabela de dados reais( no caso a tabela de destino) através de uma Primary Key e atualiza todas colunas de uma vez, sem identificar as colunas que foram alteradas.

    O que eu estou procurando é, um comando no SQL que me deixa definir uma tabela de origem ( no caso a temporária ) e uma tabela de destino ( no caso a de dados reais), e que posicionando através de uma primary key ele atualize somente as colunas que foram alteradas pelo usuário, sem mexer nas outras.


    

    Eduardo,

    Sem pensar na tabela temporária neste primeiro momento, como alternativa você poderia criar uma trigger de UPDATE na sua tabela de "Produção" (como você indicou, "dados reais") para adicionar as informações de cada coluna atualizada em outra tabela.

    Esta outra tabela com os dados modificados(pelo UPDATE na tabela de Produção) poderá ter a mesma estrutura que a tabela de "origem" ou ser semelhante à uma tabela de histórico. Faça uma análise de qual o formato é mais adequado para seu uso.

    Segue abaixo um exemplo de trigger de UPDATE para você adaptar à sua necessidade:

    CREATE TRIGGER [dbo].[TU_ORIGEM]
       ON [dbo].[TB_ORIGEM]
       AFTER INSERT, UPDATE
    AS
    BEGIN
         SET NOCOUNT ON;
    
         DECLARE @NOME         varchar(150),
                 @ADMISSAO     smalldatetime,
                 @ID           int;
    
         IF UPDATE(NM_NOME)
           BEGIN
               SELECT @NOME = NM_NOME, @ID = CD_PESSOA FROM INSERTED
    
               INSERT INTO TB_DESTINO 
    (CD_PESSOA, NM_COLUNAAFETADA, TXT_NOVOVALOR, DT_ALTERACAO)
    VALUES (@ID, 'NM_NOME', @NOME, GETDATE()) END END GO


    Para maiores informações veja:

    https://msdn.microsoft.com/pt-br/library/ms189799%28v=SQL.120%29.aspx

    https://msdn.microsoft.com/pt-br/library/ms187326.aspx


    Se ajudou na sua solução, não esqueça de marcar como resposta !


    Abraços,

    Durval Ramos
    Microsoft Partner | MTA | MCSA - SQL Server 2012 | MCSE - Data Platform
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"

    • Marcado como Resposta Marcos SJ sexta-feira, 4 de setembro de 2015 14:59
    quarta-feira, 2 de setembro de 2015 16:36
    Moderador

Todas as Respostas

  • Olá EduardoFerrari32,

    Tudo bem?

    Acredito que talvez alguns meios que vou citar podem ajudar você a fazer o que você precisa. Mas para tal você precisará fazer uma pesquisa um pouco mais aprofundada, uma vez que isto não é a solução pronta para a sua situação. Você pode começar pesquisando pelos soluções a seguir:

    SQL Server Integration Server
    Programaticamente na aplicação ou no SQL
    Ou tentar comparação dentro do SQL... comando - Except

    IF...ELSE (Transact-SQL)

    Atencisoamente


    Marcos Roberto de Souza Junior

    Esse conteúdo e fornecido sem garantias de qualquer tipo, seja expressa ou implícita

    MSDN Community Support

    Por favor, lembre-se de Marcar como Resposta as respostas que resolveram o seu problema. Essa e uma maneira comum de reconhecer aqueles que o ajudaram e fazer com que seja mais fácil para os outros visitantes encontrarem a resolução mais tarde.



    • Editado Marcos SJ terça-feira, 1 de setembro de 2015 16:32
    terça-feira, 1 de setembro de 2015 16:32
  • Eduardo,

    Qual seria o motivo do Merge não te atender?


    Pedro Antonio Galvao Junior [MVP | MCC | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitario | SoroCodigos | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    terça-feira, 1 de setembro de 2015 17:52
  • Olá Junior Galvao,

    O Merge não me atende por que nele eu precisaria setar quais colunas que deverão ser atualizadas no registro em que o usuário alterou, e para saber quais colunas atualizar eu precisaria comparar as mesmas uma a uma para identificar o que esta diferente entre tabela temporária e tabela de dados reais.

    Funciona assim: Eu tenho uma tabela de ordem de serviço e nesta tabela existem varias colunas ( umas 40 colunas mais ou menos.. ), o usuário utilizando o sistema ( um ERP no caso ) pode inserir, alterar e excluir ordens de serviço desta tabela. No momento da ATUALIZAÇÃO é criada uma tabela temporária com o registro que o usuário esta alterando.. o usuário altera o mesmo da forma que ele quer e quando ele finaliza alteração o sistema posiciona no registro da tabela de dados reais( no caso a tabela de destino) através de uma Primary Key e atualiza todas colunas de uma vez, sem identificar as colunas que foram alteradas.

    O que eu estou procurando é, um comando no SQL que me deixa definir uma tabela de origem ( no caso a temporária ) e uma tabela de destino ( no caso a de dados reais), e que posicionando através de uma primary key ele atualize somente as colunas que foram alteradas pelo usuário, sem mexer nas outras.


    

    quarta-feira, 2 de setembro de 2015 02:22
  • Olá Eduardo,

    Tudo bem?

    Você fez a pesquisa conforme sugeri?

    Atenciosamente


    Marcos Roberto de Souza Junior

    Esse conteúdo e fornecido sem garantias de qualquer tipo, seja expressa ou implícita

    MSDN Community Support

    Por favor, lembre-se de Marcar como Resposta as respostas que resolveram o seu problema. Essa e uma maneira comum de reconhecer aqueles que o ajudaram e fazer com que seja mais fácil para os outros visitantes encontrarem a resolução mais tarde.

    quarta-feira, 2 de setembro de 2015 12:08
  • Olá Junior Galvao,

    O Merge não me atende por que nele eu precisaria setar quais colunas que deverão ser atualizadas no registro em que o usuário alterou, e para saber quais colunas atualizar eu precisaria comparar as mesmas uma a uma para identificar o que esta diferente entre tabela temporária e tabela de dados reais.

    Funciona assim: Eu tenho uma tabela de ordem de serviço e nesta tabela existem varias colunas ( umas 40 colunas mais ou menos.. ), o usuário utilizando o sistema ( um ERP no caso ) pode inserir, alterar e excluir ordens de serviço desta tabela. No momento da ATUALIZAÇÃO é criada uma tabela temporária com o registro que o usuário esta alterando.. o usuário altera o mesmo da forma que ele quer e quando ele finaliza alteração o sistema posiciona no registro da tabela de dados reais( no caso a tabela de destino) através de uma Primary Key e atualiza todas colunas de uma vez, sem identificar as colunas que foram alteradas.

    O que eu estou procurando é, um comando no SQL que me deixa definir uma tabela de origem ( no caso a temporária ) e uma tabela de destino ( no caso a de dados reais), e que posicionando através de uma primary key ele atualize somente as colunas que foram alteradas pelo usuário, sem mexer nas outras.


    

    Eduardo,

    Sem pensar na tabela temporária neste primeiro momento, como alternativa você poderia criar uma trigger de UPDATE na sua tabela de "Produção" (como você indicou, "dados reais") para adicionar as informações de cada coluna atualizada em outra tabela.

    Esta outra tabela com os dados modificados(pelo UPDATE na tabela de Produção) poderá ter a mesma estrutura que a tabela de "origem" ou ser semelhante à uma tabela de histórico. Faça uma análise de qual o formato é mais adequado para seu uso.

    Segue abaixo um exemplo de trigger de UPDATE para você adaptar à sua necessidade:

    CREATE TRIGGER [dbo].[TU_ORIGEM]
       ON [dbo].[TB_ORIGEM]
       AFTER INSERT, UPDATE
    AS
    BEGIN
         SET NOCOUNT ON;
    
         DECLARE @NOME         varchar(150),
                 @ADMISSAO     smalldatetime,
                 @ID           int;
    
         IF UPDATE(NM_NOME)
           BEGIN
               SELECT @NOME = NM_NOME, @ID = CD_PESSOA FROM INSERTED
    
               INSERT INTO TB_DESTINO 
    (CD_PESSOA, NM_COLUNAAFETADA, TXT_NOVOVALOR, DT_ALTERACAO)
    VALUES (@ID, 'NM_NOME', @NOME, GETDATE()) END END GO


    Para maiores informações veja:

    https://msdn.microsoft.com/pt-br/library/ms189799%28v=SQL.120%29.aspx

    https://msdn.microsoft.com/pt-br/library/ms187326.aspx


    Se ajudou na sua solução, não esqueça de marcar como resposta !


    Abraços,

    Durval Ramos
    Microsoft Partner | MTA | MCSA - SQL Server 2012 | MCSE - Data Platform
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"

    • Marcado como Resposta Marcos SJ sexta-feira, 4 de setembro de 2015 14:59
    quarta-feira, 2 de setembro de 2015 16:36
    Moderador