前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Oracle数据库,浅谈PL/SQL异常处理

Oracle数据库,浅谈PL/SQL异常处理

作者头像
用户1289394
发布2021-03-29 17:30:43
6640
发布2021-03-29 17:30:43
举报
文章被收录于专栏:Java学习网Java学习网

众所周知,程序的错误一般情况下分为两类:编译错误和运行时错误。其中运行时错误被称为异常。PL/SQL语句块中处理异常的部分即为异常处理部分。在异常处理部分,可以指定当特定异常发生时所采取的动作。本文我们就来聊一聊PL/SQL异常处理的那些事儿。

PL/SQL有两种类型的异常:内置异常和用户自定义异常。其中,内置异常又分为预定义异常和非预定义异常。

一、内置异常

我们先来举一个抛砖引玉的例子。

代码语言:javascript
复制
DECLARE

   v_ename varchar2(10);

   v_empno number(4) := &v_empno;BEGIN

   SELECT ename

     INTO v_ename

   FROM EMP

   WHERE empno = v_empno;

   DBMS_OUTPUT.PUT_LINE('Employee name is '||v_ename);END;

该语句块通过输入员工的编号来得出员工的姓名。当输入的员工编号存在时,输出员工姓名,当员工编号不存在时,会有运行错误。如下所示:

代码语言:javascript
复制
SQL> /

Enter value for v_empno: 7788

Employee name is SCOTT              -->> 输入的员工编号存在,输出员工姓名

PL/SQL procedure successfully completed.

SQL> /

Enter value for v_empno: 1234DECLARE*

ERROR at line 1:

ORA-01403: no data found            -->> 输入的员工编号不存在,报运行时错误

ORA-06512: at line 5

由此可见,编译器无法检测运行错误。为在程序中处理这种类型的错误,必须添加异常处理部分。异常处理部分的语法结构如下:

EXCEPTION WHEN EXCEPTION_NAME THEN ERROR-PROCESSING STATEMENTS;

在语句块中,异常处理部分位于可执行部分之后,上例可修改如下:

代码语言:javascript
复制
DECLARE

   v_ename varchar2(10);

   v_empno number(4) := &v_empno;BEGIN

   SELECT ename

     INTO v_ename

   FROM EMP

   WHERE empno = v_empno;

   DBMS_OUTPUT.PUT_LINE('Employee name is '||v_ename);

EXCEPTION

   WHEN NO_DATA_FOUND THEN

   DBMS_OUTPUT.PUT_LINE('There is no such employee');END;

使用异常处理部分,可以使得程序能够正常结束,而不是非正常终止。同时,输出结果更加面向用户,而不是编程人员。

上述NO_DATA_FOUND即为Oracle预定义异常。

二、 用户自定义异常

通常,在自己的程序里,也许需要处理与所写程序相关的问题。例如,在上个语句块中,需要输入员工编号。通常,希望员工编号是正值。但是无意间,用户输入一个负数。但是,没有发生任何错误,因为变量v_empno被定义为数值类型。这时,你希望自定义异常来处理这种情况,这种类型的异常被称为用户自定义异常。在使用该异常之前,必须首先进行声明。语法结构如下所示:

代码语言:javascript
复制
DECLARE
     exception_name EXCEPTION;
BEGIN
     ...
     IF  CONDITION THEN
          RAISE exception_name;
     ELSE
          ...
     END IF;
EXCEPTION
     WHEN exception_name THEN
           ERROR-PROCESSING STATEMENTS;
END;

故上例可修改为:

代码语言:javascript
复制
DECLARE

   v_ename varchar2(10);

   v_empno number(4) := &v_empno;

   e_invalid_no exception;BEGIN

   IF v_empno < 0 THEN

        RAISE e_invalid_no;    -->>

注意:RAISE语句应该与IF语句一起使用,否则,每次执行时,执行权都会转到该语句块的异常处理部分。

代码语言:javascript
复制
  ELSE

      SELECT ename

         INTO v_ename

      FROM EMP

      WHERE empno = v_empno;

      DBMS_OUTPUT.PUT_LINE('Employee name is '||v_ename);

   END IF;

EXCEPTION

   WHEN e_invalid_no THEN

   DBMS_OUTPUT.PUT_LINE('Employee number can not be negative');END;

三、RAISE_APPLICATION_ERROR

RAISE_APPLICATION_ERROR是oracle提供的一种特殊的内置过程,允许编程人员为特定应用程序创建有意义的错误信息。RAISE_APPLICATION_ERROR过程适用于未命名的用户定义异常。它负责将错误编号和错误文本关联起来,它的语法为:

RAISE_APPLICATION_ERROR(error_number,error_message);

error_number是与特定错误信息相关联的错误编号。这个编号的范围在-20999到-20000之间。error_message是错误文本,最多包含2048个字符。

上例可修改为:

代码语言:javascript
复制
DECLARE

   v_ename varchar2(10);

   v_empno number(4) := &v_empno;BEGIN

   IF v_empno < 0 THEN

        RAISE_APPLICATION_ERROR(-20000,'Employee number can not be negative');

   ELSE

      SELECT ename

         INTO v_ename

      FROM EMP

      WHERE empno = v_empno;

      DBMS_OUTPUT.PUT_LINE('Employee name is '||v_ename);

   END IF;END;

当输入的员工编号为负数时,运行结果如下所示:

代码语言:javascript
复制
SQL> /

Enter value for v_empno: -1234DECLARE*

ERROR at line 1:

ORA-20000: Employee number can not be negative

ORA-06512: at line 6

借助于RAISE_APPLICATION_ERROR过程,编程人员能够遵循与Oracle错误一致的方式返回错误信息。

综上所述,我们发现预定义异常的错误代码有名称,譬如上文提到的NO_DATA_FOUNG,而非预定义异常只有错误代码,没有名称,如上文提到的ora-02292。这时可以通过EXCEPTION_INIT编译指令进行错误代码和名称的关联。当PL/SQL语句块的可执行部分出现某个运行错误时,会抛出不同类型的异常。但是,运行错误也可能发生在语句块的声明部分或者异常处理部分。控制在这些环境下异常抛出方式的规则称为异常传播。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java学习网 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档