PL/SQL 专题
您的位置:database > PL/SQL专题 > PL/SQL异常处理
PL/SQL异常处理
作者:--    发布时间:2019-11-20

在本章中,我们将讨论和学习pl/sql中的异常。 程序执行过程中的错误情况是一个例外(异常)。 pl/sql支持程序员在程序中使用exception块捕获这些发生错误的条件,并针对错误情况采取适当的措施。pl/sql中有两种异常 -

  • 系统定义的异常
  • 用户定义的异常

异常处理的语法

异常处理的一般语法如下。在这里,可以列举尽可能多的异常并且指定处理方式。默认的异常将使用when...then处理,如下语法所示 -

declare 
   <declarations section> 
begin 
   <executable command(s)> 
exception 
   <exception handling goes here > 
   when exception1 then  
      exception1-handling-statements  
   when exception2  then  
      exception2-handling-statements  
   when exception3 then  
      exception3-handling-statements 
   ........ 
   when others then 
      exception3-handling-statements 
end;

示例

下面写一个代码来说明和理解这个概念,这里使用前面章节中创建和使用的customers表,结构和数据如下 -

create table customers( 
   id   int not null, 
   name varchar (20) not null, 
   age int not null, 
   address char (25), 
   salary   decimal (18, 2),        
   primary key (id) 
);
-- 向customers表中插入一些数据记录 
insert into customers (id,name,age,address,salary) 
values (1, 'ramesh', 32, 'ahmedabad', 2000.00 );  

insert into customers (id,name,age,address,salary) 
values (2, 'khilan', 25, 'delhi', 1500.00 );  

insert into customers (id,name,age,address,salary) 
values (3, 'kaushik', 23, 'kota', 2000.00 );

insert into customers (id,name,age,address,salary) 
values (4, 'chaitali', 25, 'mumbai', 6500.00 ); 

insert into customers (id,name,age,address,salary) 
values (5, 'hardik', 27, 'bhopal', 8500.00 );  

insert into customers (id,name,age,address,salary) 
values (6, 'komal', 22, 'mp', 4500.00 );

下面是一个未找到数据记录时的异常处理 -

set serveroutput on size 99999;
declare 
   c_id customers.id%type := 100; 
   c_name  customers.name%type; 
   c_addr customers.address%type; 
begin 
   select  name, address into  c_name, c_addr 
   from customers 
   where id = c_id;  
   dbms_output.put_line ('姓名: '||  c_name); 
   dbms_output.put_line ('地址: ' || c_addr); 

exception 
   when no_data_found then 
      dbms_output.put_line('没有找到符合条件的客户信息!'); 
   when others then 
      dbms_output.put_line('error!'); 
end; 
/

执行上面示例代码,得到以下结果 -

上面的程序用于显示指定id的客户的名字和地址。但是由于数据库customers表中并没有id值为100的客户,因此程序引发异常,并在exception块中捕获的运行时异常no_data_found,因此最后打印了信息:‘没有找到符合条件的客户信息!’

引发异常

只要有内部数据库错误,数据库服务器就会自动产生(引发)异常,但程序员可以使用命令raise明确地引发异常。以下是引发异常的简单语法 -

declare 
   exception_name exception; 
begin 
   if condition then 
      raise exception_name; 
   end if; 
exception 
   when exception_name then 
   statement; 
end;

可以使用上述语法来引发oracle标准异常或任何用户定义的异常。 在下一节中,我们将举例说明引发用户定义的异常。您可以用类似的方式引发oracle中标准异常。

用户定义的异常

pl/sql允许根据程序的需要定义自己的异常。 用户定义的异常必须声明,然后使用raise语句或过程dbms_standard.raise_application_error显式地引发。

声明异常的语法是 -

declare 
   my-exception exception;

示例

以下示例说明了这个概念。这个程序要求输入一个客户id,当用户输入一个无效的id时,会引发异常invalid_id。参考以下示例代码的实现 -

set serveroutput on size 9999;
declare 
   c_id customers.id%type := &cc_id; 
   c_name  customers.name%type; 
   c_addr customers.address%type;  
   -- user defined exception 
   ex_invalid_id  exception; 
begin 
   if c_id <= 0 then 
      raise ex_invalid_id; 
   else 
      select  name, address into  c_name, c_addr 
      from customers 
      where id = c_id;
      dbms_output.put_line ('姓名: '||  c_name);  
      dbms_output.put_line ('地址: ' || c_addr); 
   end if; 

exception 
   when ex_invalid_id then 
      dbms_output.put_line('编号id必须要大于0!'); 
   when no_data_found then 
      dbms_output.put_line('未找到指定id的客户信息!'); 
   when others then 
      dbms_output.put_line('error!');  
end; 
/

执行上面示例代码,得到以下结果 -

输入 cc_id 的值:  -1
原值    2:    c_id customers.id%type := &cc_id;
新值    2:    c_id customers.id%type := -1;
编号id必须要大于0!

pl/sql 过程已成功完成。

预定义的异常

pl/sql提供了许多预定义的异常,这些异常在程序违反任何数据库规则时执行。 例如,当select into语句不返回任何行时,会引发预定义的异常no_data_found。下表列出了一些重要的预定义异常情况 -

异常 oracle错误代码 sqlcode 描述
access_into_null 06530 -6530 当一个空对象被自动分配一个值时会引发它。
case_not_found 06592 -6592 当没有选择case语句的when子句中的任何选项时,会引发这个错误,并且没有else子句。
collection_is_null 06531 -6531 当程序尝试将exists以外的集合方法应用于未初始化的嵌套表或varray时,或程序尝试将值分配给未初始化的嵌套表或varray的元素时,会引发此问题。
dup_val_on_index 00001 -1 当尝试将重复值存储在具有唯一索引的列中时引发此错误。
invalid_cursor 01001 -1001 当尝试进行不允许的游标操作(例如关闭未打开的游标)时会引发此错误。
invalid_number 01722 -1722 当字符串转换为数字时失败,因为字符串不代表有效的数字。
login_denied 01017 -1017 当程序尝试使用无效的用户名或密码登录到数据库时引发。
no_data_found 01403 +100 select into语句不返回任何行时会引发它。
not_logged_on 01012 -1012 当数据库调用没有连接到数据库时引发。
program_error 06501 -6501 当pl/sql遇到内部问题时会引发。
rowtype_mismatch 06504 -6504 当游标在具有不兼容数据类型的变量中获取值时引发。
self_is_null 30625 -30625 当调用成员方法时引发,但对象类型的实例未初始化。
storage_error 06500 -6500 当pl/sql用尽内存或内存已损坏时引发。
too_many_rows 01422 -1422 select into语句返回多行时引发。
value_error 06502 -6502 当发生算术,转换,截断或者sizeconstraint错误时引发。
zero_divide 01476 1476 当尝试将数字除以零时引发。

网站声明:
本站部分内容来自网络,如您发现本站内容
侵害到您的利益,请联系本站管理员处理。
联系站长
373515719@qq.com
关于本站:
编程参考手册