PL/SQL - 异常(Exceptions)

PL/SQL - 异常(Exceptions) 首页 / PL/SQL入门教程 / PL/SQL - 异常(Exceptions)

在本章中,无涯教程将讨论PL/SQL中的异常,异常是程序执行期间的错误条件, PL/SQL支持程序员使用程序中的 EXCEPTION 块捕获此类条件,并针对错误条件采取适当的措施。有两种类型的异常-

  • System-defined 异常
  • User-defined     异常

异常处理语法

异常处理的一般语法如下,在这里,您可以列出尽可能多的异常,默认异常将使用 当其他则THEN 处理-

链接:https://www.learnfk.comhttps://www.learnfk.com/plsql/plsql-exceptions.html

来源:LearnFk无涯教程网

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表-

DECLARE 
   c_id customers.id%type := 8; 
   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 ('Name: '||  c_name); 
   DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr); 

EXCEPTION 
   WHEN no_data_found THEN 
      dbms_output.put_line('No such customer!'); 
   WHEN others THEN 
      dbms_output.put_line('Error!'); 
END; 
/

当以上代码在SQL提示符下执行时,将产生以下输出-

No such customer!  

PL/SQL procedure successfully completed. 

上面的程序显示给出ID的客户的姓名和地址,由于在无涯教程的数据库中没有ID值为8的客户,该程序将引发运行时异常 NO_DATA_FOUND ,该异常在 EXCEPTION块中捕获。

引发异常

每当有内部数据库错误时,数据库服务器都会自动引发异常,但是程序员可以使用命令 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 。

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 ('Name: '||  c_name);  
      DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr); 
   END IF; 

EXCEPTION 
   WHEN ex_invalid_id THEN 
      dbms_output.put_line('ID must be greater than zero!'); 
   WHEN no_data_found THEN 
      dbms_output.put_line('No such customer!'); 
   WHEN others THEN 
      dbms_output.put_line('Error!');  
END; 
/

当以上代码在SQL提示符下执行时,将产生以下输出-

Enter value for cc_id: -6 (let's enter a value -6) 
old  2: c_id customers.id%type := &cc_id; 
new  2: c_id customers.id%type := -6; 
ID must be greater than zero! 
 
PL/SQL procedure successfully completed. 

预定义异常

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在发生算术,转换,截断或大小约束错误时引发。
ZERO_DEVIDE 01476 1476尝试将数字除以零时引发。

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

Spring Boot与Kubernetes云原生微服务实践 -〔杨波〕

研发效率破局之道 -〔葛俊〕

Node.js开发实战 -〔杨浩〕

雷蓓蓓的项目管理实战课 -〔雷蓓蓓〕

Vim 实用技巧必知必会 -〔吴咏炜〕

张汉东的Rust实战课 -〔张汉东〕

攻克视频技术 -〔李江〕

零基础学Python(2023版) -〔尹会生〕

超级访谈:对话道哥 -〔吴翰清(道哥)〕

好记忆不如烂笔头。留下您的足迹吧 :)