為什麼只有在創建語句中存在兩個或多個時間戳欄位時,mysql才會拋出“欄位的預設值無效”?
在 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
作為預設值(如果未明確聲明)添加到第一個時間戳列之後。Mysql
8.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,不要依賴預設值。始終編寫該欄位的完整規範。