Laravel迁移设置默认值'0000-00-00 00:00:00'触发1067错误,移除sql_mode中NO_ZERO_DATE和NO_ZERO_IN_DATE仍无法解决
0000-00-00 00:00:00默认值报错的问题 你已经尝试了常规的sql_mode调整,但问题依然存在,我来帮你梳理几个容易被忽略的原因和对应的解决办法:
1. SQL Mode设置未真正生效
你修改了my.ini并执行了会话级的sql_mode命令,但必须重启MySQL服务才能让my.ini的全局配置生效。在XAMPP控制面板里直接停止MySQL再启动即可。另外,建议在MySQL客户端执行SELECT @@sql_mode;,确认当前会话的sql_mode是否真的移除了NO_ZERO_DATE和NO_ZERO_IN_DATE——如果还能看到这两个参数,要么是你修改的my.ini路径不对(XAMPP的my.ini通常在mysql/bin目录下,要确保修改的是正确的文件),要么是服务没重启导致配置没加载。
2. Laravel数据库配置强制覆盖了SQL Mode
Laravel允许在数据库配置文件里单独设置sql_mode,这会直接覆盖MySQL的全局设置。打开config/database.php,找到mysql的配置块,检查是否存在modes字段:
'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), // ...其他配置项 'modes' => [ // 这里可能包含NO_ZERO_DATE、NO_ZERO_IN_DATE ], ],
如果有这个字段,要么直接删除它,要么把它设为空数组'modes' => [],这样Laravel就会使用MySQL全局的sql_mode设置。
3. 零日期默认值与nullable语义冲突
既然你已经给字段加上了nullable(),其实完全可以把默认值改为null,这更符合nullable字段的设计逻辑,也能彻底避开零日期的限制:
// 省略default,nullable字段默认就是null $table->dateTime('start_date')->nullable(); // 或者显式设置default(null) $table->dateTime('start_date')->nullable()->default(null);
这样既满足了字段可为空的需求,又不需要依赖零日期的特殊配置。
4. MySQL版本兼容性问题
如果你的MySQL版本是8.0+,即使关闭了NO_ZERO_DATE,某些环境下零日期0000-00-00 00:00:00依然可能被限制。这种情况下,改用null作为默认值是更稳妥的长期方案。
内容的提问来源于stack exchange,提问作者F_Bass

