PL/SQLEXCEPTION

错误类型      报告者                                    处理方法
编译时错误   PL/SQL编译器 编译器报告错误,             必须进行处理
运行时错误   PL/SQL运行时引擎 程序化的处理,          异常由异常处理程序引发不进行捕获

常用的两个参数分别是:
SQLCODE:返回的是当前的错误代号
SQLERRM:返回的是当前的错误信息文本

如果是用户自定义异常:

SQLCODE的值为:1
SQLERRM的值为:User-Defined EXCEPTION

 1 DECLARE
2 V_1 NUMBER(10) := 100;
3 V_2 NUMBER(10) := 0;
4 V_SQLCODE LOG_TABLE.CODE%TYPE;
5 V_SQLERRM LOG_TABLE.MESSAGE%TYPE;
6 BEGIN
7 RAISE NO_DATA_FOUND;
8 EXCEPTION
9 WHEN OTHERS THEN
10 DBMS_OUTPUT.PUT_LINE(SQLCODE || SQLERRM);
11 V_SQLCODE := SQLCODE;
12 V_SQLERRM := SQLERRM;
13 --插入到异常信息表中
14 INSERT INTO LOG_TABLE
15 VALUES
16 (V_SQLCODE, V_SQLCODE || '', 'ORACLE错误');
17 COMMIT;
18 END;


异常主要有两种类型
用户自定义异常 my_exception EXCEPTION 使用raise关键子来抛出异常
RAISE_APPLICATION_ERROR(错误代号, 错误信息);
错误代号必须介于-20000到-200999之间

1 BEGIN
2 RAISE_APPLICATION_ERROR('-20001', '11');
3 EXCEPTION
4 WHEN OTHERS THEN
5 DBMS_OUTPUT.PUT_LINE(SQLCODE);
6 DBMS_OUTPUT.PUT_LINE(SQLERRM);
7 END;


抛出自定义异常:

 1 DECLARE
2 MY_EXCEPTION EXCEPTION;
3 BEGIN
4 RAISE MY_EXCEPTION;
5 EXCEPTION
6 WHEN MY_EXCEPTION THEN
7 DBMS_OUTPUT.PUT_LINE(SQLCODE);
8 DBMS_OUTPUT.PUT_LINE(SQLERRM);
9 DBMS_OUTPUT.PUT_LINE('我抓到你了');
10 END;


预定义异常 这些是常用的异常,在standard包中定义。常见的有以下几种:
no_data_found 没有找到数据
zero_divide 被0整除
too_many_rows 查出多行记录
values_error 切割运算,算术运算,和转换运算中出现错误,一般在declare声明语句中会出现该异常
异常处理语句的语法:

1 EXCEPTION 
2 WHEN exception1 THEN 处理语句1;
3 WHEN exception2 THEN 处理语句2;
4 WHEN exception3 THEN 处理语句3;
5 WHEN OTHERS 处理语句
6 END;

--一个异常处理语句只可以出现一次。可以使用,
WHEN V_EXCEPTION_1 OR V_EXCEPTION_2
但是不可以使用WHEN V_EXCEPTION_1 AND V_EXCEPTION_2

 1 DECLARE
2 V_EXCEPTION_1 EXCEPTION;
3 V_EXCEPTION_2 EXCEPTION;
4 BEGIN
5 RAISE V_EXCEPTION_1;
6 RAISE V_EXCEPTION_2;
7 EXCEPTION
8 WHEN V_EXCEPTION_1 OR V_EXCEPTION_2 THEN
9 DBMS_OUTPUT.PUT_LINE('捕捉到该异常1 or 2' || SQLCODE || SQLERRM);
10 /*WHEN V_EXCEPTION_1 AND V_EXCEPTION_2 THEN
11 DBMS_OUTPUT.PUT_LINE('捕捉到该异常 1 and 2' || SQLCODE || SQLERRM);
12 WHEN V_EXCEPTION_1 THEN
13 DBMS_OUTPUT.PUT_LINE('捕捉到该异常1' || SQLCODE || SQLERRM) ; WHEN
14 WHEN V_EXCEPTION_2 THEN
15 DBMS_OUTPUT.PUT_LINE('捕捉到该异常2' || SQLCODE || SQLERRM);*/
16 END;


--使用goto导航

 1 BEGIN
2 <<BLOCK_1>>
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE('1');
5 BEGIN
6 BEGIN
7 BEGIN
8 BEGIN
9 DBMS_OUTPUT.PUT_LINE('11');
10 --RETURN ;
11 IF 1 = 1 THEN
12 GOTO BLOCK_2; --导航至最后一个标签,退出语句块
13 END IF;
14 END;
15 END;
16 END;
17 END;
18 END BLOCK_1;
19 <<BLOCK_2>>
20 DBMS_OUTPUT.PUT_LINE('2');
21 RETURN;
22 <<BLOCK_3>>
23 DBMS_OUTPUT.PUT_LINE('3');
24 RETURN;
25 EXCEPTION
26 WHEN OTHERS THEN
27 DBMS_OUTPUT.PUT_LINE('HWLLO WORLD');
28 END;


--捕捉声明部分的异常

--下面无法捕捉该异常

1 DECLARE
2 V_NUM NUMBER(10) := 'abc';
3 BEGIN
4 NULL;
5 EXCEPTION
6 WHEN OTHERS THEN
7 DBMS_OUTPUT.PUT_LINE('无法捕捉value_errors');
8 END;

只能把其放置在内置块中:

 1 BEGIN
2 DECLARE
3 V_NUM NUMBER(10) := 'abc';
4 BEGIN
5 NULL;
6 END;
7 EXCEPTION
8 WHEN OTHERS THEN
9 DBMS_OUTPUT.PUT_LINE('可以捕捉到');
10 END;


--RAISE关键字单独使用的时候,表示再次抛出相同的异常

 1 BEGIN
2 BEGIN
3 RAISE NO_DATA_FOUND;
4 EXCEPTION
5 WHEN NO_DATA_FOUND THEN
6 DBMS_OUTPUT.PUT_LINE('HELLO WORLD1');
7 RAISE; --表示再次抛出相同的异常,由其父语句块进行处理
8 END;
9 EXCEPTION
10 WHEN NO_DATA_FOUND THEN
11 DBMS_OUTPUT.PUT_LINE('HELLO WORLD2');
12 END;


记录发生位置的异常信息,处理方法,

 1 DECLARE
2 V_COUNT NUMBER(10) := 1;
3 V_EXP EXCEPTION;
4 V_CODE LOG_TABLE.CODE%TYPE;
5 V_MESSAGE LOG_TABLE.MESSAGE%TYPE;
6 V_INFO LOG_TABLE.INFO%TYPE;
7 V_CREATE_TIME LOG_TABLE.CREATE_TIME%TYPE;
8 BEGIN
9 --发生位置1
10 RAISE V_EXP;
11 V_COUNT := 2;
12 --发生位置2
13 RAISE V_EXP;
14 --发生位置3
15 V_COUNT := 3;
16 RAISE V_EXP;
17 EXCEPTION
18 WHEN OTHERS THEN
19 DBMS_OUTPUT.PUT_LINE('在位置' || V_COUNT || '发生错误');
20 V_CODE := SQLCODE;
21 V_MESSAGE := SQLERRM;
22 V_INFO := '在位置' || V_COUNT || '发生错误';
23 INSERT INTO LOG_TABLE
24 (CODE, MESSAGE, INFO, CREATE_TIME)
25 VALUES
26 (V_CODE, V_MESSAGE, V_INFO, SYSDATE);
27 COMMIT;
28 END;

--也可以单独的使用各个内置块独立的处理

 1 DECLARE
2 V_EXP EXCEPTION;
3 V_CODE LOG_TABLE.CODE%TYPE;
4 V_MESSAGE LOG_TABLE.MESSAGE%TYPE;
5 V_INFO LOG_TABLE.INFO%TYPE;
6 V_CREATE_TIME LOG_TABLE.CREATE_TIME%TYPE;
7 BEGIN
8 --发生位置1
9 BEGIN
10 RAISE V_EXP;
11 EXCEPTION
12 WHEN OTHERS THEN
13 DBMS_OUTPUT.PUT_LINE('在位置1发生错误');
14 V_CODE := SQLCODE;
15 V_MESSAGE := SQLERRM;
16 V_INFO := '在位置1发生错误';
17 INSERT INTO LOG_TABLE
18 (CODE, MESSAGE, INFO, CREATE_TIME)
19 VALUES
20 (V_CODE, V_MESSAGE, V_INFO, SYSDATE);
21 COMMIT;
22 END;
23 --发生位置2
24 BEGIN
25 RAISE V_EXP;
26 EXCEPTION
27 WHEN OTHERS THEN
28 DBMS_OUTPUT.PUT_LINE('在位置2发生错误');
29 V_CODE := SQLCODE;
30 V_MESSAGE := SQLERRM;
31 V_INFO := '在位置2发生错误';
32 INSERT INTO LOG_TABLE
33 (CODE, MESSAGE, INFO, CREATE_TIME)
34 VALUES
35 (V_CODE, V_MESSAGE, V_INFO, SYSDATE);
36 COMMIT;
37 END;
38 END;

 

 

I believe that we are who we choose to be. Nobody‘s going to come and save you, you‘ve got to save yourself. 我相信我们成为怎样的人是我们自己的选择。没有人会来拯救你,你必须要自己拯救自己。
原文地址:https://www.cnblogs.com/caroline/p/2289559.html