mysql創建表時,設置timestamp DEFAULT NULL報錯1067 - Invalid default value for 'updated_at'


問題背景:

線上的linux服務器上的mysql服務器中導出數據庫的結構。想要在本地創建一個測試版本

導出后再本地mysql上運行卻報錯   1067 - Invalid default value for 

 

mysql數據庫中需要使用timestamp列來存儲數據的創建時間和更新時間

例如,創建后台管理菜單表,只看created_at和updated_at兩個字段

DROP TABLE IF EXISTS `admin_menu`;
CREATE TABLE `admin_menu`  (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) NOT NULL DEFAULT 0,
  `order` int(11) NOT NULL DEFAULT 0,
  `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `icon` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `uri` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `permission` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` timestamp(0) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Compact;

執行后發現報錯

1067 - Invalid default value for 'updated_at'。updated_at字段的默認值無效。而created_ad字段類型是datetime日期時間類型默認值為NULL沒有發生報錯

 一開始以為是sql_mode模式問題,然而在sql_mode模式為嚴格或者寬松模式情況下,都會報錯。
本地和線上服務器相同的模式也不行
sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

 

接着,查看線上服務器版本和本地版本對比,
使用select VERSION()
線上mysql版本:5.7.22-log
本地mysql版本:5.7.23-log
版本相差不大,排除版本問題。那只能找資料了。
 
解決方法:
方法1
既然timestamp會報錯,就直接用datetime來保存時間就可以解決的。
將updated_at類型timestamp改為datetime,這個創建表的過程能夠正常運行
 
方法2
既然不能為NULL,那我改為一個固定值不就可以了嗎
`updated_at` timestamp(0) DEFAULT '1970-01-01 08:00:00',
將時間設置為unix時間戳為0對應的日期(默認是1970-01-01 00:00:00,中國時間要加8)。

 

方法3

網上查找,在mysql配置文件中增加配置參數

[mysqld]節點下添加

explicit_defaults_for_timestamp = ON

重啟mysql數據庫試配置生效。

之后就可以正常執行上面的數據的

 

下面是方法三的具體解釋,僅作記錄,可以不需要知道

網上搜索資料,
 
mysql5.6.6之前,timestamp時間類型有一個默認行為:
TIMESTAMP列如果沒有明確聲明NULL屬性,默認為NOT NULL。(而其他數據類型,如果沒有顯示聲明為NOT NULL,則允許NULL值。)
insert插入一條數據,TIMESTAMP的列值為NULL,會自動存儲時候,會將當前timestamp存儲到這個timestamp列中。
也就是說會自動分配 DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP 屬性。
每次更新記錄都會將timestamp列更新為當前的時間戳對應的時間值
 
 
現在mysql5.6版本以后,timestamp字段的默認行為發生的變化,多了一些限制。
如果timestamp列設置默認值為NULL,
Default NULL 這會發生報錯 1067 - Invalid default value for
 
如果需要讓timestamp列在創建表時可以為NULL值,需要將explicit_defaults_for_timestamp設為ON
explicit_defaults_for_timestamp默認為OFF關閉狀態,打開后可以阻止timestamp的默認行為。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM