代码之家  ›  专栏  ›  技术社区  ›  J. Mini

如果表变量只有其批处理的范围,那么为什么我可以在使用GO后从中进行选择?

  •  0
  • J. Mini  · 技术社区  · 2 年前

    我显然误解了批处理和会话之间的区别。我相信三件事不可能同时都是真的:

    1. 众所周知,表变量只有其批处理的作用域。
    2. 文件报告,我认为是正确的 GO marks the end of a batch
    3. 以下脚本不会抛出错误,即使 @t 应该超出范围
    declare @t table (id int)
    insert into @t values (1)
    select * from @t
    GO
    select * from @t
    

    DB fiddle link

    很明显,我在某些事情上错了,但怎么了?

    1 回复  |  直到 2 年前
        1
  •  7
  •   Aaron Bertrand    2 年前

    GO 是SSMS已知的批次分离器。如果您在SSMS中尝试小提琴中的第一个脚本块, it will fail - as expected

    这似乎是db<>小提琴忽略 go 在某些情况下 。实际上,在这种特定情况下,它似乎忽略了回车 之前 并将其作为别名应用于 @t 正如马丁所建议的, like this :

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

    这仅仅是因为db<>fiddle使用单独的输入区域,而不是 ,以分离批次。事实上,您的脚本失败了 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
    

    还有其他例子 肯定会造成错误。 For example :

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

    数据库引擎(SQL Server支持的工具)和在线工具(如db<>不停摆弄如果您试图确认文档中所说的内容,请针对SQL Server的支持版本使用支持的工具,并且 always terminate statements with statement terminators 以尽量减少意外。在线仿真器对于演示语法很有用,但对于验证记录的行为却不有用。

    推荐文章