为 PL/SQL 语句打开一个 refcursor?

Open a refcursor for a PL/SQL statement?

我正在使用 Oracle 和 SSRS 为企业创建报告。该报告要求我聚合连续范围的序列号,这些序列号可以由字母数字组成。

例如,假设我有以下连续剧:

OPS114
OPS115
OPS116
OPS117
OPS145
OPS146
OPS160
890RPT
896RPT
897RPT

报告应该为每个连续范围包含一个聚合行,其中包含每个范围的计数,如下所示:

OPS114 - OPS117 (4)
OPS145 - OPS146 (2)
OPS160 - OPS160 (1)
890RPT - 890RPT (1)
896RPT - 897RPT (2)

我已经提取了我需要的数据,并且正在将其批量收集到一个 table 变量中。现在,我需要聚合行 - 如果我只需要操作数据,这还不错,但我需要将其用作 refcursor 的查询。我可以为 PL/SQL FOR 循环打开一个 refcursor,还是我找错树了?我已经尝试 Google 这个,但是 "cursor for loop" 不是我要找的。另一种方法是尝试使用 VB 在 SSRS 中聚合结果。 (所以无论哪种方式,都不是一个好时机。)我不确定我是否有权为此创建 SQL table 类型,所以这是我寻求的替代方案.

如果有人对此有任何经验,将不胜感激!

您可以通过单个 SQL 语句执行此操作,但您需要更好地定义数据。您的列存储字符串,但您将它们用作数字来找出范围。数字部分似乎可以在字符串部分之前或之后。

如果您能够像这样编写一些逻辑来分隔数字(并且可能将字符串部分保留在另一列中)-

114
115
116
117
145
146
160
890
896
897

然后它简化为一个简单的 gaps and islands 问题。

第 1 步 - Select rownum 以及此列(这将是一个从 1 开始的连续序列)

第 2 步 - 从此数值数据列中减去 rownum。

第 3 步 - 按结果分组

第 4 步 - 从组中获取最小值(数值)、最大值(数值)和计数(数值),这将是组合为字符串时的结果。

Numeric_part     Rownum      Difference
------------     ------      ------------
114              1           113
115              2           113
116              3           113
117              4           113
145              5           140
146              6           140
160              7           153
890              8           882
896              9           887
897              10          887

按差异列对其进行分组,您会得到 -

Difference     Min(num)    Max(num)    count(num)   Result
----------     ---------   ----------  ----------   -----------------
113            114         117         4            114 - 117 (4)
140            145         146         2            145 - 146 (2)
153            160         160         1            160 - 160 (1)
882            890         890         1            890 - 890 (1)
887            896         897         2            896 - 897 (2)

SQL 语句可以在 PLSQL 中用于 return 游标,如 @MickMnemonic 在评论中的 this link 中。

基本上 -

OPEN cursor_variable FOR SELECT something FROM something...;

我和一位同事谈过这件事,他提出了一个我已经能够实现的想法。

我能够创建一个流水线函数来为我处理数据选择和转换;这让我可以根据需要聚合我的行,并且只在连续范围完成后才传递行。

我现在使用 SELECT ... FROM TABLE(MYFUNCTION()) 语法从过程中调用该函数。这使我可以毫无问题地将所有内容放入 refcursor。

虽然这可能性能不佳(遍历游标并手动聚合),但这是针对月度报告的,因此我不会在必要时尝试优化(因为我们还有其他工作要做) .