Oracle之异常信息的加工处理

引言

    很多时候,我们调用oracle存储过程都会发生各种各样的异常信息,例如ORA-12899值过大,ORA-01400不能插入空值等.虽然说这类异常是前端没控制到位的缘故,但是现实很难100%完全控制住,所以一旦发生了这类异常,并返回的前端显示时就会造成很差的用户体验了.或许,我们可以将这类异常加工一下,包装得好看些,让用户看得懂发生了什么事情,能够自行处理.下面是我的一点尝试.

    我们通常会在oracle存储过程的异常处理得到异常信息,如:

Exception
    When Others Then
     rollback;
     dbms_output.put_line(sqlerrm);
     Raise_Application_Error(-20000,sqlerrm); 

然而,我们将会得到下面的异常信息,如

ORA-12899: 列 "NIS"."T_CZL_ACCOUNT"."VC_ACCOUNT" 的值太大 (实际值: 35, 最大值: 20)

虽然说我们99%的程序员都看得懂这个是什么意思,但是也有99%的用户看不出个所以然.我们的目标是意外发生了,用户依然看得懂.接下来,我需要创建一个函数,专门处理这类的异常,返回大部分用户看得懂的信息.函数代码如下:

create or replace function f_czl_geterror(message in varchar2)
return varchar2 is
   Result varchar2(1000);

   num1 number:=0;
   num2 number:=0;
   num3 number:=0;
   num4 number:=0;
   num5 number:=0;
   num6 number:=0;
   num7 number:=0;
   num8 number:=0;
   num9 number:=0;
   num10 number:=0;
   str1 varchar2(1000);
   str2 varchar2(1000);
   str3 varchar2(1000);
   str4 varchar2(1000);
   str5 varchar2(1000);
   str6 varchar2(1000);
   str7 varchar2(1000);
   str8 varchar2(1000);
   str9 varchar2(1000);
   str10 varchar2(1000);
begin

    if instr(message, ‘ORA-12899‘)>0 then
     num1:=instr(message,‘ORA-12899‘); --得到 ORA-12899的所在位置
     str1:=substr(message,num1);    --得到ORA-12899后面的所有字符
     num2:=instr(str1,‘"‘,1,3);    --得到ORA-12899后面第三个"的位置
     num3:=instr(str1,‘"‘,1,4);    --得到ORA-12899后面第四个"的位置
     str2:=substr(str1,num2+1,num3-num2-1);  --得到表名
     num4:=instr(str1,‘"‘,1,5);    --得到ORA-12899后面第五个"的位置
     num5:=instr(str1,‘"‘,1,6);    --得到ORA-12899后面第六个"的位置
     str3:=substr(str1,num4+1,num5-num4-1);  --得到字段名

     num6:=instr(str1,‘:‘,1,2);    --得到ORA-12899后面第二个:的位置
     num7:=instr(str1,‘,‘,1,1);    --得到ORA-12899后面第1个,的位置
     str5:=substr(str1,num6+1,num7-num6-1);  --得到输入的长度

     num8:=instr(str1,‘:‘,1,3);    --得到ORA-12899后面第二个:的位置
     num9:=instr(str1,‘)‘,1,1);    --得到ORA-12899后面第1个,的位置
     str6:=substr(str1,num8+1,num9-num8-1);  --得到最大的长度

     --得到对应的字段注释
     select t.comments into str4 from SYS.USER_COL_COMMENTS t where t.column_name=str3 and t.table_name=str2;

     Result:=str4||‘长度超出限制,最大字符数为‘||str6||‘,您输入的字符数为‘||str5||‘.‘;
    elsif  instr(message, ‘ORA-01400‘)>0  then

     num1:=instr(message,‘ORA-01400‘); --得到 ORA-01400的所在位置
     str1:=substr(message,num1);    --得到ORA-01400后面的所有字符
     num2:=instr(str1,‘"‘,1,3);    --得到ORA-01400后面第三个"的位置
     num3:=instr(str1,‘"‘,1,4);    --得到ORA-01400后面第四个"的位置
     str2:=substr(str1,num2+1,num3-num2-1);  --得到表名
     num4:=instr(str1,‘"‘,1,5);    --得到ORA-01400后面第五个"的位置
     num5:=instr(str1,‘"‘,1,6);    --得到ORA-01400后面第六个"的位置
     str3:=substr(str1,num4+1,num5-num4-1);  --得到字段名

      --得到对应的字段注释
     select t.comments into str4 from SYS.USER_COL_COMMENTS t where t.column_name=str3 and t.table_name=str2;

      Result:=str4||‘不能为空,请输入内容.‘;
   elsif  instr(message, ‘ORA-01438‘)>0  then

      Result:=str4||‘数字长度超出限制,请检查!‘;
    else

        Result:=message;
    end if;

      return(Result);
end f_czl_geterror;

然后我们在存储过程的异常处理中用上这个函数,如:

Exception
    When Others Then
     rollback;
     dbms_output.put_line(f_czl_geterror(sqlerrm));
     Raise_Application_Error(-20000,f_czl_geterror(sqlerrm));   

再测试看看,我们得到了:

账号长度超出限制,最大字符数为 20,您输入的字符数为 35.

起码有的用户看得懂了是吧,咱们的目标算是达成了.

小结

  上文介绍了如何将oracle的系统异常信息转换成用户看得懂的信息.其实这只是一种补救的措施罢了,某种程度上是‘欺骗‘了用户,程序是正常运行的,但是不能否认的是我们的程序依然不完善.但是,有的补救好过没有是吧.最后,如果您有更好的建议,请不吝指教.

时间: 2024-08-27 10:31:49

Oracle之异常信息的加工处理的相关文章

oracle存储过程异常捕获

oracle存储过程异常捕获学习,执行及演示过程: 存储过程: CREATE OR REPLACE PROCEDURE sp_test_2 ( param1 in int, --输入参数 param2 in int, out_return out varchar2 --返回结果 ) is --全局变量 val int; errorException exception; --申明异常 errorCode number; --异常代号 errorMsg varchar2(1000); --异常信息

PHP 错误与异常 笔记与总结(14 )记录和发送异常信息

当发生异常时,把异常信息记录到日志文件中: 1 <?php 2 header('content-type:text/html; charset=utf-8'); 3 class LogException extends Exception{ 4 public function __construct($message = null, $code = 0){ 5 parent::__construct($message, $code); 6 error_log($this->getMessage

Atitit mysql 存储过程捕获所有异常,以及日志记录异常信息

1.1. 异常的处理模式exit  continue undo模式 1 1.2. 捕获所有异常使用        DECLARE continue HANDLER FOR   sqlexception 1 1.3. 捕获特定异常使用HANDLER FOR  errorcode 2 1.4. 记录异常到日志表,获取异常代码和异常信息 2 1.5. 抛出自定义异常 3 2. 程序语言中捕获sql自定义抛出的异常 3 2.1. 代码 3 3. 集合的循环loop while repeat模式 4 3.

VS开发ArcEngine时的一个异常信息——“ArcGIS version not specified. You must call RuntimeManager.Bind before creating any ArcGIS components.”

问题描述:程序报错"ArcGIS version not specified. You must call RuntimeManager.Bind before creating any ArcGIS components." 解决方法:打开program.cs. 把ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop); 放到Application.SetCompatibleTextRender

JAVA之IO技术-将java程序的异常信息保存在文件中

package ioTest.io2; import java.io.FileNotFoundException; import java.io.PrintStream; import java.util.Properties; /* * 将应用程序的异常信息输出到指定的log文件中 */ public class ExceptionToFile { public static void main(String[] args) throws FileNotFoundException { int

验证Oracle收集统计信息参数granularity数据分析的力度

最近在学习Oracle的统计信息这一块,收集统计信息的方法如下: DBMS_STATS.GATHER_TABLE_STATS ( ownname VARCHAR2, ---所有者名字 tabname VARCHAR2, ---表名 partname VARCHAR2 DEFAULT NULL, ---要分析的分区名 estimate_percent NUMBER DEFAULT NULL, ---采样的比例 block_sample BOOLEAN DEFAULT FALSE, ---是否块分析

Log4Net在MVC下的配置以及运用线程队列记录异常信息

Log4Net是用来记录日志的,可以将程序运行过程中的信息输出到一些地方(文件.数据库.EventLog等),日志就是程序的黑匣子,可以通过日志查看系统的运行过程,从而发现系统的问题.日志的作用:将运行过程的步骤.成功失败记录下来,将关键性的数据记录下来分析系统问题所在.Log4J.对于网站来讲,不能把异常信息显示给用户,异常信息只能记录到日志,出了问题把日志文件发给开发人员,就能知道问题所在. 配置Log4Net环境 (1)新建一个WebApplication (2)添加对log4net.dl

python打印详细的异常信息

#!/usr/bin/env python #coding=utf-8 import traceback try: 1/0 except Exception, e: print e print traceback.format_exc() python打印详细的异常信息,布布扣,bubuko.com

使用svctraceviewer查看WCF服务异常信息

这两天遇到一个问题,调用一个WCF服务的时候,服务器端正常的返回了数据,但是客户端却遇到了一场 System.ServiceModel.CommunicationException: The underlying connection was closed: The connection was closed unexpectedly. 直接调试查看堆栈信息也没有弄清楚怎么回事.最后上网搜了一下,发现一个获取WCF运行信息的工具. 1.打开服务器端wcf服务的web.config配置文件并添加如