Is there a way to loop through a table variable in TSQL without using a cursor? Is there a way to loop through a table variable in TSQL without using a cursor? sql-server sql-server

Is there a way to loop through a table variable in TSQL without using a cursor?


First of all you should be absolutely sure you need to iterate through each row — set based operations will perform faster in every case I can think of and will normally use simpler code.

Depending on your data it may be possible to loop using just SELECT statements as shown below:

Declare @Id intWhile (Select Count(*) From ATable Where Processed = 0) > 0Begin    Select Top 1 @Id = Id From ATable Where Processed = 0    --Do some processing here    Update ATable Set Processed = 1 Where Id = @Id End

Another alternative is to use a temporary table:

Select *Into   #TempFrom   ATableDeclare @Id intWhile (Select Count(*) From #Temp) > 0Begin    Select Top 1 @Id = Id From #Temp    --Do some processing here    Delete #Temp Where Id = @IdEnd

The option you should choose really depends on the structure and volume of your data.

Note: If you are using SQL Server you would be better served using:

WHILE EXISTS(SELECT * FROM #Temp)

Using COUNT will have to touch every single row in the table, the EXISTS only needs to touch the first one (see Josef's answer below).


Just a quick note, if you are using SQL Server (2008 and above), the examples that have:

While (Select Count(*) From #Temp) > 0

Would be better served with

While EXISTS(SELECT * From #Temp)

The Count will have to touch every single row in the table, the EXISTS only needs to touch the first one.


This is how I do it:

declare @RowNum int, @CustId nchar(5), @Name1 nchar(25)select @CustId=MAX(USERID) FROM UserIDs     --start with the highest IDSelect @RowNum = Count(*) From UserIDs      --get total number of recordsWHILE @RowNum > 0                          --loop until no more recordsBEGIN       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 countEND

No Cursors, no temporary tables, no extra columns.The USERID column must be a unique integer, as most Primary Keys are.