为什么no_data_found ORA-01403在Oracle中是个例外?

时间:2010-10-15 08:12:32

标签: oracle exception exception-handling plsql ora-01403

如果SELECT INTO语句没有返回至少一行,则抛出ORA-01403。

对于其他每个DBMS,我都知道这在SELECT上是正常的。 只有Oracle像这样处理SELECT INTO。

CREATE OR REPLACE PROCEDURE no_data_proc IS
   dummy dual.dummy%TYPE;
BEGIN
  BEGIN 
     SELECT dummy  
       INTO dummy
       FROM dual
      WHERE dummy = 'Y';   
  EXCEPTION 
     WHEN no_data_found THEN
        dbms_output.put_line('Why is this needed?');
  END;
END no_data_proc;

为什么吗

在我看来,你真的不需要这个例外。这是太多的开销。 有时它很方便,但你必须写一个完整的BEGIN,EXCEPTION,WHEN,END Block。

我没有看到任何基本原因吗?

7 个答案:

答案 0 :(得分:18)

异常块不是需要,您可以使用或不使用它,具体取决于上下文。

在这里你主动忽略异常(程序将成功返回)但是大部分时间如果你正在进行SELECT INTO,你希望它失败如果它没有返回一行,考虑一下:

PROCEDURE update_employee_salary (p_empno) IS
   l_salary NUMBER;
BEGIN
   SELECT sal INTO l_salary FROM emp WHERE empno = p_empno FOR UPDATE;
   /* do something with emp data */
END;

如果用EMP表中不存在的empno调用它,我希望我的函数失败。我可能会捕获异常以引发有意义的错误消息(使用raise_application_error),但大多数时候我对ORA-01403感到满意。

一般而言,您应该捕获的唯一例外是预期的例外(即,这不应该是捕获所有ORA-01403的标准,或者是所有例外情况)。

答案 1 :(得分:11)

但是我们仍然需要回答“为什么在SELECT没有要检索的数据的情况下抛出异常”的问题。

我相信这样做是因为这是一种常见的情况,否则可能会被忽视。编写代码似乎总是希望找到数据是常见的事情,如果我们应该进行错误检查,例如

SELECT <something...>
IF SQLCODE = 100 THEN -- No data found
  <no-data handler>
END IF

恕我直言,SQLCODE = 100的检查会被频繁跳过。提出异常会使你的鼻子发生爆炸,A)发生了一个重要的情况(没有发现数据),并且B)没有为此做出任何限制。具有PL / SQL引擎引发异常的IMO比在假设数据被检索的情况下继续快速运行更好,而事实上并非如此,这可能导致各种其他非常快乐的问题。

分享并享受。

答案 2 :(得分:6)

您可以尝试使用MIN来避免使用EXCEPTION子句。

 SELECT MIN(dummy)  
   INTO dummy
   FROM dual
  WHERE dummy = 'Y'; 

然后虚拟变量将为NULL

答案 3 :(得分:2)

因为你正在做SELECT INTO,它只需要一行(更多行也是一个错误)。

如果您可以有一行或没有行,则可以使用光标。

确定丢失的行不是错误并不是数据库的工作,只需将值设置为null。

答案 4 :(得分:1)

因为不清楚PL / SQL引擎应该做什么 - 它应该退出块吗?它应该在变量中按下NULL吗?如果在下一个块中尝试将其插入NOT NULL列,该怎么报告错误的位置呢?使它成为一个例外迫使你明确它。

答案 5 :(得分:1)

您还可以使用sql MAX MIN 功能。如果没有返回行,则这些函数将返回 NULL

例如: 选择 MAX (column1) 变成变数 从表格 其中Column1 ='Value';

MAX 函数将返回Maximum值,如果没有返回任何行,则返回NULL。

答案 6 :(得分:1)

MAX函数有效,不会引发错误 ORA-01403 可以通过选择INTO返回NULL来工作