PL/SQL--EXCEPTION

来源:互联网 发布:波罗蜜全球购软件 编辑:程序博客网 时间:2024/05/21 18:35

PL/SQL--EXCEPTION

错误类型 报告者       处理方法
编译时错误 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 THEN10     DBMS_OUTPUT.PUT_LINE(SQLCODE || SQLERRM);11     V_SQLCODE := SQLCODE;12     V_SQLERRM := SQLERRM;13     --插入到异常信息表中14     INSERT INTO LOG_TABLE15     VALUES16       (V_SQLCODE, V_SQLCODE || '', 'ORACLE错误');17     COMMIT;18 END;
复制代码


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

复制代码
1 BEGIN2   RAISE_APPLICATION_ERROR('-20001', '11');3 EXCEPTION4   WHEN OTHERS THEN5     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 THEN11       DBMS_OUTPUT.PUT_LINE('捕捉到该异常 1 and 2' || SQLCODE || SQLERRM);12     WHEN V_EXCEPTION_1 THEN13      DBMS_OUTPUT.PUT_LINE('捕捉到该异常1' || SQLCODE || SQLERRM) ; WHEN14     WHEN V_EXCEPTION_2 THEN15       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 THEN12               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 EXCEPTION26   WHEN OTHERS THEN27     DBMS_OUTPUT.PUT_LINE('HWLLO WORLD');28 END;
复制代码


--捕捉声明部分的异常

--下面无法捕捉该异常

复制代码
1 DECLARE2   V_NUM NUMBER(10) := 'abc';3 BEGIN4   NULL;5 EXCEPTION6   WHEN OTHERS THEN7     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 EXCEPTION10   WHEN NO_DATA_FOUND THEN11     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   --发生位置110   RAISE V_EXP;11   V_COUNT := 2;12   --发生位置213   RAISE V_EXP;14   --发生位置315   V_COUNT := 3;16   RAISE V_EXP;17 EXCEPTION18   WHEN OTHERS THEN19     DBMS_OUTPUT.PUT_LINE('在位置' || V_COUNT || '发生错误');20     V_CODE    := SQLCODE;21     V_MESSAGE := SQLERRM;22     V_INFO    := '在位置' || V_COUNT || '发生错误';23     INSERT INTO LOG_TABLE24       (CODE, MESSAGE, INFO, CREATE_TIME)25     VALUES26       (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   BEGIN10     RAISE V_EXP;11   EXCEPTION12     WHEN OTHERS THEN13       DBMS_OUTPUT.PUT_LINE('在位置1发生错误');14       V_CODE    := SQLCODE;15       V_MESSAGE := SQLERRM;16       V_INFO    := '在位置1发生错误';17       INSERT INTO LOG_TABLE18         (CODE, MESSAGE, INFO, CREATE_TIME)19       VALUES20         (V_CODE, V_MESSAGE, V_INFO, SYSDATE);21       COMMIT;22   END;23   --发生位置224   BEGIN25     RAISE V_EXP;26   EXCEPTION27     WHEN OTHERS THEN28       DBMS_OUTPUT.PUT_LINE('在位置2发生错误');29       V_CODE    := SQLCODE;30       V_MESSAGE := SQLERRM;31       V_INFO    := '在位置2发生错误';32       INSERT INTO LOG_TABLE33         (CODE, MESSAGE, INFO, CREATE_TIME)34       VALUES35         (V_CODE, V_MESSAGE, V_INFO, SYSDATE);36       COMMIT;37   END;38 END;
复制代码

原创粉丝点击