我有以下声明:
OPEN PARAM_RS FOR
SELECT *
FROM my_table
WHERE my_NUMBER = param_number;
我怎样才能准确地"测试PARAM_US,这样我可以执行另一个语句,如果它是空的吗? 我仍然需要将PARAM_US作为OUT参数返回。
我试过了
if (PARAM_RS%rowcount = 0) THEN...
但即使结果集中有行,此测试也是正面的。
我也尝试使用NO_DATA_FOUND异常,但它没有被触发。
谢谢!
答案 0 :(得分:1)
你必须从光标获取才能找到是否存在某些内容。看看下面的例子:
{
_id:5ab94cdb6b106375b6843358
credit:
Array
0:
Object
type:"mastercard"
currency:"BRL"
balance:"4627.56"
1:
Object
type:"diners-club-enroute"
currency:"USD"
balance:"5222.47"
}
db.mydb.find().forEach( function (x) {
x.credit.balance = parseFloat(x.credit.balance);
db.mydb.save(x);
});
db.mydb.aggregate([
{$unwind: "$credit"},
{$group: {_id: "$credit.currency", sumBalance: {$sum: "$credit.balance"}}}
]).forEach(printjson)
<强> [编辑] 强>
如果要重新使用它以获取整个数据集,是的 - 您将不得不再次打开它。否则,第一行(你为了检查光标中是否有东西而取出的那一行)将“丢失”。
以下是一个例子:
SQL> declare
2 param_rs sys_refcursor;
3 rec emp%rowtype;
4 begin
5 open param_rs for
6 select * from emp
7 where deptno = &par_deptno;
8 fetch param_rs into rec;
9 if param_rs%notfound then
10 dbms_output.put_line('Nothing has been found');
11 else
12 dbms_output.put_line('Oh yes, I found something!');
13 end if;
14 end;
15 /
Enter value for par_deptno: 10
Oh yes, I found something!
PL/SQL procedure successfully completed.
SQL> /
Enter value for par_deptno: 87
Nothing has been found
PL/SQL procedure successfully completed.
SQL>
答案 1 :(得分:0)
%ROWCOUNT
属性在打开时将归零,即使结果集中有行也是如此。该属性返回到目前为止提取的行数,因此在第一个FETCH
之前它将为零。
同样地,NO_DATA_FOUND
例外不会引发OPEN
例外情况,FETCH
不会返回一行时会引发此异常。
要回答你的问题,我不相信有任何打开光标的测试,以确定它是否为空#34; ,而不是试图从中获取。
答案 2 :(得分:0)
引用游标是指向一块内存的指针:打开它只是将查询与内存空间相关联但不执行它。直到我们执行fetch,我们才知道查询是否会返回任何内容。这没有什么奇怪的,它正是SQL查询的常用方式。
这就是为什么sql%rowcount
或no_data_found
的测试都不起作用的原因:它们在获取后填充。没有办法测试&#34;游标是否会返回记录而不实际尝试。
那么,如何处理没有返回任何记录的游标?正常的行为是允许调用程序处理它。这是通常的实现。通常因为它通常是具有关于当前交易的最多信息的调用程序,因此最好知道该做什么。
这看起来像(full implementation on LiveSQL - free Oracle TechNet account required):
鉴于API ...
create or replace package test1 as
type cur1 is ref cursor return my_table%rowtype;
procedure get_param (p_param in number, p_rs out cur1);
procedure get_def_param (p_rs out cur1);
end;
/
......调用程序与它交互:
declare
rc test1.cur1;
rec my_table%rowtype;
begin
test1.get_param(42, rc);
fetch rc into rec;
if rc%notfound then
close rc;
test1.get_def_param(rc);
fetch rc into rec;
end if;
dbms_output.put_line('result='||rec.description);
close rc;
end;
/
但是,如果您真的希望被调用程序处理空结果集,则可以完成。诀窍是在被调用程序中打开一个测试游标,如果没有提取任何内容,则获取默认记录,然后打开带有保证结果集的参数引用游标。
create or replace package test1 as
type cur1 is ref cursor return my_table%rowtype;
type nt is table of my_table%rowtype;
procedure get_param (p_param in number, p_rs out cur1);
end;
/
create or replace package body test1 as
procedure get_param (p_param in number, p_rs out cur1) is
rc cur1;
recs nt;
begin
open rc for
select t.*
from my_table t
where t.my_number = p_param;
fetch rc bulk collect into recs;
if recs.count() = 0 then
close rc;
open rc for
select t.*
from my_table t
where t.my_number = 1;
fetch rc bulk collect into recs;
end if;
close rc;
open p_rs for
select * from table(recs);
end get_param;
end;
/
现在调用程序更简单:
declare
rc test1.cur1;
rec my_table%rowtype;
begin
test1.get_param(42, rc);
fetch rc into rec;
dbms_output.put_line('result='||rec.description);
close rc;
end;
/