这个问题提出了一个很有趣的一点; 似乎有它是否是可能的Oracle文档中矛盾%NOTFOUND
为空取回后。 是吗?
从引用11g通用文档
注:在例6-16,如果FETCH从来没有取出一行,那么c1%NOTFOUND始终是NULL和循环永远不会退出。 为了防止无限循环,使用EXIT语句来代替:出关时C1%NOTFOUND OR(C1%NOTFOUND IS NULL);
该文件似乎直接自相矛盾的,因为它也说以下,这意味着后取%NOTFOUND
不能为空。
%NOTFOUND返回(%FOUND的逻辑相对):
显式游标后,NULL被打开,但之前的第一次提取
FALSE如果最近获取从显式游标返回的行
否则TRUE
该10克文件也有类似的警告,因为它警告说,可能会取不为了成功执行这种行为将要展出这不是必然,直接的矛盾。
的第一次提取之前,%NOTFOUND计算为NULL。 WHEN条件是不正确的,并循环永远不会退出。如果FETCH从未成功执行,退出。 为了安全起见,您可能需要使用下面的EXIT语句来代替:
出关时C1%NOTFOUND或C%NOTFOUND IS NULL;
在什么情况下可能会取一个既“失败”或可能%NOTFOUND
一个取指令执行后返回null?
我能找到的情况下取回可能失败:
declare
i integer;
cursor c is
select 1 / 0 from dual;
begin
open c;
begin
fetch c
into i;
exception
when others then
dbms_output.put_line('ex');
end;
if c%notfound is null then
dbms_output.put_line('null');
elsif c%notfound then
dbms_output.put_line('true');
else
dbms_output.put_line('false');
end if;
close c;
end;
但是,这不仅使你的问题更强大,因为它会评估为null,既不在10g中,也不在11g中...
我认为这触发您的部分是这样的:
WHEN条件是不正确的,并循环永远不会退出。如果FETCH从未成功执行,退出。
某处在过去一定有它看起来像这样的代码示例:
LOOP
FETCH c1 INTO name;
EXIT WHEN c1%NOTFOUND;
-- Do stuff
END LOOP;
鉴于此块的代码,那么该语句戒指真。 如果取从未执行(失败),那么%NOTFOUND将是无效的。 将EXIT WHEN
条件不会评价为TRUE(零计算为false)。 然后,事实上,循环将永远继续下去。
这是一个很容易测试的情况:
SET SERVEROUT ON;
DECLARE
-- this cursor returns a single row
CURSOR c1 IS
SELECT 1 FROM dual WHERE rownum = 1;
-- this cursor returns no rows
CURSOR c2 IS
SELECT 1 FROM dual WHERE 1=0;
v1 number;
BEGIN
OPEN c1;
FETCH c1 INTO v1; -- this returns a record
FETCH c1 INTO v1; -- this does not return a record
IF c1%NOTFOUND THEN
dbms_output.put_line('c1%NOTFOUND: TRUE');
ELSIF c1%NOTFOUND IS NULL THEN
dbms_output.put_line('c1%NOTFOUND: NULL');
ELSE
dbms_output.put_line('c1%NOTFOUND: FALSE');
END IF;
CLOSE c1;
OPEN c2;
FETCH c2 INTO v1; -- this does not return a record
IF c2%NOTFOUND THEN
dbms_output.put_line('c2%NOTFOUND: TRUE');
ELSIF c2%NOTFOUND IS NULL THEN
dbms_output.put_line('c2%NOTFOUND: NULL');
ELSE
dbms_output.put_line('c2%NOTFOUND: FALSE');
END IF;
CLOSE c2;
END;
/
在Oracle APEX 4.1的脚本的输出是(我认为APEX是运行Oracle 11gR2的,但你可以很容易地运行在任何版本的脚本):
c1%NOTFOUND: TRUE
c2%NOTFOUND: TRUE
在此基础上测试, %NOTFOUND
一个取指令执行后,会不会是NULL。 这符合什么10g和11g文档中的最初描述说, %NOTFOUND
属性。 关于循环永远不会退出必须是从旧版本的例子的音符。 由于它只是一个说明,我会说,这是安全的信任原说明书和忽略的注意事项。