Solución:
En primer lugar, debe estar absolutamente seguro de que necesita iterar a través de cada fila: las operaciones basadas en conjuntos se realizarán más rápido en todos los casos que se me ocurran y normalmente usarán un código más simple.
Dependiendo de sus datos, puede ser posible realizar un bucle usando solo SELECT
declaraciones como se muestra a continuación:
Declare @Id int
While (Select Count(*) From ATable Where Processed = 0) > 0
Begin
Select Top 1 @Id = Id From ATable Where Processed = 0
--Do some processing here
Update ATable Set Processed = 1 Where Id = @Id
End
Otra alternativa es utilizar una tabla temporal:
Select *
Into #Temp
From ATable
Declare @Id int
While (Select Count(*) From #Temp) > 0
Begin
Select Top 1 @Id = Id From #Temp
--Do some processing here
Delete #Temp Where Id = @Id
End
La opción que debe elegir realmente depende de la estructura y el volumen de sus datos.
Nota: Si está utilizando SQL Server, sería mejor que utilizara:
WHILE EXISTS(SELECT * FROM #Temp)
Utilizando COUNT
tendrá que tocar cada fila de la tabla, el EXISTS
solo necesita tocar el primero (ver la respuesta de Josef a continuación).
Solo una nota rápida, si está utilizando SQL Server (2008 y superior), los ejemplos que tienen:
While (Select Count(*) From #Temp) > 0
Sería mejor servido con
While EXISTS(SELECT * From #Temp)
El Conde tendrá que tocar cada fila de la tabla, el EXISTS
solo necesita tocar el primero.
Así es como lo hago:
declare @RowNum int, @CustId nchar(5), @Name1 nchar(25)
select @CustId=MAX(USERID) FROM UserIDs --start with the highest ID
Select @RowNum = Count(*) From UserIDs --get total number of records
WHILE @RowNum > 0 --loop until no more records
BEGIN
select @Name1 = username1 from UserIDs where USERID= @CustID --get other info from that row
print cast(@RowNum as char(12)) + ' ' + @CustId + ' ' + @Name1 --do whatever
select top 1 @CustId=USERID from UserIDs where USERID < @CustID order by USERID desc--get the next one
set @RowNum = @RowNum - 1 --decrease count
END
Sin cursores, sin tablas temporales, sin columnas adicionales. La columna USERID debe ser un número entero único, como lo son la mayoría de las claves primarias.