none
Update em Select RRS feed

  • Pergunta

  • Boa tarde,

    Preciso executar um Update sobre um Select, mais ou menos assim:

    UPDATE tb01_CadLeg SET Resumo = NULL
    FROM (SELECT dbo.tb01_CadLeg.Resumo
          FROM dbo.tb01_CadLeg INNER JOIN
               (SELECT IdCadLeg, Resumo FROM dbo.EMPARP
                GROUP BY Resumo, IdCadLeg) AS a ON dbo.tb01_CadLeg.Resumo = a.Resumo
                WHERE (NOT (dbo.tb01_CadLeg.Id IN
                    (SELECT IdCadLeg FROM dbo.[Base Resumo])))) as a

    É garantido que o Update será executado somente sobre os registros do Select?

    Existe alguma forma de visualizar o resultado do update antes de executá-lo, ou alguma forma de revertê-lo se algo sair errado?

    Grato

    sexta-feira, 6 de dezembro de 2013 14:34

Respostas

  • Cláudio, a melhor forma de visualizar quais serão os registros afetados é executar todo o select e ver se ele está trazendo os registros corretos.

     (SELECT dbo.tb01_CadLeg.Resumo
          FROM dbo.tb01_CadLeg
    INNER JOIN
               (SELECT IdCadLeg, Resumo
    FROM dbo.EMPARP
                GROUP
    BY Resumo, IdCadLeg)
    AS a ON dbo.tb01_CadLeg.Resumo
    = a.Resumo
                WHERE
    (NOT (dbo.tb01_CadLeg.Id
    IN
                   
    (SELECT IdCadLeg FROM dbo.[Base Resumo])))

    Com relação a reversão, você usar uma transação para que caso seu update saia errado, você possa retornar os registros ao estado que se se encontravam antes da execução da query

    Exemplo:

    BEGIN TRANSATION

    Seu comando UPDATE

    Se a query foi executada com sucesso você pode confirmar a operação usando a palavra COMMIT, se após o update você identificou que houve alguma falha, você usa o ROLLBACK.

    http://msdn.microsoft.com/pt-br/library/ms188929.aspx


    sexta-feira, 6 de dezembro de 2013 15:08
  • Cláudio,

         Eu não utilizaria subqueries como você está fazendo... Eu utilizaria uma sintaxe bem mais simples, conforme o exemplo abaixo retirado do BOL:

    UPDATE dbo.Table2
    SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
    FROM dbo.Table2
        INNER JOIN dbo.Table1
        ON (dbo.Table2.ColA = dbo.Table1.ColA);

    Em todo o caso, você ainda pode fazer

    begin tran

    update....

    select na tabela para ver se o update foi ok.

    commit (ou rollback, se não atendenr sua necessidade)...


    Roberto Fonseca MCT / MCITP - Database Administrator 2008 MCITP - Database Developer 2008 MCITP - Business Intelligence 2008

    sexta-feira, 6 de dezembro de 2013 15:08
    Moderador
  • Claúdio,

    Além disso, para garantir ainda mais que os dados afetados são somente aqueles que estão declarados na sua Subquery eu faria uso da cláusula Where utilizando o mesmo Select que esta na SubQuery.


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    • Marcado como Resposta Cláudio Más sexta-feira, 6 de dezembro de 2013 15:47
    sexta-feira, 6 de dezembro de 2013 15:36
  • Claúdio,

    Concordo plenamente com o Roberto, eu particularmente gosto de fazer uso de Joins mesmo no Update, pois desta forma, você estará trabalhando somente a com a porção de dados que estão respeitando a condição imposta no Join, como também, o SQL Server terá uma plano de manutenção mais claro e simples para ser processado.


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    • Marcado como Resposta Cláudio Más sexta-feira, 6 de dezembro de 2013 15:53
    sexta-feira, 6 de dezembro de 2013 15:37

Todas as Respostas

  • Cláudio, a melhor forma de visualizar quais serão os registros afetados é executar todo o select e ver se ele está trazendo os registros corretos.

     (SELECT dbo.tb01_CadLeg.Resumo
          FROM dbo.tb01_CadLeg
    INNER JOIN
               (SELECT IdCadLeg, Resumo
    FROM dbo.EMPARP
                GROUP
    BY Resumo, IdCadLeg)
    AS a ON dbo.tb01_CadLeg.Resumo
    = a.Resumo
                WHERE
    (NOT (dbo.tb01_CadLeg.Id
    IN
                   
    (SELECT IdCadLeg FROM dbo.[Base Resumo])))

    Com relação a reversão, você usar uma transação para que caso seu update saia errado, você possa retornar os registros ao estado que se se encontravam antes da execução da query

    Exemplo:

    BEGIN TRANSATION

    Seu comando UPDATE

    Se a query foi executada com sucesso você pode confirmar a operação usando a palavra COMMIT, se após o update você identificou que houve alguma falha, você usa o ROLLBACK.

    http://msdn.microsoft.com/pt-br/library/ms188929.aspx


    sexta-feira, 6 de dezembro de 2013 15:08
  • Cláudio,

         Eu não utilizaria subqueries como você está fazendo... Eu utilizaria uma sintaxe bem mais simples, conforme o exemplo abaixo retirado do BOL:

    UPDATE dbo.Table2
    SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
    FROM dbo.Table2
        INNER JOIN dbo.Table1
        ON (dbo.Table2.ColA = dbo.Table1.ColA);

    Em todo o caso, você ainda pode fazer

    begin tran

    update....

    select na tabela para ver se o update foi ok.

    commit (ou rollback, se não atendenr sua necessidade)...


    Roberto Fonseca MCT / MCITP - Database Administrator 2008 MCITP - Database Developer 2008 MCITP - Business Intelligence 2008

    sexta-feira, 6 de dezembro de 2013 15:08
    Moderador
  • Ok, Guilherme.

    Obrigado

    sexta-feira, 6 de dezembro de 2013 15:35
  • Claúdio,

    Além disso, para garantir ainda mais que os dados afetados são somente aqueles que estão declarados na sua Subquery eu faria uso da cláusula Where utilizando o mesmo Select que esta na SubQuery.


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    • Marcado como Resposta Cláudio Más sexta-feira, 6 de dezembro de 2013 15:47
    sexta-feira, 6 de dezembro de 2013 15:36
  • Roberto, entendo que poderia simplificar sem subqueries, mas o script será executado somente uma vez.

    Vou usar o begin tran/commit ou rollback.

    Obrigado.

    sexta-feira, 6 de dezembro de 2013 15:37
  • Claúdio,

    Concordo plenamente com o Roberto, eu particularmente gosto de fazer uso de Joins mesmo no Update, pois desta forma, você estará trabalhando somente a com a porção de dados que estão respeitando a condição imposta no Join, como também, o SQL Server terá uma plano de manutenção mais claro e simples para ser processado.


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    • Marcado como Resposta Cláudio Más sexta-feira, 6 de dezembro de 2013 15:53
    sexta-feira, 6 de dezembro de 2013 15:37
  • Junior,

    Vou tentar assim, porque a quantidade de registros afetados foi maior do que o resultado do select, o que foi resolvido com o rollback.

    Obrigado

    sexta-feira, 6 de dezembro de 2013 15:47