为什么 no_data_found ORA-01403 在 Oracle 中是异常?

发布于 2024-09-27 06:23:41 字数 560 浏览 4 评论 0原文

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

有什么我看不到的重要原因吗?

If the SELECT INTO statement doesn't return at least one row, ORA-01403 is thrown.

For every other DBMS I know this is normal on a SELECT.
Only Oracle treats a SELECT INTO like this.

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;

Why?

In my opinion you don't need this exception really. It is too much overhead.
Sometimes it is handy but you have to write a whole BEGIN, EXCEPTION, WHEN, END Block.

Are there any essential reasons I don't see?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

羁〃客ぐ 2024-10-04 06:23:41

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

在这里,您主动忽略异常(过程将成功返回),但大多数时候,如果您正在执行 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 或与此相关的所有异常的标准)。

The exception block is not needed, you might use it or not, depending on the context.

Here you are actively ignoring the exception (the procedure will return successfully) but most of the time if you're doing a SELECT INTO you want it to fail if it doesn't return a row, consider:

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;

Here I want my function to fail if it is called with an empno that doesn't exist in the EMP table. I might catch the exception to raise a meaningful error message (with raise_application_error) but most of the time I'm happy with the ORA-01403.

In general, the only exceptions you should catch are the expected exceptions (i.e. this should not be the standard to catch all ORA-01403, or all exceptions for that matter).

司马昭之心 2024-10-04 06:23:41

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

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

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

恕我直言,对 SQLCODE = 100 的检查很可能会被频繁跳过。发生异常会立即让您意识到 A)发生了重要情况(未找到数据),并且 B)对此没有任何允许。在我看来,让 PL/SQL 引擎引发异常比让程序在假设数据已被检索而实际上没有检索到的情况下继续愉快地运行要好,这可能会导致各种不愉快的问题。

分享并享受。

But we still need to answer the question of "why is an exception thrown in the case where a SELECT has no data to be retrieved".

I believe this is done because it's a common situation which might otherwise be overlooked. Writing code as though it always expects to find data is a common thing to do, and if we were supposed to put in error checks such as

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

it is likely IMHO that the check for SQLCODE = 100 would be skipped frequently. Having an exception raised rams it right up your nose that A) an important condition (no data found) occurred, and B) NO ALLOWANCE WAS MADE FOR THIS. IMO having the PL/SQL engine raise an exception is better than having the program continue merrily on its way under the assumption that data was retrieved when in fact it wasn't, which can lead to all sorts of other-than-merry problems.

Share and enjoy.

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

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

那么虚拟变量将为 NULL

You can try use MIN for avoid use EXCEPTION clause.

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

then dummy variable will be NULL

梦里泪两行 2024-10-04 06:23:41

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

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

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

Because you are doing SELECT INTO which requires exactly one row (more rows would also be an error).

If you can have one or no row, you can use a cursor.

It is not the database's job to decide for you that a missing row is not an error, and just set the value to null.

红ご颜醉 2024-10-04 06:23:41

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

例如:
选择MAX(第 1 列)
转化为变量
从表
其中 Column1 = '值';

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

You can also use the sql MAX or MIN functions. If no row is return then these functions will return a NULL.

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

The MAX function will return the Maximum value or if no row is returned then it will return NULL.

调妓 2024-10-04 06:23:41

MAX 函数有效,不会抛出错误 ORA-01403 当 select INTO 返回 NULL 时有效

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

世界和平 2024-10-04 06:23:41

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

Because it's not clear what the PL/SQL engine should do - should it exit the block? Should it press on with NULL in the variable? What if in the next block you try to insert that into a NOT NULL column, how should it report the location of the error? Making it an exception forces you to be explicit about it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文