如果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。
我没有看到任何基本原因吗?
答案 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来工作