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是游标的,还是临时表的,还是数据?