PL/SQL 异常处理2025 年 2 月 14 日 | 11 分钟阅读 引言在本文中,我们将讨论 PL/SQL 异常、其类型以及如何通过各种示例进行处理。没有人是完美的,每个人都会以一种或另一种形式犯一些错误。编程错误通常在尝试执行程序之前不会被发现。由于错误会阻止程序成功执行,因此应在执行前将其删除。为了处理这些错误,PL/SQL 提供了异常。 什么是异常在 PL/SQL 中,程序执行期间发生的错误称为异常。 PL/SQL 使程序员能够使用程序中的异常块捕获此类情况,并针对错误情况采取适当的措施。 ![]() 上图显示,当引发执行并将控制权转移到程序的异常部分时,它无法返回到程序的执行,并且 PL/SQL 块成功终止。 ![]() 如果上图显示在块的可执行部分中引发了异常,并且没有相应的异常处理程序,则该异常将转发到宿主环境 SQL * PLUS,此时环境确定如何响应异常。 异常有两种类型
PL/SQL 异常处理异常处理程序是程序的一部分,您可以在其中编写代码来处理代码在程序执行期间可能遇到的各种问题。每当在可执行部分中遇到错误时,它将退出可执行部分并在异常部分中搜索与错误匹配的异常处理程序。如果找到,它将执行该异常处理的代码。 它是 PL/SQL 块的最后一部分,也称为错误处理部分。它以关键字 <EXCEPTION> 开头。每个异常部分可以进一步细分为单个异常处理程序。 异常处理的语法 以下是异常处理的通用语法 在上面的语法中,<DECLARE> 部分用于声明,例如变量、函数等,<BEGIN> 部分用于程序执行的开始,<EXCEPTION> 部分用于处理部分,其中 exception1、exception2、exception3 可能是预定义的异常或由布尔逻辑运算符(例如 OR 和 AND)分隔的 oracle 预定义异常的组合。它也可以是 PRAGMA EXCEPTION_INIT 异常。它还提供了一个可选的异常处理子句,称为 "others",用于捕获所有未指定的异常。最后一部分是 <END> 部分,用于结束 PL/SQL 程序。 异常处理示例让我们举一个简单的例子来演示异常处理的概念。这里我们使用已经创建的 CUSTOMERS 表。
在 SQL 提示符下执行上述代码后,会产生以下结果 No such customer! PL/SQL procedure successfully completed. PL/SQL 用户定义的异常PL/SQL 方便其用户根据程序的需要定义自己的异常。可以使用 RAISE 语句或过程 DBMS_STANDARD.RAISE_APPLICATION_ERROR 显式引发用户定义的异常。例如: 在员工管理系统的情况下,员工代码的数据库必须以字母 "E" 开头。因此,应用程序开发人员会应用检查以确保不会发生这种情况。每当程序中发生错误时,就会引发这些用户定义的异常。 声明用户定义的异常 异常的声明与变量类似,仅在 PL/SQL 块的声明部分中声明。它被分配一个唯一的名称,用于在程序中引用该异常。 用户定义异常的语法 在上面的语法中,my_exception 是异常的名称。 引发用户定义的异常在任何内部数据库错误的情况下,异常由数据库服务器自动引发。但程序员也可以使用命令 RAISE 显式引发异常。 引发异常的语法 在上面的语法中,每当使用 raised 语句调用定义的异常时,程序控制权就会传递给定义的用于处理该异常的异常处理程序。 示例 编写一个 PL/SQL 程序,该程序选择给定部门编号的部门名称和位置,如果该部门编号不存在,则该程序会引发用户定义的异常。 说明 执行时,它会提示您输入要获取其信息的 deptno。如果您输入现有的部门编号,它将获取该部门编号的部门名称和位置。如果您输入无效的部门编号,它将引发异常 "deptno_err" 并提示您输入相应的消息。 用户定义异常的作用域规则
PL/SQL 预定义的异常PL/SQL 提供了一组预定义的异常,这些异常由系统在运行时内部隐式引发。如果在 PL/SQL 中遇到错误,则会发生这种情况。每当 Oracle 在运行时遇到系统错误时,都会隐式引发相应的预定义异常,因此正常执行停止,控制权转移到程序中指定的异常处理程序。PL/SQL 中有许多预定义的异常,当程序违反任何数据库规则时,这些异常会执行。例如: NO_DATA_FOUND 是一个预定义的异常,当 SELECT INTO 语句未返回任何行时,会引发该异常。 以下是一些重要的预定义异常的列表
示例 编写一个 PL/SQL 程序,该程序可以处理多个异常。 说明 在上面的编程示例中,在执行时,由于 SELECT INTO 语句将返回多于一行,这是不可能的,因此会引发异常。通过这种方式,控制权转移到异常部分,并调用 TOO_MANY_ROWS 异常处理程序,然后显示 DBMS_OUTPUT 程序包中包含的消息,即 "返回多于一行"。 使用 PRAGMA EXCEPTION_INIT 使用 PRAGMA _ EXCEPTION_INIT 来处理未命名的内部异常。PL/SQL 开发人员可以使用它将用户定义的异常与内部错误代码关联起来。在本例中
建立关联后,您可以通过名称引发该异常,并编写捕获该错误的异常处理程序。它必须出现在 PL/SQL 块子程序的声明部分中。异常名称必须已在同一块、外部块或程序包规范中定义。使用以下语法: PRAGMA EXCEPTION_INIT(exception_name, Oracle_err_num); 在上面的语法中,exception_name 是先前声明的异常的名称,Oracle_err_num 是 Oracle 错误的编号。它可以是具有以下约束的整数值:
示例 编写一个程序,如果用户想要将用户定义的异常名称与 ORACLE_ERR_NUM 2292 关联,则只能通过使用 PRAGMA EXCEPTION_INIT。 说明 执行时,它会显示消息 "首先删除子记录"。执行 Delete 语句时,会生成一个 Oracle 错误,其 err_num 为 -2292。现在,在声明部分中,我们声明了一个 PRAGMA 异常。因此,在遇到错误时,控制权将转移到 EXCEPTION 部分,并在其中打印相应的消息。 使用 RAISE_APPLICATION_Error Oracle 提供了一种 RAISE_APPLICATION_Error 方法,用于在您的应用程序中引发特定于应用程序的错误。它在 DBMS_STANDARD 程序包中定义。使用 RAISE_APPLICATION_ERROR 而不是 "raise" 的主要目的是您可以将错误消息与异常关联起来。 使用以下语法来调用 RAISE_APPLICATION_ERROR 在上面的语法中,error_number 是 -20999 到 -20000 范围内的负整数。第二个参数是错误消息,长度不应超过 2KB 个字符。如果最后一个参数,则将该错误放置在先前错误的堆栈中,否则,它将替换所有当前错误。默认情况下,它是 FALSE。 示例:使用 RAISE_APPLICATION_Error 的程序 说明 执行时,它将提示用户输入员工代码。如果我们输入佣金不存在的员工的 empcode(即 7342),则它将显示错误编号以及错误消息。但是,将为佣金存在的员工(即 7899)添加 empcode,然后将佣金更新 50%。 在处理程序子句中使用 SQLCODE 和 SQLERRM 以下是两个可以在任何异常处理程序中使用的内置函数,当与 WHEN OTHERS 子句结合使用时,它们变得非常有用。由于抛出的任何异常都将在 WHEN OTHERS 异常处理程序中捕获,因此使用像 SQLCODE 和 SQLERRM 这样的错误捕获函数可以提供一种自描述的错误机制。 SQLCODE: 它是用于标识先前执行的 PL/SQL 语句的错误的错误代码。 SQLCODE 返回
SQLERRM: 它将显示您传递给它的错误号的错误消息。它包含一个错误消息,即 512 个字符长,错误代码和嵌套消息,例如表名和列名。 示例:在处理程序子句中使用 SQLCODE 和 SQLERRM 的程序 说明 执行时,它将提示您输入 Empno。如果 Empno 存在于表中,它将显示相应的员工工资。否则,将引发异常,并显示错误代码和消息。 EXCEPTION PROPAGATION 的使用 引发异常时,PL/SQL 会在异常的当前块中查找异常处理程序。如果在异常部分中找到异常处理程序,则子块处理异常并正常终止。控制权在子块 END 语句之后的 CLOSE 块中立即恢复。如果找不到处理程序,PL/SQL 会将异常传播到该当前块的封闭块。然后,PL/SQL 尝试通过在封闭块中再次引发异常来处理该异常。它将继续,直到合适的异常处理程序捕获了该异常,或者可执行代码停止处理并将错误返回给运行 PL/SQL 的宿主环境。 示例:使用 EXCEPTION PROPAGATION 的程序 说明 在上面的例子中,它会要求你输入员工编号 (E),然后检查工资是否大于 5000。如果为真,它会引发异常,并在当前块中搜索异常处理程序。如果在处理程序块中没有找到,则尝试将异常与异常部分事件处理程序匹配。当这个异常处理程序找到 "greater_year" 并执行相应的语句。 PL/SQL 异常的好处以下是 PL/SQL 异常的各种好处。
下一个主题PL/SQL 触发器 |
我们请求您订阅我们的新闻通讯以获取最新更新。