【问题标题】:How to check if DataReader value is not null?如何检查 DataReader 值是否不为空?
【发布时间】:2015-01-04 12:39:59
【问题描述】:

我正在编写一个通过 SQL 查询读取 Oracle 表的 VB.Net 代码。

SQL 查询可能会返回一些空列。我正在尝试检查这些列是否为空,但我收到错误 Oracle.DataAccess.dll 中出现“System.InvalidCastException”类型的异常,但未在用户代码中处理。该列包含一些 Null 数据

这是我的代码:

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

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

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

谢谢

【问题讨论】:

    标签: vb.net oracle


    【解决方案1】:

    Nothing 表示对象尚未初始化,DBNull 表示数据未定义/丢失。有几种检查方法:

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

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

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

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

    If myReader.IsDbNull(index) Then 
    

    在此基础上,您可以将函数组合为 Shared 类成员,也可以重新设计为 Extensions 以测试 DBNull 并返回默认值:

    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 转换器,您必须决定要返回什么。我更喜欢单独做这些。

    【讨论】:

      【解决方案2】:

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

      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
      

      【讨论】:

        【解决方案3】:

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

        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))
        

        【讨论】: