Область действия табличной переменной внутри курсора SQL

Если я запускаю ниже в 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

в каждой итерации - что также подтверждает мое предположение о том, что он все еще находится в области видимости.

Кто-нибудь может объяснить это поведение?

2 ответа

Решение

Да, это так - объем не определяется begin / end заявления, но к концу хранимой процедуры, или go

Область действия переменной - это диапазон операторов Transact-SQL, которые могут ссылаться на переменную. Область действия переменной длится с момента ее объявления до конца пакета или хранимой процедуры, в которой она объявлена.

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

Объявления переменных в T-SQL являются чем-то вроде странного зверя - объявления переменных игнорируют поток управления.

Это приводит к ошибке:

set @a = 2

Это работает без проблем и не выдает "Никогда":

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

Время жизни переменной - от момента объявления до завершения пакета.

Другие вопросы по тегам