问题复现
Oracle的Clob类型字段理论上可以存储32TB大小的数据,但是当存储字符串时,长度限制仍然会被限制到4000,也就是即使存储的数据小于最大存储容量也会出现存储失败。
insert into table_name(id,text) values(1,'大于4000长度的文本...');
解决方案
我们可以采用分段存储的方式进行存储,sql语句入下:
insert into table_name(id,text) values(1,to_clob('小于4000长度')||to_clob('小于4000长度')||to_clob('小于4000长度')||to_clob('小于4000长度')||to_clob('小于4000长度'));
这样处理后语句就可以成功存储了。
Java代码
public static void main(String[] args){
String result = convertClobMsg(2000, richText.getContent());
String sql = "insert into table_name(id,content,sync_time) values(1," + result + ")";
System.out.println(sql);
}
/**
* 长文本转换可存储的Clob语句
* @param msgItemLength 每次截取的长度
* @param msg 原始长报文
*/
public static String convertClobMsg(int msgItemLength, String msg) {
int i = msg.length() / msgItemLength;
StringBuilder sb = new StringBuilder(); //不能给初始值,报文可能超长未知。
for (int j = 0; j < 1 + i; j++) {
int starSize = j * msgItemLength;
int endSize = (j + 1) * msgItemLength;
if (endSize <= msg.length()) { // 前面的分批截取
String substring = msg.substring(starSize, endSize);
sb.append("to_clob('").append(substring).append("')||");
} else if (starSize != msg.length()) { // 最后一个批次,本次截取至结尾,如果startSize与字符串长度相等,就不再截取
String substring = msg.substring(starSize);
sb.append("to_clob('").append(substring).append("')||");
}
}
return sb.append("to_clob('')").toString();
}