【问题标题】: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。请告诉我哪里出错了。

【问题讨论】:

    标签: oracle plsql oracle10g oracle11g


    【解决方案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
        猜你喜欢
        • 2014-07-18
        • 1970-01-01
        • 2012-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-22
        • 1970-01-01
        • 2020-12-19
        相关资源
        最近更新 更多