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

Liquibase向MS SQL插入数据时Blob列引发特殊字符乱码问题

问题原因

  • 核心是 Liquibase 4.2.2 + MSSQL JDBC 8.4.1 版本在处理同时包含 Unicode 文本(NVARCHAR 类型)和 BLOB 字段的插入语句时,在默认校对规则为 Latin1_General_CI_AS 的数据库环境下存在参数类型推导缺陷:当插入语句中包含 BLOB 类型参数时,JDBC 驱动会错误将前面的 NVARCHAR 字符串参数按照 Latin1 单字节字符集转码后传输,西里尔文这类非 Latin1 字符无法被编码,直接被替换为 ? 存入数据库。没有 BLOB 字段的插入语句不会触发这个推导错误,所以 Unicode 内容可以正常存储。
  • 本地环境无法复现大概率是因为本地数据库实例/库的默认校对规则不是 Latin1_General_CI_AS,参数推导逻辑走了另一个分支,不会触发编码转换错误。

可行解决方案

  1. 显式指定 NVARCHAR 字段的 valueType(最优先推荐)
    给所有变更集中 NVARCHAR 类型字段的插入配置加上 valueType="NVARCHAR" 属性,强制 Liquibase 和 JDBC 驱动按照 Unicode 类型处理参数,不会被错误转码,示例如下:

    <column name="NAME_NATIVE" value="Белару́сь" valueType="NVARCHAR"/>
    

    所有 NVARCHAR 类型的列(NAME_LATIN、ADDR_FORMAT、REQUIRED_FIELDS、ZIP_REGEX 等)都要加上这个属性配置即可解决问题。

  2. 拆分 BLOB 字段的插入逻辑
    把 BLOB 字段的写入拆成独立的变更集:先执行不带 BLOB 字段的插入操作写入所有文本内容,再单独执行 update 语句更新对应行的 FLAG 字段,避开同一条插入语句同时存在 BLOB 和 Unicode 文本参数的场景。

  3. 升级组件版本
    把 Liquibase 升级到 4.10 以上版本,MSSQL JDBC 驱动升级到 12.2 以上版本,这两个版本官方已经修复了大量混合类型参数的推导缺陷,这类编码错误基本不会再触发。

  4. 临时验证方案
    可以在数据库 JDBC 连接串中加上 sendStringParametersAsUnicode=true 参数,强制所有字符串参数按照 Unicode 格式传输,但该配置可能会影响普通 VARCHAR 字段的查询性能,只建议做问题验证使用,不推荐长期在生产环境配置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 23:45:05