开发中遇到SQL IN传入参数的个数超过2100的bug

发布于:2024-05-17 ⋅ 阅读:(114) ⋅ 点赞:(0)

在SQL Server或者MySQL中,当你在IN子句中需要处理的结果集可能超过2100个元素时,由于SQL Server对IN子句中的参数数量存在大约2100个左右的限制,直接使用IN会导致错误。为了解决这个问题,可以采取以下策略:

1、将参数拆分,分批次查询出结果然后合并

2、建立临时表批量插入IN参数 join 或者 exists 查询后删除掉

1.创建临时表

create table #temp(columnname1   type,columnname2 type)

2.为临时表插入数据

insert into #temp(columnname1,columnname1)

values(?,?)

3.注意事项:在使用临时表的时候自己写分页,如果使用mybatis自带的page对象进行分页会报错:SQL语句中创建临时表create附近有错

4.开发中遇到问题:

List<String>=dto.getGrids().split(",");

原来的SQL

<select id="queryPageInfo" resultType="UserInfo">

select A.name,A.adress,A.createtime createTime from UserInfo A

<if dto.getGrids!=null && dto.getGrids!=''>

A.grid in (

<foreach collect=dto.gridValues,seperator=',',item=date>

(#{data})

<\foreach>

</if>

)

</select>

dto.getGrids传入的参数过多报错:

在SQL Serve中, Server对IN子句中的参数数量超过2100个左右的限制,请重新传入参数

 

解决方法:

第一步:Mapper.xml中SQL修改

<sql id="queryInfo>

<if dto.gridValues!=null && dto.GridValues!=''>

create table #temp(grid varchar (20))

insert into #temp(grid)

values (

<foreach collect=dto.gridValues,seperator=',',item=data>

(#{data})

<\foreach>

)

</if>

</sql>

<select id="queryPageInfo" resultType="UserInfo">

<if dto.gridValues!=null && dto.gridValues!=''>

<include ref="queryInfo">

</if>

select A.name,A.adress,A.createtime createTime from UserInfo A

<if dto.gridValues!=null && dto.gridValues!=''>

A.grid=#temp.grid

</if>

</select>

第二步:手动分页

public List <UserInfo> queryPageInfo(UserInfoDto dto,Page page){

List <UserInfo> list=new ArrayList <>;

List<String> gridsList=dto.getGrids.split(",");

Integer  num=1000;

Integer size=gridsList.size();

//关键代码解决 SQL in参数个数超过2100错误

if(size>1000){

//n代表数据需要分几次查询

Integer n=size/num==0?size/num:size/num+1;

for (int j=0;j<n;j++){

Integer start=j*num;

Integer end=start+page.getPageSize()>size?size:start+page.getPageSize();

dto.setGridValues(list.subList(start,end));

list.addAll(userMapper.queryPageInfo(dto,null);

//创建时间降序

list.sort(Comparator.comparing(UserInfer::getCreateTime).reverse());

//手动分页

Integer offset=(page.curren