ERROR 1064 语法错误主因是 MySQL 升级后默认 SQL 模式变严格,导致旧脚本中 TYPE=MyISAM 或零日期等非标准写法被拒绝;建议先查版本与 sql_mode,临时可加 --sql-mode="" 导入。
导入 SQL 文件报 ERROR 1064 语法错误
直接原因通常是 mysql 版本升级后默认 sql 模式变严格,老 sql 脚本里用了被禁用的非标准写法。比如 create table 里带 type=myisam(5.5+ 已废弃),或时间字段写成 datetime not null default '0000-00-00 00:00:00'(严格模式下不认零日期)。
实操建议:
- 先用
mysql --version确认服务端版本,再查当前模式:SELECT @@sql_mode; - 临时绕过:导入时加参数
--sql-mode="",例如mysql -u root -p --sql-mode="" db_name - 更稳妥的做法是改脚本本身:把
TYPE=MyISAM换成ENGINE=MyISAM,零日期替换成CURRENT_TIMESTAMP或删掉DEFAULT - 注意:
NO_ZERO_DATE和STRICT_TRANS_TABLES是最常触发ERROR 1064的两个模式项
MySQL 5.7 升 8.0 后导入失败,ERROR 1231 提示变量未设置
典型现象是脚本里有 SET NAMES utf8 或 SET CHARACTER SET utf8,而 8.0 默认只认 utf8mb4,且部分系统变量名已变更(如 sql_mode 变成只读,不能在会话中用 SET 动态改)。
实操建议:
- 把脚本开头所有
SET NAMES utf8替换为SET NAMES utf8mb4 - 删掉或注释掉试图修改
sql_mode的行,比如SET sql_mode = '...'—— 8.0 不允许运行时覆盖全局配置 - 如果必须兼容旧脚本,启动 mysqld 时加
--sql-mode="MODE1,MODE2"显式降级,但别开ONLY_FULL_GROUP_BY,它容易让 GROUP BY 查询直接报错 - 检查是否有
CREATE FUNCTION或存储过程,8.0 要求必须声明DETERMINISTIC或对应特性,否则拒绝创建
用 source 命令导入大文件卡住或报错
source 是 MySQL 客户端命令,不是 SQL 语句,它对语法容错低、不支持注释嵌套、遇到空行或反斜杠转义就可能中断。尤其当 dump 文件含 DELIMITER $$ 和多行函数体时,source 往往解析失败。
实操建议:
- 优先用 shell 层导入:
mysql -u user -p db_name ,它走标准协议,能正确处理分隔符和转义 - 如果非要用
source,确保文件开头没 BOM,且每条语句结尾是分号 + 换行,不要有多余空格或 Windows 回车(\r\n) - 大文件导入前先执行
SET autocommit=0;和SET unique_checks=0;加速,但记得最后COMMIT;和SET unique_checks=1; - 遇到超时,调高客户端参数:
mysql --max-allowed-packet=512M -u user -p
导入后中文乱码,但 SHOW VARIABLES LIKE 'character%' 看着都对
字符集问题往往出在「连接层」和「表定义层」不一致。即使服务器设了 utf8mb4,如果客户端连接时没声明编码,或者建表语句漏写 CHARACTER SET utf8mb4,数据一写进去就变形,后续怎么查都救不回。
实操建议:
- 导入命令必须显式指定字符集:
mysql -u user -p --default-character-set=utf8mb4 db_name - 检查 dump 文件头部是否有
SET NAMES utf8mb4;;没有就手动加一行,放在USE db_name;后面 - 导入后立刻验证:
SELECT CHARSET(column_name), COLLATION(column_name) FROM information_schema.COLUMNS WHERE table_name='t';,确认列级字符集也是utf8mb4 - 别信
SHOW CREATE TABLE输出里的DEFAULT CHARSET=utf8mb4—— 它只管表,不管列;每个VARCHAR字段得单独带CHARACTER SET utf8mb4才真正生效
最容易被忽略的是:mysqld 配置里 [client] 段的 default-character-set 和 [mysql] 段的 default-character-set 必须一致,否则命令行客户端连上去就自动用错编码,脚本里写再多 SET NAMES 都晚了。











