Как мне избежать использования курсоров в Sybase (T-SQL)?

StackOverflow https://stackoverflow.com/questions/14577

  •  08-06-2019
  •  | 
  •  

Вопрос

Представьте себе сцену: вы обновляете какой-то устаревший код Sybase и натыкаетесь на курсор.Хранимая процедура создает результирующий набор в таблице #temporary, которая полностью готова к возврату, за исключением того, что один из столбцов не очень удобочитаем для человека, это буквенно-цифровой код.

Что нам нужно сделать, так это выяснить возможные различные значения этого кода, вызвать другую хранимую процедуру для перекрестной ссылки на эти скрытые значения, а затем обновить результирующий набор новыми расшифрованными значениями:

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

Это было полезно?

Решение

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

Другие советы

Если вы не хотите дублировать код во внешней ссылке proc, нет никакого способа избежать использования курсора.

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

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top