传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。此 RPC 请求中提供了过多的参数。最多应为 2100。

Error updating database. Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。此 RPC 请求中提供了过多的参数。最多应为 2100。

这是因为集合数据量过大,需要对集合进行拆分操作,就是将大集合折分成几个小集合,再进行分批操作,如:[1,2,3,4,5,6,7] 按三个一组拆分成 [[1,2,3]、[4,5,6]、[7]]

java 复制代码
    // 批量增加受理样品
    @Override
    public void addBatch(List<ApplySample> applySampleList) {
        // 如果样品过多,SQL语句的参数大于2100,会报错【此 RPC 请求中提供了过多的参数。最多应为 2100】
        // applySampleMapper.insertBatch(applySampleList);
        /*
        这是插入一条样品信息的SQL语句,用到参数29个,2100 / 29 = 72.4,所以单次最多插入72条样品信息,最好插入50条样品信息
        <!--批量增加受理样品-->
        <insert id="insertBatch">
        <foreach collection="list" item="item">
            if not exists(select as_ID from ApplySampleInfoC where as_OuterApplyId = #{item.outerApplyId} and as_ApplyID = #{item.applyId} and as_SampleNo = #{item.sampleNo})
            insert into ApplySampleInfoC(
            as_OuterApplyID, as_ApplyID, as_SampleNo,
            as_SampleName, as_SampleType, as_YCDD, as_SCDW,
            as_SCDWDZ, as_BatchNo, as_TradeMark, as_Packing,
            as_Property, as_Specs, as_CheckCondition, as_Amount, as_Unit,
            as_Gerder, as_Age, as_SJRQ, as_Vocation,
            as_nationality, as_Ethnics, as_Marriage, as_Education,
            as_IdentityCard, as_Telephone, as_Address,
            as_IdentityAddress, as_TakeMedicineSolutions)
            values(#{item.outerApplyId}, #{item.applyId}, #{item.sampleNo},
            #{item.sampleName}, #{item.sampleType}, #{item.location}, #{item.scdwName},
            #{item.scdwAddress}, #{item.batchNo}, #{item.trademark}, #{item.packing},
            #{item.property}, #{item.specs}, #{item.condition}, #{item.amount}, #{item.unit},
            #{item.gender}, #{item.age}, #{item.peopleGroup}, #{item.vocation},
            #{item.nationality}, #{item.ethnics}, #{item.marriage}, #{item.education},
            #{item.identityNumber}, #{item.telephone}, #{item.residenceAddress},
            #{item.identityAddress}, #{item.previousMedicalHistory})
        </foreach>
        </insert>
         */
        // 批处理,拆分数据,满50条,执行批量插入
        if (applySampleList != null && applySampleList.size() > 50) {
            List<ApplySample> applySampleNewList = new ArrayList<>();
            // 遍历提取数据
            for (int i = 0; i < applySampleList.size(); i++) {
                applySampleNewList.add(applySampleList.get(i));
                // 满50条数据,提交一次
                if ((i + 1) % 50 == 0) {
                    applySampleMapper.insertBatch(applySampleNewList);
                    applySampleNewList.clear();
                }
            }
            // 最后一次提交
            if (!applySampleNewList.isEmpty()) {
                applySampleMapper.insertBatch(applySampleNewList);
                applySampleNewList.clear();
            }
        } else{ // 不够50条数据,不需要分批,直接插入
            // 列表有数据才进行插入,否则不执行任何操作。这样写代码才健壮
            if (applySampleList != null && !applySampleList.isEmpty()) {
                applySampleMapper.insertBatch(applySampleList);
            }
        }
    }

对上面代码进行优化:

java 复制代码
    // 批量增加受理样品
    @Override
    public void addBatch(List<ApplySample> applySampleList) {
        // 如果样品过多,SQL语句的参数大于2100,会报错【此 RPC 请求中提供了过多的参数。最多应为 2100】
        // applySampleMapper.insertBatch(applySampleList);
        /*
        这是插入一条样品信息的SQL语句,用到参数29个,2100 / 29 = 72.4,所以单次最多插入72条样品信息,最好插入50条样品信息
        <!--批量增加受理样品-->
        <insert id="insertBatch">
        <foreach collection="list" item="item">
            if not exists(select as_ID from ApplySampleInfoC where as_OuterApplyId = #{item.outerApplyId} and as_ApplyID = #{item.applyId} and as_SampleNo = #{item.sampleNo})
            insert into ApplySampleInfoC(
            as_OuterApplyID, as_ApplyID, as_SampleNo,
            as_SampleName, as_SampleType, as_YCDD, as_SCDW,
            as_SCDWDZ, as_BatchNo, as_TradeMark, as_Packing,
            as_Property, as_Specs, as_CheckCondition, as_Amount, as_Unit,
            as_Gerder, as_Age, as_SJRQ, as_Vocation,
            as_nationality, as_Ethnics, as_Marriage, as_Education,
            as_IdentityCard, as_Telephone, as_Address,
            as_IdentityAddress, as_TakeMedicineSolutions)
            values(#{item.outerApplyId}, #{item.applyId}, #{item.sampleNo},
            #{item.sampleName}, #{item.sampleType}, #{item.location}, #{item.scdwName},
            #{item.scdwAddress}, #{item.batchNo}, #{item.trademark}, #{item.packing},
            #{item.property}, #{item.specs}, #{item.condition}, #{item.amount}, #{item.unit},
            #{item.gender}, #{item.age}, #{item.peopleGroup}, #{item.vocation},
            #{item.nationality}, #{item.ethnics}, #{item.marriage}, #{item.education},
            #{item.identityNumber}, #{item.telephone}, #{item.residenceAddress},
            #{item.identityAddress}, #{item.previousMedicalHistory})
        </foreach>
        </insert>
         */
        // 集合不为空
        if (!applySampleList.isEmpty()) {
            // 批处理,拆分数据,满50条,执行批量插入
            List<List<ApplySample>> lists = splitList(applySampleList, 50);
            for (List<ApplySample> list: lists) {
                applySampleMapper.insertBatch(list);
            }
        }

        
        // 集合分割,将一个大集合分割成多个小集合,数据示例:[1,2,3,4,5,6,7] 按3个元素一组分割成 [[1,2,3],[4,5,6],[7]]
        public List<List<ApplySample>> splitList(List<ApplySample> list, int chunkSize) {
            List<List<ApplySample>> result = new ArrayList<>();

            for (int i = 0; i < list.size(); i += chunkSize) {
                int end = Math.min(i + chunkSize, list.size());
                result.add(list.subList(i, end));
            }

            return result;
        }
    }

对上面代码再一步优化:

1、提取集合拆分的逻辑,做成集合拆分通用工具

java 复制代码
package com.weiyu.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class PublicUtils {
    /**
     * 集合分割,将一个大集合分割成多个小集合,数据示例:[1,2,3,4,5,6,7] 按3个元素一组分割成 [[1,2,3],[4,5,6],[7]]
     * @param list 集合
     * @param chunkSize 分割大小
     * @return 返回分割集合
     */
    public static <E> Collection<List<E>> splitList(List<E> list, int chunkSize) {
        List<List<E>> result = new ArrayList<>();

        for (int i = 0; i < list.size(); i += chunkSize) {
            int end = Math.min(i + chunkSize, list.size());
            result.add(list.subList(i, end));
        }

        return result;
    }
}

2、使用集合拆分通用工具

java 复制代码
    // 批量增加受理样品
    @Override
    public void addBatch(List<ApplySample> applySampleList) {
        // 如果样品过多,SQL语句的参数大于2100,会报错【此 RPC 请求中提供了过多的参数。最多应为 2100】
        // applySampleMapper.insertBatch(applySampleList);
        /*
        这是插入一条样品信息的SQL语句,用到参数29个,2100 / 29 = 72.4,所以单次最多插入72条样品信息,最好插入50条样品信息
        <!--批量增加受理样品-->
        <insert id="insertBatch">
        <foreach collection="list" item="item">
            if not exists(select as_ID from ApplySampleInfoC where as_OuterApplyId = #{item.outerApplyId} and as_ApplyID = #{item.applyId} and as_SampleNo = #{item.sampleNo})
            insert into ApplySampleInfoC(
            as_OuterApplyID, as_ApplyID, as_SampleNo,
            as_SampleName, as_SampleType, as_YCDD, as_SCDW,
            as_SCDWDZ, as_BatchNo, as_TradeMark, as_Packing,
            as_Property, as_Specs, as_CheckCondition, as_Amount, as_Unit,
            as_Gerder, as_Age, as_SJRQ, as_Vocation,
            as_nationality, as_Ethnics, as_Marriage, as_Education,
            as_IdentityCard, as_Telephone, as_Address,
            as_IdentityAddress, as_TakeMedicineSolutions)
            values(#{item.outerApplyId}, #{item.applyId}, #{item.sampleNo},
            #{item.sampleName}, #{item.sampleType}, #{item.location}, #{item.scdwName},
            #{item.scdwAddress}, #{item.batchNo}, #{item.trademark}, #{item.packing},
            #{item.property}, #{item.specs}, #{item.condition}, #{item.amount}, #{item.unit},
            #{item.gender}, #{item.age}, #{item.peopleGroup}, #{item.vocation},
            #{item.nationality}, #{item.ethnics}, #{item.marriage}, #{item.education},
            #{item.identityNumber}, #{item.telephone}, #{item.residenceAddress},
            #{item.identityAddress}, #{item.previousMedicalHistory})
        </foreach>
        </insert>
         */
        // 集合不为空
        if (!applySampleList.isEmpty()) {
            // 批处理,拆分数据,满50条,执行批量插入
            List<List<ApplySample>> lists = (List<List<ApplySample>>)PublicUtils.splitList(applySampleList, 50);
            for (List<ApplySample> list: lists) {
                applySampleMapper.insertBatch(list);
            }
        }
    }
相关推荐
其实防守也摸鱼14 分钟前
CTF密码学综合教学指南--第三章
开发语言·网络·python·安全·网络安全·密码学
其实防守也摸鱼16 分钟前
CTF密码学综合教学指南--第四章
网络·笔记·安全·网络安全·密码学·ctf
草履虫君1 小时前
VMware 虚拟机网络性能优化指南:从 11 秒到 4 秒的完整调优实践
服务器·网络·经验分享·性能优化
@insist1231 小时前
信息安全-防火墙技术演进全景:从代理NAT 到下一代及专项防火墙
网络·安全·web安全·软考·信息安全工程师·软件水平考试
优化Henry2 小时前
TDD-LTE站点Rilink=3链路故障处理案例---BBU侧C口“有发光、无收光”的排查与恢复
运维·网络·信息与通信·tdd
浪客灿心2 小时前
Linux网络传输层协议
linux·运维·网络
段一凡-华北理工大学3 小时前
【高炉炼铁领域炉温监测、预警、调控智能体设计与应用】~系列文章06:智能决策:从经验驱动到数据驱动
网络·人工智能·数据挖掘·高炉炼铁·工业智能体·高炉炉温
时空系5 小时前
第7篇:功能——打造你的工具箱 Rust中文编程
开发语言·网络·rust
BizViewStudio5 小时前
甄选方法:2026 企业新媒体代运营的短视频精细化运营与流量转化技巧
大数据·网络·人工智能·媒体
凯瑟琳.奥古斯特5 小时前
NAT原理及作用详解
网络·网络协议