錯誤 Incorrect integer value: '' for column 'id' at row 1 通常發生在 **嚴格模式(STRICT_TRANS_TABLES)** 下,向整數欄位插入空字串 '' 或非數值字串。本文解析根因,提供三種解決方案並對比優劣。
CREATE TABLE t (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20));
INSERT INTO t (id, name) VALUES ('', 'test'); -- 錯誤:id 為空字串
-- 或 PHP 代碼未過濾 $_POST['id'] 直接入庫
STRICT_TRANS_TABLES。
-- 確保自增主鍵不手動賦值
CREATE TABLE t (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL
);
-- 插入時**完全不傳 id** 或傳 NULL
INSERT INTO t (name) VALUES ('test');
INSERT INTO t (id, name) VALUES (NULL, 'test'); -- 等效
-- 查看當前模式
SHOW VARIABLES LIKE 'sql_mode';
-- my.cnf 修改(永久生效,需重啟)
[mysqld]
sql_mode = "NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
# 移除 STRICT_TRANS_TABLES, STRICT_ALL_TABLES
-- 會話級臨時生效(不需重啟)
SET SESSION sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
SET GLOBAL sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'; -- 需 SUPER 權限
| 模式 | 含義 | 建議 |
|---|---|---|
STRICT_TRANS_TABLES | 事務表嚴格模式,數據截斷/類型錯誤報錯 | **保留**(生產環境數據完整性保障) |
NO_AUTO_CREATE_USER | 禁止 GRANT 自動建用戶 | 保留 |
NO_ENGINE_SUBSTITUTION | 指定引擎不可用時不自動替換 | 保留 |
ONLY_FULL_GROUP_BY | GROUP BY 必須包含所有非聚合欄位 | 建議保留(SQL 標準相容) |
強烈不建議關閉 STRICT_TRANS_TABLES:會掩蓋應用層 Bug,導致髒數據寫入(如 id=0、空字串變 0),後續排查極難。
prepare("INSERT INTO t (name) VALUES (?)");
$stmt->execute([$_POST['name']]); // id 自動由資料庫生成
// 若必須傳 id(如業務主鍵),嚴格驗證
$id = filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1]
]);
if ($id === false) {
throw new InvalidArgumentException('Invalid id');
}
$stmt = $pdo->prepare("INSERT INTO t (id, name) VALUES (?, ?)");
$stmt->execute([$id, $name]);
?>
STRICT_TRANS_TABLES,配合參數綁定、輸入驗證。