19

如果 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 块。

有什么我看不到的根本原因吗?

4

7 回答 7

22

不需要异常块,您可以根据上下文使用或不使用它。

在这里,您正在主动忽略异常(该过程将成功返回),但大多数情况下,如果您正在执行 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;

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

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

于 2010-10-15T08:36:13.637 回答
12

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

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

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

恕我直言,SQLCODE = 100 的检查可能会经常被跳过。提出一个异常会让你一头雾水:A)发生了重要情况(没有找到数据),B)没有为此做任何准备。IMO 让 PL/SQL 引擎引发异常比让程序愉快地继续运行要好,假设数据被检索到,而实际上它没有被检索到,这可能会导致各种非愉快的问题。

分享和享受。

于 2010-10-15T12:13:07.993 回答
7

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

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

那么虚拟变量将为NULL

于 2010-10-15T08:16:29.270 回答
4

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

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

为您确定缺少的行不是错误不是数据库的工作,只需将该值设置为 null。

于 2010-10-15T08:16:11.343 回答
2

您还可以使用 sql MAXMIN函数。如果没有返回行,那么这些函数将返回NULL

例如:Select MAX (column1) Into variable From Table Where Column1 = 'Value';

MAX函数将返回最大值,或者如果没有返回行,则返回 NULL。

于 2015-11-18T15:26:18.843 回答
1

因为不清楚 PL/SQL 引擎应该做什么——它应该退出块吗?它应该在变量中使用 NULL 吗?如果在下一个块中您尝试将其插入到 NOT NULL 列中,它应该如何报告错误的位置?将其设为例外会迫使您明确说明它。

于 2010-10-16T17:02:22.157 回答
1

MAX function works it does not throws error ORA-01403 works when NULL is returned by select INTO

于 2019-06-25T04:20:07.127 回答