存储过程异常处理
Posted
技术标签:
【中文标题】存储过程异常处理【英文标题】:Stored procedure exception handling 【发布时间】:2011-09-29 11:47:18 【问题描述】:SQL> DECLARE
2 TotalUpd NUMBER(36) := 0;
3 BEGIN
4 dbms_output.put_line ('Job Start time............... : ' || to_char(SYSDATE, ' hh24:mi:ss'));
5 UPDATE Asset SET _status = 'PROGRESS' WHERE status is null;
6 TotalUpd := SQL%ROWCOUNT;
7 dbms_output.put_line('Total Records Updated. : ' || TotalUpd);
8 COMMIT;
9 EXCEPTION
10 WHEN NO_DATA_FOUND THEN
11 dbms_output.put_line ('No more data to update.');
12 WHEN OTHERS THEN
13 dbms_output.put_line ('Error while status as SUCCESS ');
14 END ;
15 /
上述过程的结果是 作业开始时间...... : 04:41:41 更新的总记录。 : 0
但是我的预期结果是“没有更多的行要更新”必须打印,因为我已经截断了表 Asset。请告诉我哪里出错了。
【问题讨论】:
【参考方案1】:NO_DATA_FOUND
错误不会在更新语句中引发。
如果 select 语句不返回任何内容,则会在 select into
语句中抛出。
另请参阅 select_item 下的 Tahiti on select into:*如果 SELECT INTO 语句不返回任何行,PL/SQL 将引发预定义的异常 NO_DATA_FOUND。*
如果更新语句没有更新任何内容,Oracle 不会将其视为异常,因此不会引发异常。然而,如果一个 select into 语句不能填充变量,它被认为是一个错误(因此在这种情况下 NO_DATA_EXCEPTION 被抛出(
【讨论】:
【参考方案2】:很简单,如果没有数据,更新不会产生错误。
如果你想控制你的代码流,你需要查看TotalUpd
的值
DECLARE
TotalUpd NUMBER(36) := 0;
BEGIN
dbms_output.put_line ('Job Start time............... : '
|| TO_CHAR(SYSDATE, ' hh24:mi:ss'));
UPDATE Asset SET _status = 'PROGRESS' WHERE status IS null;
TotalUpd := SQL%ROWCOUNT;
IF TotalUpd = 0 THEN
dbms_output.put_line ('No more data to update.');
ELSE
dbms_output.put_line('Total Records Updated. : '
|| TotalUpd);
END IF;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line ('Error while status as SUCCESS ');
END;
【讨论】:
您可以在使用 WHEN OTHERS 异常时添加 SQLERRM 和 SQLCODE。 WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('ERROR IS : ' || SQLCODE || ' : ' || SQLERRM); @Mahi007 - SQLERRM 已经包含 SQLCODE。并且通常不建议使用调试消息处理 OTHERS 异常。 请记住,我只是在回答所提出的问题,我发现最好假设功能是正确的,并且可能对输出存在依赖性。 @William Robertson - 同意 Sqlerrm 包含 sqlcode。我认为它是非生产环境。也许使用“找不到数据时”然后引发应用程序错误(-20001,)似乎是更好的选择,或者插入到错误日志表中【参考方案3】:如果select into
不返回任何行,则抛出NO_DATA_FOUND
,而不是如果在更新语句后没有更新任何行。
我建议您在更新本身之后移动处理此异常的逻辑:
IF (SQL%ROWCOUNT = 0) THEN
dbms_output.put_line ('No more data to update.');
【讨论】:
【参考方案4】:认为 NO_DATA_FOUND 异常仅由您未使用的 SELECT 语句引发。尝试测试 SQL%COUNT 并根据需要输出。
【讨论】:
...我猜你是想写SQL%ROWCOUNT
以上是关于存储过程异常处理的主要内容,如果未能解决你的问题,请参考以下文章