首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 5.0 自增主鍵失效排查:sql_mode STRICT_TRANS_TABLES 導致隱式默認值報錯

     編輯:MySQL 資料庫相關知識

MySQL 5.0.2+ 默認開啟 STRICT_TRANS_TABLES sql_mode,導致自增主鍵列顯式插入 NULL/0/DEFAULT 時不再自動生成值,改為報錯 Incorrect integer value 或 Field 'id' doesn't have a default value。本文給出定位與修正方案。

一、現象

CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(10));
INSERT INTO t (name) VALUES ('test');  -- 正常

-- 但某些框架/代碼生成如下語句:
INSERT INTO t (id, name) VALUES (NULL, 'test');  -- 報錯
INSERT INTO t (id, name) VALUES (0, 'test');     -- 報錯
INSERT INTO t (id, name) VALUES (DEFAULT, 'test'); -- 報錯

二、根因

my.ini 默認配置:

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

STRICT_TRANS_TABLES:嚴格模式下,整數列不接受 NULL/0/DEFAULT 作為隱式自增值,**必須省略該列**或顯式指定合法整數。

三、解決方案

方案一:移除 STRICT_TRANS_TABLES(推薦,兼容舊代碼)

[mysqld]
# sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
# 重啟 mysqld 生效

方案二:代碼層面修正(規範、長久)

  • INSERT 語句**省略自增列**:INSERT INTO t (name) VALUES ('test');
  • 或顯式指定 NULL **僅在非嚴格模式下生效**
  • 框架層面:Hibernate @GeneratedValue、MyBatis useGeneratedKeys、JPA GenerationType.IDENTITY 均會自動省略列

四、sql_mode 關鍵值速查

模式作用建議
STRICT_TRANS_TABLES事務表嚴格模式:非法值報錯而非警告+截斷生產建議開啟,配合代碼規範
STRICT_ALL_TABLES所有表嚴格模式同左
NO_AUTO_CREATE_USER禁止 GRANT 隱式創建用戶保留(安全)
NO_ENGINE_SUBSTITUTION指定引擎不可用時不自動替換、報錯保留(防患)
ONLY_FULL_GROUP_BYSELECT 非聚合列必須出現在 GROUP BY8.0 默認開啟,建議保留
NO_ZERO_DATE/NO_ZERO_IN_DATE禁止 '0000-00-00' 日期保留(數據質量)

五、驗證修正

mysql> SELECT @@sql_mode;
-- 應不含 STRICT_TRANS_TABLES

INSERT INTO t (id, name) VALUES (NULL, 'test');  -- 應成功,id 自增
INSERT INTO t (id, name) VALUES (0, 'test');     -- 應成功(0 視同 NULL)
INSERT INTO t (id, name) VALUES (DEFAULT, 'test'); -- 應成功

「嚴格模式 + 代碼規範」是正道;若歷史代碼量大難以改造,移除 STRICT_TRANS_TABLES 可作過渡,但需承擔數據質量下降風險(如空字符串入數值列變 0、截斷不報錯)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved