Inquiridor
GOTO while

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 0Fiz 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?
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.
- Sugerido como Resposta Junior Galvão - MVPMVP sexta-feira, 7 de junho de 2013 14:49
-
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?
-
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.
- Sugerido como Resposta Junior Galvão - MVPMVP sexta-feira, 7 de junho de 2013 14:50
-
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]