create table报1067错误是sql执行时因默认值违反sql mode(如strict_trans_tables、no_zero_date)被拒绝,常见于timestamp/datetime字段设default null或'0000-00-00';应改用default current_timestamp,并确认@@sql_mode一致性。

为什么CREATE TABLE报1067:Invalid default value for 'xxx'
这不是MySQL服务启动失败,而是执行CREATE TABLE或ALTER TABLE时SQL层面直接拒绝——根本原因是字段默认值违反了当前SQL mode的校验规则。最常见于TIMESTAMP或DATETIME字段声明了NOT NULL却配了DEFAULT NULL,或者用了已禁用的零日期'0000-00-00'。MySQL 5.7+默认启用STRICT_TRANS_TABLES和NO_ZERO_DATE,这两项一开,宽松写法立刻失效。
改DEFAULT CURRENT_TIMESTAMP是最稳妥的解法
对TIMESTAMP字段,优先把DEFAULT NULL换成CURRENT_TIMESTAMP;5.6.5+版本的DATETIME也支持该语法。它既满足NOT NULL约束,又符合严格模式要求,还能自动记录插入时间。
CREATE TABLE t (ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP);- 如果还要自动更新,加
ON UPDATE CURRENT_TIMESTAMP:ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP - 注意:
CURRENT_TIMESTAMP不能带括号参数(如CURRENT_TIMESTAMP(3)在旧版可能被拒),除非确认MySQL版本支持微秒精度且SQL mode允许
别硬扛NO_ZERO_DATE,先确认它是否真开着
零日期'0000-00-00'不是“写法错”,而是被NO_ZERO_DATE显式禁止。不查就改配置,容易掩盖数据逻辑问题。
- 运行
SELECT @@sql_mode;,看输出里有没有NO_ZERO_DATE - 再跑
SELECT @@sql_mode LIKE '%NO_ZERO_DATE%';,返回1说明它生效中 - 如果业务真依赖零日期(极少见),临时去掉该mode比改所有表结构更轻量,但必须同步检查应用层是否能处理
NULL或空时间
ALTER TABLE时容易漏掉隐式NOT NULL
有些老表建的时候没写NOT NULL,但TIMESTAMP字段在旧版本会自动补上——升级到5.7+后,ALTER TABLE ... MODIFY若没显式声明NULL,MySQL仍按隐式NOT NULL校验,默认值就会被卡住。
- 安全写法是显式带上
NULL或NOT NULL:ALTER TABLE t MODIFY ts TIMESTAMP NULL DEFAULT '0000-00-00'; - 或者干脆换类型:
ALTER TABLE t MODIFY ts DATETIME DEFAULT '2000-01-01 00:00:00';(DATETIME对零日期限制更松) - 执行前务必
SHOW CREATE TABLE t;确认当前定义,避免凭记忆操作
真正麻烦的不是语法怎么写,而是同一个建表语句在开发机跑得通、上线就报1067——因为两边sql_mode不同。每次迁移或升级,第一件事不是改SQL,是查@@sql_mode。











