Search code examples
sql-servert-sqltable-variable

If table variables only have the scope of their batch, then why can I select from one after using GO?


I clearly misunderstand the difference between a batch and a session. I believe three things that cannot all be true at the same time:

  1. It is very well known that table variable only have the scope of their batch.
  2. The documentation reports, I believe correctly, that GO marks the end of a batch.
  3. The following script does not throw an error, even though @t should be out of scope
declare @t table (id int)
insert into @t values (1)
select * from @t
GO
select * from @t

DB fiddle link.

Clearly I am mistaken about something, but what?


Solution

  • GO is a batch separator known to SSMS. If you try the first script block from your fiddle in SSMS, it will fail - as expected.

    This seems to be a symptom of db<>fiddle ignoring go in some cases. Actually, in this specific case, it seems to be ignoring the carriage return before go and applying it as an alias to @t in the preceding line, as Martin suggested, like this:

    declare @t table (id int);
    insert into @t values (1);
    select go.* from @t as go;
    select * from @t;
    

    This is simply because db<>fiddle uses separate input areas, not GO, to separate batches. In fact your script fails by adding a single character (properly terminating the insert):

    declare @t table (id int)
    insert into @t values (1)
    select * from @t;
    ----------------^
    go
    select * from @t
    

    There are other examples where go will definitely cause errors. For example:

    create table #t(id int);
    go
    select * from #t;
    

    There are a lot of limitations and behavior differences between the database engine, the supported tools that ship for SQL Server, and online tools like db<>fiddle. If you're trying to confirm what the documentation says, please use the supported tooling against supported versions of SQL Server, and always terminate statements with statement terminators to minimize surprises. Online emulators are useful for demonstrating syntax but not for validating documented behavior.