1/9用友股份-LE支持服务业务本部技术方案--《NC56数据传输报错问题》建立日期:2013-07-01修改日期:xxxx-xx-xx文档属性:客户文控编号:LE-DY-JS-2013-00772/9文档控制创建记录适用范围审阅人日期审阅签字所属部门发布范围内部员工伙伴客户发布人姓名所属部门发布时间日期作者所属部门邮件地址版本2013-7-01魏享林产品支持部V1.0版本领域模块备注3/9目录数据传输报错问题........................................................................................................4一、系统环境................................................................................................................4二、问题描述................................................................................................................4三、检查分析................................................................................................................4(一)上网搜索DB2报错的含义....................................................................................4(二)查找是哪一条SQL执行有错误............................................................................4(三)检查数据库表上的约束.........................................................................................6(四)将目的库中表记录删除,再做传输,问题依旧...............................................6(五)检查日志,发现puncdate字段插入的值为null...............................................7(六)去掉数据库表上的notnull约束,再做传输,发现问题一样........................7(七)怀疑同表上的主键约束有关,去掉表上的主键,发现传输不报错,但主键字段值有重复....................................................................................................8(八)猜测NC是有意将Long按Float处理...................................................8(九)修改代码,提供补丁,补丁验证通过.................................................9四、解决方法................................................................................................................94/9数据传输报错问题一、系统环境NC版本:NC56;中间件:Was单机;数据库:DB2V97;操作系统:Linux二、问题描述数据传输时,报DB2错误,数据无法传输过去,错误如下三、检查分析(一)上网搜索DB2报错的含义[ibm][db2][jcc][102][10040]这个错误的含义是:批处理中某一条SQL语句执行报错,致使批处理无法提交,关键还是SQL语句执行有错误。(二)查找是哪一条SQL执行有错误检查代码,发现在调试执行时,程序会不走批处理,会一条一条语句地执行,这样就能看出是哪一条SQL运行出错及具体的出错信息。5/9对应界面上的设置为:把该任务设为“调试执行”后,再做数据传输,得到日志如下,发现是违反了DB2的约束。6/9(三)检查数据库表上的约束数据库表上的约束如下:可以看出,除了主键约束外,别的约束只有字段上的notnull约束。(四)将目的库中表记录删除,再做传输,问题依旧怀疑是同目的库中已有的表记录相冲突,为此将目的库中表记录删除,再做传输,发现问题一样。7/9(五)检查日志,发现puncdate字段插入的值为null检查NC相关代码,发现此处对于Date类型,确实输出为null,修改代码,增加对于Date类型的处理,发现问题一样。(六)去掉数据库表上的notnull约束,再做传输,发现问题一样说明同notnull约束无关,至于为什么日志中date类型字段的输入值为null,仔细检查代码发现,并不是真的设成null值,而是程序在打印完整的SQL语句,要替换SQL语句中的?号时,对于date类型的字段,其值没有替换,即只是在输出的SQL语句日志中未替换,提交给数据库的参数值是正确的。8/9(七)怀疑同表上的主键约束有关,去掉表上的主键,发现传输不报错,但主键字段值有重复发现C_PUBLISH_ID字段的值同源库不一致,且在源库中不同的值,导入到目的库中变成同一个值。检查NC中处理Long类型字段的方法,发现代码有问题,对于Long类型,应该调用PreparedStatement.setLong,而现在系统中调用的是setFloat,导致传给数据库的值同实际值不一致。(八)猜测NC是有意将Long按Float处理NC中对于ID类型字段,都是用varchar,不使用BigInt,而且在Oracle中,Long,Float,Integer最后都会转变成Number,所以这三种类型差别不大,估计NC是有意将Long类型按Float类型处理。9/9(九)修改代码,提供补丁,补丁验证通过修改NC中对于Long类型的处理,调用jdbc的setLong方法,补丁打到用户环境后,将主键、notnull约束都加上,再做数据传输,发现传输成功,且数据正确。四、解决方法修改NC中对于Long类型的处理,调用jdbc的setLong方法,而不是setFloat方法。提供补丁。