DataRowの値にNothinglを設定するとエラーになる場合とならない場合があります。その法則と対処方法です。
エラーの発生例と、対処方法
DataRowでは、Nothingの代わりにDBNull.Valueを使用します。そのため、Nothingを代入するとエラーが発生します。 NothingをDBNull.Valueに置き換えるとエラーは発生しなくなります。-
エラーの発生するコード
System.ArgumentException 列 'XXXXXXXX' を null に設定できません。DBNull を使用してください。Dim row As DataRow = dataTable.NewRow() row("col") = Nothing ' 例外発生
-
対処方法
Nothingではなく、DBNull.Valueを代入します。Dim row As DataRow = dataTable.NewRow() row("col") = DBNull.Value
Nothingをセットしてもエラーが発生しない場合がある
様々なデータ型の列を定義し、Nothingをセットしてみます。' 様々なデータ型で、データテーブルに列を追加
Dim dataTable As DataTable = New DataTable()
dataTable.Columns.Add("col_Boolean", GetType(System.Boolean))
dataTable.Columns.Add("col_Byte", GetType(System.Byte))
dataTable.Columns.Add("col_Byte()", GetType(System.Byte()))
dataTable.Columns.Add("col_Char", GetType(System.Char))
dataTable.Columns.Add("col_DateTime", GetType(System.DateTime))
dataTable.Columns.Add("col_Decimal", GetType(System.Decimal))
dataTable.Columns.Add("col_Double", GetType(System.Double))
dataTable.Columns.Add("col_Guid", GetType(System.Guid))
dataTable.Columns.Add("col_Int16", GetType(System.Int16))
dataTable.Columns.Add("col_Int32", GetType(System.Int32))
dataTable.Columns.Add("col_Int64", GetType(System.Int64))
dataTable.Columns.Add("col_SByte", GetType(System.SByte))
dataTable.Columns.Add("col_Single", GetType(System.Single))
dataTable.Columns.Add("col_String", GetType(System.String))
dataTable.Columns.Add("col_TimeSpan", GetType(System.TimeSpan))
dataTable.Columns.Add("col_UInt16", GetType(System.UInt16))
dataTable.Columns.Add("col_UInt32", GetType(System.UInt32))
dataTable.Columns.Add("col_UInt64", GetType(System.UInt64))
' -------------------------------------------------------
' Nothingを設定して例外が発生するか調べる
' -------------------------------------------------------
Dim row As DataRow = dataTable.NewRow()
'row("col_Boolean") = Nothing ' 例外発生
'row("col_Byte") = Nothing ' 例外発生
row("col_Byte()") = Nothing
'row("col_Char") = Nothing ' 例外発生
'row("col_DateTime") = Nothing ' 例外発生
'row("col_Decimal") = Nothing ' 例外発生
'row("col_Double") = Nothing ' 例外発生
'row("col_Guid") = Nothing ' 例外発生
'row("col_Int16") = Nothing ' 例外発生
'row("col_Int32") = Nothing ' 例外発生
'row("col_Int64") = Nothing ' 例外発生
'row("col_SByte") = Nothing ' 例外発生
'row("col_Single") = Nothing ' 例外発生
row("col_String") = Nothing
'row("col_TimeSpan") = Nothing ' 例外発生
'row("col_UInt16") = Nothing ' 例外発生
'row("col_UInt32") = Nothing ' 例外発生
'row("col_UInt64") = Nothing ' 例外発生
Byte配列とString以外は例外が発生しました。 このことから、参照型の列はNothingを設定しても例外が発生しないことがわかります。 (String型は値型のように錯覚しますが、参照型です)
参照型ではNothingとDBNull.Valueのどちらを使うべきか?
DBNull.Valueを使うべきです。Nothingをセットしても、取り出すとDBNull.Valueになるためです。 次のサンプルを実行すると2つ目のメッセージは表示されません。row("col_String") = Nothing
If row("col_String") Is DBNull.Value Then
' 表示される
MessageBox.Show("DBNull.Valueです。")
End If
If row("col_String") Is Nothing Then
' 表示されない
MessageBox.Show("Nothingです。")
End If
サンプルコードのダウンロード
サンプルコードの実行には 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))