解決:timestamp 預設值 ‘0000-00-00 00:00:00’ 報錯
技術標籤:MySql資料庫mysql資料庫timestampsql_mode
一、問題描述
在 mysql5.7 版本建立如下表結構時出現,timestamp 欄位預設值錯誤:如下所示:
CREATE TABLE `login_log` ( `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT , `uuid` VARCHAR(34) UNIQUE NOT NULL COMMENT '登入編號', `number` VARCHAR(20) NOT NULL COMMENT '登入賬號', `name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '登入姓名', `login_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '登入時間', `logout_time` TIMESTAMP COMMENT '退出時間', `login_ip` VARCHAR(15) COMMENT '登入IP', `device` VARCHAR(15) COMMENT '裝置型別', `status` INT(3) COMMENT '登入狀態', `message` VARCHAR(30) COMMENT '登入結果描述', PRIMARY KEY (`id`) )ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci COMMENT='登入日誌'; [Err] 1067 - Invalid default value for 'logout_time'
錯誤資訊為:
[Err] 1067 - Invalid default value for 'logout_time'
二、問題源頭sql_mode
引起這個問題的原因是在沒有指定 timestamp 預設值時,系統是按‘0000-00-00 00:00:00’ 處理的,但是在 sql_mode 中 模式是不允許設定 此預設值的。我們看下:sql_mode 的具體資訊,可以使用如下命令檢視 當前會話或者全域性的 sql_mode,如下所示:
SELECT @@GLOBAL.sql_mode; -- 檢視全域性模式
SELECT @@SESSION.sql_mode; -- 檢視當前會話的模式
檢視全域性的輸出結果如下:
通過上圖中的結果我們可以看到sql_mode中有 NO_ZERO_IN_DATE和 NO_ZERO_DATE在命令列中輸入
三、解決方法
1、可以通過命令直接設定,如下所示:
SET GLOBAL sql_mode = 'modes'; // 設定全域性
SET SESSION sql_mode = 'modes'; // 設定當前會話
說明:
1、其中 modes 為: 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'。也就是把NO_ZERO_IN_DATE 和 NO_ZERO_DATE
去掉即可。2、如果使用全域性的設定完成後需要重新連線資料庫。
2、修改配置檔案
通過上述命令的方式設定完成後,如果重啟資料庫,設定的就會失效了。可以通過修改配置檔案的方式更改,這樣更改完,即使資料庫重啟也不會失效。設定方式如下:
找到 MySQL 資料庫的配置檔案,在配置檔案中加入如下,然後重啟資料庫即可。
sql_mode = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
四、幾種常見 mode 說明
ONLY_FULL_GROUP_BY:出現在select語句、HAVING條件和ORDER BY語句中的列,必須是GROUP BY的列或者依賴於GROUP BY列的函式列。
NO_AUTO_VALUE_ON_ZERO:該值影響自增長列的插入。預設設定下,插入0或NULL代表生成下一個自增長值。如果使用者希望插入的值為0,而該列又是自增長的,那麼這個選項就有用了。
STRICT_TRANS_TABLES:在該模式下,如果一個值不能插入到一個事務表中,則中斷當前的操作,對非事務表不做限制
NO_ZERO_IN_DATE:這個模式影響了是否允許日期中的月份和日包含0。如果開啟此模式,2016-01-00是不允許的,但是0000-02-01是允許的。它實際的行為受到 strict mode是否開啟的影響1。
NO_ZERO_DATE:設定該值,mysql資料庫不允許插入零日期。它實際的行為受到 strictmode是否開啟的影響2。
ERROR_FOR_DIVISION_BY_ZERO:在INSERT或UPDATE過程中,如果資料被零除,則產生錯誤而非警告。如果未給出該模式,那麼資料被零除時MySQL返回NULL
NO_AUTO_CREATE_USER:禁止GRANT建立密碼為空的使用者
NO_ENGINE_SUBSTITUTION:如果需要的儲存引擎被禁用或未編譯,那麼丟擲錯誤。不設定此值時,用預設的儲存引擎替代,並丟擲一個異常
PIPES_AS_CONCAT:將”||”視為字串的連線操作符而非或運算子,這和Oracle資料庫是一樣的,也和字串的拼接函式Concat相類似
ANSI_QUOTES:啟用ANSI_QUOTES後,不能用雙引號來引用字串,因為它被解釋為識別符。
參考: