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

Ste*_*lke 18 sql oracle plsql exception 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;
Run Code Online (Sandbox Code Playgroud)

为什么?

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

有没有我没看到的重要原因?

Vin*_*rat 19

不需要例外块,您可以使用或不使用,具体取决于上下文.

在这里你主动忽略异常(程序将成功返回)但是大部分时间如果你正在执行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;
Run Code Online (Sandbox Code Playgroud)

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

通常,您应该捕获的唯一例外是预期的异常(即,这不应该是捕获所有ORA-01403的标准,或者所有异常).


Bob*_*ica 12

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

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

SELECT <something...>
IF SQLCODE = 100 THEN -- No data found
  <no-data handler>
END IF
Run Code Online (Sandbox Code Playgroud)

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

分享和享受.


Mic*_*sov 7

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

 SELECT MIN(dummy)  
   INTO dummy
   FROM dual
  WHERE dummy = 'Y'; 
Run Code Online (Sandbox Code Playgroud)

然后虚拟变量将为NULL