none
GOTO while RRS feed

  • Pergunta

  • Olá,

    Boa Tarde,

    Estou com o seguinte problema:

    Este script abaixo entra em loop infinito:

    use baseteste
    go
    SET ROWCOUNT 500
    update_more:

    Update table a

    set...

    from table a

    inner join table b

    on ...

    where...

    IF @@ROWCOUNT > 0 GOTO update_more
    SET ROWCOUNT 0

    Fiz conforme recomendação da microsoft.

    http://support.microsoft.com/kb/323630/pt-br

    Só que ao meu ver o goto não considera registros com = na clausula where portando ele entra em loop infinito.

    Porém se houver <> e a condição não for satisfeita ele encerra.

    Gostaria de validar melhor esta informação alguém pode me ajudar?

    quarta-feira, 5 de junho de 2013 17:06

Todas as Respostas

  • Boa tarde !

    Não costumo trabalhar muito com o GOTO, uma sugestão seria voce fazer um looping baseado nas mesmas condições de 500 em 500 e quando o @@rowcount for igual a zero parar, tente algo assim:

    use baseteste
     go
    
    Declare @i int
    set @i = 1
    while @i <> 0 
    begin
     SET ROWCOUNT 500
     update_more:
     
    
    
    Update table a 
    
    set...
     
    from table a
     
    inner join table b
     
    on ...
     
    where...
     
    set @i = @@ROWCOUNT
    end
    SET ROWCOUNT 0


    Alexandre Matayosi Conde Mauricio.

    quarta-feira, 5 de junho de 2013 17:32
  • Alexandre,

    Mais uma vez Obrigado por me ajudar!

    Seu script é mais performático pois pelo que vi no Plano de execução o GOTO utiliza um cursor internamente consumindo tempdb.

    Porém ele mantém em loop infinito também, pelo jeito tenho que colocar as colunas dos sets do update na clausula where dizendo que uma é diferente da outra.

    Ou seja ele não faz um fetch como os cursores.

    Tem ocorrido este comportamento de loop infinito no seu caso?

    quarta-feira, 5 de junho de 2013 18:54
  • No meu caso não, talvez por que não utilize da mesma forma utilizando o @@rowcount, o que faço normalmente quando tem que fazer como se fosse cursor 1 a 1 é antes de tudo verificar quantos registros a minha logica passará, a partir dai seto a variavel inicial com esse numero no exemplo que te passei seria o @i, rodo o processo fazendo somente 1 não como voce que é 500 e depois do processo só decremento a variavel @i = @i -1 no final quando chegar a zero vai sair do looping.

    No seu caso tem como colocar algum tipo de log em uma tabela para saber se esta travado no looping ou ainda esta fazendo ? pergunto isso pois acredito que o @@rowcount não esta chegando a zero e por isso continua no looping.


    Alexandre Matayosi Conde Mauricio.

    quarta-feira, 5 de junho de 2013 19:13
  • Alexandre,

    Concordo plenamente com você, para termos uma controle de Loop através do While eu também tenho esta prática de definir o limitador de contagem e registros que serão processados.

    Maumauboy,

    Veja este exemplo do uso de Goto com While:

    DECLARE @Counter int;
    SET @Counter = 1;
    WHILE @Counter < 10
    BEGIN 
        SELECT @Counter
        SET @Counter = @Counter + 1
        IF @Counter = 4 GOTO Branch_One --Jumps to the first branch.
        IF @Counter = 5 GOTO Branch_Two  --This will never execute.
    END
    Branch_One:
        SELECT 'Jumping To Branch One.'
        GOTO Branch_Three; --This will prevent Branch_Two from executing.
    Branch_Two:
        SELECT 'Jumping To Branch Two.'
    Branch_Three:
        SELECT 'Jumping To Branch Three.'
    

    Em relação ao plano de execução, como o Goto é uma técnica de desvio de fluxo de execução de processamento, na verdade ele trabalha em segundo plano ou processos temporários, fazendo uso do TEMPDB para possibilitar o desvio.

    Outro detalhe que por padrão ao usar o comando GOTO toda estimativa de plano de execução é praticamente descartada por parte do Query Optimizer, pois o GOTO não permite ser utilizada como um recurso aninhado.


    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]

    sexta-feira, 7 de junho de 2013 14:57