2012-09-10 14 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 

私は唯一のテーブル変数@tempTableはカーソル反復間の範囲に保たれているようです

someValue 
ID5_ASDF 

が見込まhaved - しかし、どのように各繰り返しで変数を再宣言することが可能ですか?私には分かりません。

私は、各反復で

delete @tempTable 

ことによってそれを解決 - も、それはまだスコープ内にあることについての私の仮定をバックアップします。

誰でもこの動作を説明できますか?

答えて

5

はい、それはない - 範囲がbegin/end文が、ストアドプロシージャの終了によって、またはTで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

変数宣言によって定義されていません-SQLは、奇妙な獣のビットです - 変数の宣言を無視する制御フロー。

これはエラーを生成します。

set @a = 2 

これは問題なく実行され、「絶対に」印刷されません。

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

変数の寿命は宣言の時点からまでですバッチが完了しました。

+0

ha、strange。私はそれが私のような何かを表示するときに同じ変数を2回宣言することが可能であるかどうかについて私が疑問に思う理由はないと思う:) – zmaster

+0

@ zmaster - 宣言は制御フローを無視するので、ループやカーソルの中に入れます。そうした場合、エラーが発生し、ループの内部で変数を宣言することはできません。同じ変数名を持つ2つの宣言文を明示的に使用していた場合、ループ内にあるかどうかにかかわらずエラーが発生します。 – JeffO