koko的oracle杂货铺

 

ora-600问题一则


一开发人员在用java程序调用数据库一个包A里的某个存储过程时,报以下错误

ORA-00600: internal error code, arguments: [kcbz_check_objd_typ_1], [0], [0], [1], [], [], [], []
Current SQL statement for this session:

select * from tmp_hotelinfolisttest a where salesprice > 0 order by   decode(a.hotel_comm_type,4,6,nvl(a.hotel_comm_type,5)),a.hotel
star,a.lowestprice ,a.hotelid,a.ROOM_TYPE_ID,a.CHILDROOMTYPEID,a.PAY_METHOD,a.able_sale_date,a.salesprice

存储过程简单调试了下没什么问题:从一些表里取到数据,先暂时放在tmp_hotelinfolisttest这个临时表里,最后用一个游标类型的返回参数返回给java,上面报错的sql就是游标所使用的sql.

代码截取如下:

.....

v_sqlstr := 'select * from tmp_hotelinfolisttest a where salesprice > 0 order by '|| v_tempstr;  
open return_list for v_sqlstr;
    --------
commit;

.........

把开发人员提供的输入参数传入,直接在sqlplus下调用,没错误,但用java调用就报错。

google metalink上search了一把,没发现和这个情景一模一样的案例。

据开发人员描述,这个存储过程和另一个包B里的同一存储过程相似,但B不存在这个问题。

仔细比对2个存储过程,没发现有特别之出,除了2个存储过程分别采用了2个不同的临时表.

比较2个临时表的区别,发现A包里用的临时表是on commit delete rows.而B包里的是on on commit preserve rows.

问题就在这里:

如果采用事务级的临时表,那么java在调用完存储过程以后(存储过程最后有commit),临时表里的数据会被delete掉,但是它拿到的那个游标返回参数却需要这些数据,这样就产生了冲突。

而如果采用会话级的临时表,由于java在调用完存储过程后,会话并未结束,数据会一直保存到会话结束为止,因此就不会有问题。

把临时表改成on commit preserve rows 问题解决。

还有3个疑问:

1 当返回一个游标类型的参数时,oracle返回的到底是一个指向sql的指针,还是一个指向数据的指针?

2 为什么在数据库直接调用该存储过程就不会报错?

是不是只有在真正要取游标里的数据时,oracle才会做校验?

还是在 open return_list for v_sqlstr做了校验 然后数据被delete,最后拿数据的时候再次校验的时候报错。

3 从报错误的字面上理解,kcbz_check_objd_typ_1应该是在做check object type

这个check究竟是在check哪个object type是游标的,还是临时表的,还是数据?




 
 
 
 
评论:

REF CURSOR类型返回的是一个CURSOR的指针,你描述的问题不清晰,所以还没搞明白实验环境是怎么回事,最好把整个过程贴出来

发表于 白鳝 在 2009年03月04日, 01:57 下午 CST #

发表一条评论:
  • HTML语法: 启用
 

Valid XHTML or CSS?

[This is a Roller site]
Theme by koko.
 
© koko