Navicat导出SQL文件报错主因是DELIMITER指令不被MySQL服务端识别,而非行尾符问题;错误常现于首行因DELIMITER $$开头,需用source命令、--force参数或sed清洗解决,同时注意BOM头干扰。
navicat 导出的 sql 文件本身没有“行尾符导致解析错误”这回事——真正出问题的是 delimiter 指令,不是换行符(\n 或 \r\n)。
为什么错误提示总出现在第一行?
报错如 ERROR 1064 (42000): You have an error in your SQL syntax 看似像编码或换行问题,但只要文件开头是 DELIMITER $$,就是它在作祟。MySQL 服务端根本不认识 DELIMITER 这个词,它只认标准 SQL 语句;而该指令只是 mysql 命令行客户端用来切分多行语句(比如存储过程)的会话级开关。
- Navicat 自己能执行成功,是因为它内部做了预解析:识别
DELIMITER、按新定界符切分语句块、再逐段发给服务端 - 命令行
mysql -u user -p db_name < backup.sql是直连协议执行,把DELIMITER $$当成普通 SQL 发给服务器,必然炸 - PHP 的
mysqli::multi_query()同理不支持,会卡在第一个DELIMITER行
怎么快速确认是不是 DELIMITER 问题?
用文本编辑器打开 SQL 文件,搜索以下任意一项:
-
DELIMITER $$、DELIMITER ;、DELIMITER // -
CREATE PROCEDURE、CREATE FUNCTION、CREATE TRIGGER - 语句末尾带
$$或//而不是分号;
三者只要出现一组,基本可断定是 DELIMITER 干扰,和行尾符无关。
绕过 DELIMITER 的三种实操方式
不推荐手动删——容易误删注释或字符串里的 $$。更可靠的做法:
- 用
source命令:先mysql -u user -p db_name进入交互模式,再输入source /path/to/backup.sql;—— 它原生支持DELIMITER - 用
--force强制跳过(慎用):mysql -u user -p --force db_name < backup.sql,但可能掩盖真实语法错误 - 自动化清洗(CI/CD 场景首选):
sed '/^DELIMITER/d; s/\$\$;/;/g' backup.sql | mysql -u user -p db_name,删掉所有DELIMITER行,并把结尾$$替换成;
真正要防的“行尾符陷阱”其实只有一个
某些 Windows 编辑器保存时加了 BOM 头(EF BB BF),会导致 MySQL 报类似 Unknown system variable 'DELIMITER' —— 看似是乱码,其实是 BOM 被当成了 SQL 开头字符。解决方法只有:用 VS Code 或 Notepad++ 保存为 UTF-8 without BOM,别信“UTF-8”字面意思。


















