Как избежать использования курсоров в Sybase (T-SQL)? - PullRequest
2 голосов
/ 18 августа 2008

Представьте себе сцену, вы обновляете какой-то унаследованный код 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: для целей этого примера вы также можете представить, что набор результатов находится в области 500 000 строк и что существует 100 различных значений look_up_code и, наконец, что невозможно получить таблицу с внешней ссылкой значения в качестве логики в proc_code_xref слишком загадочны ._

Ответы [ 3 ]

1 голос
/ 18 августа 2008

Вам нужно иметь таблицу XRef, если вы хотите убрать курсор. Предполагая, что вы знаете 100 различных значений поиска (и что они являются статическими), легко сгенерировать одно, вызвав proc_code_xref 100 раз и вставив результаты в таблицу

1 голос
/ 18 августа 2008

Если вы не хотите дублировать код в процедуре xref, невозможно избежать использования курсора.

0 голосов
/ 12 июня 2009

Говорят, что если вы должны использовать курсор, значит, вы сделали что-то не так ;-) вот решение без курсора:

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
...