2012-09-10 61 views
5

如果我在MS SQL 2008 R2中運行以下代碼,則會得到意外的結果。SQL遊標中表變量的範圍

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 

我haved預計只看到

someValue 
ID5_ASDF 

看來,表變量@tempTable保持在光標迭代之間的範圍 - 但那麼如何在每次迭代中重新聲明變量呢?對我沒有意義。這也備份我的假設它仍然在保護範圍 -

我在每次迭代中解決它通過

delete @tempTable 

任何人都可以解釋這種行爲嗎?

回答

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

+1

謝謝 - 但是如何在每次迭代中再次聲明變量?公主, – zmaster

2

聲明變量T中定義的,但由存儲過程的結束時,或-SQL有點怪獸 - 變量聲明忽略控制流。

這將產生一個錯誤:

set @a = 2 

此運行沒有問題,不打印「從不」:

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

變量的生存期是從聲明的時候,直到批量完成。

+0

哈,奇怪。我認爲我沒有理由想知道當你向我展示類似的東西時,如何在遊標中聲明相同的變量兩次如何:) – zmaster

+0

@zmaster - 因爲聲明忽略控制流,所以聲明不會超過一旦進入任何循環或遊標。如果他們這樣做了,你會得到一個錯誤,並且不允許在循環中聲明一個變量。如果你顯式地使用了兩個具有相同變量名的聲明語句,那麼無論它們是否在循環中,你都會得到一個錯誤。 – JeffO