Трюк с курсором

добавлено: 10 май 12
понравилось:0
просмотров: 1868
комментов: 6

теги:

Автор: Sergey Zenzinov

Баловство, конечно, но мне кажется, имеет право на существование

В Oracle есть замечательные типы данных %ROWTYPE. В переменную такого типа можно вытаскивать данные из курсора легко и просто. К сожалению, в MSSQL подобного нет, и для каждой колонки необходимо сначала объявить переменную, затем указать ее в инструкции fetch. Если колонок много, то и без того не самая приятная работа с курсором становится еще хуже :)

Почему бы не считать данные в таблицу? Напрямую, разумеется, не получится - синтаксис не позволит, но это легко обходится.

declare @cur cursor;

set @cur = cursor
for
select 1
union all
select 2;

open @cur;

declare @table table (id int);

while 1 = 1
begin

	insert into @table 
	exec sp_executesql N'fetch next from @cur', N'@cur cursor', @cur;

	if @@fetch_status <> 0
		break;

end;

close @cur;
deallocate @cur;

select * from @table;

Комментарии


  • 11 мая 2012, 13:00 Александр Гладченко

    В MSSQL использование курсоров - дурной тон :)))

  • 11 мая 2012, 13:06 Sergey Zenzinov

    Разумеется, но иногда без них не обойтись, а иногда с ними таки быстрее работает. Хотя Вы и сами это прекрасно знаете, я думаю :)

  • 12 мая 2012, 09:52 SIMPLicity_

    Совсем не понял...
    А если так:
    select top 10 *
    into #tmp_table
    from syscolumns
    where length > 10;
    -- И теперь позырим чо набрали в табло:
    select * from #tmp_table
    PS Вообще нафик из курсора сначала кидать в табличную переменную что бы затем всё разом обработать?!
    PPS Изините, если чонитак...

  • 12 мая 2012, 10:06 Sergey Zenzinov

    Пару лет назад, когда я это придумал, пришлось работать с курсором колонок на 100-200, из которых в действительности нам нужны были только 5 или 6 полей. Переписывать все это, разумеется, не хотелось - код не наш был, надо было добавить пару полей. Далее с нужными колонками проводились какие-то расчеты, и потом вся куча колонок вставлялась в другую таблицу.

    мне показалось намного проще сначала сделать таблицу как select top (0) * into #row from source_table, потом выбрать из нее нужные поля, проапдейтить #row и дальше вставить куда надо. Смысла во вставке в таблицу из курсора и дальнейшей обработке именно таблицей, разумеется, нет. На каждой итерации таблица должна очищаться, чтобы всегда была одна строка

  • Почему надо извращаться с курсором, если можно сразу
    declare @table table (id int);
    insert @table(id)
    select 1
    union all
    select 2;
    ?????

  • 04 апреля 2013, 11:12 Sergey Zenzinov

    1. Там в комментарии выше написано :)
    2. Это все-таки баловство, т.е. я так делать не стал в коде, хотя мне кажется немного проще.



Необходимо войти на сайт, чтобы оставлять комментарии