You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MS SQL Server JDBC高版本批量插入118列VARCHAR字段报错求助

问题描述

向包含118列的SQL Server表插入数据时,使用mssql-jdbc-8.2.2.jre8.jar驱动一切正常,但升级到9.2.1至12.8.1版本的驱动后,会抛出java.sql.BatchUpdateException,提示第118列列长度无效。

关键现象:

  • 仅当第118列为VARCHAR或NVARCHAR类型时触发报错,改为FLOAT等数值类型则无问题
  • 将该字段改为NVARCHAR无法解决问题
  • 新增一列VARCHAR字段后,错误转移到第119列

插入SQL语句

insert into tt
(CUSTOMER_ID,Value_date,_default,J_termek1,J_termek2,J_termek1_appl_pont,J_termek1_beh_pont,J_termek2_appl_pont,J_termek2_beh_pont,J_t
ermek1_appl_intercept,J_termek1_appl_beta,J_termek1_beh_intercept,J_termek1_beh_beta,J_t
ermek1_appl_weight,J_termek1_beh_weight,J_REL_def_STD,J_macro_correction,J_termek2_appl_intercept,J_termek2_appl_beta,J_termek2_beh_in
tercept,J_termek2_beh_beta,J_termek2_appl_weight,J_termek2_beh_weight,J_termek1_weight,J_termek2_weight,L_termek1,L_
termek2,L_termek1_appl_pont,L_termek1_beh_pont,L_termek2_appl_pont,L_termek2_beh_pont,L_termek1_appl_intercept,L_termek1_appl_beta,L_t
ermek1_beh_intercept,L_termek1_beh_beta,L_termek1_appl_weight,L_termek1_beh_weight,L_REL_def_STD,L_macro_correction,
L_termek2_appl_intercept,L_termek2_appl_beta,L_termek2_beh_intercept,L_termek2_beh_beta,L_termek2_appl_weight,L_termek2_beh_weight,L_t
ermek1_weight,L_termek2_weight,S_termek1,S_termek2,S_termek1_appl_pont,S_termek1_beh_pont,S_termek2_appl_pont,S_term
ek2_beh_pont,S_termek1_appl_intercept,S_termek1_appl_beta,S_termek1_beh_intercept,S_termek1_beh_beta,S_termek1_appl_weight,S_termek1_b
eh_weight,S_REL_def_STD,S_macro_correction,S_termek2_appl_intercept,S_termek2_appl_beta,S_termek2_beh_intercept,S_te
rmek2_beh_beta,S_termek2_appl_weight,S_termek2_beh_weight,S_termek1_weight,S_termek2_weight,O_termek1,O_termek2,O_termek1_appl_pont,O_
termek1_beh_pont,O_termek2_appl_pont,O_termek2_beh_pont,O_termek1_appl_intercept,O_termek1_appl_beta,O_termek1_beh_i
ntercept,O_termek1_beh_beta,O_termek1_appl_weight,O_termek1_beh_weight,O_REL_def_STD,O_macro_correction,O_termek2_appl_intercept,O_ter
mek2_appl_beta,O_termek2_beh_intercept,O_termek2_beh_beta,O_termek2_appl_weight,O_termek2_beh_weight,O_termek1_weigh
t,O_termek2_weight,H_termek1,H_termek2,H_termek1_appl_pont,H_termek1_beh_pont,H_termek2_appl_pont,H_termek2_beh_pont,H_termek1_appl_in
tercept,H_termek1_appl_beta,H_termek1_beh_intercept,H_termek1_beh_beta,H_termek1_appl_weight,H_termek1_beh_weight,H_
REL_def_STD,H_macro_correction,H_termek2_appl_intercept,H_termek2_appl_beta,H_termek2_beh_intercept,H_termek2_beh_beta,H_termek2_appl_
weight,H_termek2_beh_weight,H_termek1_weight,H_termek2_weight,H_atlag_pd,spare3,BEH_PD,behpd,txt1) VALUES
(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)

报错堆栈

java.sql.BatchUpdateException: A rendszer érvénytelen oszlophosszt kapott a BCP-ügyféltől a következő oszlopazonosítóhoz: 118.
   at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeBatch(SQLServerPreparedStatement.java:2042)
   at SAS2SQL.writeToOutput(SAS2SQL.java:1098)
   at SAS2SQL.main(SAS2SQL.java:121)

英文报错翻译:

系统从BCP客户端收到以下列ID的无效列长度:118


插入逻辑代码

String str = stdin.readLine();
        while (str != null) {
            counter++;
            //log(str);
            split(str);
            //log(arrayToText(elemek));
            int k;
            for (int j = 0; j < fields.length; j++) {
                tip=fieldtypes[j];
                textelem=elemek[j];
                k=j+1;
                if (textelem==null)pstmt.setString(k,null);
                else {
                    if (tip==Types.VARCHAR || tip==Types.NVARCHAR ) {
                    pstmt.setString(k, textelem);
                    
                    //if (insertedRows<15) log("TXT: "+textelem);
                    }
                if (tip==Types.INTEGER ||
                    tip==Types.BIGINT ||
                    tip==Types.SMALLINT ||
                    tip==Types.TINYINT 
                         ){
                         //log2("INT:"+Float.parseFloat());
                         if (textelem.trim().equals(".")) pstmt.setNull(k, java.sql.Types.FLOAT);
                         else pstmt.setFloat(k, Float.parseFloat(textelem));
                         }
                if (tip==Types.FLOAT ||
                    tip==Types.NUMERIC ||
                    tip==Types.DOUBLE ||
                    tip==Types.DECIMAL ) {
                         if (textelem.trim().equals(".")) pstmt.setNull(k, java.sql.Types.DOUBLE);
                         else pstmt.setDouble(k, Double.parseDouble(textelem));
                        }
                if (tip==Types.DATE) {
                        if (textelem.trim().equals(".")) pstmt.setNull(k, java.sql.Types.DATE);
                        else pstmt.setDate(k, java.sql.Date.valueOf(textelem));
                        //log2("DATE:"+SASResultSet.getDate(j).toString());
                     }
                if (tip==Types.TIMESTAMP) {
                        if (textelem.trim().equals(".")) pstmt.setNull(k, java.sql.Types.TIMESTAMP);
                        else pstmt.setTimestamp(k,Timestamp.valueOf(textelem.trim()));
                     }
                if (tip==Types.TIME) {
                        if (textelem.trim().equals(".")) pstmt.setNull(k, java.sql.Types.TIME);
                        else pstmt.setTime(k,Time.valueOf(textelem.trim()));
                        //log2("TIME:"+SASResultSet.getTime(j).toString());
                     }
                    }
                 }
            str = stdin.readLine(); 
            insertedRows++;
            pstmt.addBatch();
            bulkcounter++;
            if (bulkcounter==batchSize){
                pstmt.executeBatch();
                pstmt.clearBatch();
                bulkcounter=0;
                if (monitor)log(getTime()+" / "+insertedRows);
                }
             //pstmt.executeUpdate();
            }
        if (bulkcounter!=0) {
            pstmt.executeBatch();
            pstmt.clearBatch();
            if (monitor)log(getTime()+" / "+insertedRows);
            }
        //if (siker==0) log(""+counter+". sor beszúrása sikertelen");
        sqlServerConnection.commit();
        //outputConnection.commit();
        stdin.close();
        pstmt.close();
        log("Number of inserted rows: "+insertedRows); 

解决方案

这个问题是mssql-jdbc驱动在9.x及以后版本中,对批量插入时字符串类型字段的长度校验逻辑发生变化,字段数量较多时易触发索引偏移或长度计算错误。可尝试以下解决方法:

  1. 显式指定字符串参数长度
    设置字符串参数时,使用带长度参数的重载方法,确保驱动正确识别参数长度:

    pstmt.setString(k, textelem, textelem.length());
    

    也可提前获取数据库字段的定义长度,传入对应值。

  2. 禁用BCP批量插入模式
    新版本驱动默认启用BCP优化批量插入,字段数量较多时可能出现兼容性问题。在JDBC URL中添加参数关闭该模式:

    jdbc:sqlserver://<server>:<port>;databaseName=<db>;useBcpBatch=false;
    
  3. 回退驱动版本或提交bug
    若上述方法无效,可暂时回退到8.2.2版本驱动,或向Microsoft提交兼容性问题等待官方修复。

  4. 检查字符串内容
    确认第118列的字符串是否包含不可见字符、超长字符,或因编码转换导致的长度异常(如Unicode字符被错误计算为单字节长度)。


内容的提问来源于stack exchange,提问作者Laszlo voros

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 14:54:53