DataRowの値にNullを設定するとエラーになる場合とならない場合があります。その法則と対処方法です。
エラーの発生例と、対処方法
DataRowでは、nullの代わりにDBNull.Valueを使用します。そのため、nullを代入するとエラーが発生します。 nullをDBNull.Valueに置き換えるとエラーは発生しなくなります。-
エラーの発生するコード
System.ArgumentException 列 'XXXXXXXX' を Null に設定できません。DBNull を使用してください。DataRow row = dataTable.NewRow(); row["col"] = null; // 例外発生
-
対処方法
nullではなく、DBNull.Valueを代入します。DataRow row = dataTable.NewRow(); row["col"] = DBNull.Value;
Nullをセットしてもエラーが発生しない場合がある
様々なデータ型の列を定義し、Nullをセットしてみます。// 様々なデータ型で、データテーブルに列を追加
DataTable dataTable = new DataTable();
dataTable.Columns.Add("col_Boolean", typeof(System.Boolean));
dataTable.Columns.Add("col_Byte", typeof(System.Byte));
dataTable.Columns.Add("col_Byte[]", typeof(System.Byte[]));
dataTable.Columns.Add("col_Char", typeof(System.Char));
dataTable.Columns.Add("col_DateTime", typeof(System.DateTime));
dataTable.Columns.Add("col_Decimal", typeof(System.Decimal));
dataTable.Columns.Add("col_Double", typeof(System.Double));
dataTable.Columns.Add("col_Guid", typeof(System.Guid));
dataTable.Columns.Add("col_Int16", typeof(System.Int16));
dataTable.Columns.Add("col_Int32", typeof(System.Int32));
dataTable.Columns.Add("col_Int64", typeof(System.Int64));
dataTable.Columns.Add("col_SByte", typeof(System.SByte));
dataTable.Columns.Add("col_Single", typeof(System.Single));
dataTable.Columns.Add("col_String", typeof(System.String));
dataTable.Columns.Add("col_TimeSpan", typeof(System.TimeSpan));
dataTable.Columns.Add("col_UInt16", typeof(System.UInt16));
dataTable.Columns.Add("col_UInt32", typeof(System.UInt32));
dataTable.Columns.Add("col_UInt64", typeof(System.UInt64));
// -------------------------------------------------------
// NULLを設定して例外が発生するか調べる
// -------------------------------------------------------
DataRow row = dataTable.NewRow();
//row["col_Boolean"] = null; // 例外発生
//row["col_Byte"] = null; // 例外発生
row["col_Byte[]"] = null;
//row["col_Char"] = null; // 例外発生
//row["col_DateTime"] = null; // 例外発生
//row["col_Decimal"] = null; // 例外発生
//row["col_Double"] = null; // 例外発生
//row["col_Guid"] = null; // 例外発生
//row["col_Int16"] = null; // 例外発生
//row["col_Int32"] = null; // 例外発生
//row["col_Int64"] = null; // 例外発生
//row["col_SByte"] = null; // 例外発生
//row["col_Single"] = null; // 例外発生
row["col_String"] = null;
//row["col_TimeSpan"] = null; // 例外発生
//row["col_UInt16"] = null; // 例外発生
//row["col_UInt32"] = null; // 例外発生
//row["col_UInt64"] = null; // 例外発生
Byte配列とString以外は例外が発生しました。 このことから、参照型の列はNullを設定しても例外が発生しないことがわかります。 (String型は値型のように錯覚しますが、参照型です)
参照型ではNullとDBNull.Valueのどちらを使うべきか?
DBNull.Valueを使うべきです。nullをセットしても、取り出すとDBNull.Valueになるためです。 次のサンプルを実行すると2つ目のメッセージは表示されません。row["col_String"] = null;
if (row["col_String"] == DBNull.Value)
{
// 表示される
MessageBox.Show("DBNull.Valueです。");
}
if (row["col_String"] == null)
{
// 表示されない
MessageBox.Show("nullです。");
}
サンプルコードのダウンロード
サンプルコードの実行には Microsoft Visual Studio 2008 以上のバージョンが必要です。 2008以外のバージョンではプロジェクトを開いた際にファイルの変換が必要な場合があります。その場合は変換後に実行してください。検証環境
- Microsoft Visual Studio 2008 Version 9.0.30729.4462 QFE Edition: Professional
- Microsoft .NET Framework Version 3.5 SP1
- Microsoft Windows 7 Professional Service Pack 1 (Microsoft Windows NT 6.1 (7601))