返回介绍

PL/SQL 异常 - PL/SQL 教程

发布于 2025-02-22 13:46:46 字数 4898 浏览 0 评论 0 收藏 0

程序执行过程中出现错误情况被称为在 PL/SQL 异常。 PL/SQL 支持程序员在程序中使用异常块捕获这样的条件并采取适当的动作应对错误情况。有两种类型的异常:

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

异常处理语法

一般异常处理的语法如下。在这里可以列出下来很多,要处理异常。默认的异常将使用 WHEN others 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 表:

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 提供许多预先定义的异常,这是在被执行时的任何数据库规则由程序引发。例如,预定义异常 NO_DATA_FOUND 时引发一个 SELECT INTO 语句返回数据行。下表列出了一些重要的预先定义的异常:

ExceptionOracle ErrorSQLCODE描述
ACCESS_INTO_NULL06530-6530当一个空对象会自动分配一个值引发此异常
CASE_NOT_FOUND06592-6592当没有任何选择,在当选择一个 CASE 语句的子句,并且没有 ELSE 子句时被引发
COLLECTION_IS_NULL06531-6531当程序试图申请其他收集方法不是存在未初始化的嵌套表或 VARRAY,或程序试图值分配给未初始化的嵌套表或变长数组的元素时被引发
DUP_VAL_ON_INDEX00001-1当重复值试图被存储在具有唯一索引的列时被引发
INVALID_CURSOR01001-1001当尝试以使这是不允许的,如关闭一个未打开的游标的游标操作时被引发
INVALID_NUMBER01722-1722当一个字符的字符串转换成一个数失败,因为字符串不表示一个有效的数据被引发
LOGIN_DENIED01017-1017当程序试图登录到数据库使用无效的用户名或密码被引发
NO_DATA_FOUND01403+100它被引发当一个 SELECT INTO 语句无任何行返回
NOT_LOGGED_ON01012-1012在不连接到数据库发出数据库调用它被引发
PROGRAM_ERROR06501-6501它被引发当 PL/SQL 有一个内部问题
ROWTYPE_MISMATCH06504-6504当游标取值有不兼容的数据类型的变量被引发
SELF_IS_NULL30625-30625它被引发,当对象的成员方法被调用,但对象类型的实例没有被初始化。
STORAGE_ERROR06500-6500它被引发当 PL/SQL 内存不足或内存已损坏
TOO_MANY_ROWS01422-1422它被引发当 SELECT INTO 语句返回多行
VALUE_ERROR06502-6502当算术,转换,截短,或大小约束错误时引发
ZERO_DIVIDE014761476它被引发当一个数试图除以零。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文