共计 1521 个字符,预计需要花费 4 分钟才能阅读完成。
前言
做项目的时候遇到一个报错:ORA-22835 缓冲区对于 CLOB 到 CHAR 转换或 BLOB 到 RAW 转换而言太小。查找原因发现是某个字段在数据库中是 clob 类型。然后 sql 语句进行查询的时候,对该字段进行了 to_char 操作。由于 varchar 类型最大长度为 4000,而 clob 中的内容长度高于 4000。于是产生这样的问题。针对这个问题,结合自己的测试,想了以下三种解决方法,在此进行记录。
一、进行实体映射及获取字段数据时,直接当成 string 处理
比如说,我们使用 jdbctemplate 来进行查询的时候,封装实体对象字段,我们不将字段封为 clob 类型而是直接封为 string 类型。然后我们进行查询的时候,会发现没有问题,clob 中的内容完整的封入了 string 字段中。
二、对 clob 进行截取
对数据库中的 clob 字段的内容进行截取,也可以解决这一问题,但是会造成 clob 中内容获取的不完整。
比如下方 name 字段是 clob 类型,sql 写法如下:
select to_char(substr(name,0,4000)) as name from people
我们截取 name 的前 4000 位,这样没有超过 varchar 类型的最大值,所以不会报错。
需要注意的是:如果 clob 中有中文会占两个字符。所以比较安全的方式就是除以 2,进行截取。
sql 写法如下:
select to_char(substr(name,0,2000)) as name from people
三、通过 java 代码将 clob 转为 string
我们获取到一个 clob 类型的数据后,对其进行处理,使其转换为 string 类型。
转换代码如下:
public String ClobtoString(Clob clob){
String reString = “”;
Reader is = null;
try {
is = clob.getCharacterStream();
} catch (Exception e) {
e.printStackTrace();
}
// 得到流
BufferedReader br = new BufferedReader(is);
String s = null;
try {
s = br.readLine();
} catch (Exception e) {
e.printStackTrace();
}
StringBuffer sb = new StringBuffer();
while (s != null) {
// 执行循环将字符串全部取出付值给 StringBuffer 由 StringBuffer 转成 STRING
sb.append(s);
try {
s = br.readLine();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
reString = sb.toString();
return reString;
}
总结
三种方式,推荐大家使用第三种。
第三种方式正规,靠谱。
第二种方式,如果图便捷,又对数据完整性没要求,可以使用。
第一种方式,只在 spring 中的 jdbcTemplate 下使用没有发现问题,其他操作方式或数据库框架可能引起问题,需要大家来测试了。
更多 Oracle 相关信息见 Oracle 专题页面 https://www.linuxidc.com/topicnews.aspx?tid=12
: