【问题标题】:Scope of table variable within SQL cursorSQL游标内表变量的范围
【发布时间】:2012-09-03 02:55:37
【问题描述】:

如果我在 MS SQL 2008 R2 中运行以下命令,我会得到意想不到的结果。

create table #DataTable (someID varchar(5))
insert into #DataTable 
values ('ID1'),('ID2'),('ID3'),('ID4'),('ID5')

declare @data varchar(8);

declare myCursor cursor for
select someID from #DataTable

open myCursor
FETCH NEXT FROM myCursor INTO
@data

WHILE(@@Fetch_Status >=0)
BEGIN 

    declare @tempTable table (someValue varchar(10))

    insert into @tempTable select @data + '_ASDF'
    select * from @tempTable    

FETCH NEXT FROM myCursor INTO
@data

END

close myCursor
deallocate myCursor

drop table #DataTable

上一次迭代的结果:

someValue
ID1_ASDF
ID2_ASDF
ID3_ASDF
ID4_ASDF
ID5_ASDF

我本以为只是看到

someValue
ID5_ASDF

似乎表变量@tempTable 在游标迭代之间保持在范围内 - 但是如何在每次迭代中重新声明变量?对我来说毫无意义。

我解决了

delete @tempTable

在每次迭代中 - 这也支持了我关于它仍在范围内的假设。

谁能解释这种行为?

【问题讨论】:

    标签: sql cursor scope temp-tables table-variable


    【解决方案1】:

    T-SQL 中的变量声明有点奇怪——变量声明忽略控制流。

    这会产生错误:

    set @a = 2
    

    这运行没有问题,并且不打印“从不”:

    if 1=0
    begin
        print 'Never'
        declare @a int
    end
    set @a = 2
    

    变量的生命周期是从声明点到批处理完成。

    【讨论】:

    • 哈,奇怪。我认为当您向我展示类似的内容时,我没有理由怀疑如何在游标中两次声明相同的变量:)
    • @zmaster - 由于声明忽略控制流,它们不会在任何循环或游标中多次声明。如果他们这样做了,你会得到一个错误,并且不允许在循环内声明一个变量。如果你明确地有两个具有相同变量名的声明语句,那么无论它们是否在循环中,你都会得到一个错误。
    【解决方案2】:

    是的,确实如此 - 范围不是由 begin / end 语句定义的,而是由存储过程的结尾或 go 定义的

    变量的范围是 Transact-SQL 语句的范围 可以引用变量。变量的范围从 点它声明直到批处理或存储过程结束 它被宣布。

    http://msdn.microsoft.com/en-us/library/ms187953(v=sql.105).aspx

    【讨论】:

    • 谢谢 - 但是如何在每次迭代中再次声明变量?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 2021-10-04
    相关资源
    最近更新 更多