获取Oracle中ref游标的计数



我有一个过程,它返回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通常不知道将从游标中提取多少行,直到最后一次提取找不到要返回的行为止。由于Oracle不知道将返回多少行,因此在不获取所有行的情况下(就像您在重新运行查询时所做的那样),您也不能这样做。

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

如果您真的决定要生成准确的计数,那么可以在用于打开光标的查询中添加一个定义为count(*) over ()cnt列。然后,光标中的每一行都将有一个列cnt,它将告诉您将返回的行总数。Oracle需要做更多的工作来生成cnt,但这比两次运行同一查询要少。

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

最新更新