SQL中泰语字符存入后乱码问题求助(nvarchar(MAX))
我之前帮同事排查过几乎一模一样的泰文乱码问题!哪怕你用了nvarchar(MAX)这种原生支持Unicode的类型,还是会因为编码传输/写入环节的疏漏导致字符损坏,下面是具体的原因分析和防范方案:
核心原因
nvarchar确实是SQL Server用来存储Unicode字符的类型,但如果写入数据时没有明确指定Unicode编码,SQL Server会把输入的字符串当成非Unicode(默认是数据库的默认单字节编码,比如SQL_Latin1_General_CP1_CI_AS)处理,泰文这类不在单字节编码范围内的字符就会被错误转码,变成你看到的Ó╣éÓ©úÓ©ç这种乱码。
具体防范方法
SQL语句插入时必须加
N前缀:这是最容易踩的坑!直接写字符串的话,一定要在前面加N,告诉SQL Server这是Unicode字符串:INSERT INTO your_table (company_name) VALUES (N'Yamato-Esulon (Thailand) Co.,Ltd (โรง 1)');不加
N的话,哪怕列是nvarchar,SQL也会先把字符串转成数据库默认的非Unicode编码,再转成Unicode,中间就会丢失泰文的字符信息。检查应用程序的数据库连接配置:如果是通过代码(比如C#、Java)写入数据,要确保连接字符串和驱动配置支持Unicode:
- .NET的SqlConnection默认支持Unicode,但如果手动设置了
UseAnsi=true这类参数,一定要去掉; - Java的JDBC连接要添加
useUnicode=true&characterEncoding=utf-16(因为SQL Server用UTF-16存储Unicode),避免驱动把字符串转成ANSI再传输。
- .NET的SqlConnection默认支持Unicode,但如果手动设置了
确认列的排序规则:虽然
nvarchar存储不依赖排序规则,但设置对应语言的排序规则可以避免隐式转换时的编码问题。你可以把列的排序规则改成泰文专用的:ALTER TABLE your_table ALTER COLUMN company_name NVARCHAR(MAX) COLLATE Thai_CI_AS;排查数据导入的中间环节:如果是通过文件、ETL工具导入数据,要确保源文件是UTF-8(带BOM)或UTF-16编码,导入工具也要正确识别编码——比如用SSIS导入时,数据源的编码不能选“默认”或ANSI,必须选对应Unicode编码。
快速排查步骤
先在SSMS里执行带N前缀的插入语句,如果能正确存储泰文,说明问题出在应用程序或导入工具的编码配置上;如果还是乱码,再检查数据库的默认排序规则和服务器的区域设置。
内容的提问来源于stack exchange,提问作者Anil Thomas

