MySQLのERROR 1366「Incorrect integer value」を修正する:空文字列によるエラーへの対処

中級🗄️ MySQL2026-05-01| MySQL 5.7+, MySQL 8.0+, MariaDB 10.2+(Linux (Ubuntu/CentOS), Windows (XAMPP/WAMP), または Docker コンテナ環境)

Error Message

ERROR 1366 (HY000): Incorrect integer value: '' for column 'id' at row 1
#mysql#厳密モード#整数型#データ型#sql-mode

移行時に発生する悩みこれは典型的なシナリオです。レガシーなアプリケーションが古いサーバーでは完璧に動作していたのに、最新の MySQL 8.0 インスタンスに移行した途端、突然クラッシュするというものです。このエラーは通常、PHP 5.6 や Python 2.7 のコードベースをモダンなスタックに移行する際に発生します。コードは何年も問題なく動作していましたが、INSERTUPDATE クエリが以下のメッセージとともに壁に突き当たることになります。

ERROR 1366 (HY000): Incorrect integer value: '' for column 'id' at row 1

問題の原因は単純です。アプリケーションが空文字列('')を INT または BIGINT カラムに保存しようとしているためです。古いバージョンの MySQL は寛容で、空文字列を受け取るとそれを黙って 0 に変換してくれていました。しかし、モダンなバージョンでは推測を拒否します。

原因:厳密モード(Strict Mode)この挙動は STRICT_TRANS_TABLES という設定に起因しています。MySQL 5.7.5 以降、厳密モードはデフォルトで有効になっています。これが有効な場合、データベースはデータ損失につながる可能性のある「暗黙的なデータ変換」を停止します。空文字列は有効な数値ではないため、MySQL は警告ではなくハードエラーをスローします。

MySQL ターミナルで以下のクエリを実行して、現在の設定を確認してください。

SELECT @@sql_mode;

結果に STRICT_TRANS_TABLESSTRICT_ALL_TABLES が含まれている場合、データベースは厳格な型安全性を強制しています。

解決策1:アプリケーションロジックを修正する(正しい方法)これは最も堅牢で、長期的な解決策です。数値フィールドがオプションである場合、コードは空文字列ではなく NULL または実際の 0 を送信するようにすべきです。

PHPでの例検証されていない生の入力を直接 SQL 文字列に渡すのは避けましょう。POST 値が空の場合は、明示的に NULL を設定します。

// 空文字列を送信する代わりに...
$age = ($_POST['age'] === '') ? "NULL" : (int)$_POST['age'];
$sql = "INSERT INTO users (age) VALUES ($age)";

標準的なSQLでのアプローチ手動クエリをリファクタリングして、以下のパターンに従うようにします。

-- これは厳密モードで失敗します
INSERT INTO products (stock) VALUES ('');

-- これらは成功します
INSERT INTO products (stock) VALUES (NULL);
INSERT INTO products (stock) VALUES (0);

解決策2:クイックフィックス:セッションレベルでの変更急ぎでアプリをすぐに動かす必要がある場合は、現在のデータベース接続に対してのみルールを緩和することができます。これは、恒久的なコード修正を行うまでの間、レガシーなスクリプトに対する一時的な応急処置として機能します。

アプリケーションがデータベース接続を確立した直後に、以下のクエリを実行してください。

SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION';

厳密モードのフラグを取り除くことで、MySQL はレガシーな挙動に戻り、バックグラウンドで軽微な警告を出しつつ空文字列を 0 に変換するようになります。

解決策3:サーバー全体での恒久的な調整インフラを自身で管理しており、簡単にパッチを当てられない古い CMS や ERP システムをサポートする必要がある場合は、グローバルで厳密モードを無効にできます。

Linux (Ubuntu/Debian) の場合- 設定ファイルを開きます: sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf- [mysqld] ブロックを探します。- sql_mode の定義を追加または更新します:```

[mysqld] sql_mode = "NO_ENGINE_SUBSTITUTION" ```- サービスを再起動して変更を適用します: sudo systemctl restart mysql### Windows (XAMPP) の場合- XAMPP コントロールパネルを開き、MySQL の横にある Config をクリックします。- リストから my.ini を選択します。- sql-mode の行を探し、sql-mode="NO_ENGINE_SUBSTITUTION" に変更します。- MySQL モジュールを再起動します。## 確認変更後は必ず確認してください。まずグローバル変数を確認します:

SELECT @@GLOBAL.sql_mode;

STRICT_TRANS_TABLES が消えていることを確認します。最後に、手動テストを実行してエラーが解決されたことを確認してください:

INSERT INTO your_table (your_int_column) VALUES ('');

「1 row affected」と表示され、その後に警告が続く場合は、修正が成功しています。 SHOW WARNINGS; を実行すると、MySQL がどのように変換を処理したかを正確に確認できます。

予防のヒント- スキーマ戦略: 厳密に必須でない場合は、整数カラムを DEFAULT NULL に設定します。- 厳密な型指定: 数値入力がクエリビルダーに到達する前に、すべてキャスト(例:PHP の intval($value))します。- ORMの活用: Eloquent や SQLAlchemy などのツールは、「空の入力」と「データベースの NULL」のギャップを自動的に処理します。- 環境の同期: デプロイ時に不意を突かれないよう、ローカルの開発用データベースのバージョンを本番サーバーと一致させておきましょう。

Related Error Notes