The following query is a contrived example that demonstrates a bug I found in a stored procedure this week.
CREATE TABLE #temp
(
ID int IDENTITY(1,1),
Value char(1)
)
INSERT INTO #temp(Value) Values('a')
INSERT INTO #temp(Value) Values('b')
INSERT INTO #temp(Value) Values('c')
INSERT INTO #temp(Value) Values('d')
DECLARE
@i int,
@ID int,
@Count int,
@Value char(1)
SELECT @Count = COUNT(*) FROM #temp
SET @i = 1
SET @ID = 2
WHILE @i < @Count
BEGIN
SELECT
@ID = ID,
@Value = (SELECT Value FROM #temp WHERE ID = @ID)
FROM
#temp
WHERE
@i = ID
PRINT @Value
SET @i = @i + 1
END
At first glance the output should be a b c d but it isn’t! It’s b b c d. So the order of execution within a statement is not what we might assume it to be.
Is there a specific order of execution that can be relied on?
The WHERE clause in the line
is uncorrelated with the WHERE clause here
So, 1st loop
b2nd loop
a3rd loop
bThen it stops because of
@i < @countSQL has no “order of execution” as such because it’s declarative. The SELECT clause is evalauted in one go, there is no expectation that says @ID will be assigned before it uses on the next line.