根本原因是导出链路中utf-8被系统默认按ansi(如gbk/windows-1252)解析,而非数据库或excel问题;必须用bcp加-f 65001参数导出带bom的utf-8文件,并配合字段引号与正确转义。

SQL 视图导出的 CSV 文件出现乱码,根本原因不是数据库存错了,也不是 Excel 读错了,而是导出链路中 UTF-8 字节流被系统或工具当成 ANSI(如 GBK / Windows-1252)去解析了。哪怕数据库用的是 Chinese_PRC_CI_AS 或 utf8mb4,只要导出环节没显式声明编码、没加 BOM,Windows 就默认按 ANSI 处理。
bcp 导出不加 -f 65001 必然乱码
bcp 默认输出纯 UTF-8(无 BOM),而 Excel 双击打开时不会检测编码,直接用系统 ANSI 解析——一个汉字(3 字节 UTF-8)被拆成 3 个无效字符,显示为“”或“???”。
- 必须加上
-f 65001:这是 Windows 下指定 UTF-8 with BOM 的唯一可靠方式 - 配合
-c(字符模式)和-t","(逗号分隔)才完整 - 示例命令:
bcp "SELECT * FROM my_view" queryout "data.csv" -c -t"," -f 65001 -S localhost -T - 注意:
bcp不生成表头,需手动用UNION ALL拼接,且所有列要CAST成VARCHAR保持类型一致
SSMS “将结果另存为 CSV” 本质不可靠
这个功能在右键查询结果后出现,但它:
- 完全不提供编码选择界面
- 输出文件无 BOM,且内部编码取决于当前 SSMS 窗口的连接设置(常为
SQL_Latin1_General_CP1_CI_AS) - 即使你改了服务器默认排序规则,它也不认
- 临时补救只能用记事本打开 → 另存为 → 编码选“ANSI”→ 再用 Excel 打开(但会丢生僻字)
真正要用 SSMS 导出中文,得走「导入和导出向导」,并在数据源步骤里手动选「Unicode(UTF-8)」,而不是依赖右键菜单。
HeidiSQL / PLSQL Developer 等客户端未勾选 UTF-8 with BOM
这类工具导出对话框里通常有编码下拉菜单,但默认值往往是 Windows-1252 或 ANSI:
- HeidiSQL:必须手动选「UTF-8 with BOM」,并勾选「用引号包围字符串」+「转义引号」
- PLSQL Developer:导出向导中要设字符集为
UTF-8,否则直接走 Oracle 客户端默认的AL32UTF8或ZHS16GBK,二者混用就丢字 - 字段含换行、逗号、双引号时,不加引号会导致 Excel 列错位,这不是乱码,但常被误认为是同一问题
关键点其实就一个:CSV 是纯文本,没有元信息,谁读它,就由谁决定怎么解码。你不能指望 Excel 自动猜对,必须让导出端把编码意图明确表达出来——最稳的方式就是带 BOM 的 UTF-8,且工具支持该选项。
很多人卡在“试了 UTF-8 还是乱码”,往往是因为漏掉了 with BOM 这个限定条件。











