Представьте себе сцену, вы обновляете какой-то устаревший код Sybase и натолкнетесь на курсор. Хранимая процедура создает результирующий набор в таблице #tevent, которая готова к возврату, за исключением того, что один из столбцов не очень удобен для чтения человеком, это буквенно-цифровой код.
Что нам нужно сделать, так это выяснить возможные различные значения этого кода, вызвать другую хранимую процедуру для перекрестной ссылки на эти дискретные значения и затем обновить результирующий набор новыми расшифрованными значениями:
declare c_lookup_codes for
select distinct lookup_code
from #workinprogress
while(1=1)
begin
fetch c_lookup_codes into @lookup_code
if @@sqlstatus<>0
begin
break
end
exec proc_code_xref @lookup_code @xref_code OUTPUT
update #workinprogress
set xref = @xref_code
where lookup_code = @lookup_code
end
Теперь, хотя это может вызвать у некоторых учащенное сердцебиение, оно работает. Мой вопрос: как лучше всего избегать такого рода вещей?
_NB: для целей этого примера вы также можете представить, что результирующий набор находится в области 500k строк и что есть 100 различных значений look_up_code и, наконец, что невозможно иметь таблицу со значениями внешних ссылок в виде логика в proc_code_xref слишком загадочная.
Вы должны иметь таблицу XRef, если вы хотите убрать курсор. Предполагая, что вы знаете 100 различных значений поиска (и что они являются статическими), легко сгенерировать одно, вызвав proc_code_xref 100 раз и вставив результаты в таблицу.
Если вы не хотите дублировать код в процедуре xref, вы не сможете избежать использования курсора.
Говорят, что если вы должны использовать курсор, значит, вы сделали что-то не так ;-) вот решение без курсора:
declare @lookup_code char(8)
select distinct lookup_code
into #lookup_codes
from #workinprogress
while 1=1
begin
select @lookup_code = lookup_code from #lookup_codes
if @@rowcount = 0 break
exec proc_code_xref @lookup_code @xref_code OUTPUT
delete #lookup_codes
where lookup_code = @lookup_code
end