一、問題描述
線上插入SQL的時候遇到一個報錯:
mysql> insert into tete values(11,null);
ERROR 1048 (23000): Column 'createTime' cannot be null
二、問題分析
查看表結構:
mysql> show create table tete\G
*************************** 1. row ***************************
Table: tete
Create Table: CREATE TABLE `tete` (
`id` int NOT NULL,
`createTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
1 row in set (0.00 sec)
查看參數
mysql> show variables like 'explicit_defaults_for_timestamp';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| explicit_defaults_for_timestamp | ON |
+---------------------------------+-------+
1 row in set (0.00 sec)
explicit_defaults_for_timestamp 系統變量決定MySQL服務端對timestamp列中的默認值和NULL值的不同處理方法。
當explicit_defaults_for_timestamp=ON時,如果timestamp列被加上了not null屬性,并且沒有指定默認值。這時如果向表中插入記錄,但是沒有給該TIMESTAMP列指定值的時候,如果strict sql_mode被指定了,那么會直接報錯。
當explicit_defaults_for_timestamp=OFF時,如果timestamp列沒有顯式的指明null屬性,那么該列會被自動加上not null屬性(而其他類型的列如果沒有被顯式的指定not null,那么是允許null值的),如果往這個列中插入null值,會自動的設置該列的值為current timestamp值。
三、問題解決
所以這里為了把文章開始的SQL執行成功,可以把explicit_defaults_for_timestamp設為OFF
mysql> set global explicit_defaults_for_timestamp=off;
Query OK, 0 rows affected, 1 warning (0.00 sec)
接著再執行文章開頭的SQL可以執行成功。
mysql> insert into tete values(11,null);
Query OK, 1 row affected (0.01 sec)
mysql> select * from tete where id =11;
+----+---------------------+
| id | createTime |
+----+---------------------+
| 11 | 2024-06-28 11:21:48 |
+----+---------------------+
1 row in set (0.00 sec)