1 问题出现:
由于在sql需要将多行转为一行,便使用了聚合函数wmsys.wm_concat(),但开始在数据库执行时返回到页面
的都是varchar类型的字符串,后来数据库迁移发现执行sql返回的是CLOB类型,而且通过
javax.persistence.EntityManager.createNativeQuery(Sql) 查询出的数据是Clob的代理$Proxy。问
谷哥说是11g后返回的类型会不同,通过DBA确认两个数据库的版本分别为10.2.0.1和10.2.0.5,无法确认问
题所在。
2 问题初解:
其他的字符串拼接聚合方法感觉太过繁琐,且有可能出现版本问题,不得已采用遍历循环,在每条结果中再插
入查询的所需值,但总感觉有疙瘩。
3 问题补充:
中间还试过在外面包层to_char函数,to_char(wmsys.wm_concat(...)),在数据库中执行正常,但在代码中执行
时后台报错:ORA-22922: nonexistent LOB value
4 问题解决:
今天搜SerializableBlobProxy发现相同的转化问题,不过他们直接得到的是Proxy,而我代码返回的
是Object,那就再转一次吧,代码如下
1 //将得到的object强转成Proxy
java.lang.reflect.Proxy javaProxy = ( java.lang.reflect.Proxy)object;
2 //再得到InvocationHandler(SerializableClobProxy实现了接口InvocationHandler )
SerializableClobProxy proxy = (SerializableClobProxy )javaProxy.getInvocationHandler(object);
java.sql.Clob realClob = (java.sql.Clob) proxy.getWrappedClob();
3 将Clob转化为String
public String clob2String(Clob c) {
StringBuffer sb = new StringBuffer(1024);
Reader instream = null;
try {
instream = c.getCharacterStream();
char[] buffer = new char[( int) c.length()];
while ((instream.read(buffer)) != -1) {
sb.append(buffer);
}
} catch (Exception ex) {
ex.printStackTrace();
}
finally {
try {
if (instream != null)
instream.close();
} catch (Exception dx) {
instream = null;
return sb.toString();
}
}
return sb.toString();
}
5 最终方案:
为了确保以后ORACLE变换版本时不会出题问题,最终用了比较笨的第2步的解决方法
在使用Hibernate查询时遇到Oracle数据库返回Clob类型数据的问题,原SQL中的wm_concat()函数在不同版本的Oracle数据库中返回类型不一致。尝试了通过遍历循环和to_char函数解决,但分别出现了效率问题和ORA-22922错误。最后通过转化为SerializableBlobProxy并利用InvocationHandler成功将Clob转换为String,以避免Oracle版本变化带来的影响。

315

被折叠的 条评论
为什么被折叠?



