1 排查过程
1.1 出错场景
将任务执行异常结果插入异常表时,column_a的实际长度4000小于实际长度5005,报错
1.2 解决思路
解决方案分为两种:1,修改数据库的字段长度;2,把数据截取至字段上线后,插入
首先,跟业务确认,得知,该异常字段可只截取异常信息的一部分进行保存即可,所以我决定在代码中将异常信息截取,后执行插入操作。
接着,通过调试,发现同事有做这方面的处理,代码如下,猛一看没问题,实则不然。因为:Java中String的长度与Oracle的varchar2的长度的单位不同:(这个在后边会讲)
// 修改前
if(columnA.length() > 4000){
columnA = columnA.substring(0, 3500);
}
2 知识点
2.1 Java中string的长度和Oracle中varchar2的长度的单位
- String的长度表示字符个数
- varchar2的长度表示的是字节的个数
- Oracle的字符集不同,一个字符占的字节数也不一样
2.2 两个常见的Oracle字符集(其实是我接触过的0_0)
- ZHS16GBK:一个中文字符占两个字节
- AL32UTF8:一个中文字符占三个字节
3 解决思路
- 获得当前数据库的字符集
- 根据字符集来判断string的字符上限,并做截取
3.1 查询当前数据库的字符集SQL
select * from v$nls_parameters t where t.PARAMETER='NLS_CHARACTERSET';