データベースから取得したレコードのフィールドのNULLを検出する

C#でデータベースから取得したレコードのフィールドのNULLを検出するコードを紹介します。

事前準備

下記のテーブルを作成します。
id=3のレコードはcategory列の値がNULLになっています。

working テーブル
列名
idint
namenchar(64)
valuedecimal(18,0)
categorynchar(16)
memotext


working テーブル
idnamevaluecategorymemo
1Penguin300B南国にすむペンギンです
2Whale420M北極海のクジラです
3Moffu880NULLよくわからない生き物です
4Camel220M砂漠にすむラクダです
5Owl90B関東のフクロウです
6Duck120Bそこらへんのアヒルです

NULLでエラーになる例

UI

下図のUIを作成します。テキストボックスとボタンを配置します。
データベースから取得したレコードのフィールドのNULLを検出する:画像1

コード

下記のコードを記述します。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace SQLExecDemo
{
  public partial class FormSQLNull : Form
  {
    public FormSQLNull()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      string constr = @"Data Source=192.168.64.98;Initial Catalog=iPentecSandBox;Connect Timeout=60;Persist Security Info=True;User ID=sa;Password=adelieC#8851SQL";

      SqlConnection con = new SqlConnection(constr);
      con.Open();
      try {
        string sqlstr = "select * from working";
        SqlCommand com = new SqlCommand(sqlstr, con);
        SqlDataReader sdr = com.ExecuteReader();

        while (sdr.Read() == true) {
          string name = (string)sdr["name"];
          decimal value = (decimal)sdr["value"];
          string category = (string)sdr["category"];
          string memo = (string)sdr["memo"];
          textBox1.Text += string.Format("{0} / {1:g} / {2} / {3} \r\n", 
            name.Trim(), value, category.Trim(), memo.Trim());
        }
      }
      finally {
        con.Close();
      }

    }
  }
}

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。
データベースから取得したレコードのフィールドのNULLを検出する:画像2

[button1]をクリックすると、InvalidCastException 例外が発生します。データベースのフィールドのNULLをstring型にはキャストできないため、エラーが発生します。
データベースから取得したレコードのフィールドのNULLを検出する:画像3

解説

データベースのNULLフィールドをキャストすると、InvalidCastExceptionの例外が発生します。対処法としてはNULLを判定するか、キャスト部分をtryブロックで囲みcatchで処理する方法があります。tryブロックで囲む場合は、それぞれの代入部をブロックで囲む必要があるため、コードが冗長になります。

対処法

キャストする直前でフィールドがNULLか判定する方法を利用します。

コード

コードを下記に変更します。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace SQLExecDemo
{
  public partial class FormSQLNull : Form
  {
    public FormSQLNull()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      string constr = @"Data Source=192.168.64.98;Initial Catalog=iPentecSandBox;Connect Timeout=60;Persist Security Info=True;User ID=sa;Password=adelieC#8851SQL";

      SqlConnection con = new SqlConnection(constr);
      con.Open();
      try {
        string sqlstr = "select * from working";
        SqlCommand com = new SqlCommand(sqlstr, con);
        SqlDataReader sdr = com.ExecuteReader();

        while (sdr.Read() == true) {
          string name = (string)sdr["name"];
          decimal value = (decimal)sdr["value"];

          string category = "";
          if (sdr["category"] == DBNull.Value) {
            category = "(NULL)";
          }
          else {
            category = (string)sdr["category"];
          }

          string memo = (string)sdr["memo"];
          textBox1.Text += string.Format("{0} / {1:g} / {2} / {3} \r\n", 
            name.Trim(), value, category.Trim(), memo.Trim());
        }
      }
      finally {
        con.Close();
      }

    }
  }
}

解説

NULLの可能性があるフィールドを読み込む部分のコードが下記になります。
SqlDataReaderで列名を添え字にしてアクセスし、フィールドの値を取得しますが、フィールドの値がNULLの場合、値がDBNull.Valueになります。フィールドの値がDBNull.Valueであるか判定し、NULLでない場合のみにキャストする動作にすることで、NULLのキャストによるInvalidCastException例外の発生を防ぐことができます。

  string category = "";
  if (sdr["category"] == DBNull.Value) {
    category = "(NULL)";
  }
  else {
    category = (string)sdr["category"];
  }

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。
データベースから取得したレコードのフィールドのNULLを検出する:画像4

[button1]をクリックします。テーブルのレコード一覧がテキストボックスに表示されます。NULLのキャストで例外は発生せず、NULLのフィールドは"(NULL)"の文字列が表示される動作となっています。
データベースから取得したレコードのフィールドのNULLを検出する:画像5


AuthorPortraitAlt
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
作成日: 2018-05-08
Copyright © 1995–2025 iPentec all rights reserverd.