mysql 5.7+默认严格模式导致旧sql报错,可临时用set session sql_mode修改会话级配置,或永久修改my.cnf中sql_mode并重启,云数据库需通过控制台调整。

MySQL 5.7+ 默认 strict mode 导致旧 SQL 报错怎么办
MySQL 5.7 及以上版本默认启用严格模式(STRICT_TRANS_TABLES 和 STRICT_ALL_TABLES),这会让很多旧版应用中常见的“隐式类型转换”“插入空字符串到 NOT NULL 字段”“截断超长字符串”等操作直接报错,而不是警告后继续执行。这不是 bug,是行为变更——但你确实可以关掉它,前提是清楚后果。
查看当前 sql_mode 并识别哪些项属于“严苛模式”
先连上 MySQL 执行:
SELECT @@sql_mode;常见输出类似:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION。其中真正触发“插入失败”的核心是:STRICT_TRANS_TABLES(对事务表生效)和 STRICT_ALL_TABLES(对所有表生效)。其他如 NO_ZERO_DATE、ERROR_FOR_DIVISION_BY_ZERO 也属于“更严格”的校验,是否保留取决于你的业务容忍度。
临时修改(会话级):快速验证兼容性
只影响当前连接,重启或断开就失效,适合测试:
- 去掉全部严苛项:
SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
- 最简兼容写法(仅保留 MySQL 5.6 默认项):
SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION';
- 彻底清空(不推荐,会绕过几乎所有校验):
SET SESSION sql_mode = '';
注意:SET SESSION 不影响其他连接,也不能绕过全局限制(比如某些托管数据库禁止修改 sql_mode)。
永久修改(需重启或动态生效)
编辑 MySQL 配置文件(通常是 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf),在 [mysqld] 段落下添加:
sql_mode = "NO_ENGINE_SUBSTITUTION"
或按需补充其他非严苛项,例如:
sql_mode = "ONLY_FULL_GROUP_BY,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"然后重启 MySQL:
sudo systemctl restart mysql(或
mysqld)。若用的是 MySQL 8.0.11+ 且支持动态变量,也可运行:SET PERSIST sql_mode = 'NO_ENGINE_SUBSTITUTION';该命令会写入
mysqld-auto.cnf 并持久化,无需重启。
真正容易被忽略的是:有些云数据库(如阿里云 RDS、腾讯云 CDB)不允许修改 sql_mode,只能通过控制台参数模板调整;而 Docker 启动的 MySQL 容器,必须把配置挂载进容器并确保 mysqld 读取到了它——光改宿主机文件没用。











