能否%NOTFOUND后取返回null?(Can %NOTFOUND return null aft

2019-06-25 22:03发布

这个问题提出了一个很有趣的一点; 似乎有它是否是可能的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?

Answer 1:

我能找到的情况下取回可能失败:

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中...



Answer 2:

我认为这触发您的部分是这样的:

WHEN条件是不正确的,并循环永远不会退出。如果FETCH从未成功执行,退出。

某处在过去一定有它看起来像这样的代码示例:

LOOP
  FETCH c1 INTO name;
  EXIT WHEN c1%NOTFOUND;
  -- Do stuff
END LOOP;

鉴于此块的代码,那么该语句戒指真。 如果取从未执行(失败),那么%NOTFOUND将是无效的。 将EXIT WHEN条件不会评价为TRUE(零计算为false)。 然后,事实上,循环将永远继续下去。



Answer 3:

这是一个很容易测试的情况:

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属性。 关于循环永远不会退出必须是从旧版本的例子的音符。 由于它只是一个说明,我会说,这是安全的信任原说明书和忽略的注意事项。



文章来源: Can %NOTFOUND return null after a fetch?