打开PL / SQL语句的refcursor?

时间:2015-04-07 15:33:05

标签: oracle plsql cursor sys-refcursor

我正在使用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)

我已经提取了我需要的数据,并且我将其大量收集到表变量中。现在,我需要聚合行 - 如果我只需要操作数据,这也不错,但我需要将它作为refcursor的查询。我可以打开PL / SQL FOR循环的refcursor,还是我咆哮错误的树?我试图谷歌这个,但“游标循环”不是我想要的。另一种方法是尝试使用VB在SSRS中聚合结果。 (无论哪种方式,这都不是一个好时机。)我不确定我是否有权为此创建一个SQL表类型,所以这是我所寻求的替代方案。

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

2 个答案:

答案 0 :(得分:0)

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

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

114
115
116
117
145
146
160
890
896
897

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

步骤1 - 选择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)

可以在PLSQL中使用该SQL语句来返回游标,就像@MickMnemonic在评论中所拥有的this链接一样。

基本上 -

OPEN cursor_variable FOR SELECT something FROM something...;

答案 1 :(得分:0)

我和一位同事谈到了这个问题,他知道我已经能够实施。

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

我现在使用SELECT ... FROM TABLE(MYFUNCTION())语法从一个过程调用该函数。这使我可以将所有内容都放入refcursor而不会出现太多问题。

虽然这可能不具备性能(循环光标并手动聚合),但这是针对月度报告,因此我不会尝试进行优化,直到需要(因为我们有其他的)工作要做)。