nested exception is java.sql.BatchUpdateException: 批处理中出现错误: ORA-00972: 标识符过长
最近开发项目,跑批处理遇到一个问题:2013-07-28 09:53:35,715[P17Quartz_CAScheduler_Worker-7]ERROR [JobRunShell]run(line:211)Job DEFAULT.propertySmsJobDetail threw an unhandled Exception: org.springframework.jdbc.UncategorizedSQLException: StatementCallback; uncategorized SQLException for SQL [update T_CC_L2_SMS_Send set LastUpt_Dttm=to_date('2013-07-28 09:53:35','yyyy-mm-dd hh24:mi:ss'), ENABLE_FLG = '2' where ACT_ID =350791104]; SQL state [null]; error code [17081]; 批处理中出现错误: ORA-00972: 标识符过长; nested exception is java.sql.BatchUpdateException: 批处理中出现错误: ORA-00972: 标识符过长==============================================报错是因为SQL语句:update T_CC_L2_SMS_Send set LastUpt_Dttm=to_date('2013-07-28 09:53:35','yyyy-mm-dd hh24:mi:ss'), ENABLE_FLG = '2' where ACT_ID =350791104但是该语句在PL-SQL 单独运行时正常的。 而且该quartz的从去年9月份到现在都没有改动过。 昨天忽然出错。 我初步分析可能原因如下:1 因为报错的方法如下, 怀疑入参的数据组的长度,超出的batchUpdate的,比如达到 1000条。/** * SQL批处理 */public void bachUpdate(String[] sql){ this.getJdbcTemplate().batchUpdate(sql);}2 怀疑SQL:update T_CC_L2_SMS_Send set LastUpt_Dttm=to_date('2013-07-28 09:53:35','yyyy-mm-dd hh24:mi:ss'), ENABLE_FLG = '2' where ACT_ID =350791104 其中【ACT_ID =350791104】 应该写成【ACT_ID ='350791104'】,但是该字段act_id 的类型为number(10) ,按理应该可以执行的。3 怀疑因为是批量处理,前面一批SQL 是insert语句,刚巧这个update语句是紧排在insert后面。 意思是出错的是上一个SQL,日志截获的是下一个SQL。形如: insert …………;insert …………;insert …………;(此句报错)update T_CC_L2_SMS_Send set LastUpt_Dttm=to_date('2013-07-28 09:53:35','yyyy-mm-dd hh24:mi:ss'), ENABLE_FLG = '2' where ACT_ID =350791104 (拦截此句)网上关于标识符过长的解释 都无法说明原因; =================================================================最终结果,正如上述第3种的怀疑, 在调用Spring的JdbcTemplate.batchUpdate(String[] sqlArray)方法时,因为是个Quartz的跑批处理程序,所以在在入参的数组中,包含了insert、update等语句。 其中一个最后一个insert语句字段包含一个英文单引号,导致,后面的update语句报错:ORA-00972: 标识符过长。但是,异常只给出了当前出错的SQL语句。总结:在首次插入短信表记录事,采用是JdbcTemplate.update(String sql, Object args[]). 支持字段中包含英文单引号,但是跑批时,为了提供性能,采用另一种方式JdbcTemplate.batchUpdate(String[] sqlArray), 该方法不支持表字段中包含英文单引号。所以导致搞问题。最终通过,采用统一的JdbcTemplate.update(String sql, Object args[]) 进行插入数据即可!