异常处理语句
异常处理语句共包括三个部分:
- 异常定义
- 抛出异常
- 异常处理
异常定义ExceptionDef
语法格式
sql
ExceptionDef::=
exception_name EXCEPTION
参数说明
ExceptionDef
:用户自定义异常语句,使用关键字EXCEPTION
在DECLARE中定义。exception_name
:用户自定义异常名称。
抛出异常ThrowStmt
语法格式
sql
ThrowStmt::=
{RAISE | THROW} [EXCEPTION] exception_name;
参数说明
ThrowStmt
:抛出异常语句,抛出异常语句在块语句体或过程体中使用,可使用关键字RAISE
或THROW
。b_expr
:附带错误信息。
异常处理OptExceptionStmt
语法格式
sql
OptExceptionStmt::=
EXCEPTION Exception_Item [Exception_Item...]
Exception_Item::=
WHEN exception_name THEN pl_stmt_list
| WHEN ICONST THEN pl_stmt_list
可以有多个WHEN子句,每个子句处理一种特定的异常。使用WHEN OTHERS THEN可以捕获所有未被捕获的异常。
参数说明
ICONST
:预定义的系统异常,如ERR_MORE_DATA_FOUND
、ERR_NO_DATA_FOUND
等。pl_stmt_list
:异常发生时执行的PL/SQL语句列表。
示例
示例1
定义一个常数变量与两个异常定义的块语句,当常数变量x大于0时抛出异常exce_1,否则抛出exce_2;对应exce_1的异常处理输出消息“raise exception 1”,对应exce_2异常处理输出消息“raise exception 2”,其他异常则输出“others exception”。sqlDECLARE x INT; exce_1 EXCEPTION; exce_2 EXCEPTION; BEGIN x:=1; IF x>0 THEN RAISE exce_1; ELSE RAISE exce_2; END IF; EXCEPTION WHEN exce_1 THEN DBMS_OUTPUT.PUT_LINE('raise exception 1'); WHEN exce_2 THEN DBMS_OUTPUT.PUT_LINE('raise exception 2'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('others exception'); END; / -- 输出: raise exception 1
示例2
定义错误信息直接抛出错误不进入异常处理流程。sqlDECLARE exec EXCEPTION; BEGIN IF 1!=2 THEN RAISE exec '数据错误'; END IF; END; / -- 输出: Error: [E50001 L5 C1] 数据错误
示例3
存储过程直接使用系统预定义的异常。捕获异常后,执行相应的处理。说明:
自V12.7版本起,支持预定义异常:
DUP_VAL_ON_INDEX
:违反唯一值约束,对应之前版本ERR_DUP_VAL_ON_INDEX
。NO_DATA_FOUND
:未找到任何数据,对应之前版本ERR_NO_DATA_FOUND
。TOO_MANY_ROWS
:查询结果过多,对应之前版本ERR_MORE_DATA_FOUND
。ZERO_DIVIDE
:除数为0,对应之前版本ERR_DIV_ZERO
。
sqlSQL> CREATE TABLE EMP(emp_id INT,name VARCHAR(32), age SMALLINT); SQL> CREATE OR REPLACE PROCEDURE test_proc(id INT) AS temp_name VARCHAR(32); BEGIN -- 查询并返回数据 SELECT name INTO temp_name FROM EMP WHERE emp_id = id; DBMS_OUTPUT.PUT_LINE(temp_name); EXCEPTION -- 异常处理 WHEN NO_DATA_FOUND THEN -- 没有找到数据 DBMS_OUTPUT.PUT_LINE('没有找到该员工'); WHEN TOO_MANY_ROWS THEN -- 找到多条数据 DBMS_OUTPUT.PUT_LINE('找到多个员工:' || temp_name); WHEN OTHERS THEN -- 其他异常 DBMS_OUTPUT.PUT_LINE('发生其它错误'); END; / SQL> EXEC test_proc(1); 没有找到该员工