5

如果我在 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

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

谁能解释这种行为?

4

2 回答 2

5

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

The scope of a variable is the range of Transact-SQL statements that can reference the variable. The scope of a variable lasts from the point it is declared until the end of the batch or stored procedure in which it is declared.

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

于 2012-09-10T09:06:08.057 回答
2

Variable declarations in T-SQL are a bit of an odd beast - variable declarations ignore control flow.

This produces an error:

set @a = 2

This runs without issue, and doesn't print "Never":

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

The lifetime of a variable is from the point of declaration until the batch completes.

于 2012-09-10T09:34:31.153 回答