引言

    很多时候,我们调用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的系统异常信息转换成用户看得懂的信息.其实这只是一种补救的措施罢了,某种程度上是'欺骗'了用户,程序是正常运行的,但是不能否认的是我们的程序依然不完善.但是,有的补救好过没有是吧.最后,如果您有更好的建议,请不吝指教.

【Oracle】异常信息的加工处理的更多相关文章

  1. oracle存储过程获取异常信息码和异常信息

    oracle存储过程,可以通过sqlcode 获取异常编码.通过sqlerrm获取异常信息. 例子: create or replace procedure write2blob(p_id in nu ...

  2. oracle 异常

    ORACLE 异常错误处理 本篇主要内容如下: 5.1 异常处理概念 5.1.1 预定义的异常处理 5.1.2 非预定义的异常处理 5.1.3 用户自定义的异常处理 5.1.4  用户定义的异常处理 ...

  3. 也谈Oracle异常: ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小

    场景: .Net程序调用Oracle方法 command.ExecuteNonQuery()执行存储过程;弹出如标题异常信息. 存储过程有4个输入参数,一个输出参数.一旦执行到给输出参数赋值的时候就报 ...

  4. [转]ORACLE 异常错误处理

    本文转自:http://www.cnblogs.com/soundcode/archive/2012/01/10/2318385.html 本篇主要内容如下: 5.1 异常处理概念 5.1.1 预定义 ...

  5. 总结:整理 oracle异常错误处理 .

    5.1 异常处理概念 5.1.1 预定义的异常处理 5.1.2 非预定义的异常处理 5.1.3 用户自定义的异常处理 5.1.4  用户定义的异常处理 5.2 异常错误传播 5.2.1 在执行部分引发 ...

  6. Oracle异常汇总

    持续更新中,可参见https://hnuhell.gitbooks.io/oracle_errmg/content/或https://hnuhell.github.io/Oracle_ERRMG/上的 ...

  7. 整理 oracle异常错误处理

    5.1 异常处理概念 5.1.1 预定义的异常处理 5.1.2 非预定义的异常处理 5.1.3 用户自定义的异常处理 5.1.4  用户定义的异常处理 5.2 异常错误传播 5.2.1 在执行部分引发 ...

  8. oracle 异常错误处理

    分类: Oracle 5.1 异常处理概念 5.1.1 预定义的异常处理 5.1.2 非预定义的异常处理 5.1.3 用户自定义的异常处理 5.1.4 用户定义的异常处理 5.2 异常错误传播 5.2 ...

  9. 异常信息:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed

    上周五遇到一个问题,工程本地编译运行正常,打包本地tomcat运行也正常.部署到测试环境报错: 2017-05-05 09:38:11.645 ERROR [HttpPoolClientsUtil.j ...

随机推荐

  1. 基于nodejs的wiki系统

    jingo:        https://github.com/claudioc/jingo nodewiki:    https://github.com/nhoss2/nodewiki Tidd ...

  2. zabbix3.2.4监控MySQL5.7.16状态

    一.添加监控用户mysql> grant all privileges on *.* to 'zabbix'@'localhost' identified by 'zabbix';mysql&g ...

  3. Java多线程(Java总结篇)

    Java总结篇:Java多线程 多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的. 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上 ...

  4. python默认参数不能定义为可变对象类型

    python的默认参数只会在函数定义时被确定,而不是每次调用时重新确定,所以,一旦在函数中修改了默认参数,则在随后的调用中都会生效 由于这个特性,在定义函数时,如果默认参数使用可变的对象类型,如空列表 ...

  5. android 对话框中的进度条 (ProgressDialog)

    from:http://byandby.iteye.com/blog/817214 显然要定义对话框进度条就要用ProgressDialog,首先我们需要创建ProgressDialog对象,当然这里 ...

  6. 02 Spring框架 简单配置和三种bean的创建方式

    整理了一下之前学习Spring框架时候的一点笔记.如有错误欢迎指正,不喜勿喷. 上一节学习了如何搭建SpringIOC的环境,下一步我们就来讨论一下如何利用ioc来管理对象和维护对象关系. <? ...

  7. Linux Shell编程 sort、wc命令

    sort命令:字符串排序 sort 命令可以依据不同的数据类型来进行排序.sort 将文件的每一行作为一个单位,相互比较.比较原则是从首字符向后,依次按 ASCII 码值进行比较,最后将它们按升序输出 ...

  8. Linux文件系统管理 fdisk分区命令

    概述 我们在安装操作系统的过程中已经对系统硬盘进行了分区,但是如果我新添加了一块硬盘,想要正常使用时,在Linux中有专门的分区命令 fdisk 和 parted.其中 fdisk 命令较为常用,但不 ...

  9. 20145230《java程序设计》 第四次实验报告

    20145230实验4 Android开发基础 实验内容 基于Android Studio开发简单的Android应用并部署测试; 了解Android组件.布局管理器的使用: 掌握Android中事件 ...

  10. MySQL实验1: 新建一个名为 library 的数据库,包含 book、reader 两张表,根据自己的理解安排表的内容并插入数据。

    数据表(table)简称表,它是数据库最重要的组成部分之一.数据库只是一个框架,表才是实质内容. 实验: 新建一个名为 library的数据库,包含 book.reader两张表,根据自己的理解安排表 ...