1.由于procedure和function均是客户交由第三方开发的,不能随意修改。
function返回为boolean类型的处理:
oracle本身没有boolean类型,就是说跟数据库相关的类型中不包括boolea,一般采用number(1)和char(1)来实现。
plsql为了实现结构化编程,支持了boolean类型,所以可能会出现的问题是一个存储过程或者函数的返回参数是boolean型的,但在call这个procedure的时候,无法注册boolean类型的返回参数,执行时会抛出”参数类型不对“的exception,解决的方案就是把boolean的参数用别的类型代替。
具体可参考博文:http://blog.sina.com.cn/s/blog_451f596201014wkw.html
但是如果不能修改改procedure 程序中调用时 可进行一个转换:
String sysCall ="begin :1:=sys.diutil.bool_to_int(MAILING_AUX.ISRESVCONDITIONVALID(IN_QUERY_ID=> :2,IN_RESV_NAME_ID =>:3)); end;";
CallableStatement stmt = this.connection.prepareCall(complexSql);
stmt.registerOutParameter(1, OracleTypes.INTEGER);
2.还可以将返回结果放到一个cursor中返回,但是由于查询出来的是个列表,而在cursor中再一次查询的时候作为in条件里的查询条件,不能直接传递过来,需要组成一个字符串。
open ret_cursor_value for 'select resv_alert_id, description, alert_code, area,screen_yn,printer_yn from reservation_alerts where resv_alert_id in '||ret||'order by resv_alert_id desc'; 其中ret是一个组装的字符串。
3.java代码直接调用procedure时,最好使用?作为占位符,会省掉很多麻烦。
this.connection = connection;
String complexSql = "declare cursor cur_alert(in_resort in varchar2,in_resv_name_id in number)is select query_id, resv_alert_id"
+ " from reservation_alerts where resort = pms_p.resort and resv_name_id = 0;"
+ "rec_alert cur_alert%rowtype; "
+"type mytype is table of nvarchar2(200) index by binary_integer; "
+"alertIds mytype; ret_cursor_value sys_refcursor; b Boolean; "
+"ret varchar2(2000):='(';"
+ "begin if not cur_alert%isopen then open cur_alert(?,?);"
+ "loop "
+ "fetch cur_alert into rec_alert;"
+ "if rec_alert.query_id is not null then "
+ "b:=mailing_aux.isresvconditionvalid(rec_alert.query_id,?);"
+"if b then ret:=ret||to_char(rec_alert.resv_alert_id); ret:=ret||','; "
+ "end if; "
+ "end if;"
+ "exit when cur_alert%notfound; "
+ "end loop;"
+"ret:=substr(ret,1,length(ret)-1); ret:=ret||')';"
+ "end if; close cur_alert;"
+" open ret_cursor_value for 'select resv_alert_id, description, alert_code, area,screen_yn,printer_yn from reservation_alerts where resv_alert_id in '||ret||'order by resv_alert_id desc';"
+"?:=ret_cursor_value;"
+ "end;";
CallableStatement stmt = this.connection.prepareCall(complexSql);
try {
stmt.setString(1, resort);
stmt.setLong(2, resvNameId);
stmt.setLong(3, resvNameId);
stmt.registerOutParameter(4, OracleTypes.CURSOR);
stmt.executeQuery();
ResultSet rs = (ResultSet) stmt.getObject(4);