1. 问题

最近在项目中修bug的时候,碰到这样一个错误:

Caused by: java.sql.SQLException:Prepared or callable statement has more than 2000 parameter markers.    

at net.sourceforge.jtds.jdbc.SQLParser.parse(SQLParser.java:1139)
at net.sourceforge.jtds.jdbc.SQLParser.parse(SQLParser.java:156)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.<init>(JtdsPreparedStatement.java:107) Caused by: java.sql.SQLException:Prepared or callable statement has more than 2000 parameter markers.

出错的代码简化如下(list中的元素个数可能大于2000):

 SELECT * FROM xxx x
WHERE x.date <= :today AND x.id IN (:list)

2. 收获

起初并不明白是什么情况,经过一番google加请教之后,有一些收获。项目中用的JTDS的driver版本为1.2.4,数据库为SQL Server。在该driver的源码中找到如下一个片段(在net.sourceforge.jtds.jdbc.SQLParser类中):


     从这段代码中可以看出,其实这并不是一个bug,而是work as designed。我们得到的另一个信息是,对于不同类型的数据库,不同的版本之间,这种约束是有差别的,分别是255,1000,2000。这样看来,之前的查询语句出错也就很好理解了,在IN子句中的参数个数多于2000是肯定会抛异常的。

3. 解决方案

主要有两种解决方案:一种是优化SQL语句,一种是优化查询逻辑(即分批处理)。
     对于第一种方案,如果IN子句中的参数来自于另一张表的话,可以考虑类似如下的查询方式:

 SELECT * FROM xxx x
INNER JOIN yyy y ON x.id = y.id
WHERE x.date <= :today

对于第二种方案,分批来查询速度没有第一种快,但是不用修改SQL语句。

         List<Item> result = Lists.newArrayList();
List<List<String>> partitionIds = Lists.partition(ids, BATCH_SIZE);
for (List<String> partitionId : partitionIds) {
param.put("list", partitionId);
List<Item> resultItems = xxxService.query(param);
result.addAll(resultItems);
}
return result;

这种方案的劣势在于速度上会有损失,但是可以从Java代码的逻辑层避免上面的问题。

希望这些对大家有所帮助。

java.sql.SQLException: Prepared or callable statement has more than 2000 parameter markers及解决方案的更多相关文章

  1. HiveServer2 的jdbc方式创建udf的修改(add jar 最好不要使用),否则会造成异常: java.sql.SQLException: Error while processing statement: null

    自从Hive0.13.0开始,使用HiveServer2 的jdbc方式创建udf的临时函数的方法由: ADD JAR ${HiveUDFJarPath} create TEMPORARY funct ...

  2. java.sql.SQLException: Error while processing statement: FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask

    执行Hive查询: Console是这样报错的 java.sql.SQLException: Error from org.apache.hadoop.hive.ql.exec.mr.MapRedTa ...

  3. java.sql.SQLException: The SQL statement must not be null or empty.这个错误

    今天发现了这个错误 java.sql.SQLException: The SQL statement must not be null or empty. 并且看了些网页:综合说下这个错误. 一般都是 ...

  4. 在mybatis中使用存储过程报错java.sql.SQLException: ORA-06550: 第 1 行, 第 7 列: PLS-00905: 对象 USER1.HELLO_TEST 无效 ORA-06550: 第 1 行, 第 7 列:

    hello_test是我的存储过程的名字,在mapper.xml文件中是这么写的 <select id="getPageByProcedure" statementType= ...

  5. Oracle java.sql.SQLException: 数字溢出

    六月 30, 2016 5:47:47 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinit ...

  6. java.sql.SQLException: 对只转发结果集的无效操作: last

    出错代码如下:static String u = "user";static String p = "psw";static String url = &quo ...

  7. Hive报错之java.sql.SQLException: Field 'IS_STOREDASSUBDIRECTORIES' doesn't have a default value

    在创建表的时候报出如下错误: hive> create table if not exists testfile_table( > site string, > url string ...

  8. java.sql.SQLException: Lock wait timeout exceeded --转

    org.springframework.dao.CannotAcquireLockException 的解决> 直接上 bug 的详细信息: 2012-03-12 15:20:31 XmlBea ...

  9. java.sql.SQLException: Before start of result set

    在使用JDBC查询数据库报了这么一个错误 CREATE TABLE `d_user` ( `id` int(10) NOT NULL, `name` varchar(10) DEFAULT NULL, ...

随机推荐

  1. M1/M2 总结

    时光是一列不会回头的列车. 这一学期这么快就过去了,当时刚开始软件工程的那些日子还历历在目.不知道那些如风般过去的日子带给我了什么.然而我又清楚地认识到自己已经改变了. 刚开始软件工程的时候,我对团队 ...

  2. iOS GCD中级篇 - dispatch_semaphore(信号量)的理解及使用

    理解这个概念之前,先抛出一个问题 问题描述: 假设现在系统有两个空闲资源可以被利用,但同一时间却有三个线程要进行访问,这种情况下,该如何处理呢? 或者 我们要下载很多图片,并发异步进行,每个下载都会开 ...

  3. MYSQL使用中字符编码一坑

    AJAX提交的字符出错,还以为是AJAX配置的错误呢!幸亏检查了一下MYSQL连接的字符集,发现开发库与本地库配置的字符集是也不一样的.

  4. Event事件2

    1,阻止默认行为: 2,事件监听 3,事件流之事件捕获 4,事件委托 阻止默认行为 浏览器中有很多默认行为,比如当点击a标签后,会发生链接的跳转.当点击鼠标的右键时, 会显示右键菜单等. 有些时候,浏 ...

  5. [转帖]关于网络编程中MTU、TCP、UDP优化配置的一些总结

    关于网络编程中MTU.TCP.UDP优化配置的一些总结 https://www.cnblogs.com/maowang1991/archive/2013/04/15/3022955.html 感谢原作 ...

  6. 一个简单的修改 iis默认页面的方法..

    1. IIS 默认打开的是欢迎页面 2. 然后找到了一个比较简单的修改默认界面的方法: 找到这个文件的默认路径 C:\inetpub\wwwroot 然后修改 iisstart.htm 文件 在hea ...

  7. Win10 1803 升级之后无法使用 共享目录的解决方法

    1. 自己的虚拟机升级了win10 最新版本 1803 但是发现 使用共享文件夹时报错: 2, 百度发现解决方案还是非常简单的. 需要安装一个 功能 3.方法: 开始 运行 输入 control 打开 ...

  8. 研究VCL源码的原因和起点

    ---恢复内容开始--- 研究VCL源码的原因和起点 根本原因:当然是希望自己成为Delphi高手,因为这么多年过去,觉得自己始终不得要领,修改一个控件都无从下手,一直都只是个会拖控件的白痴.而我却拥 ...

  9. 二本毕业,我是如何逆袭成为BAT年薪40W的Java工程师的?

    身边的师弟师妹经常问到:非计算机专业出身,你是在2年内如何逆袭成BAT年薪40W的资深开发工程师的.其实很简单——努力! 我16年毕业于普通的二本学校,非计算机专业出身,只因为对软件开发感兴趣,所以找 ...

  10. C-Lodop的https扩展版,火狐下添加例外

    LODOP综合版里的c-lodop是标准版,没有https和广域网打印功能,如果使用了标准版,调试JS的时候会提示,,loaded over HTTPS,,,the content must be s ...