PLSQLOracle中的异常

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PLSQLOracle中的异常相关的知识,希望对你有一定的参考价值。

一、摘要

在PLSQL程序开发过程中,很重要的部分就是对程序异常的监控和处理,包括如何触发异常,何时进行处理,如何进行处理,是否将程式中的所有异常集中在一起,通过公共异常处理的procedure或function,如果没有完善的程式处理机制,很难说该程式是一只健壮的程式,当程式遇到很多类型或者量很多资料时,系统若没有异常处理必然会导致程式的出错

当预判到了某些异常,需要对预判到的异常进行合适相应的处理,是否抛出异常还是忽略还是其他

当然程式没有预判到或者是一些未知的异常遇到,所以异常处理模块也要考虑这些未预见到的程式

PLSQL异常的资料网络流传很多,都有些类似,归纳的很详细了,资料被转来转去,也不太清楚原文的出处,向未知的大神致敬

本文整理下网络上的资料,并重新排版了下

  • 异常的分类
    • 系统自带异常
    • 用户自定异常
  • 异常的抛出
    • PLSQL引擎自动处理
    • Raise
    • Raise_Application_Error
  • 异常的处理
    • 用户自定异常处理
    • 系统自带异常处理
    • 未知异常处理
    • 在声明阶段中异常
  • 异常的传播异常的SQLCode 和 SQL Errm
    • 异常在声明块中传播
    • 异常在执行块中传播
  • Oracle ERP Fnd_file工具
    • fnd_file.output
    • fnd_file.log
  • 附件
    • 附件 - Oracle自带异常列表
    • 附件 - Oracle Standard Error 列表

二、概述

1. 异常的分类

1.1 系统自带异常

1.1.1 概念 : 执行期间返回到PL/SQL块的ORACLE错误或由PL/SQL代码的某操作引起的错误,如除数为零或内存溢出的情况

                   每当PL/SQL违背了ORACLE原则或超越了系统依赖的原则就会隐式的产生内部异常。

                   因为每个ORACLE错误都有一个号码并且在PL/SQL中异常通过名字处理,ORACLE提供了预定义的内部异常

1.1.2 例子: 未定义异常,系统遇到预定义异常时,自动抛出,如no_data_found

        技术分享

1.2 用户定义异常

1.2.1 概念: 由开发者显示定义,在PL/SQL块中传递信息以控制对于应用的错误处理

                        如果要处理未命名的内部异常,必须使用OTHERS异常处理器或PRAGMA EXCEPTION_INIT 。

                          PRAGMA由编译器控制,或者是对于编译器的注释。PRAGMA在编译时处理,而不是在运行时处理。

                          EXCEPTION_INIT告诉编译器将异常名 与ORACLE错误码结合起来,这样可以通过名字引用任意的内部异常,并且可以通过名字为异常编写一适当的异常处理器。

1.1.2 例子: 自定义一个异常bxj_exception,并抛出

        技术分享

2. 异常的抛出

2.1 通过PLSQL引擎自动处理

2.1.1 概念: 当数据库或PL/SQL在运行时发生错误时,一个异常被PL/SQL运行时引擎自动抛出

2.1.2 例子: 系统自导抛出异常,并处理

               技术分享

2.2 通过Raise

2.2.1 概念: 异常也可以通过RAISE语句抛出RAISE exception_name;
              显式抛出异常是程序员处理声明的异常的习惯用法,但RAISE不限于声明了的异常,它可以抛出任何任何异常。例如,你希望用TIMEOUT_ON_RESOURCE错误检测新的运行时异常处理器

2.2.2 例子: 通过raise语句将异常抛出

               技术分享

2.3 通过Raise_Application_Error

2.3.1 概念: RAISE_APPLICATION_ERROR 内建函数用于抛出一个异常并给异常赋予一个错误号以及错误信息。

                   自定义异常的缺省错误号是+1,缺省信息是 User_Defined_Exception。

                   RAISE_APPLICATION_ERROR函数能够在pl/sql程序块的执行部分和异常部分调 用,显式抛出带特殊错误号的命名异常。

                   Raise_application_error(error_number,message[,true,false])

                   错误号的范围是-20,000到-20,999。错误信息是文本字符串,最多为2048字节。TRUE和FALSE表示是添加(TRUE)进错误堆(ERROR STACK)还是覆盖(overwrite)错误堆(FALSE)

2.3.2 例子: 通过raise_application_error语句将异常抛出

技术分享

3. 异常的处理

3.1 用户自定异常处理 、 系统自带异常处理、 未知异常处理

以下一个简单的例子说明了程式三种异常的捕捉和处理

技术分享

3.2 在声明阶段中异常

以下一个简单的例子说明了在声明阶段的异常,一般来说package执行过程中很少遇到这种错误,因为在编译过程中就会审计

除非所引用的table的结构发生变化,导致引用失败

技术分享

4. 异常的传播

4.1 如果异常发生在执行块

当一个异常错误在执行部分引发时,有下列情况:

如果当前块对该异常错误设置了处理,则执行它并成功完成该块的执行,然后控制转给包含块。

如果没有对当前块异常错误设置定义处理器,则通过在包含块中引发它来传播异常错误。然后对该包含块执行步骤

4.2 如果异常发生在声明块

如果在声明部分引起异常情况,即在声明部分出现错误,那么该错误就能影响到其它的块

5. 异常的SQLCode 和 SQL Errm

5.1 概念

由于ORACLE 的错信息最大长度是512字节,为了得到完整的错误提示信息,我们可用 SQLERRM和 SUBSTR 函数一起得到错误提示信息,方便进行错误,特别是如果WHEN OTHERS异常处理器时更为方便。

  • SQLCODE  返回遇到的Oracle 错误号
  • SQLERRM  返回遇到的Oracle错误信息

5.2 例子

产生SQLCode和SQLErrm

技术分享

6. Oracle fnd_file.output 和 fnd_file.log

6.1 fnd_file.output

用于Request输出报表产生layout,一般不能在这里写log语句

6.2 fnd_file.log

用于存放程式log记录,用于写log,程式异常处理记录都可以通过这个api进行记录

技术分享

7. 附件 

7.1 附件 - Oracle自带异常列表

  • ACCESS_INTO_NULL                     未定义对象  
  • CASE_NOT_FOUND                       CASE 中若未包含相应的 WHEN ,并且没有设置 ELSE 时  
  • COLLECTION_IS_NULL                  集合元素未初始化  
  • CURSER_ALREADY_OPEN              游标已经打开  
  • DUP_VAL_ON_INDEX                    唯一索引对应的列上有重复的值  
  • INVALID_CURSOR                        在不合法的游标上进行操作  
  • INVALID_NUMBER                        内嵌的 SQL 语句不能将字符转换为数字  
  • NO_DATA_FOUND                        使用 select into 未返回行,或应用索引表未初始化的元素时  
  • TOO_MANY_ROWS                       执行 select into 时,结果集超过一行  
  • ZERO_DIVIDE                              除数为 0  
  • SUBSCRIPT_BEYOND_COUNT        元素下标超过嵌套表或 VARRAY 的最大值  
  • SUBSCRIPT_OUTSIDE_LIMIT         使用嵌套表或 VARRAY 时,将下标指定为负数  
  • VALUE_ERROR                             赋值时,变量长度不足以容纳实际数据  
  • LOGIN_DENIED                            PL/SQL 应用程序连接到 oracle 数据库时,提供了不正确的用户名或密码  
  • NOT_LOGGED_ON                        PL/SQL 应用程序在没有连接 oralce 数据库的情况下访问数据  
  • PROGRAM_ERROR                        PL/SQL 内部问题,可能需要重装数据字典& pl./SQL 系统包  
  • ROWTYPE_MISMATCH                  宿主游标变量与 PL/SQL 游标变量的返回类型不兼容  
  • SELF_IS_NULL                             使用对象类型时,在 null 对象上调用对象方法  
  • STORAGE_ERROR                        运行 PL/SQL 时,超出内存空间  
  • SYS_INVALID_ID                         无效的 ROWID 字符串  
  • TIMEOUT_ON_RESOURCE          Oracle 在等待资源时超时 
7.2 附件 - Oracle Standard Error 列表
技术分享 Oracle Standard Error

 原文连接:PLSQL_ORACLE EXCEPTION 异常分类,处理,抛出,传播

以上是关于PLSQLOracle中的异常的主要内容,如果未能解决你的问题,请参考以下文章

PLSQL ORACLE:表变量之间的内连接

如何从 PLSQL Oracle 过程中删除数据或清空游标?

plsql oracle检查约束错误

返回 PLSQL ORACLE 的错误不工作

PLSQLOracle函数与索引

编写 PLSQL Oracle 函数来查询表