日期:2014-05-16  浏览次数:20533 次

ORA-00600报错--引用
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是游标的,还是临时表的,还是数据?