如何检测获取游标是否返回任何值?
How to detect if fetch cursor returned no value?
我有这个:
declare
toStoreA varchar2(10);
toStoreB varchar2(10);
toStoreC varchar2(10);
cursor c1 is
select a, b, c
from table1
where login = 'myLogin';
begin
open c1;
fetch c1 into toStoreA,
toStoreB,
toStoreC
close c1;
if toStoreB = NULL then
dbms_output.put_line('OK, we are in if, toStoreB is null');
end if;
dbms_output.put_line('toStoreA:' || toStoreA || '_');
dbms_output.put_line('toStoreB:' || toStoreB || '_');
dbms_output.put_line('toStoreC:' || toStoreC || '_');
end;
我的目标是检测 fetch cursor
是否没有返回任何值。
如果我在 sql window 中查询我的 sql 语句,我将得到:
> select a, b, c from table1 where login = 'myLogin';
++++++++++++++++++++++++++++++++++++++++++++
+ some val + + +
++++++++++++++++++++++++++++++++++++++++++++
这是我在 DBMS 输出中得到的 window:
toStoreA:some val_
toStoreB:_
toStoreC:_
如您所见,我在 DBMS 输出中没有得到字符串 OK, we are in if, toStoreB is null
。为什么?好吧,很明显如果没有通过。问题是如何正确检查 fetch cursor
是否返回 null
值(无值)?
我也试过 if toStoreB = '' then
但没有用。
你不能用相等来测试 null; null 永远不等于(或 not 等于)任何东西,包括它自己。并且空字符串 ''
与 null 无法区分,因此您也不能对其使用相等性测试。 See the explanation in the documentation. You can fix the immediate problem by using the is null
operator 改为:
if toStoreB is NULL then
有了这个改变,你会看到:
anonymous block completed
OK, we are in if, toStoreB is null
toStoreA:some val_
toStoreB:_
toStoreC:_
最初我对这个问题有一点误解,以为你的意思是你想检查提取是否没有返回任何行,而不是特定列没有值;所以其余部分并不直接相关。如果您总是期待单行,那么您可以使用 select into ...
而不是命名游标;但是使用游标,您可以更灵活地测试获取的内容...
这只是告诉你,如果 b
不能为 null,则 fetch 没有找到任何东西;即使您现在认为是这种情况,也不是您必须依赖的东西,也不是通用解决方案。
您可以使用 the `%notfound' cursor attribute:
检查是否已获取任何内容
open c1;
fetch c1 into toStoreA,
toStoreB,
toStoreC;
if c1%notfound then
dbms_output.put_line('No row was fetched');
end if;
close c1;
请注意,在关闭游标之前必须检查它,通常是在获取之后立即检查。如果在 close
之后尝试检查它会出错。一旦检索到所有数据,这通常用于中断获取循环。
因此,通过更改和未找到任何数据的修改后的查询,您会看到:
anonymous block completed
No row was fetched
OK, we are in if, toStoreB is null
toStoreA:_
toStoreB:_
toStoreC:_
我有这个:
declare
toStoreA varchar2(10);
toStoreB varchar2(10);
toStoreC varchar2(10);
cursor c1 is
select a, b, c
from table1
where login = 'myLogin';
begin
open c1;
fetch c1 into toStoreA,
toStoreB,
toStoreC
close c1;
if toStoreB = NULL then
dbms_output.put_line('OK, we are in if, toStoreB is null');
end if;
dbms_output.put_line('toStoreA:' || toStoreA || '_');
dbms_output.put_line('toStoreB:' || toStoreB || '_');
dbms_output.put_line('toStoreC:' || toStoreC || '_');
end;
我的目标是检测 fetch cursor
是否没有返回任何值。
如果我在 sql window 中查询我的 sql 语句,我将得到:
> select a, b, c from table1 where login = 'myLogin';
++++++++++++++++++++++++++++++++++++++++++++
+ some val + + +
++++++++++++++++++++++++++++++++++++++++++++
这是我在 DBMS 输出中得到的 window:
toStoreA:some val_
toStoreB:_
toStoreC:_
如您所见,我在 DBMS 输出中没有得到字符串 OK, we are in if, toStoreB is null
。为什么?好吧,很明显如果没有通过。问题是如何正确检查 fetch cursor
是否返回 null
值(无值)?
我也试过 if toStoreB = '' then
但没有用。
你不能用相等来测试 null; null 永远不等于(或 not 等于)任何东西,包括它自己。并且空字符串 ''
与 null 无法区分,因此您也不能对其使用相等性测试。 See the explanation in the documentation. You can fix the immediate problem by using the is null
operator 改为:
if toStoreB is NULL then
有了这个改变,你会看到:
anonymous block completed
OK, we are in if, toStoreB is null
toStoreA:some val_
toStoreB:_
toStoreC:_
最初我对这个问题有一点误解,以为你的意思是你想检查提取是否没有返回任何行,而不是特定列没有值;所以其余部分并不直接相关。如果您总是期待单行,那么您可以使用 select into ...
而不是命名游标;但是使用游标,您可以更灵活地测试获取的内容...
这只是告诉你,如果 b
不能为 null,则 fetch 没有找到任何东西;即使您现在认为是这种情况,也不是您必须依赖的东西,也不是通用解决方案。
您可以使用 the `%notfound' cursor attribute:
检查是否已获取任何内容 open c1;
fetch c1 into toStoreA,
toStoreB,
toStoreC;
if c1%notfound then
dbms_output.put_line('No row was fetched');
end if;
close c1;
请注意,在关闭游标之前必须检查它,通常是在获取之后立即检查。如果在 close
之后尝试检查它会出错。一旦检索到所有数据,这通常用于中断获取循环。
因此,通过更改和未找到任何数据的修改后的查询,您会看到:
anonymous block completed
No row was fetched
OK, we are in if, toStoreB is null
toStoreA:_
toStoreB:_
toStoreC:_