【问题标题】:How to do nested cursor in sybase ase如何在sybase ase中做嵌套游标
【发布时间】:2019-11-20 20:39:29
【问题描述】:

请问如何在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

【问题讨论】:

  • 对于批处理,您需要一种跨批处理('go')边界传递数据的方法;一个例子是使用临时表来保存所述值;在这种情况下,嵌套游标将被定义为将 M3_SHP_ACCOUNT_NOTES 与临时表连接,并且在执行期间,您将在每个 open C2 之前截断/重新填充临时表;如果您有权创建存储过程,那么您可以将所有代码(游标、游标中的@variable 引用)放在单个存储过程中(例如,create proc、exec proc、drop proc)
  • @markp 抱歉,你能显示示例代码吗?

标签: sybase sap-ase


【解决方案1】:

仅基于提供的代码,它看起来(在我看来)可以用单个光标完成。

假设:

  • 虽然示例只显示了一个cust_ac_no,但'in()' 子句的使用让我认为我们可能需要处理cust_ac_no 的列表,所以我会写这个来支持多个@987654324 @在列表中
  • 示例代码显示了一个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

【讨论】:

    猜你喜欢
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 1970-01-01
    • 2016-07-11
    相关资源
    最近更新 更多