我有这个:
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窗口中查询我的sql语句,我会得到这个:
> select a, b, c from table1 where login = 'myLogin';
++++++++++++++++++++++++++++++++++++++++++++
+ some val + + +
++++++++++++++++++++++++++++++++++++++++++++
这是我在DBMS输出窗口中得到的:
toStoreA:some val_
toStoreB:_
toStoreC:_
如您所见,我在DBMS输出中没有得到字符串OK, we are in if, toStoreB is null
。为什么?嗯,很明显,如果没有通过。问题是如何正确检查fetch cursor
是否返回null
值(无值)?
我也试过if toStoreB = '' then
,但没有帮助。
答案 0 :(得分:4)
你不能平等地测试null; null永远不等于(或不等于)任何东西,包括它自己。并且空字符串''
与null无法区分,因此您也不能使用相等测试。 See the explanation in the documentation。您可以使用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:_
我最初稍微误解了这个问题,认为你的意思是你想检查fetch是否没有返回任何行,而不是特定的列没有值;所以其余部分并不直接相关。如果您总是期望单行,那么您可以使用select into ...
而不是命名游标;但是使用光标,您可以更灵活地测试所获取的内容......
这只会告诉您,如果b
不能为空,则抓取功能找不到任何内容;即使你认为现在的情况不是你应该依赖的东西,也不是一般的解决方案。
您可以使用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:_