1. 程式人生 > 其它 >解決:timestamp 預設值 ‘0000-00-00 00:00:00’ 報錯

解決: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_DATENO_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後,不能用雙引號來引用字串,因為它被解釋為識別符。

參考:

https://blog.csdn.net/han_cui/article/details/82497329

https://www.cnblogs.com/wang666/p/9186559.html