自定义例外是指由PL/SQL开发人员所定义的例外。预定义例外和非预定义例外都和Oracle错误有关,并且出现Oracle错误时会隐含的处罚相应例外;而自定义例外与Oracle错误没有任何关联,它是由开发人员为特定情况所定义的例外。 看一看以下PL/SQL块的运行。 decla
自定义例外是指由PL/SQL开发人员所定义的例外。预定义例外和非预定义例外都和Oracle错误有关,并且出现Oracle错误时会隐含的处罚相应例外;而自定义例外与Oracle错误没有任何关联,它是由开发人员为特定情况所定义的例外。
看一看以下PL/SQL块的运行。
1 2 3 4 5 6 7 8 9 | declare
e_integrity exception;
pragma exception_init(e_integrity,-2291);
begin
update emp set deptno=&dno where empno=&eno;
exception
when e_integrity then
dbms_output.put_line( '该部门不存在' );
end ;
|
ログイン後にコピー
使用例外函数:
1、SQLCODE 和SQLERRM
SQLCODE用于返回Oracle错误号,而SQLERRM则用于返回错误号所对应的错误消息。为了在PL/SQL应用程序中处理其他未预料到的Oracle错误,用户可以在例外处理部分的WHEN OTHERS 子句后引用这两个函数,以取得相关的Oracle错误.示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | DECLARE
v_ename emp.ename%type;
BEGIN
SELECT ename INTO v_ename
FROM emp
WHERE sal=&v_sal;
dbms_output.put_line( '雇员名:' ||v_ename);
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line( '不存在工资为' ||&v_sal|| '的雇员' );
WHEN OTHERS THEN
dbms_output.put_line( '错误号:' ||SQLCODE);
dbms_output.put_line(SQLERRM);
END ;
|
ログイン後にコピー
当输入v_sal:1250时。
1 2 | 错误号:-1422
ORA-01422: 实际返回的行数超出请求的行数
|
ログイン後にコピー
2. RAISE_APPLICATION_ERROR
该函数用于在PL/SQL应用程序中自定义错误消息。注意该过程只能在数据端的子过程(过程、函数、包、触发器)中使用,而不能在匿名块和客户端的子程序中使用,使用该函数的语法如下:
raise_application_error(error_number,message[ , {TRUE| FALSE}]);
其中,error_number用于定义错误号,该错误号必须是在-20000至-20999之间的负整数;message用于指定错误消息,并且该消息的长度不能超过2048字节;第三个参数为可选参数,如果设置为TURE,则该错误会放在先前错误的堆栈中;如果设置为FALSE(默认值),则会替换先前所有的错误。使用该过程的示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | CREATE OR REPLACE PROCEDURE raise_comm
(eno number,
commission number
)
IS
v_comm emp.comm%TYPE;
BEGIN
SELECT comm INTO v_comm
FROM emp
WHERE empno=eno;
IF v_comm IS NULL THEN
RAISE_APPLICATION_ERROR(-20021, '该雇员无补助啊' ,TRUE);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line( '该雇员不存在' );
END ;
|
ログイン後にコピー
call raise_comm(7900,100);
显示如下错误:
ORA-20021: 该雇员无补助啊
ORA-06512: 在 "SCOTT.RAISE_COMM", line 13
上面出现的错误,会在异常栈中打印出来。
下面是本人认为比较不错的异常处理方式:
一般情况下,我们会把异常名和异常号进行绑定,可能就是你所想要的结果吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | DECLARE
vnumber NUMBER(4);
biger EXCEPTION; --异常名
PRAGMA EXCEPTION_INIT(biger,-20001); --异常名和异常号绑定
equal EXCEPTION;
PRAGMA EXCEPTION_INIT(equal,-20002);
small EXCEPTION;
PRAGMA EXCEPTION_INIT(small,-20003);
BEGIN
vnumber:=&vnumber;
IF vnumber >10 THEN
RAISE_APPLICATION_ERROR(-20001, '哈哈,大于10啊' );
ELSIF vnumber = 10 THEN
RAISE_APPLICATION_ERROR(-20002, '嗯,等于10...' );
ELSIF vnumber
<p> </p>
<p>除了上面自定义的异常,我们还可以采用下面的这种方式定义异常</p>
<pre class = "brush:php;toolbar:false" > CREATE OR REPLACE PROCEDURE pro_emp
(
--- 多个用逗号隔开
v_eno IN NUMBER
)
IS
--------多个用分号隔开
v_max_id NUMBER;
v_ename VARCHAR2(10);
v_raise EXCEPTION; ---------定义一个异常
BEGIN
SELECT max(a.empno) into v_max_id from emp a;
IF v_eno >v_max_id THEN
RAISE v_raise; ---遇到例外,执行这个异常,退出程序 进入到Exception部分
END IF;
SELECT ename into v_ename from emp where empno=v_eno;
dbms_output.put_line( '员工名称为:' ||v_ename);
EXCEPTION
WHEN v_raise THEN ---------捕获v_raise异常
dbms_output.put_line( 'V_ENO大于最大员工号' );
WHEN NO_DATA_FOUND THEN
dbms_output.put_line( '没有获得有效数据' );
END ;
|
ログイン後にコピー