MSSQL从WinSrv2012R2迁移至Linux后瑞典语字符编码异常求助
瑞典语特殊字符ÅÄÖ迁移异常解决方案
问题根因说明
你遇到的是双层编码错误叠加问题:旧Windows环境的字符存储本身就存在代码页不匹配的问题(Ö提前被错误转码为Í),跨操作系统迁移到Linux侧SQL Server时,不同系统的默认字符集差异导致二次转码错误,最终显示为乱码。仅修改库级排序规则和兼容级别无法修复已经错误存储的字符,需要从编码层、存储层、迁移流程三个维度调整。
可执行解决步骤
- 先校验列级存储类型与排序规则
库级排序规则不会覆盖表、列的自定义排序规则,优先查询对应存储列的配置:
若列类型为SELECT COLUMN_NAME, DATA_TYPE, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'你的业务表名' AND COLUMN_NAME = N'存储异常字符串的列名'varchar而非nvarchar,且排序规则不是Finnish_Swedish_CI_AS,说明旧数据在写入时就已经发生了代码页转码错误,属于原始存储问题。 - 调整系统级locale配置(Debian侧)
SQL Server on Linux会继承操作系统的默认locale配置,需要先确认系统与SQL Server的locale匹配北欧字符集:- 查看Debian系统当前locale:
locale - 若不存在
sv_SE.UTF-8或fi_FI.UTF-8,先生成对应locale:sudo locale-gen sv_SE.UTF-8 - 修改SQL Server默认locale:
sudo /opt/mssql/bin/mssql-conf set locale sv_SE.UTF-8 - 重启SQL Server服务生效:
sudo systemctl restart mssql-server
- 查看Debian系统当前locale:
- 重新走编码兼容的迁移流程
不要直接做库级备份还原,改用Unicode兼容的导出导入方式:- 旧Windows侧用bcp工具以Unicode格式导出数据:
bcp 库名.模式名.表名 out 导出文件路径 -w -S 旧实例地址 -U 用户名 -P 密码 - 新实例侧先把目标列修改为
nvarchar类型,保留Finnish_Swedish_CI_AS排序规则 - 用bcp导入到新实例:
bcp 库名.模式名.表名 in 导出文件路径 -w -S 新实例地址 -U 用户名 -P 密码
- 旧Windows侧用bcp工具以Unicode格式导出数据:
- 存量错误数据快速修复
如果不想重新全量迁移,可先验证字符映射关系后做批量替换,注意:替换前必须备份对应表数据,先小范围测试验证效果:-- 先测试替换效果 SELECT 列名, REPLACE(列名, N'+', N'Ö') AS 修复后结果 FROM 表名 WHERE 列名 LIKE N'%+RSTA' -- 验证无误后执行更新 UPDATE 表名 SET 列名 = REPLACE(列名, N'+', N'Ö') WHERE 列名 LIKE N'%+RSTA'
内容的提问来源于stack exchange,提问作者Emil G
相关产品推荐
相关产品推荐

