隐式游标和NO_DATA_FOUND异常

时间:2017-02-28 11:36:02

标签: sql oracle exception-handling

我有以下PL/SQL代码:

BEGIN
  FOR c IN (SELECT ...) LOOP
     <code1>;
  END LOOP;
  <code2>;
EXCEPTION WHEN NO_DATA_FOUND THEN
  NULL;
END;

此代码应在循环内多次运行 code1 ,并在完成此循环后应执行 code2 。否则,如果SELECT查询找不到数据,那么我希望这会引发异常并超越 code2 ,但这不会发生。为什么呢?

2 个答案:

答案 0 :(得分:2)

NO_DATA_FOUND由必须返回一行但未找到匹配行的语句引发,例如

DECLARE x NUMBER;
BEGIN
  SELECT foo INTO x FROM bar WHERE xyz='abc';
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    ...
END;

在您的情况下,您可以执行以下操作:

DECLARE foundSomething BOOLEAN := FALSE;
BEGIN
  FOR c IN (SELECT ...) LOOP
     foundSomething := TRUE;
     <code1>;
  END LOOP;     
  IF NOT foundSomething THEN
    NULL;  -- handle the situation
  ELSE
    <code2>;
  END IF;
END; 

答案 1 :(得分:1)

不,这不是应该发生的事情。

如果没有数据,则循环运行0次 - 即它跳过code1并执行code2。

您可以定义显式游标并对数据不可用性进行检查,如下所示:

DECLARE
  cursor cur is select 1 a from dual where 1 = 1;
  type tab is table of cur%rowtype;
  v tab;
BEGIN
  open cur;
  loop
    fetch cur bulk collect into v;
    if v.count = 0 then
        raise no_data_found;
    end if;
    dbms_output.put_line('Code1');
  end loop;
  close cur;
  dbms_output.put_line('Code2');
EXCEPTION 
  WHEN NO_DATA_FOUND THEN
    dbms_output.put_line('Error');
END;
/

您可以轻松地扩展此代码以执行其他操作,例如将获取分成批次等。