SQL Server BULK INSERT导入捷克字符文本乱码如何解决
乱码问题根因
- 生成bcp格式文件时使用了
-c参数,该参数默认按系统当前ANSI代码页解析文本,未指定源文件编码,捷克语特殊字符(č、ý、ř、ě等)在非捷克语代码页环境下会直接解析错误。你的目标列是nvarchar类型,未做正确的编码转换时,单字节编码的字符写入双字节的Unicode字段必然出现乱码。 - 格式文件配置与导入参数冲突:你生成的fmt文件里第二字段行终止符写的是
\r\n(CRLF换行),但实际BULK INSERT时强制指定行终止符为0x0A(LF换行),不仅会把每行末尾的回车符\r带入NAME字段内容,还会导致字段解析偏移。 - 格式文件未指定正确的源代码页:现有fmt文件仅在列上指定了Czech_CI_AS排序规则,但没有声明源文本对应的代码页,SQL Server会用服务端默认代码页解析源文件,完全无法正确识别捷克语特殊字符。
修复步骤
前置确认
先用记事本打开C:\temp\cznames.txt,看窗口右下角标注的文件编码,分两种场景处理:
场景1:源文件为UTF-8编码(绝大多数文本编辑器默认保存格式)
- 清空之前导入的错误数据:
TRUNCATE TABLE myDatabase.dbo.myNameTable;
- 重新生成格式文件,执行bcp命令时指定UTF-8代码页:
bcp myDatabase.dbo.myNameTable format nul -c -C 65001 -f "C:\temp\Czech.fmt" -T -S myserver -U myuser -P 1mypwd
- 编辑生成的
Czech.fmt文件,修正行终止符配置,修改后内容如下:
10.0 2 1 SQLCHAR 0 7 "\t" 1 ID "" 2 SQLCHAR 0 100 "\n" 2 NAME Czech_CI_AS
注:原fmt文件中第二列列名写为Region,与表结构的NAME字段不一致,bcp按序号映射不影响导入,但建议修正避免后续维护混淆。
- 执行导入命令,明确指定UTF-8代码页:
BULK INSERT myDatabase.dbo.myNameTable FROM 'C:\temp\cznames.txt' WITH ( FormatFile = 'C:\temp\Czech.fmt', FIRSTROW = 2, CODEPAGE = '65001' );
场景2:源文件为UTF-16 LE(Windows Unicode)编码
- 清空旧的错误数据:
TRUNCATE TABLE myDatabase.dbo.myNameTable;
- 用Unicode模式重新生成格式文件:
bcp myDatabase.dbo.myNameTable format nul -w -f "C:\temp\Czech.fmt" -T -S myserver -U myuser -P 1mypwd
- 编辑fmt文件修正行终止符,修改后内容如下:
10.0 2 1 SQLNCHAR 0 7 "\t" 1 ID "" 2 SQLNCHAR 0 100 "\n" 2 NAME Czech_CI_AS
- 执行导入命令,指定宽字符数据类型:
BULK INSERT myDatabase.dbo.myNameTable FROM 'C:\temp\cznames.txt' WITH ( FormatFile = 'C:\temp\Czech.fmt', FIRSTROW = 2, DATAFILETYPE = 'WideChar' );
验证结果
导入完成后执行查询,确认NAME字段值和源文件一致即可:
SELECT * FROM myDatabase.dbo.myNameTable;
预期返回结果:
| ID | NAME |
|---|---|
| 1 | Vysočina |
| 2 | Olomoucký |
| 3 | Středočeský |
| 4 | Hlavní město |
内容的提问来源于stack exchange,提问作者user2726975
相关产品推荐
相关产品推荐

