问题
在客户现场执行写入逻辑时遇到异常
ORA-01461:can bind a LONG value only for insert into a LONG column
场景1:sql中使用from dual
出问题的sql如下:
insert into ttt(id, text)
select SEQ_TTT.nextval, t.*
from (
<foreach collection="lists" item="item" separator="union all">
select #{item.text}
from dual
</foreach>
) t;
分析
text字段是Clob类型
当从dual中取数据时,会将Clob对象的字段转为Long型,于是就有了can bind a LONG value only for insert into a LONG column这个报错
解决
修改sql如下:
begin
<foreach collection="lists" item="item">
insert into ttt(id, text)values (
SEQ_TTT.nextval,#{item.text}
);
</foreach>
end;
场景2:字符串超长
首先说一下本例Oracle中该字段类型是nvarchar2(2000)
,什么意思呢?
重点说明:该字段不管存储中文还是英文,都能存入2000个字符,并且每个字符占2字节,即该字段最大存入字节数4000。
解决
在业务代码中,限制该字段最大字节数<=4000,即如果该字段字节数大于4000了,就截取<=4000字节数的最大字符串。方法如下:
/**
* 字符串限制截取
*
* @param str 待处理字符串
* @param limit 限制字节数
* @return 最大字节数以内的最长字符串
*/
public static String subString(String str, int limit) {
if (str == null) {
return "";
}
int length = 0;
StringBuilder stringBuilder = new StringBuilder();
for (char c : str.toCharArray()) {
if (length + String.valueOf(c).getBytes().length <= limit) {
stringBuilder.append(c);
length += String.valueOf(c).getBytes().length;
} else {
break;
}
}
return stringBuilder.toString();
}