【问题标题】:Get count of ref cursor in Oracle获取Oracle中的引用游标计数
【发布时间】:2013-11-25 23:21:15
【问题描述】:

我有一个返回 ref 游标作为输出参数的过程。我需要找到一种方法来获取游标中记录的数量。目前我已经通过重复相同的选择查询来获取计数,这会妨碍性能。

例如:

create or replace package temp 
TYPE metacur IS REF CURSOR;

PROCEDURE prcSumm (
pStartDate          IN          DATE,
pEndDate            IN          DATE,
pKey        IN          NUMBER,
pCursor             OUT         metacur
) ;

  package body temp is

  procedure prcSumm(  
  pStartDate          IN          DATE,
  pEndDate            IN          DATE,
  pKey        IN          NUMBER,
  pCursor             OUT         metacur
   )
 IS
 vCount NUMBER;

 BEGIN

  vCount := 0;

select count(*) into vCount
   from customer c, program p, custprog cp
   where c.custno = cp.custno
   and cp.programid = p.programid
   and p.programid = pKey
   and c.lastupdate >= pStartDate
   and c.lastupdate < pEndDate;

 OPEN pCursor for SELECT 
  c.custno, p.programid, c.fname, c.lname, c.address1, c.address2, cp.plan               
   from customer c, program p, custprog cp
   where c.custno = cp.custno
   and cp.programid = p.programid
   and p.programid = pKey
   and c.lastupdate >= pStartDate
   and c.lastupdate < pEndDate;
    end prcSumm;

有没有办法将 out 游标中的行数转换为 vCount。

谢谢!

【问题讨论】:

    标签: oracle cursor


    【解决方案1】:

    Oracle 通常不知道将从游标中提取多少行,直到最后一次提取没有找到要返回的行。由于 Oracle 不知道将返回多少行,因此您也不能不获取所有行(正如您在重新运行查询时所做的那样)。

    除非您使用的是单用户系统或您使用的是非默认事务隔离级别(这会带来额外的复杂性),否则无法保证您的游标将返回的行数和count(*)第二个查询返回将匹配。在您打开游标和运行count(*) 的时间之间,另一个会话完全有可能提交了更改。

    如果您确实确定要生成准确的计数,可以将定义为count(*) over ()cnt 列添加到您用来打开游标的查询中。游标中的每一行都会有一个列cnt,它会告诉您将返回的总行数。 Oracle 必须做更多的工作来生成cnt,但它比运行相同的查询两次要少。

    但是,从架构上讲,从同一段代码返回结果和计数是没有意义的。确定计数是调用者应该负责的事情,因为调用者必须能够遍历结果。每个调用者都应该能够处理明显的边界情况(即查询返回 0 行),而不需要单独的计数。每个调用者都应该能够遍历结果,而无需知道会有多少结果。每次我看到有人尝试遵循返回光标和计数的模式时,正确的答案是重新设计过程并修复调用者上提示设计的任何错误。

    【讨论】:

    • 在架构部分不能再同意了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-16
    相关资源
    最近更新 更多