PHPのenum型ではまった件 Warning: 1265 Data truncated for column
いまさらながらPHPのenum型を使っていてはまった話
PHPのバージョン8から利用できるようになったenumですが、使い方が悪いとエラーに陥るケースがあったのでまとめておきます。
発生事象:Warning: 1265 Data truncated for column
テーブルにデータをinsertしようとしたところタイトルのエラーが発生しました。
こちらはenumで定義された値の中に入力しようとした値が存在しないときに発生するエラーです。
ただenumの定義は問題なさそう。
SQLも特に間違ってはなさそう。
insert into `users` (`name`,`user_level`) values ('テストさん', 10)
何が起きたのだろう、、
原因
enumで設定した列挙メンバーに対し、SQLで指定したのが「数値インデックス」になっていることが原因です。
要はこういうこと。
数値インデックス | 列挙メンバー |
---|---|
1 | '1' |
2 | '10' |
3 | '20' |
insert文で意図せず数値インデックスの指定となっていたため、「数値インデックス:10」の設定が見つからずエラーになっていました。
詳細な解説
ENUM カラムに数字を格納すると、その数字は指定可能な値のインデックスとして扱われ、格納された値がそのインデックスを持つ列挙メンバーとなります。 (ただし、これはすべての入力を文字列として扱う LOAD DATA では機能 しません。) 数値が引用符で囲まれている場合、列挙値のリストに一致する文字列がなければ、そのままインデックスとして解釈されます。
これらの理由により、ENUM カラムを数字のように見える列挙値で定義することは、混乱を招きやすくなるのでお勧めできません。
MySQL 8.0 リファレンスマニュアル
最後の一文が超重要
これらの理由により、ENUM カラムを数字のように見える列挙値で定義することは、混乱を招きやすくなるのでお勧めできません。
大事なことなので2回書きました。enum型に数値を列挙するのは止めなさいとのお告げです。
エラー解消した結果
今回の例では下記のようにenumの設定を変更しました。
数値インデックス | 列挙メンバー |
---|---|
1 | 'temp' |
2 | 'general' |
3 | 'special' |
insert into `users` (`name`,`user_level`) values ('テストさん', 'general')
列挙メンバーに数値を使わず文字列指定することで、数値インデックスと混同しないようにしましょう。