table variable declaration inside a loop

  • But you still can't use a variable before you declare it...

    This 'logic' makes my head hurt.

  • Xavon (7/30/2014)


    But you still can't use a variable before you declare it...

    This 'logic' makes my head hurt.

    When that error is picked up, its actually checking to see if its defined, remember the source code is still being translated into a form the computer will actually read from when executing. Some interpreters start executing immediately, I'm hazarding a guess that SQL Server doesn't!

    http://en.wikipedia.org/wiki/Translator_(computing)

    http://en.wikipedia.org/wiki/Compiler probably a better article

  • patrickmcginnis59 10839 (7/30/2014)


    Xavon (7/30/2014)


    But you still can't use a variable before you declare it...

    This 'logic' makes my head hurt.

    When that error is picked up, its actually checking to see if its defined, remember the source code is still being translated into a form the computer will actually read from when executing. Some interpreters start executing immediately, I'm hazarding a guess that SQL Server doesn't!

    http://en.wikipedia.org/wiki/Translator_(computing)

    Oh I get it. Still gives me a headache.

  • Xavon (7/30/2014)


    patrickmcginnis59 10839 (7/30/2014)


    Xavon (7/30/2014)


    But you still can't use a variable before you declare it...

    This 'logic' makes my head hurt.

    When that error is picked up, its actually checking to see if its defined, remember the source code is still being translated into a form the computer will actually read from when executing. Some interpreters start executing immediately, I'm hazarding a guess that SQL Server doesn't!

    http://en.wikipedia.org/wiki/Translator_(computing)

    Oh I get it. Still gives me a headache.

    Oh, sorry about that! More appropriate link then:

    http://en.wikipedia.org/wiki/Tylenol

  • patrickmcginnis59 10839 (7/30/2014)


    Some interpreters start executing immediately, I'm hazarding a guess that SQL Server doesn't!

    Correct. SQL Server will parse and compile the entire batch (and the compiling part includes generating execution plans for all queries), and only start executing when the compilation is done.

    (And then, during execution, some conditions may trigger a recompilation of specific statements - if there are reasons to believe that intermittent changes may result in poor performance of the original execution plan)


    Hugo Kornelis, SQL Server/Data Platform MVP (2006-2016)
    Visit my SQL Server blog: https://sqlserverfast.com/blog/
    SQL Server Execution Plan Reference: https://sqlserverfast.com/epr/

  • Nice question, Sreepathi, thanks!

  • Thanks for the question. I've never given much thought to the topic, so it's been good to dig around and learn something new. Thanks to everyone who added to the discussion on this topic.



    Everything is awesome!

  • Nice - thanks, Sreepathi!

  • Xavon (7/30/2014)


    patrickmcginnis59 10839 (7/30/2014)


    Xavon (7/30/2014)


    But you still can't use a variable before you declare it...

    This 'logic' makes my head hurt.

    When that error is picked up, its actually checking to see if its defined, remember the source code is still being translated into a form the computer will actually read from when executing. Some interpreters start executing immediately, I'm hazarding a guess that SQL Server doesn't!

    http://en.wikipedia.org/wiki/Translator_(computing)

    Oh I get it. Still gives me a headache.

    Maybe this will help your headache (to get worse :hehe:)

    GOTO Loop

    Declaration:

    PRINT 'DECLARE @i'

    DECLARE @i INT = 1

    GOTO Finish

    Loop:

    PRINT 'Loop'

    WHILE @i < 10 -- While loop will not be entered. Can you guess why?

    BEGIN

    PRINT 'DECLARE @j-2'

    DECLARE @j-2 AS TABLE

    (

    i INT

    )

    SET @i = @i + 1

    INSERT INTO @j-2

    SELECT @i

    END

    GOTO Declaration

    Finish:

    PRINT 'Finish'

    SELECT * FROM @j-2

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2
  • Nice question, correct answer, appallingly wrong explanation.

    The reason this works is nothing to do with scope (which isn't the batch unless the declaration is the first statement in the batch, so the explanation was wrong on that too).

    The reason that it works is that all declarations are executed when the batch is parsed (so that the parser can know what variables are in scope and what their types are at every point in the source code without requiring multiple passes), they are not exectuted at run time, so being in the body of a loop doesn't mean the declaration gets executed each time round a loop.

    Its important to note that something like declare @i int = @j-2*@k;is not a declaration, it's not even a single statement, it stands for the two statementsdeclare @i int;

    set @i=@j*@k;which are a declaration and an assignment; if it occurrs in the body of a loop, the declaration is executed once (at parse time) but the assignment is executed every time round the loop (which might be never).

    edit: (spoiler:) and Luis' post above gives a perfect example of the "never" case.

    edit; fix []s

    Tom

  • Good question

    -Vijred (http://vijredblog.wordpress.com)

  • Nice one

    Thanks

  • TomThomson (7/30/2014)


    Nice question, correct answer, appallingly wrong explanation.

    The reason this works is nothing to do with scope (which isn't the batch unless the declaration is the first statement in the batch, so the explanation was wrong on that too).

    The reason that it works is that all declarations are executed when the batch is parsed (so that the parser can know what variables are in scope and what their types are at every point in the source code without requiring multiple passes), they are not exectuted at run time, so being in the body of a loop doesn't mean the declaration gets executed each time round a loop.

    Its important to note that something like declare @i int = @j-2*@k;is not a declaration, it's not even a single statement, it stands for the two statementsdeclare @i int;

    set @i=@j*@k;which are a declaration and an assignment; if it occurrs in the body of a loop, the declaration is executed once (at parse time) but the assignment is executed every time round the loop (which might be never).

    Hi Tom , that sounds interesting , I wander if this is documented somewhere.

    I based my answer on the feeling that table variables might work somehow as temporary tables so not necessary dependent of the scope of the loop. I also have to admit I have not checked the docs on this so I was lucky to answer correctly.

    But now I am curious how table vars are implemented.

    Cheers,

    Iulian

  • Iulian -207023 (8/6/2014)


    Hi Tom , that sounds interesting , I wander if this is documented somewhere.

    I don't think it's documented. And of course it's slightly more complicated than that, because the scoping rules are somewhat screwed up for commas separated declarations like declare @i int - 7, @j-2 int = @i*3 ; in that none of the variables declared in any of the comma separated declarations is in scope on the RHS of any of the associated comma separated assignments, so my example will complain that @i does not exist when it parses the second declaration and assignment.

    I guess the best way of seeing how table variables work will be to run declarations and assignments one statement at a time and look in tempdb to see what is happening. A good rule of thumb is don't believe what you see in blogs about table variables unless you know that the author is someone you can trust (like one of sqlkiwi, gilamonster, sqlrnnr, jeff moden) because there are a lot of popular myths about them.

    Tom

Viewing 14 posts - 16 through 28 (of 28 total)

You must be logged in to reply to this topic. Login to reply