Mysql

為什麼只有在創建語句中存在兩個或多個時間戳欄位時,mysql才會拋出“欄位的預設值無效”?

  • January 21, 2020

在 mysql 5.7.28 中,我創建了一個像這樣的表:

create table t1 (
id int not null,
d1 timestamp) 
engine=innodb;

可以正常工作並與,d1一樣創建。non-null``default value current_timetamp``on update current_timestamp

但是當我嘗試使用以下兩個時間戳欄位創建同一個表時:

create table t1 (
id int not null,
d1 timestamp,
d2 timestamp) 
engine=innodb;

我收到一個錯誤:

SQL 錯誤 (1067): ‘d2’ 的預設值無效

為什麼只有在添加第二個時間戳欄位時才會出現錯誤?

這是 mysql 中的錯誤還是某些預期行為?

此行為在explicit_defaults_for_timestamp系統變數中進行了描述,預設情況下禁用 , (****並有效禁用)並在.5.6``5.7``5.1``8.0

從上面的連結引用:

(5.7) 如果 explicit_defaults_for_timestamp被禁用,則伺服器啟用非標準行為並按如下方式處理 TIMESTAMP 列:

  • 未使用 NULL 屬性顯式聲明的 TIMESTAMP 列會自動使用 NOT NULL 屬性聲明。允許為這樣的列分配 NULL 值並將該列設置為目前時間戳。
  • 如果未使用 NULL 屬性或顯式 DEFAULT 或 ON UPDATE 屬性顯式聲明表中的第一個 TIMESTAMP 列

,則會自動使用 DEFAULT

CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP 屬性聲明。

  • 第一個之後的 TIMESTAMP 列,如果沒有使用 NULL 屬性或顯式 DEFAULT 屬性顯式聲明,將自動聲明為 DEFAULT ‘0000-00-00 00:00:00’(“零”時間戳)。對於未為此類列指定顯式值的插入行,將為該列分配“0000-00-00 00:00:00”並且不會出現警告。

根據是否啟用嚴格 SQL 模式或 NO_ZERO_DATE SQL 模式,預設值 ‘0000-00-00 00:00:00’ 可能無效

現在的問題是啟用了5.7該模式。NO_ZERO_DATE不允許將文件中描述的預設值0000-00-00 00:00:00作為預設值(如果未明確聲明)添加到第一個時間戳列之後

Mysql8.0仍然NO_ZERO_DATE啟用了該模式,但explicit_defaults_for_timestamp預設情況下啟用了 envvar,根據文件,它將添加 null 作為預設值,如下所示(這不會導致表創建時出現任何錯誤):

(8.0) 如果啟用了 explicit_defaults_for_timestamp ,伺服器將禁用非標準行為並按如下方式處理 TIMESTAMP 列:

$$ .. $$

  • 未使用 NOT NULL 屬性顯式聲明的 TIMESTAMP 列會自動使用 NULL 屬性聲明並允許 NULL 值。為這樣的列分配 NULL 值會將其設置為 NULL,而不是目前時間戳。

$$ .. $$

  • 表中第一個 TIMESTAMP 列的處理方式與第一個之後的 TIMESTAMP 列的處理方式不同。

這種行為也在MySQL 的問題跟踪器上進行了討論,但已標記為“不是錯誤”。

正如評論中提到的@Akina,不要依賴預設值。始終編寫該欄位的完整規範。

引用自:https://dba.stackexchange.com/questions/257863