I clearly misunderstand the difference between a batch and a session. I believe three things that cannot all be true at the same time:
- It is very well known that table variable only have the scope of their batch.
- The documentation reports, I believe correctly, that
GOmarks the end of a batch. - The following script does not throw an error, even though
@tshould be out of scope
declare @t table (id int)
insert into @t values (1)
select * from @t
GO
select * from @t
Clearly I am mistaken about something, but what?
GOis 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
goin some cases. Actually, in this specific case, it seems to be ignoring the carriage return beforegoand applying it as an alias to@tin the preceding line, as Martin suggested, like this: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):There are other examples where
gowill definitely cause errors. For example: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.