版本:mysql5.7mysql
執行sql:sql
CREATE TABLE seckill( `seckill_id` BIGINT NOT NUll AUTO_INCREMENT COMMENT '商品庫存ID', `name` VARCHAR(120) NOT NULL COMMENT '商品名稱', `number` int NOT NULL COMMENT '庫存數量', `start_time` TIMESTAMP NOT NULL COMMENT '秒殺開始時間', `end_time` TIMESTAMP NOT NULL COMMENT '秒殺結束時間', `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間', PRIMARY KEY (seckill_id), key idx_start_time(start_time), key idx_end_time(end_time), key idx_create_time(create_time) )ENGINE=INNODB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 COMMENT='秒殺庫存表';
執行結果:ERROR 1067 (42000): Invalid default value for 'end_time'服務器
緣由是:mysql5.7的explicit_defaults_for_timestamp參數默認是OFF與sql_mode的NO_ZERO_DATE衝突ide
經過執行mysql>show variables;查看explicit_defaults_for_timestamp和sql_mode變量的值spa
explicit_defaults_for_timestamp = OFFci
sql_mode = ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTIONit
分析過程:
class
1)在默認狀況下,若是TIMESTAMP列沒有顯示的指明null屬性,那麼該列會被自動加上not null屬性(而其餘類型的列若是沒有被顯示的指定not null,那麼是容許null值的),若是往這個列中插入null值,會自動的設置該列的值爲current timestamp值。變量
2)表中的第一個TIMESTAMP列,若是沒有指定null屬性或者沒有指定默認值,也沒有指定ON UPDATE語句。那麼該列會自動被加上DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP屬性。秒殺
3)第一個TIMESTAMP列以後的其餘的TIMESTAMP類型的列,若是沒有指定null屬性,也沒有指定默認值,那麼該列會被自動加上DEFAULT ‘0000-00-00 00:00:00’屬性。若是insert語句中沒有爲該列指定值,那麼該列中插入’0000-00-00 00:00:00’,而且沒有warning。
解決辦法:
mysql>set @@explicit_defaults_for_timestamp = 1;
1)此時若是TIMESTAMP列沒有顯示的指定not null屬性,那麼默認的該列能夠爲null,此時向該列中插入null值時,會直接記錄null,而不是current timestamp。
2)不會自動的爲表中的第一個TIMESTAMP列加上DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP屬性,除非你在建表的時候顯示的指明。
3)若是TIMESTAMP列被加上了not null屬性,而且沒有指定默認值。這時若是向表中插入記錄,可是沒有給該TIMESTAMP列指定值的時候,若是strict sql_mode被指定了,那麼會直接報錯。若是strict sql_mode沒有被指定,那麼會向該列中插入’0000-00-00 00:00:00’而且產生一個warning。
NO_ZERO_DATE:
在這個模式下,不容許時間值爲'0000-00-00 00:00:00'格式;
解決辦法:
mysql>set @@sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
去掉NO_ZERO_IN_DATE,NO_ZERO_DATE
重啓服務器,正常執行建立語句.