I was recently debugging a problem in a Stored Procedure where the wrong values where inserted into a table, in the middle of a long running cursor operation.
The culprit turned out to be the scope of a variable in SQL versus the scope most (object orientated) developers are used to in the language they usually code in.
The problem can be illustrated with this syntax:
DECLARE @Counter INT = 1
WHILE @Counter < 5 BEGIN
DECLARE @Var VARCHAR(MAX)
IF @Counter = 2
SET @Var = ‘SomeValue’
SELECT @Var
SET @Counter += 1
END
The way scope works for variables in T-SQL is “batch scope”, whereas most OO developers are used to the scope being limited within the innermost context.
The way it functions in SQL is that in the first iteration of the while loop the variable “@Var” gets declared but not assigned a value.
Thus, when selecting it out, the result will be NULL.
However in the second iteration, the variable is already declared once, so SQL Server will not “recreate” it, because the scope is “batch scope”.
So here it’ll just be assigned the value “SomeValue”.
The third iteration is like the second. The variable is already declared, and because it in the previous iteration had the value set to “SomeValue”, that value will persist in this iteration, and all subsequent iterations until another value is set.
This is a source of errors if not careful, because the object orientated developer will – if not aware of this – most likely read the above as only iteration 2 will contain the value “SomeValue”, whereas all other iterations will contain NULL.
But because of the batch scope, it is not so.
As the result from the query shows:


