でデータベースのデータを使う - DBのNULLの判定について


データベースのNULLの判定にいきなりハマった

C#の記事

C#の慣習で、取得失敗といえば「null」だろうという感覚でソースコードを組んでいた私。。。( ´ •̥ ̫ •̥ ` )実はデータベースに関してはハマったことがあります。

それはC#のデータベースのNULLの扱いは、データベース(SQL)の世界ではNULLは不定値であり、C言語やJavaでいう「完全なゼロ」を意味するnullとは別物である現実を知らずに、DBのNULLを「<変数> == null」で判定してしまったということです。

DBの世界ではNULLは無効な不定値を意味するので、今になって、さすがに混同なんてできないものだって反省しました…

環境

  • OS:Windows 10 Pro
  • 開発環境:Visual Studio 2019
  • データベース:MySQL 5.7

もともとのソースコードの状態

今回は、MySQLをC#に導入したとき
のプログラムを組んでみたのですが、実際のデータは以下のようになっています。

id name memo
1 テスト用 Only for testing.
2 π 3.14159265358797323...
4 3.14 NULL
6 超難しい Difficult Testing
7 難しい テスト
8 √5 2.2360679...

実際には、memoの一部にはNULLが含まれているため、以下のコードでは、実行すると空白で表示されてしまったんです

listBox1.Items.Add(row[1]);
listBox2.Items.Add(row[2]);

「== null」ではNULLの判定ができなかった

そこで、取得したmemoはrow[2]に該当するので「row[2] == null」「row[2] != null」で、NULLかどうかの判定をしたのですが…

listBox1.Items.Add(row[1]);
if (row[2] != null) {
    listBox2.Items.Add(row[2]);
}
else {
    listBox2.Items.Add("(未設定)");
}

うまく比較されていませんでした( ´ •̥ ̫ •̥ ` )

正しいDBのNULLの判定

データベースのNULLは不定値である

最近はDBのNULLについて理解を深めていったけど、データベースの世界では、NULLは不定値を意味するのであって、C言語やJavaのように、完全無効なゼロを意味するものではないということで、C言語でDBのNULLについていうと、初期化されていない変数みたいなもので、不安定な値を含んでいるものに近いらしい。

そうなれば、DBのNULLを「==」「!=」演算子で比較しようとしても、当然うまくいかないのかもね。。。

正しい比較のしかた

っということで、正しい比較としては、DBNull.Valueというものが用意されているので、その値に等しければ、取得したデータはNULLだということが判別できる

listBox1.Items.Add(row[1]);
if (!row[2].Equals(DBNull.Value)) {
    listBox2.Items.Add(row[2]);
}
else {
    listBox2.Items.Add("(未設定)");
}

これでNULLの場合の比較ができた(♥´꒳`*)

参考文献

 1. [C#]DataRowの値がNullかチェックする方法
 2. DBNull.Value フィールド - Microsoft .NET 公式