要解决Java中BigDecimal
类型与SQL Server中real
类型冲突导致的varbinary与real不兼容
错误,请按以下步骤操作:
错误原因分析
-
类型映射错误:JDBC驱动尝试将
BigDecimal
转换为varbinary
(二进制类型),而非目标字段的real
类型。 -
根本原因:MyBatis等ORM框架未能自动推断正确的JDBC类型(
REAL
),导致驱动使用默认的varbinary
处理。
解决方案(二选一)
✅ 方案1:显式指定JDBC类型(推荐)
在MyBatis的SQL映射中,显式声明jdbcType=REAL
:
xml
复制
下载
运行
<!-- XML映射示例 --> <insert id="insertData">INSERT INTO your_table (your_real_column)VALUES (#{yourBigDecimalValue, jdbcType=REAL}) </insert>
java
复制
下载
// 注解映射示例 @Insert("INSERT INTO your_table (your_real_column) VALUES (#{value, jdbcType=REAL})") void insertData(@Param("value") BigDecimal value);
✅ 方案2:修改数据库字段类型(治本)
将SQL Server的real
类型改为与BigDecimal
兼容的精确小数类型:
sql
复制
下载
ALTER TABLE your_table ALTER COLUMN your_real_column DECIMAL(18, 6) -- 根据需求调整精度
优势:
-
彻底解决类型冲突
-
避免浮点数精度丢失(
real
是近似浮点,BigDecimal
需精确存储)
关键注意事项
-
类型匹配原则:
-
real
→ Javafloat
(4字节浮点) -
float
→ Javadouble
(8字节浮点) -
decimal/numeric
→ JavaBigDecimal
(精确小数)
-
-
精度风险:
-
real
有精度损失风险(如存储0.1
可能变为0.10000000149
) -
金融等场景必须使用
DECIMAL
类型
-
验证步骤
-
检查SQL Server列类型:
sql
复制
下载
SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'your_table'
-
确认ORM中
jdbcType=REAL
已正确添加 -
测试插入/更新操作
推荐选择方案2:长期来看,使用
DECIMAL
类型能避免精度问题和类型映射隐患。若因历史原因不能改库,则必须使用方案1显式指定jdbcType
。