0

During investigation of a bug in our project I came across some strange to me behaviour. Check the code:

--CREATE TYPE dbo.test AS TABLE(DocumentVersionId INT, ResourceId INT, Deadline DATE)

DECLARE @documents dbo.test
DECLARE @resourceId INT

INSERT INTO @documents(DocumentVersionId, ResourceId, Deadline)
SELECT * FROM (VALUES(1, 1, GETDATE()),(2, 2, GETDATE()),(3, 3, GETDATE())) T(A, B, C)

DECLARE mails CURSOR FAST_FORWARD FOR
SELECT DISTINCT ResourceId 
FROM @documents

OPEN mails

FETCH NEXT FROM mails INTO @resourceId

WHILE @@FETCH_STATUS = 0
BEGIN
    DECLARE @docs dbo.test

    --DELETE FROM @docs

    INSERT INTO @docs(DocumentVersionId, Deadline)
    SELECT DocumentVersionId, Deadline
    FROM @documents
    WHERE ResourceId = @resourceId

    SELECT * FROM @docs

    FETCH NEXT FROM mails INTO @resourceId
END

CLOSE mails
DEALLOCATE mails

We have procedure that generate mails for data transfered by TVP. Each execution of this procedure must be executed in a loop(cursor) for filtered data. The problem is that, on each loop iteration, the @docs variable contains data from previous iterations even when the variable is recreating each time.

We can delete data from this variable each time, but this is not the behaviour we expect. The question is, why is that happening?

enter image description here

2
  • You assume that @docs has local scope. Are you sure that is indeed correct? Commented Feb 23, 2016 at 13:16
  • It's a bit strange to me that it does not raise "variable already defined" at compile time... Commented Feb 23, 2016 at 15:01

1 Answer 1

1

Variables do not have local scope. From the docs:

The scope of a variable is the range of Transact-SQL statements that can reference the variable. The scope of a variable lasts from the point it is declared until the end of the batch or stored procedure in which it is declared.

Which means that @docs is in scope from the first loop iteration until the procedure terminates. This is more-or-less how scope worked in VB6 and it did create some ... interesting scoping issues.

You'll have to call DELETE FROM @docs; in each iteration to clear it

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.