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

SpringBoot中用JdbcTemplate向MSSQL插入Varbinary值异常问题

解决SpringBoot JdbcTemplate插入MSSQL二进制字段异常问题

问题分析

你遇到的问题核心在于:MSSQL的CONVERT(varbinary, ?)默认会把传入的字符串当成普通字符序列转换,而不是解析十六进制格式的字符串。你的ELCORResourceTimeRegistr.getEntryNo()返回的是"0x00173672"这样的字符串,直接传给CONVERT(varbinary, ?)时,数据库会把每个字符(比如'0'、'x'、'0'等)转换成对应的Unicode字节(也就是你看到的<30007800 30003000...>),而不是把十六进制字符串解析成真正的二进制值。

另外注意你原代码里有个小笔误:ELCORResourceTimeRegistr.getEntryNo(), ELCORResourceTimeRegistr.getEntryNo())这里多了一个闭合括号,得先去掉,不然代码编译不过。

解决方案

这里给你两个简单可行的方案,选一个适合你的就行:

方案一:修改SQL的CONVERT语句(最简单)

MSSQL的CONVERT函数支持第三个参数,当传入1时,会自动识别带0x前缀的十六进制字符串,并解析成对应的二进制值。只需要修改你的SQL语句:

int numOfRowsAffected = remoteJdbcTemplate.update(
    "insert into dbo.[ELCOR Resource Time Registr_] " +
    "( [Entry No_], [Record ID], [Posting Date], [Resource No_], [Job No_], [Work Type], [Quantity], [Unit of Measure], [Description], [Company Name], [Created Date-Time], [Status] ) " +
    " VALUES (?,CONVERT(varbinary,?,1),?,?,?,?,?,?,?,?,?,?);",
    ELCORResourceTimeRegistr.getEntryNo(), 
    ELCORResourceTimeRegistr.getEntryNo(), 
    ELCORResourceTimeRegistr.getPostingDate(), 
    ELCORResourceTimeRegistr.getResourceNo(), 
    jobNo, 
    ELCORResourceTimeRegistr.getWorkType(), 
    ELCORResourceTimeRegistr.getQuantity(), 
    ELCORResourceTimeRegistr.getUnitOfMeasure(), 
    ELCORResourceTimeRegistr.getDescription(), 
    ELCORResourceTimeRegistr.getCompanyName(), 
    ELCORResourceTimeRegistr.getCreatedDate(), 
    0
);

方案二:在Java层转换为byte数组后传入

如果不想在SQL里处理转换逻辑,可以在Java代码中将十六进制字符串转换成byte数组,直接传入SQL(此时不需要CONVERT):

首先写一个转换工具方法:

private byte[] hexToBytes(String hexStr) {
    // 去掉0x前缀
    String hex = hexStr.startsWith("0x") ? hexStr.substring(2) : hexStr;
    int length = hex.length();
    byte[] bytes = new byte[length / 2];
    for (int i = 0; i < length; i += 2) {
        bytes[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                + Character.digit(hex.charAt(i + 1), 16));
    }
    return bytes;
}

然后修改插入代码:

// 先转换十六进制字符串为byte数组
byte[] recordIdBytes = hexToBytes(ELCORResourceTimeRegistr.getEntryNo());

int numOfRowsAffected = remoteJdbcTemplate.update(
    "insert into dbo.[ELCOR Resource Time Registr_] " +
    "( [Entry No_], [Record ID], [Posting Date], [Resource No_], [Job No_], [Work Type], [Quantity], [Unit of Measure], [Description], [Company Name], [Created Date-Time], [Status] ) " +
    " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
    ELCORResourceTimeRegistr.getEntryNo(), 
    recordIdBytes, 
    ELCORResourceTimeRegistr.getPostingDate(), 
    ELCORResourceTimeRegistr.getResourceNo(), 
    jobNo, 
    ELCORResourceTimeRegistr.getWorkType(), 
    ELCORResourceTimeRegistr.getQuantity(), 
    ELCORResourceTimeRegistr.getUnitOfMeasure(), 
    ELCORResourceTimeRegistr.getDescription(), 
    ELCORResourceTimeRegistr.getCompanyName(), 
    ELCORResourceTimeRegistr.getCreatedDate(), 
    0
);

内容的提问来源于stack exchange,提问作者en Peris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:12:53