根本原因是SQL文件编码与Navicat解析编码不一致,Navicat不识别BOM及SET NAMES声明,需在“运行SQL文件”时手动选对UTF-8(无BOM)或UTF-8 with BOM;导入后乱码还需检查MySQL四层字符集是否均为utf8mb4。
Navicat导入SQL脚本时中文变问号或方块
根本原因是脚本文件编码与navicat默认解析编码不一致,常见于utf-8无bom格式被当成gbk处理。navicat本身不主动探测文件bom,也不读取set names或create database ... character set这类语句的编码声明——它只认你打开文件时指定的编码。
实操建议:
- 用记事本或VS Code确认SQL文件真实编码:右下角看是
UTF-8、UTF-8 with BOM还是GBK;别信文件扩展名或编辑器默认保存设置 - 在Navicat中不要双击打开SQL文件,而要通过
运行SQL文件功能(右键连接 →运行SQL文件),弹窗里手动选对编码 - 如果脚本里有
SET NAMES utf8mb4,它只影响MySQL会话层面的字符集,**不改变Navicat读取文件的解码方式**,所以不能替代编码选择
Navicat“运行SQL文件”对话框里该选UTF-8还是UTF-8 with BOM
选错会导致前几个字节被当作文本内容解析,轻则开头SQL报错,重则整段乱码。BOM本质是三个不可见字节EF BB BF,UTF-8文本加了BOM后,Navicat可能把它当普通字符读入,导致SET变成SET,执行失败。
实操建议:
- 优先选
UTF-8(无BOM)——这是绝大多数现代编辑器(VS Code、Sublime、Notepad++)的默认UTF-8保存选项 - 只有当你明确知道文件带BOM(比如用Windows记事本另存为“UTF-8”时生成的),才选
UTF-8 with BOM - 不确定?用
xxd或file -i命令看头三字节:file -i your.sql输出含charset=utf-8≠带BOM,得看xxd your.sql | head -1是否以ef bb bf开头
导入后表里中文正常,但查询结果仍是乱码
说明SQL执行成功了,但MySQL服务端、数据库、表、连接这四层字符集没对齐。Navicat只是个客户端,它传过去的SQL能执行,不代表返回结果会被正确解码。
实操建议:
- 检查连接字符集:
SHOW VARIABLES LIKE 'character_set%',重点关注character_set_client、character_set_connection、character_set_results是否都是utf8mb4 - 检查库和表字符集:
SHOW CREATE DATABASE your_db和SHOW CREATE TABLE your_table,确保CHARACTER SET是utf8mb4,不是utf8(MySQL的utf8是阉割版,不支持emoji) - Navicat连接属性里勾选
使用MySQL字符集,并手动填utf8mb4到初始化命令框中:SET NAMES utf8mb4
批量导入多个SQL文件时编码不一致怎么办
一个项目里混着GBK导出的旧备份、UTF-8生成的新脚本,Navicat单次只能设一种编码,硬塞会批量翻车。
实操建议:
- 别在Navicat里逐个点开导入——用命令行统一转码:
iconv -f gbk -t utf8mb4 old.sql > new.sql,再统一用UTF-8导入 - 如果必须用Navicat界面操作,先用
file -i *.sql批量查编码,按编码分组,每组单独导入,避免“一个错全崩” - 长期项目建议定规范:所有SQL脚本保存为
UTF-8 no BOM,建库语句开头强制写CREATE DATABASE ... CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci
最常被忽略的一点:Navicat的“工具 → 选项 → 环境 → 默认编码”只影响新建查询窗口,**不影响“运行SQL文件”功能**——那个对话框永远要手动选,没有默认值。











