【问题标题】:Conversion from type 'DBNull' to type 'Date' is not valid从“DBNull”类型到“Date”类型的转换无效
【发布时间】:2011-10-05 12:29:27
【问题描述】:

我仅在某些月份从以下 VB.NET 代码中收到此异常:

System.InvalidCastException: Conversion from type 'DBNull' to type 'Date' is not valid.

发生就行了:

If CDate(dRow("CompleteDate")).ToString("d") = arrWeekYear(i, 1).ToString("d") Then

如果我理解正确,那么问题是我试图将 CompleteDate 的一些 NULL 值与非 NULL 值进行比较。

我该如何解决这个问题?对于某些日期,上面的代码运行良好。然而,对于一些最近的记录,它没有。但是我能够从具有相同日期范围的 T-SQL 查询中获得输出,并且没有错误;它也运行得很快。我检查了这个 T-SQL 查询的“Date_Completed”和“Review_Date”NULL 值,但无论哪种方式,“CompleteDate”总是 = NON-Null 值。所以我不明白这是怎么回事。

这是我的 VB.NET 查询:

            commandstring = "SELECT Batch_Records.Part_Number, Batch_Records.Lot_Number, Batch_Records.Date_Received, " & _
                "IsNull([Date_Completed], [Review_Date]) AS [CompleteDate], Batch_Records.Error, " & _
                "Batch_Records.[Group], Batch_Records.MFG, Batch_Records.MFG2, Batch_Records.QC, Batch_Records.QC2, " & _
                "QC_CODES.CODE_DESC, DATEADD(DD, 1 - DATEPART(DW, Batch_Records.Date_Received), Batch_Records.Date_Received) AS SundayDate " & _
                "FROM EXCEL.Batch_Records LEFT JOIN EXCEL.QC_CODES ON Batch_Records.Part_Number = QC_CODES.CODE_ID " & _
                "WHERE (Batch_Records.[Group]" & TheGroup & " AND Batch_Records.Date_Received > '" & FirstWeek & "' AND Batch_Records.Date_Received < dateadd(Day, 1, '" & LastWeek & "'))" & _
                   "ORDER BY Batch_Records.Date_Received"

当我在上面导致错误的行上方添加此行时,我的报告在这几个月内超时。那么该怎么办呢?

If Not dRow("CompleteDate") Is System.DBNull.Value Then

【问题讨论】:

  • 不!不要使用字符串连接将值替换到您的查询中! 别这样!
  • 他是对的,用这段代码你可以很容易地被sql注入!!!
  • 在您的查询中,EXCEL 是架构,还是您以某种方式加入了 Excel 工作表?还是我们只处理 SQL?
  • CompleteDate 列的数据类型是什么?
  • +1 给大卫解释 why it's so bad!!!

标签: vb.net exception


【解决方案1】:

在请求值之前使用 dRow.IsNull("CompleteDate") 检查 null。

或者,如果这“应该”是不可能的,请将您的查询更改为从不返回可能为空的行。

【讨论】:

  • @Joel,我认为 OP 正在使用 DataRow,所以正确的函数是 IsNull。如果它是一个 DataReader,你是对的,它应该是 IsDBNull
  • 谢谢乔尔,但这不起作用。 IsNull 不是公认的 VB.NET 函数。我尝试了 IsDBNull,但这会导致编译错误,因为它不是正确的数据类型。我看到我可以使用 IsDBNull 的唯一方法是按照我上面解释的那样做单独的“If”语句。但这对我来说已经超时了。还有其他建议吗?
  • @OP,卓尔是什么?数据行?这就是我说的方法:msdn.microsoft.com/en-us/library/3fwatee0.aspx
  • 因此,如果您点击该链接,您会发现它实际上是一种方法,但您说错了。试试Console.WriteLine(drow.IsNull("FirstName"))
  • 谢谢大家,我现在添加了这个,但它仍然超时。我将数据集超时增加到 12000,但它仍然超时。如果你有任何其他想法,请告诉我。 (我也尝试只选择前 1000 行,然后完成)。不过,根据我的 SQL 查询结果,这个日期范围内肯定有一些 NULL 日期值
【解决方案2】:

我使用 sub(每种数据类型不同)从 Datareader 获取数据,但使用索引而不是名称:

#If Access Then
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Friend Function GetDbStringValue(ByVal Dr As OleDbDataReader, ByVal nr As Integer) As String
#Else
<Global.System.Diagnostics.DebuggerStepThroughAttribute()> _
Friend Function GetDbStringValue(ByVal Dr As MySqlDataReader, ByVal nr As Integer) As String
#End If
    If IsDBNull(Dr.Item(nr)) Then
        Return ""
    Else
        Return Dr.GetString(nr).TrimEnd
    End If
End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-10
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多