Как сделать вложенный курсор в sybase ase

Могу я спросить, как правильно сделать вложенный курсор в sybase? Я получаю две ошибки в моем коде ниже.

  1. Необходимо объявить переменную @notes
  2. Объявление курсора должно быть единственным оператором в пакете запросов.

Текущая попытка кодирования:

DECLARE c3 cursor FOR
select distinct cust_ac_no from tempdb..M3_SHP_ACCOUNT_NOTES
where cust_ac_no in ('851243048')
--,'851261620
--order by cust_ac_no, inst_seq_no, ord_no, ref_no, acv_no
GO

DECLARE 
@exec_str1 varchar(8000),
@exec_str2 varchar(8000),
@cust_ac_no varchar(10),
@c_ac varchar(10),
@notes varchar(4000),
@notes2 varchar(8000)

--select @exec_str1 = "select distinct notes from tempdb..M3_SHP_ACCOUNT_NOTES where cust_ac_no = "

OPEN c3
FETCH c3 into @cust_ac_no

WHILE @@sqlstatus = 0

  BEGIN

  DECLARE c2 cursor FOR
  select distinct notes from tempdb..M3_SHP_ACCOUNT_NOTES
  where cust_ac_no = + "'" + @cust_ac_no + "'"
  order by cust_ac_no, inst_seq_no, ord_no, ref_no, acv_no
  GO


  OPEN c2
  FETCH c2 into @notes

  WHILE @@sqlstatus = 0
  BEGIN

  print @notes

  FETCH c2 into @notes  
  END
  CLOSE c2
  DEALLOCATE c2

  print @cust_ac_no
  FETCH c3 into @cust_ac_no
  END

CLOSE c3
DEALLOCATE c3

person user2058738    schedule 11.07.2019    source источник
comment
Для пакетной обработки вам нужен метод передачи данных через границы пакета («переход»); одним из примеров может быть использование временной таблицы для хранения указанных значений; в этом сценарии вложенный курсор будет определен для соединения M3_SHP_ACCOUNT_NOTES с временной таблицей, и во время выполнения вы будете усекать/повторно заполнять временную таблицу перед каждым open C2; если у вас есть разрешения на создание хранимой процедуры, вы можете поместите весь свой код (оба курсора, ссылки @variable в курсорах) в один хранимый процесс (например, создайте процесс, выполните процесс, удалите процесс)   -  person markp-fuso    schedule 11.07.2019
comment
@markp извините, но можете ли вы показать пример кода?   -  person user2058738    schedule 11.07.2019


Ответы (1)


Основываясь исключительно на предоставленном коде, мне кажется, что это можно сделать с помощью одного курсора.

Предположения:

  • хотя в примере показан только один cust_ac_no, использование предложения 'in()' наводит меня на мысль, что нам может понадобиться обработать список cust_ac_no, поэтому я напишу это для поддержки нескольких cust_ac_no в списке.
  • пример кода показывает, что cust_ac_no печатается после соответствующего notes.

Одно возможное решение с одним курсором:

declare c3 cursor
for
select distinct
       cust_ac_no,
       notes
from   tempdb..M3_SHP_ACCOUNT_NOTES
where  cust_ac_no in ('851243048')  -- could be multiple cust_ac_no's
order by cust_ac_no, inst_seq_no, ord_no, ref_no, acv_no
go

declare @cust_ac_no        varchar(10),
        @cust_ac_no_prev   varchar(10),
        @notes             varchar(4000)

select @cust_ac_no_prev = NULL

open c3

fetch c3 into @cust_ac_no, @notes

while @@sqlstatus = 0
begin
    if @cust_ac_no_prev is NULL
        select @cust_ac_no_prev = @cust_ac_no

    -- print cust_ac_no *after* its associated notes have been printed;
    -- this should be done when we fetch a new cust_ac_no:

    if @cust_ac_no_prev != @cust_ac_no
        print @cust_ac_no_prev

    print @notes

    fetch c3 into @cust_ac_no, @notes
end

-- print the last fetched cust_ac_no:

print @cust_ac_no

close c3
deallocate c3
go
person markp-fuso    schedule 11.07.2019