Oracle入门(十四.15)之捕获Oracle服务器异常

一、异常类型

本课讨论预定义和非预定义的Oracle服务器异常。


(1)使用PL / SQL处理异常

有两种提出异常的方法:
•Oracle服务器隐式(自动):

- 发生Oracle错误并自动引发相关异常。

- 例如,如果在SELECT语句中没有从数据库中检索行时发生错误ORA-01403,则PL / SQL引发异常NO_DATA_FOUND。

•程序员明确指出:

- 根据您的程序正在执行的业务功能,您可能必须明确提出异常。

- 通过在块内发出RAISE语句显式引发异常。

- 引发的异常可以是用户定义的或预定义的。 这些在下一课中解释。

(2)两种类型的Oracle服务器错误

    当发生Oracle服务器错误时,Oracle服务器会自动引发关联的异常,跳过块的可执行部分的其余部分,并在异常部分查找处理程序。

有两种类型的Oracle服务器错误:
•预定义的Oracle服务器错误:

- 每个错误都有一个预定义的名称。

- 例如,如果在SELECT语句中没有从数据库中检索到行时发生错误ORA-01403,则PL / SQL会引发预定义的异常名称NO_DATA_FOUND。

•非预定义的Oracle服务器错误:

- 这些错误中的每一个都有一个标准的Oracle错误编号(ORA-nnnnn)和错误消息,但不是预定义的名称。

- 为这些名称声明自己的名称,以便可以在异常部分中引用这些名称。

(3)捕获预定义的Oracle服务器错误

在异常处理例程中引用预定义的名称。
•预定义例外示例:

- NO_DATA_FOUND

- TOO_MANY_ROWS

- INVALID_CURSOR

- ZERO_DIVIDE

- DUP_VAL_ON_INDEX

有关预定义例外的部分列表,请参阅第0部分中的学生资源中提供的简短列表。

有关预定义例外的完整列表,请参阅PL / SQL用户指南和参考。

以下示例使用TOO_MANY_ROWS预定义的Oracle服务器错误。 请注意,它未在声明部分中声明。

DECLARE
 v_lname VARCHAR2(15);
BEGIN
 SELECT last_name INTO v_lname
 FROM employees WHERE job_id = 'ST_CLERK';
 DBMS_OUTPUT.PUT_LINE('The last name of the ST_CLERK is: '||v_lname);
EXCEPTION
 WHEN TOO_MANY_ROWS THEN
 DBMS_OUTPUT.PUT_LINE (' Your select statement retrieved multiple
rows. Consider using a cursor.');
END;

此示例处理TOO_MANY_ROWS和NO_DATA_FOUND,并在出现任何其他错误时使用OTHERS处理程序。

DECLARE
 v_lname VARCHAR2(15);
BEGIN
 SELECT last_name INTO v_lname
 FROM employees WHERE job_id = 'ST_CLERK';
 DBMS_OUTPUT.PUT_LINE('The last name of the ST_CLERK is: '||v_lname);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
 DBMS_OUTPUT.PUT_LINE ('Select statement found multiple rows');
 WHEN NO_DATA_FOUND THEN
 DBMS_OUTPUT.PUT_LINE ('Select statement found no rows');
 WHEN OTHERS THEN
 DBMS_OUTPUT.PUT_LINE ('Another type of error occurred');
END;

捕获非预定义的Oracle服务器错误非预定义的例外与预定义的例外类似; 但是,它们在PL / SQL中没有预定义的名称。 它们是标准的Oracle服务器错误,并具有ORA错误编号。

可以在DECLARE部分为他们创建自己的名称,并使用PRAGMA EXCEPTION_INIT函数将这些名称与ORA-错误号相关联。


•可以通过首先声明它来捕获非预定义的Oracle服务器错误。 声明的异常是隐含提出的。 在PL / SQL中,PRAGMA EXCEPTION_INIT指示编译器将异常名称与Oracle错误号关联。
•这允许通过名称引用任何Oracle Server异常并为其编写特定的处理程序。


二、非预定义错误

检查以下示例。

BEGIN
INSERT INTO departments
 (department_id, department_name) VALUES (280, NULL);
END;
ORA-01400: cannot insert NULL into (“USVA_TEST_SQL01_S01”.“DEPARTMENTS”. “DEPARTMENT_NAME”)

INSERT语句尝试插入department表的department_name列的值NULL。但是,操作不成功,因为department_name是NOT NULL列。 没有违反NOT NULL约束的预定义错误名称。解决此问题的方法是声明您自己的名称并将其与ORA-01400错误关联。

1.在声明部分声明异常的名称。


2.使用PRAGMA EXCEPTION_INIT函数将声明的异常与标准Oracle服务器错误号相关联。


3.在相应的异常处理例程中引用声明的异常名称。



三、捕获异常的函数

发生异常时,可以使用两个函数检索相关的错误代码或错误消息。
根据代码或消息的值,您可以决定采取哪些后续操作。
•SQLERRM返回包含与错误编号关联的消息的字符数据。

•SQLCODE返回错误代码的数字值。 (您可以将其分配给NUMBER变量。)


不能在SQL语句中直接使用SQLCODE或SQLERRM。 相反,您必须将它们的值分配给本地变量,然后使用SQL语句中的变量,如以下示例中所示:

DECLARE
 v_error_code NUMBER;
 v_error_message VARCHAR2(255);
BEGIN
...
EXCEPTION
 WHEN OTHERS THEN
 ROLLBACK;
 v_error_code := SQLCODE ;
 v_error_message := SQLERRM ;
 INSERT INTO error_log(e_user,e_date,error_code,error_message)
VALUES(USER,SYSDATE,v_error_code,v_error_message);
END;





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值