Oracle 在PL/SQL中打开游标后捕获NO_DATA_FOUND异常的正确方法

Oracle 在PL/SQL中打开游标后捕获NO_DATA_FOUND异常的正确方法,oracle,plsql,cursor,Oracle,Plsql,Cursor,我有两种方法可以捕获未发现的异常(第二种方法不能正确捕获异常…) 第一条路 create or replace package body pkg_mnt_departments is procedure p_get_data(ls_cursor out sys_refcursor) is begin begin open ls_cursor for select field1, field2 from mytable where

我有两种方法可以捕获未发现的异常(第二种方法不能正确捕获异常…)

第一条路

create or replace package body pkg_mnt_departments is
  procedure p_get_data(ls_cursor out sys_refcursor) is
  begin

    begin
      open ls_cursor for
        select field1, field2 from mytable
          where 1 = 2;
    exception
      when others then
        dbms_output.put_line('Exception');
    end;
  end p_get_data;
end pkg_mnt_departments;
procedure get_data(id  in number,
                   l_cursor out sys_refcursor)
  is

  begin

    if (condition1) then
        open l_cursor for
               select field1, field2
                 from mytable
                where fieldid = id;

        fetch l_cursor into v_field1, v_field2;

        if(v_field1 is null) then
            --Execute sentences when cursor is empty
        end if;
    end if;

end;
第二种方式

create or replace package body pkg_mnt_departments is
  procedure p_get_data(ls_cursor out sys_refcursor) is
  begin

    begin
      open ls_cursor for
        select field1, field2 from mytable
          where 1 = 2;
    exception
      when others then
        dbms_output.put_line('Exception');
    end;
  end p_get_data;
end pkg_mnt_departments;
procedure get_data(id  in number,
                   l_cursor out sys_refcursor)
  is

  begin

    if (condition1) then
        open l_cursor for
               select field1, field2
                 from mytable
                where fieldid = id;

        fetch l_cursor into v_field1, v_field2;

        if(v_field1 is null) then
            --Execute sentences when cursor is empty
        end if;
    end if;

end;
我想这些方法中的哪一种是正确的。第一种方法不管用,但第二种方法管用……但我想知道我是否做对了

PD:在某些情况下,第二种方法不起作用……我在过程之外执行了查询并返回了行,但当它被过程执行时,我不知道haveindexedfield(fieldid)的事实是否影响了查询。 谢谢你帮我:)

更新

我对我的程序做了一些更改:

程序获取_数据(id编号, l_光标输出系统(参考光标) 是


但是,两者都不起作用…由于某种奇怪的原因,游标没有返回数据…我的最终解决方案是使用游标…结果以另一种方式返回

只有在
选择时才会引发
未找到数据
异常。。。INTO…
子句不返回任何行。当您使用显式游标和
FETCH
语句时,将不会引发它

我认为一般来说,使用隐式还是显式游标是风格/偏好的问题。我不是一个真正的开发者,所以其他人可能希望在这里发表评论。但隐式游标应获取0或1行。如果它获取0,则您找不到数据。 显式游标用于0到多行。因此,您通常会在一个循环中打开游标,从中获取变量。在这种情况下,您正在测试“提取结束”。有一个cusror变量可用于测试此-%NOTFOUND。这用于退出循环,类似于

open c1
LOOP
  fetch c1 into var;
  exit when c1%notfound;
  -- do stuff
END LOOP;
close c1;

第一种方法什么时候不起作用?我正在尝试捕获未发现异常的数据,而第一种方法对此不起作用…@CesarMiguel。我把我的回答再详细一点。我希望这能有所帮助。在这种情况下,检测空游标的正确方法是什么(在我的句子
打开ls\u cursor for
…)您不能检查after open语句,但可以检查after fetch语句,如l_游标%rowcount=0@CesarMiguel如果您返回一个ref游标,那么它不是需要处理游标中没有行的情况的过程;需要处理的是调用过程的任何代码。对于您来说,打开一个ref游标并从中获取一行,然后将其传递回调用代码是没有意义的;该调用代码将无法再看到您提取的行(如果该行是结果集中的唯一行怎么办?。@Bobc
但是隐式游标将提取0或1行
-我认为隐式游标将提取1行。如果它获取0行或多行,则会出错(分别是找不到数据行或太多行)。