問題
對定義了ctime爲not null的表,insert ctime null
在開發環境可以通過,但是部署上線出問題了,提示
ERROR 1048 (23000): Column ‘ctime’ cannot be null
分析
Dev env: Mysql 5.6.30
Online env: Mysql 5.7.10
- 對比表結構
- 對比執行sql
- 考慮可配置參數
解決方案
表結構一樣
查看關於insert syntax的文檔
http://dev.mysql.com/doc/refman/5.7/en/insert.html
(doc version 5.7)
定義 not null 的字段,insert null 分兩種情況:- 單行會報錯,1048錯誤;
- 多行會忽略,如果是時間字段,會插入 ‘0000-00-00 00:00:00’
按照https://mariadb.com/kb/en/mariadb/null-values/的解釋
對於 AUTO_INCREMENT, TIMESTAMP and virtual columns類型字段,insert null會特殊處理,其他的情況符合2的說明。可以影響提示的參數是sql_mod
http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html
可以查看SQL Mode Changes in MySQL 5.7部分,但也沒有明確說明。開發環境是Mysql 5.6.30; 線上環境是Mysql 5.7.11
考慮到版本問題對Mysql 5.6.27 / Mysql 5.7.10 / Mysql 5.6.24 進行測試,與線上環境的情況一致。
結論
綜上,結合4,5可以判斷爲,在定義了not null的字段,只有5.6.30 insert null會通過,屬於特別情況。 屬於版本問題,建議你如果需要insert null,就不要定義爲not null!
測試腳本
DROP TABLE IF EXISTS test;
CREATE TABLE `test` (
`id` BIGINT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`number` VARCHAR(20) NOT NULL,
`status` TINYINT(1) NOT NULL DEFAULT '1',
`ctime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`utime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_number_UNIQUE` (`number`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='test';
SELECT * FROM test;
INSERT INTO test(`status`) VALUE(1);
SELECT * FROM test;
INSERT INTO test(number,`status`,ctime) VALUE(2,2,NULL);
SELECT * FROM test;
Wait for your reward