如何获得 sysref 游标选择的记录总数?
How can I get the total number of records selected by a sysref cursor?
背景
我正在开发一个调用 PLSQL 存储过程来检索和操作信息的 Web 应用程序。在这种情况下,数据库有两个存储过程;一个是 select 一组给定参数的记录总数,另一个是 return 具有相同参数的实际记录,加上分页参数(最小和最大行数)。
EX(不是实际代码):
PROCEDURE get_records_count(
p_first_name IN record_table.first_name%TYPE,
p_last_name IN record_table.last_name%TYPE,
p_resultCursor OUT sys_refcursor
)
IS BEGIN
OPEN p_resultCursor FOR
SELECT count(*) from record_table
WHERE first_name LIKE (p_first_name || '%')
OR last_name LIKE (p_last_name || '%');
END;
PROCEDURE get_records(
p_first_name IN record_table.first_name%TYPE,
p_last_name IN record_table.last_name%TYPE,
p_min IN NUMBER,
p_max IN NUMBER,
p_resultCursor OUT sys_refcursor
)
IS BEGIN
OPEN p_resultCursor FOR
SELECT * from record_table
WHERE first_name LIKE (p_first_name || '%')
OR last_name LIKE (p_last_name || '%')
AND rownum >= p_min AND rownum <= p_max;
END;
是否认为这是一个好主意超出了我的立场范围。问题是无论何时更改存储过程,结果都不匹配。短期修复是查看两个存储过程,确定哪个 selection 标准来自哪个存储过程是合适的,然后编辑另一个存储过程,以便它们都匹配。
作为长期修复,我想更改 get_records_count 过程以调用 get_records 过程,然后 return 记录总数 return 从结果 sys_refcursor 编辑。
EX:
PROCEDURE get_records_count(
p_first_name IN record_table.first_name%TYPE,
p_last_name IN record_table.last_name%TYPE,
p_resultCursor OUT sys_refcursor
)
AS
v_recordsSelectedCursor sys_refcursor;
BEGIN
/*I understand that I will need to change some logic in get_records to
handle the case in which p_max is set to zero.
It should take this case to not apply an upper limit.*/
get_records(p_first_name,p_last_name,0,0,v_recordsSelectedCursor);
/*This is where I really have NO idea what I'm doing.
Hopefully, you can infer what I'm trying to do. */
OPEN p_resultCursor FOR
SELECT count(*) FROM v_recordsSelectedCursor;
END;
实际问题
如何 select return 为 sys_refcursor 编辑的记录数?结果数字需要 returned inside a sys_refcursor
How can I select the number of records that would be returned for a
sys_refcursor? The resulting number needs to be returned inside a
sys_refcursor.
您可以修改您的程序如下:
PROCEDURE get_records_count(
p_first_name IN record_table.first_name%TYPE,
p_last_name IN record_table.last_name%TYPE,
p_resultCursor OUT sys_refcursor
)
AS
v_recordsSelectedCursor sys_refcursor;
type y is table of record_table%rowtype;
z y;
num number:=0;
BEGIN
get_records(p_first_name,p_last_name,0,0,v_recordsSelectedCursor);
fetch v_recordsSelectedCursor bulk collect into z;
---taking the count of refcursor
num:=z.count;
OPEN p_resultCursor FOR
select num from dual;
dbms_output.put_line(num);
END;
查看演示:
SQL> SELECT count(*)
FROM emp;
COUNT(*)
----------
14
SQL> CREATE OR REPLACE PROCEDURE sys_ref_rec_cnt (var OUT sys_refcursor)
2 AS
3 BEGIN
4 OPEN var FOR
5 SELECT *
6 FROM emp;
7 END;
8 /
Procedure created.
SQL> DECLARE
2 x sys_refcursor;
3 k sys_refcursor;
4 TYPE y IS TABLE OF emp%ROWTYPE;
5 z y;
6 num NUMBER := 0;
7 BEGIN
8 sys_ref_rec_cnt (x);
9
10 FETCH x
11 BULK COLLECT INTO z;
12
13 num :=z.count;
14
15 open k for
16 select num from dual;
17
18 DBMS_OUTPUT.put_line ('No. Of records-->'||num);
19 END;
20 /
No. Of records-->14
PL/SQL procedure successfully completed.
游标只是获取行的规范 - 在获取所有行之前,它不知道将返回多少行。
除非您在过程开始时使用 dbms_flashback.enable_at_time
(并在结束时禁用它),否则涉及两次调用它的任何方法都有可能得到不一致的结果。当然还有性能开销。
让游标包含其总行数的唯一方法是在 select
列表中包含一个解析 count(*) over ()
表达式。
背景
我正在开发一个调用 PLSQL 存储过程来检索和操作信息的 Web 应用程序。在这种情况下,数据库有两个存储过程;一个是 select 一组给定参数的记录总数,另一个是 return 具有相同参数的实际记录,加上分页参数(最小和最大行数)。
EX(不是实际代码):
PROCEDURE get_records_count(
p_first_name IN record_table.first_name%TYPE,
p_last_name IN record_table.last_name%TYPE,
p_resultCursor OUT sys_refcursor
)
IS BEGIN
OPEN p_resultCursor FOR
SELECT count(*) from record_table
WHERE first_name LIKE (p_first_name || '%')
OR last_name LIKE (p_last_name || '%');
END;
PROCEDURE get_records(
p_first_name IN record_table.first_name%TYPE,
p_last_name IN record_table.last_name%TYPE,
p_min IN NUMBER,
p_max IN NUMBER,
p_resultCursor OUT sys_refcursor
)
IS BEGIN
OPEN p_resultCursor FOR
SELECT * from record_table
WHERE first_name LIKE (p_first_name || '%')
OR last_name LIKE (p_last_name || '%')
AND rownum >= p_min AND rownum <= p_max;
END;
是否认为这是一个好主意超出了我的立场范围。问题是无论何时更改存储过程,结果都不匹配。短期修复是查看两个存储过程,确定哪个 selection 标准来自哪个存储过程是合适的,然后编辑另一个存储过程,以便它们都匹配。
作为长期修复,我想更改 get_records_count 过程以调用 get_records 过程,然后 return 记录总数 return 从结果 sys_refcursor 编辑。
EX:
PROCEDURE get_records_count(
p_first_name IN record_table.first_name%TYPE,
p_last_name IN record_table.last_name%TYPE,
p_resultCursor OUT sys_refcursor
)
AS
v_recordsSelectedCursor sys_refcursor;
BEGIN
/*I understand that I will need to change some logic in get_records to
handle the case in which p_max is set to zero.
It should take this case to not apply an upper limit.*/
get_records(p_first_name,p_last_name,0,0,v_recordsSelectedCursor);
/*This is where I really have NO idea what I'm doing.
Hopefully, you can infer what I'm trying to do. */
OPEN p_resultCursor FOR
SELECT count(*) FROM v_recordsSelectedCursor;
END;
实际问题
如何 select return 为 sys_refcursor 编辑的记录数?结果数字需要 returned inside a sys_refcursor
How can I select the number of records that would be returned for a sys_refcursor? The resulting number needs to be returned inside a sys_refcursor.
您可以修改您的程序如下:
PROCEDURE get_records_count(
p_first_name IN record_table.first_name%TYPE,
p_last_name IN record_table.last_name%TYPE,
p_resultCursor OUT sys_refcursor
)
AS
v_recordsSelectedCursor sys_refcursor;
type y is table of record_table%rowtype;
z y;
num number:=0;
BEGIN
get_records(p_first_name,p_last_name,0,0,v_recordsSelectedCursor);
fetch v_recordsSelectedCursor bulk collect into z;
---taking the count of refcursor
num:=z.count;
OPEN p_resultCursor FOR
select num from dual;
dbms_output.put_line(num);
END;
查看演示:
SQL> SELECT count(*)
FROM emp;
COUNT(*)
----------
14
SQL> CREATE OR REPLACE PROCEDURE sys_ref_rec_cnt (var OUT sys_refcursor)
2 AS
3 BEGIN
4 OPEN var FOR
5 SELECT *
6 FROM emp;
7 END;
8 /
Procedure created.
SQL> DECLARE
2 x sys_refcursor;
3 k sys_refcursor;
4 TYPE y IS TABLE OF emp%ROWTYPE;
5 z y;
6 num NUMBER := 0;
7 BEGIN
8 sys_ref_rec_cnt (x);
9
10 FETCH x
11 BULK COLLECT INTO z;
12
13 num :=z.count;
14
15 open k for
16 select num from dual;
17
18 DBMS_OUTPUT.put_line ('No. Of records-->'||num);
19 END;
20 /
No. Of records-->14
PL/SQL procedure successfully completed.
游标只是获取行的规范 - 在获取所有行之前,它不知道将返回多少行。
除非您在过程开始时使用 dbms_flashback.enable_at_time
(并在结束时禁用它),否则涉及两次调用它的任何方法都有可能得到不一致的结果。当然还有性能开销。
让游标包含其总行数的唯一方法是在 select
列表中包含一个解析 count(*) over ()
表达式。