[探讨]论java调用存储过程的异常处理

youthy_yy 2004-02-03 09:20:30
下面是一个颇有争议的论题:

我们要探讨的是在java(jsp)调用Oracle数据库的存储过程时,如果数据库操作出现异常,对于该异常应该如何处理的问题.要求异常情况提示在客户端.

用一个最简单的例子来说明

有一个表test,拥有两个字段id,name,其中id为主键
现在向test表插入数据(1,'aaa'),(2,'bbb'),(3,'ccc')自然没有问题
如果再插入记录(1,'ddd')就会发生主键不唯一的异常,我们讨论的就是如何处理该异常.

如果插入记录的操作是用存储过程实现的,则至少存在以下两个典型的写法:
写法1:
create or replace procedure cp_test1
( i_id int,
i_name varchar2,
o_retvalue int
)
is
t_errorcode int;
begin
t_errorcode:=0;
begin
insert into test(id,name) values(i_id,i_name);
exception
when others then
t_errorcode:=sqlcode;
end;
o_retvalue:=t_errorcode;
end cp_test1;

写法2:
create or replace procedure cp_test2
( i_id int,
i_name varchar2
)
is
begin
insert into test(id,name) values(i_id,i_name);
end cp_test2;

写法1与写法2的区别在于写法1用了一个output输出值o_retvalue,而写法2没有

现在假设jsp均是通过javabean调用存储过程,执行javabean的executeProc方法
则有:
写法1将数据库的错误代码通过sqlcode得到了,所以在页面中只需检测executeProc的
返回值是否为0,非零即表示数据库出错,提示出错信息即可,这种方法简化了jsp页面,但增加了存储过程的编写工作量.

写法2将数据库的异常依赖于异常的传播机制,希望将数据库异常由运行时抛出,然后在javabean和jsp中捕获它,再实现异常信息的再现.这种方法简化了数据库存储过程的编写,也充分利用的java语言的异常处理机制.

问题来了:
究竟哪一种写法合理些?或者说使用更普遍些?
如果是写法2,那么javaben和jsp对该异常应该如何处理?
如何抛出?如何捕获?代码应怎样写才合理?

请大家不吝发言,谢谢!

...全文
364 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
wander1997 2004-02-03
  • 打赏
  • 举报
回复
不应该自己定义错误代码
oracle应该有系统变量捕捉错误代码,直接输出。
youthy_yy 2004-02-03
  • 打赏
  • 举报
回复
如果采用NO.2
我在测试中发现,如果想在javabean中抛出异常,则必须显式的用throws关键字

如:
public void executeProc(String Procedure) throws SQLException{
cstmt=null;
try{
cstmt = dbc.prepareCall("{call " + Procedure + "}");
cstmt.execute();
}
catch(SQLException ex){
System.err.println("aq.executeProc:"+ex.getMessage());
throw new SQLException(ex.getMessage());

}
其中throws SQLException是不可少的,否则会编译出错.
而对于
throw new SQLException(ex.getMessage());
见过有人写成
throw new ApplicationException 的,但我试过不能通过.
所以,我现在觉得这个executeProc方法写得不够合理,期待指正.

另一方面,如果采用No2.则在jsp页面中
大量的try...catch会充滞页面的主体,似乎也不够理想
或者采用统一的error.jsp来处理?
或者采用配置web.xml文件的error片断?

实在有太多的东西值得讨论......
youthy_yy 2004-02-03
  • 打赏
  • 举报
回复
多谢 Leemaasn()

几天不见,又由一星变两星了!

还得向你学习,追赶ing
youthy_yy 2004-02-03
  • 打赏
  • 举报
回复
我不大同意楼上 kongxiangli(笑看红尘) 兄台的看法,"往表里插数据最好是不会有错误发生的",只要是数据库的操作,错误是随时都可能出现的,既便是选择(select),在某些情况下出现的没有找到相关数据(NO_DATA_FOUND)的异常,也是需要进行处理的.

异常是否出现在很大程度上取决于存储过程的执行时间,从开始执行到结束之间的时间段越短,出现异常的可能性越小,但异常处理是必须步步考虑的,在大数据量/高并发访问的情况下更加如此.

这里,我只是用一个最简单的例子来说明此问题而已,重要的在例子背后的意义,而不在例子本身.
Leemaasn 2004-02-03
  • 打赏
  • 举报
回复
首先赞扬楼主提问题有技巧。。。
(热烈鼓掌)

我比较倾向No.2。。

先Mark一下,好帖不容错过。
再回头已是千层叠。。。
xrfei 2004-02-03
  • 打赏
  • 举报
回复
我赞成第一种写法.写程序本来就要有足够的容错代码,这也应该是一种良好的编程风格.
ye255 2004-02-03
  • 打赏
  • 举报
回复
具体的实现应该取决于具体的客户要求吧。
若单就数据库的存储过程来说,它只处理数据库操作,返回成功与否;而业务上怎么样给客户一个合理的交代则是另一个层面的问题。这不应该混在一起来考虑。
这是我的个人意见。
凋零的老树 2004-02-03
  • 打赏
  • 举报
回复
最好不要用存储过程来实现,用存储过程往表里插数据最好是不会有错误发生的,如:主键是自动生成的
cheqiang 2004-02-03
  • 打赏
  • 举报
回复
我很菜,但看了第一种写法之后,感觉很不错,根据errorcode来显示错误提示信息,还可以自己建立一个出错信息提示库!
wjmmml 2004-02-03
  • 打赏
  • 举报
回复
都不合理。
dailindl 2004-02-03
  • 打赏
  • 举报
回复
关注,学习
runnersun 2004-02-03
  • 打赏
  • 举报
回复
关注
Leemaasn 2004-02-03
  • 打赏
  • 举报
回复
先对楼主说的
“其中throws SQLException是不可少的”
做一下补充,你可以自定义异常。
封装。。


晚上有空再看看。。。

youthy_yy 2004-02-03
  • 打赏
  • 举报
回复
up!

up有分
cooboo 2004-02-03
  • 打赏
  • 举报
回复
好帖,这几天正好也用存储过程
学习:)
youthy_yy 2004-02-03
  • 打赏
  • 举报
回复
sqlcode已经是系统错误代码了

81,094

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧