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
相关产品推荐
相关产品推荐

