我有一个返回ref cursor作为输出参数的过程。我需要找到一种方法来获取光标中no.of记录的计数。目前我通过重复相同的选择查询来获取计数,这会影响性能。
例如:
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光标中的no.of行转换为vCount。
谢谢!
答案 0 :(得分:2)
除非您使用单用户系统或使用非默认事务隔离级别(这会引入其他复杂性),否则无法保证游标返回的行数和{{1第二个查询返回匹配。完全可能的是,另一个会话在您打开游标的时间和运行count(*)
的时间之间进行了更改。
如果您确实想要生成准确的计数,可以将count(*)
列定义为cnt
列到您用来打开游标的查询中。然后,游标中的每一行都会有一列count(*) over ()
,它会告诉您将返回的总行数。 Oracle必须做更多的工作才能生成cnt
,但它比两次运行相同的查询要少。
但从结构上讲,从同一段代码返回结果和计数是没有意义的。由于调用者必须能够遍历结果,因此确定计数是调用者应该负责的事情。每个调用者都应该能够处理明显的边界情况(即查询返回0行)而无需单独计数。每个调用者都应该能够遍历结果而无需知道将会有多少结果。每次我看到有人试图按照返回光标和计数的模式,正确的答案是重新设计程序并修复调用者提示设计的任何错误。