このすみノート

Webエンジニアが技術や趣味を書くブログです。

SQLのNULL値を比較してしまい、想定した値が更新されず失敗してしまった

  • プロジェクトで最近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カラムは偉大であると改めて感じました。