Oracle游标使用方法及语法大全 下载本文

EXCEPTION

WHEN 错误1[OR 错误2] THEN 语句序列1;

WHEN 错误3[OR 错误4] THEN 语句序列2; WHEN OTHERS 语句序列n; END; 其中:

错误是在标准包中由系统预定义的标准错误,或是由用户在程序的说明部分自定义的错误,参见下一节系统预定义的错误类型。 语句序列就是不同分支的错误处理部分。

凡是出现在WHEN后面的错误都是可以捕捉到的错误,其他未被捕捉到的错误,将在WHEN OTHERS部分进行统一处理,OTHENS必须是EXCEPTION部分的最后一个错误处理分支。如要在该分支中进一步判断错误种类,可以通过使用预定义函数SQLCODE( )和SQLERRM( )来获得系统错误号和错误信息。

如果在程序的子块中发生了错误,但子块没有错误处理部分,则错误会传递到主程序中。 下面是由于查询编号错误而引起系统预定义异常的例子。 【训练1】 查询编号为1234的雇员名字。 Sql代码

1. SET SERVEROUTPUT ON 2. DECLARE

3. v_name VARCHAR2(10); 4. BEGIN 5. 6. 7. 8.

SELECT ename INTO v_name FROM emp

WHERE empno = 1234;

9. DBMS_OUTPUT.PUT_LINE('该雇员名字为:'|| v_name);

10. EXCEPTION

11. WHEN NO_DATA_FOUND THEN

12. DBMS_OUTPUT.PUT_LINE('编号错误,没有找到相应雇员!'); 13. WHEN OTHERS THEN

14. DBMS_OUTPUT.PUT_LINE('发生其他错误!'); 15. END;

执行结果为: Sql代码

1. 编号错误,没有找到相应雇员! 2. PL/SQL 过程已成功完成。

说明:在以上查询中,因为编号为1234的雇员不存在,所以将发生类型为“NO_DATA_ FOUND”的异常。“NO_DATA_FOUND”是系统预定义的错误类型,EXCEPTION部分下的WHEN语句将捕捉到该异常,并执行相应代码部分。在本例中,输出用户自定义的错误信息“编号错误,没有找到相应雇员!”。如果发生其他类型的错误,将执行OTHERS条件下的代码部分,显示“发生其他错误!”。

【训练2】 由程序代码显示系统错误。 Sql代码

1. SET SERVEROUTPUT ON 2. DECLARE

3. v_temp NUMBER(5):=1; 4. BEGIN

5. v_temp:=v_temp/0; 6. EXCEPTION

7. WHEN OTHERS THEN

8. DBMS_OUTPUT.PUT_LINE('发生系统错误!');

9. DBMS_OUTPUT.PUT_LINE('错误代码:'|| SQLCODE( )); 10. DBMS_OUTPUT.PUT_LINE('错误信息:' ||SQLERRM( )); 11. END;

执行结果为: Sql代码

1. 发生系统错误!

2. 错误代码:?1476

3. 错误信息:ORA-01476: 除数为 0 4. PL/SQL 过程已成功完成。

说明:程序运行中发生除零错误,由WHEN OTHERS捕捉到,执行用户自己的输出语句显示错误信息,然后正常结束。在错误处理部分使用了预定义函数SQLCODE( )和SQLERRM( )来进一步获得错误的代码和种类信息。

预定义错误

Oracle的系统错误很多,但只有一部分常见错误在标准包中予以定义。定义的错误可以在EXCEPTION部分通过标准的错误名来进行判断,并进行异常处理。常见的系统预定义异常如下所示。 Sql代码

1. 错 误 名 称 错误代码 错 误 含 义

2. CURSOR_ALREADY_OPEN ORA_06511 试图打开已经打开的游标 3. INVALID_CURSOR ORA_01001 试图使用没有打开的游标

4. DUP_VAL_ON_INDEX ORA_00001 保存重复值到惟一索引约束的列中 5. ZERO_DIVIDE ORA_01476 发生除数为零的除法错误

6. INVALID_NUMBER ORA_01722 试图对无效字符进行数值转换

7. ROWTYPE_MISMATCH ORA_06504 主变量和游标的类型不兼容 8. VALUE_ERROR ORA_06502 转换、截断或算术运算发生错误

9. TOO_MANY_ROWS ORA_01422 SELECT?INTO?语句返回多于一行的数据 10. NO_DATA_FOUND ORA_01403 SELECT?INTO?语句没有数据返回 11. TIMEOUT_ON_RESOURCE ORA_00051 等待资源时发生超时错误 12. TRANSACTION_BACKED_OUT ORA_00060 由于死锁,提交失败 13. STORAGE_ERROR ORA_06500 发生内存错误

14. PROGRAM_ERROR ORA_06501 发生PL/SQL内部错误 15. NOT_LOGGED_ON ORA_01012 试图操作未连接的数据库 16. LOGIN_DENIED ORA_01017 在连接时提供了无效用户名或口令

比如,如果程序向表的主键列插入重复值,则将发生DUP_VAL_ON_INDEX错误。 如果一个系统错误没有在标准包中定义,则需要在说明部分定义,语法如下: 错误名 EXCEPTION;

定义后使用PRAGMA EXCEPTION_INIT来将一个定义的错误同一个特别的Oracle错误代码相关联,就可以同系统预定义的错误一样使用了。语法如下: PRAGMA EXCEPTION_INIT(错误名,- 错误代码); 【训练1】 定义新的系统错误类型。 Sql代码

1. SET SERVEROUTPUT ON 2. DECLARE

3. V_ENAME VARCHAR2(10); 4. 5. 6. 7.

NULL_INSERT_ERROR EXCEPTION;

PRAGMA EXCEPTION_INIT(NULL_INSERT_ERROR,-1400); BEGIN

INSERT INTO EMP(EMPNO) VALUES(NULL);

8. EXCEPTION

9. WHEN NULL_INSERT_ERROR THEN

10. DBMS_OUTPUT.PUT_LINE('无法插入NULL值!'); 11. WHEN OTHERS THEN

12. DBMS_OUTPUT.PUT_LINE('发生其他系统错误!'); 13. END;

执行结果为: Sql代码

1. 无法插入NULL值!

2. PL/SQL 过程已成功完成。

说明:NULL_INSERT_ERROR是自定义异常,同系统错误1400相关联。

自定义异常

程序设计者可以利用引发异常的机制来进行程序设计,自己定义异常类型。可以在声明部分定义新的异常类型,定义的语法是: 错误名 EXCEPTION;

用户定义的错误不能由系统来触发,必须由程序显式地触发,触发的语法是:

RAISE 错误名;

RAISE也可以用来引发模拟系统错误,比如,RAISE ZERO_DIVIDE将引发模拟的除零错误。 使用RAISE_APPLICATION_ERROR函数也可以引发异常。该函数要传递两个参数,第一个是用户自定义的错误编号,第二个参数是用户自定义的错误信息。使用该函数引发的异常的编号应该在20 000和20 999之间选择。 自定义异常处理错误的方式同前。

【训练1】 插入新雇员,限定插入雇员的编号在7000~8000之间。 Java代码

1. SET SERVEROUTPUT ON

2. DECLARE

3. new_no NUMBER(10); 4. new_excp1 EXCEPTION; 5. new_excp2 EXCEPTION; 6. BEGIN

7. new_no:=6789;

8. INSERT INTO emp(empno,ename) 9. VALUES(new_no, '小郑'); 10. IF new_no<7000 THEN 11. RAISE new_excp1; 12. END IF;

13. IF new_no>8000 THEN 14. RAISE new_excp2; 15. END IF; 16. COMMIT;

17. EXCEPTION

18. WHEN new_excp1 THEN 19. ROLLBACK;

20. DBMS_OUTPUT.PUT_LINE('雇员编号小于7000的下限!'); 21. WHEN new_excp2 THEN 22. ROLLBACK;

23. DBMS_OUTPUT.PUT_LINE('雇员编号超过8000的上限!'); 24. END;

执行结果为:

雇员编号小于7000的下限! PL/SQL 过程已成功完成。

说明:在此例中,自定义了两个异常:new_excp1和new_excp2,分别代表编号小于7000和编号大于8000的错误。在程序中通过判断编号大小,产生对应的异常,并在异常处理部