Message: Prepared statement contains too many placeholders MySQL的prepared statement只能支持至多65535个占位变量,但原因不详。
具体到当前项目组遇到的问题,我们在使用MySQL JDBC驱动时,为了提升数据插入的效率,启用了rewriteBatchedStatements特性,在批量插入数据时,
MySQL的JDBC驱动会将单条的插入语句合并为一条多值的插入语句;而我们导入的数据规模,一条记录有60列,当导入数据时为1000条记录时,
SQL中占位符的数目恰好小于65535;当导入2000条记录时,SQL中点位符的数目已超过65535,语句执行时必然报错。
了解了引发问题的原因,修复的方法就明确了,将待入库的数据按照1000拆分为多批,在多个事务中完成插入操作,规避MySQL对占位符的限制。
这个解决方法不完美,破坏了预期的数据事务性,但暂时没有想到更好的方法。
使用jdbc进行Mysql批量入库时,PreparedStatment.executeBatch()可能会报错:prepared statement contains too many placeholders,提示占位符过多。
原因是批量入库时,rewriteBatchedStatements为true,其作用是将多条sql语句重写为一条,所以会将一个批次的sql重写为一条,而mysql预编译语句时,一条语句占位符最多为65535。当每批次数据量较大时就会超过这个数量。
解决的方法有两个:一个是减少每批次的数量,但是这样就达不到批量的效果了。第二个办法就是将useServerPrepStmts设置为false,即不启用mysql的预编译功能。这样jdbc会进行预编译,然后将编译好的sql发送到mysql。就不会有这个问题了。