Your issue must be that at some point your SELECT statement doesn't find any value and doesn't assign anything new to your @catID variable and it keeps exactly the same as it was in previous loop. As a result - you never exit your while statement.
Code snippet to explain that:
DECLARE @catID INT = 5; DECLARE @Test TABLE ( CategoryID INT ); /** * Notice that I do not insert into table intentionally, * so that following query doesn't assign anything * to @catID variable */ SELECT TOP (1) @catID = CategoryID FROM @Test; SELECT @catID AS [@catID];
Result:
@catID ----------- 5
This query returns 5, and not NULL as you would expect.
Assigning value using subquery will either assign an actual value or NULL if nothing's found, that means when there's no category higher than @catID it will become NULL and your query will escape loop.
DECLARE @catID INT; SET @catID = ( SELECT TOP (1) CategoryID FROM Production.Categories ORDER BY CategoryID ); WHILE @catID IS NOT NULL BEGIN PRINT @catID; SET @catID = ( SELECT TOP (1) CategoryID FROM Production.Categories WHERE CategoryID > @catID ORDER BY CategoryID ); END