如何检查 DataReader 值是否不为空?

How to check if DataReader value is not null?

我正在编写 VB.Net 代码,通过 SQL 查询读取 Oracle Table。

SQL 查询可能 return 一些空列。我正在尝试检查这些列是否为空,但我收到错误 Oracle.DataAccess.dll 中发生了 'System.InvalidCastException' 类型的异常,但未在用户代码中处理。该列包含一些空数据

这是我的代码:

Dim Reader as OracleDataReader 
'Execute the query here...

Reader.Read()
If IsNothing(Reader.GetDateTime(0)) Then  'Error here !!
    'Do some staff 
end if

有人知道如何检查列是否为空吗?

谢谢

在将值转换为日期之前您需要检查该字段是否为空

If (Reader.IsDBNull(0)) Then
    'Null: Do not call GetDateTime
End If

If (Not Reader.IsDBNull(0)) Then
    'Not null: Retrieve the datetime.
    Dim dt As DateTime = Reader.GetDateTime(0)
End If

Nothing表示对象还没有初始化,DBNull表示数据没有defined/missing。有几种检查方式:

' The VB Function
If IsDBNull(Reader.Item(0)) Then...

GetDateTime 方法有问题,因为您要求它将非值转换为 DateTime。 Item() returns 可以在 转换之前 轻松测试的对象。

 ' System Type
 If System.DBNull.Value.Equals(...)

您也可以使用 DbReader。这仅适用于序号索引,不适用于列名:

If myReader.IsDbNull(index) Then 

基于此,您可以将函数放在一起作为共享 class 成员或重新编写为扩展以测试 DBNull 和 return 默认值:

Public Class SafeConvert
    Public Shared Function ToInt32(Value As Object) As Integer
        If DBNull.Value.Equals(Value) Then
            Return 0
        Else
            Return Convert.ToInt32(Value)
        End If
    End Function

    Public Shared Function ToInt64(Value As Object) As Int64
        If DBNull.Value.Equals(Value) Then
            Return 0
        Else
            Return Convert.ToInt64(Value)
        End If
    End Function

    ' etc
End Class

用法:

myDate = SafeConvert.ToDateTime(Reader.Item(0))

对于 DateTime 转换器,您必须决定要 return 的内容。我更喜欢单独做这些。

使用带扩展的通用函数,会更容易。

Imports System.Runtime.CompilerServices

<Extension()>
Public Module DataReaderExtensions
  Public Function GetValue(Of T)(ByVal drVar As Object) As T
    If drVar.Equals(DBNull.Value) Then
        ' Value is null, determine the return type for a default
        If GetType(T).Equals(GetType(String)) Then
            Return CType(CType("", Object), T)
        Else
            ' If it's anything else just return nothing
            Return CType(Nothing, T)
        End If
    Else
        ' Cast the value into the correct return type
        Return CType(drVar, T)
    End If
  End Function
End Module

你可以这样称呼它

dr.Item("abc").GetValue(string)
dr.Item("def").GetValue(Nullable(of Date))