异常处理总结

来源:互联网 发布:深入浅出node.js完整版 编辑:程序博客网 时间:2024/06/05 10:34
Exception

例1:zero_divide ----除数为0
  1. declare
  2.    v_a number := &A;
  3.    v_b number := &B;
  4.    v_result number;
  5. begin
  6.    v_result := v_a / v_b;
  7.    dbms_output.put_line(v_result);
  8. exception
  9.    when zero_divide then
  10.        dbms_output.put_line('0');
  11. end;
  12. /
  13. 0
  14. PL/SQL procedure successfully completed.

例2:value_error ----比如sqrt平方根不能接受负数
  1. SQL> declare
  2.  2      v_a number := &A;
  3.  3      v_result number;
  4.  4  begin
  5.    v_result := sqrt(v_a);
  6.  6      dbms_output.put_line(v_result);
  7.  7  end;
  8.  8  /
  9. Enter value for a: -2
  10. declare
  11. *
  12. ERROR at line 1:
  13. ORA-06502: PL/SQL: numeric or value error
  14. ORA-06512: at line 5
  15. declare
  16.    v_a number := &A;
  17.    v_result number;
  18. begin
  19.    v_result := sqrt(v_a);
  20.    dbms_output.put_line(v_result);
  21. exception
  22.    when value_error then
  23.    dbms_output.put_line('enter the right type');
  24. end;
  25. /
  26. enter the right type
  27. PL/SQL procedure successfully completed.
  1. declare
  2.    v_a number := &A;
  3.    v_result number;
  4.    error_v exception;
  5. begin
  6.    case when v_a < 0 then
  7.        raise error_v;
  8.    end case;
  9.    v_result := sqrt(v_a);
  10.    dbms_output.put_line(v_result);
  11. exception
  12.    when error_v then
  13.    dbms_output.put_line('enter the right type');    
  14. end;
  15. /

例3:no_data_found
  1. DECLARE
  2.  v_ename emp.ename%TYPE;
  3.  err_num NUMBER;
  4.  err_msg VARCHAR2(100);
  5. BEGIN
  6.  SELECT ename INTO v_ename FROM emp WHERE empno=3000;
  7. EXCEPTION
  8.  WHEN OTHERS THEN
  9.      err_num := SQLCODE;
  10.      err_msg := SUBSTR(SQLERRM, 1, 100);
  11.      DBMS_OUTPUT.PUT_LINE(err_num||'----'||err_msg);
  12. END;
  13. /
  14. 100----ORA-01403: no data found
  15. PL/SQL procedure successfully completed.
这里使用了SQLCODE和SQLERRM函数

例4:再次抛出异常
  1. SQL> declare
  2.  2      v_course_no number := 430;
  3.  3      v_total number;
  4.  4      e_no_sections exception;
  5.  5  begin
  6.  6      begin
  7.  7          select count(*) into v_total from section where course_no = v_course_no;
  8.  8          if v_total=0 then
  9.  9              raise e_no_sections;
  10. 10          else
  11. 11          DBMS_OUTPUT.PUT_LINE('course, '||v_course_no||' has '||v_total||' section');
  12. 12          end if;
  13. 13      exception
  14. 14          when e_no_sections then
  15. 15              DBMS_OUTPUT.PUT_LINE('inner exception');
  16. 16          raise;
  17. 17      end;
  18. 18      DBMS_OUTPUT.PUT_LINE('done..');
  19. 19  exception
  20. 20      when e_no_sections then
  21. 21          DBMS_OUTPUT.PUT_LINE('outer exception');
  22. 22  end;
  23. 23  /
  24. inner exception
  25. outer exception
  26. PL/SQL procedure successfully completed.
  27. 内部的PLSQL块的exception中使用了raise,唤起外部plsql块的异常
  28. 所以没有执行DBMS_OUTPUT.PUT_LINE('done..');
  29. 而是直接进入了异常部分
  30. SQL> declare
  31.  2      v_course_no number := 430;
  32.  3      v_total number;
  33.  4      e_no_sections exception;
  34.  5  begin
  35.  6      begin
  36.  7          select count(*) into v_total from section where course_no = v_course_no;
  37.  8          if v_total=0 then
  38.  9              raise e_no_sections;
  39. 10          else
  40. 11          DBMS_OUTPUT.PUT_LINE('course, '||v_course_no||' has '||v_total||' section');
  41. 12          end if;
  42. 13      exception
  43. 14          when e_no_sections then
  44. 15              DBMS_OUTPUT.PUT_LINE('inner exception');
  45. 16         /* raise;*/
  46. 17      end;
  47. 18      DBMS_OUTPUT.PUT_LINE('done..');
  48. 19  exception
  49. 20      when e_no_sections then
  50. 21          DBMS_OUTPUT.PUT_LINE('outer exception');
  51. 22  end;
  52. 23  /
  53. inner exception
  54. done..
  55. PL/SQL procedure successfully completed.
  56. 没有raise再次抛出异常的例子

用户定义异常
通过raise唤起用户定义异常
  1. declare
  2. v_a number := &enter_value_for_a;
  3. v_err exception;
  4. begin
  5. if v_a > 2 then
  6. dbms_output.put_line(v_a);
  7. elsif v_a < 2 then
  8. raise v_err;
  9. end if;
  10. exception
  11. when v_err then
  12. dbms_output.put_line('wrong!!! a < 2');
  13. end;
  14. /
  15. Enter value for enter_value_for_a: 1
  16. wrong!!! a < 2
  17. PL/SQL procedure successfully completed.

RAISE_APPLICATION_ERROR
RAISE_APPLICATION_ERROR是oracle提供的一种特殊的内置过程,允许程序员为特定应用程序创建有意义的错误消息。
RAISE_APPLICATION_ERROR过程适用于用户定义异常。它的语法为:
    RAISE_APPLICATION_ERROR(error_number,error_message);
    或者
    RAISE_APPLICATION_ERROR(error_number,error_message,keep_errors);
正如所看到的那样,RAISE_APPLICATION_ERROR过程存在两种形式。第一种形式包含两个参数:error_number和erroe_message。
error_number是与特定错误消息相关联的错误编号。这个编号的范围在-20999和-20000之间。error_message是错误的文本,最多包含2048个字符。
    RAISE_APPLICATION_ERROR过程第二种形式还多包含一个参数:keep_errors,这是可选的Boolean参数。如果keep_errors被设置为True,新错误会被添加到已经被抛出的错误列表中.
这种错误列表被称为错误栈。如果keep_errors被设置为FALSE,新错误会替换已经被抛出的错误栈。keep_errors参数的默认值是FALSE。

目的是自定义一个错误编号和异常message,和oracle一起抛出错误
  1. declare
  2.    v_a number := &A;
  3.    v_result number;
  4. begin
  5.    if v_a < 0 then
  6.        raise_application_error(-20000,'wrong value');
  7.    end if;
  8.    v_result := sqrt(v_a);
  9.    dbms_output.put_line(v_result);
  10. end;
  11. /
  12. 输入 a 的值:  -1
  13. 原值    2: v_a number := &A;
  14. 新值    2: v_a number := -1;
  15. declare
  16. *
  17. 1 行出现错误:
  18. ORA-20000: wrong value
  19. ORA-06512: line 6


EXCEPTION_INIT
目的是把错误编号和我们自定义的异常关联起来,让用户体验更好
  1. 违反外键约束
  2. DECLARE
  3.  v_zip zipcode.zip%type := '&sv_zip';
  4. BEGIN
  5.  DELETE FROM zipcode WHERE zip = v_zip;
  6.  DBMS_OUTPUT.PUT_LINE('Zip ' || v_zip || ' has been deleted');
  7.  COMMIT;
  8. END;
  9. /
  10. Enter value for sv_zip: 06870
  11. DECLARE
  12. *
  13. ERROR at line 1:
  14. ORA-02292: integrity constraint (SCOTT.STU_ZIP_FK) violated - child record
  15. found
  16. ORA-06512: at line 4
  17. 现在我们通过PRAGMA EXCEPTION_INIT()捕获这个异常,并给出我们更友好的提示
  18. DECLARE
  19.  v_zip zipcode.zip%type := '&sv_zip';
  20.  e_child_exists EXCEPTION;
  21.  PRAGMA EXCEPTION_INIT(e_child_exists, -2292);
  22. BEGIN
  23.  DELETE FROM zipcode WHERE zip = v_zip;
  24.  DBMS_OUTPUT.PUT_LINE('Zip ' || v_zip || ' has been deleted');
  25.  COMMIT;
  26. EXCEPTION
  27.  WHEN e_child_exists THEN
  28.    DBMS_OUTPUT.PUT_LINE('Delete students for this ' || 'zipcode first');
  29. END;
  30. /
  31. Enter value for sv_zip: 06870
  32. Delete students for this zipcode first
  33. PL/SQL procedure successfully completed.
  1. 再来一个例子
  2. insert数据,not null的列不插入任何值,会报错
  3. begin
  4.    insert into emp(empno,ename) values(null,'fan');
  5.    commit;
  6. end;
  7. /
  8. SQL> begin
  9.  2  insert into emp(empno,ename) values(null,'fan');
  10. commit;
  11. end;
  12.  5  /
  13. begin
  14. *
  15. 1 行出现错误:
  16. ORA-01400: 无法将 NULL 插入 ("SCOTT"."EMP"."EMPNO")
  17. ORA-06512: line 2
  18. 然后我们关联ORA-01400这个错误
  19. declare
  20.    v_err exception;
  21.    pragma exception_init(v_err,-1400);
  22. begin
  23.    insert into emp(empno,ename) values(null,'fan');
  24.    commit;
  25. exception
  26.    when v_err then
  27.        dbms_output.put_line('你插了空值到非空列');
  28. end;
  29. /


注意
no_data_found -1403不可以用,因为no_data_found的sqlcode函数返回时100
  1. SQL> declare
  2.  2      v_err exception;
  3.  3      pragma exception_init(v_err,-01403);
  4.  4      v_number number;
  5.  5  begin
  6.  6      select empno into v_number from emp where empno=7777;
  7.  7  exception
  8.  8      when v_err then
  9.  9          dbms_output.put_line('no data found');
  10. 10  end;
  11. 11  /
  12.    v_err exception;
  13.    *
  14. ERROR at line 2:
  15. ORA-06550: line 2, column 5:
  16. PLS-00701: illegal ORACLE error number -1403 for PRAGMA EXCEPTION_INIT
  1. SQL> BEGIN
  2.  2    DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE);
  3.  3    DBMS_OUTPUT.PUT_LINE('Error message1: ' || SQLERRM(SQLCODE));
  4.  4    DBMS_OUTPUT.PUT_LINE('Error message2: ' || SQLERRM(100));
  5.  5    DBMS_OUTPUT.PUT_LINE('Error message3: ' || SQLERRM(200));
  6.  6    DBMS_OUTPUT.PUT_LINE('Error message4: ' || SQLERRM(-20000));
  7.  7  END;
  8.  8  /
  9. Error code: 0
  10. Error message1: ORA-0000: normal, successful completion
  11. Error message2: ORA-01403: no data found
  12. Error message3:  -200: non-ORACLE exception
  13. Error message4: ORA-20000:
  14. PL/SQL procedure successfully completed.
  1. declare
  2. v_a number := &enter_value_for_a;
  3. v_err exception;
  4. v_err_no number;
  5.    v_err_msg varchar2(200);
  6. begin
  7. if v_a > 2 then
  8. dbms_output.put_line(v_a);
  9. elsif v_a < 2 then
  10. raise v_err;
  11. end if;
  12. exception
  13. when v_err then
  14. dbms_output.put_line('a < 2');
  15. v_err_no := sqlcode;
  16.        v_err_msg := sqlerrm;
  17.        dbms_output.put_line(v_err_no);
  18.        dbms_output.put_line(v_err_msg);
  19. end;
  20. /
  21. Enter value for enter_value_for_a: 1
  22. a < 2
  23. 1
  24. User-Defined Exception
  25. PL/SQL procedure successfully completed.
同常SQLCODE函数会返回错误编号的复数。凡是也存在一些例外情况
当在异常部分的外部引用SQLCODE是,所返回的错误编号是0。错误编号是0意味着成功结束
当与用户定义异常一起使用SQLCODE函数时,返回的错误编号是+1.
当排除NO_DATA_FOUND异常时,SQLCODE函数返回100












1 0
原创粉丝点击