java.sql.SQLException: Prepared or callable statement has more than 2000 parameter markers及解决方案
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及解决方案的更多相关文章
- 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 ...
- 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 ...
- java.sql.SQLException: The SQL statement must not be null or empty.这个错误
今天发现了这个错误 java.sql.SQLException: The SQL statement must not be null or empty. 并且看了些网页:综合说下这个错误. 一般都是 ...
- 在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= ...
- Oracle java.sql.SQLException: 数字溢出
六月 30, 2016 5:47:47 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinit ...
- java.sql.SQLException: 对只转发结果集的无效操作: last
出错代码如下:static String u = "user";static String p = "psw";static String url = &quo ...
- 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 ...
- java.sql.SQLException: Lock wait timeout exceeded --转
org.springframework.dao.CannotAcquireLockException 的解决> 直接上 bug 的详细信息: 2012-03-12 15:20:31 XmlBea ...
- java.sql.SQLException: Before start of result set
在使用JDBC查询数据库报了这么一个错误 CREATE TABLE `d_user` ( `id` int(10) NOT NULL, `name` varchar(10) DEFAULT NULL, ...
随机推荐
- Docker容器学习梳理 - Volume数据卷使用
之前部署了Docker容器学习梳理--基础环境安装,接下来看看Docker Volume的使用. Docker volume使用 Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker ...
- margin不生效问题
问题机型 魅族M353 Android 5.0.1 问题描述 设置了margin-top: 15px; 但是在该机型上不生效 解决方案 使用padding 替代 margin
- linux-shell-引用-命令替换-命令退出状态-逻辑操作符
命令替换:bash7步扩展的之一 嵌套 这里没什么意义 退出状态可以参与逻辑判断 表达式 算数表达式和条件表达式,逻辑表达式 查看passwd命令比,避免用户捕获输入密码的接口 这种方式就可以直接输 ...
- STL next_permutation()
用法 字典序全排列 可以发现函数next_permutation()是按照字典序产生排列的,并且是从数组中当前的字典序开始依次增大直至到最大字典序. 代码 #include<iostream&g ...
- BugPhobia休息篇章:Beta阶段第IX次Scrum Meeting前奏
特别说明:此次Scrum Meeting不计入正式的Scrum Meeting,因此此次工作仅为第IX次Scrum Meeting的前奏,而笔者也首次采用休息篇章作为子命题 0x01 :Scrum ...
- Scrum Meeting NO.6
Scrum Meeting No.6 1.会议内容 今晚是提交编译测试程序的截至日期,大家果断都在忙着写编译,所以今天的进度不大. 2.任务清单 徐越 序号 近期的任务 进行中 已完成 1 代码重构: ...
- 猫咪记单词Beta版使用说明
猫咪记单词Beta版使用说明 一.项目背景 英语四级考试.六级考试.托福.雅思等英语方面的考试是现在大学生必须面对的问题.同时因为学生对手机的使用越来越频繁,而且仅仅通过书本背诵单词又比较无聊坚持的时 ...
- 使用Eclipse可以方便的统计工程或文件的代码行数,
使用Eclipse可以方便的统计工程或文件的代码行数,方法如下: 1.点击要统计的项目或许文件夹,在菜单栏点击Search,然后点击File... 2.选中正则表达式(Regular expressi ...
- 去掉ambiguous expansion of macro警告
查看原文:http://www.heyuan110.com/?p=1221 用pod install后,pod工程里出现ambiguous expansion of macro的warning,对于有 ...
- TestNG—学习笔记2
关于TestNG,也是一边学一边总结,对于TestNG和Junit的比较其实也没有什么意义,都是一种测试框架,都是为了应用而生的东西,没有必要说谁好谁不好了.用的熟练用的好就是真的好啊. 下面简单的总 ...