- プロジェクトで最近SQLをいろいろ触る機会がありまして、その時にフラグを更新するSQLに遭遇しました。
- イメージとしてはこんな感じ。
UPDATE flag = 1, updated_at = NOW() WHERE id = 2;
- なお、このflagの型はSMALLINTでした。
- そして、これだと元のフラグの有無に関わらず毎回updated_atが更新されてしまうので、以下に変更しました。
UPDATE flag = 1, updated_at = NOW() WHERE id = 2 AND flag != 1;
- 一見flagが1以外だったら1に更新するので、良さそうに見えます。
- しかし、これが失敗でした。
NULLとなりえるカラムにおける比較
- 失敗の理由は、flagカラムがNOT NULLではなく、NULL値が存在したことです。
- NULL値は!=で比較するとNULLを返すという事実を、すっかり忘れておりました。
- つまり、NULLABLEな値は、IS NULLやIS NOT NULLで追加チェックする必要があります。
zenn.dev
あとがき
- 日常的にPHPとかのプログラミングをしていると、
1 != NULL
はFALSEである感覚に陥りやすいです。
- SQLにおけるNULLは特別である事実を、常に忘れないようにしなければと反省した次第です。
- 余談ですが、SQLのNULLは扱いが面倒なので、NOT NULLカラムは偉大であると改めて感じました。