4

我遇到了一个我没想到并且需要帮助回答的场景。我们当前的系统调用 SQL 存储过程,因此创建 SQL 命令,添加参数并添加这些参数的值……比如插入。

我们有如下代码......

cmd.Parameters.Add("@MyTimestamp", SqlDbType.DateTime)
If MyObject.MyTimestamp <> Nothing Then
   cmd.Parameters.Item("@MyTimestamp").Value = MyObject.MyTimestamp
Else
   cmd.Parameters.Item("@MyTimestamp").Value = Nothing
End If

现在,当我第一次看到这个时,我有点惊讶 MyObject.MyTimestamp 曾经评估为 Nothing,但它已经存在多年没有问题。在清理工作期间,添加参数并设置其值的代码被合并,因此上面的代码变成了......

cmd.Parameters.Add("@MyTimestamp", SqlDbType.DateTime).Value = If(MyObject.MyTimestamp <> Nothing, MyObject.MyTimestamp, Nothing)

对我来说,这看起来等同于代码最初所做的,但这不是在测试期间发现的。在测试时我收到了一个 SqlTypeException:

SqlDateTime 溢出。必须介于 1753 年 1 月 1 日上午 12:00:00 和 9999 年 12 月 31 日晚上 11:59:59 之间。

那是因为使用 If 运算符将 MyObject.MyTimestamp 评估为不是 Nothing,它不是 Nothing 它是 DateTime.MinValue 并且它试图将其插入 sql 并且它爆炸了。原始代码的编写方式将相同的 Timestamp 评估为 Nothing (不确定如何/为什么)并且做了错误的部分。所以我的问题是有什么区别,我应该关注其他数据类型......?

4

1 回答 1

3

记住(我经常不记得)这Nothing不等同null于 C#,但更像是Default(T),以下内容不检查 MyObject.MyTimestamp 是否已设置:

MyObject.MyTimestamp <> Nothing

但是正在检查它是否是默认的日期时间(DateTime.MinValue),它大概总是这样。

此外,当您使用:

If(MyObject.MyTimestamp <> Nothing, MyObject.MyTimestamp, Nothing)

两个返回类型 ( MyObject.MyTimestamp, Nothing) 必须是相同的类型,因此由于编译器知道MyObject.Timestamp应该是日期时间,因此它不会将任何内容转换为默认日期时间。

但是,当您使用它时:

If MyObject.MyTimestamp <> Nothing Then
   cmd.Parameters.Item("@MyTimestamp").Value = MyObject.MyTimestamp
Else
   cmd.Parameters.Item("@MyTimestamp").Value = Nothing
End If

它识别出参数 for"@MyTimestamp"的类型为SqlDbType.DateTime,因此为此创建默认值。我不知道这是 DbNull 还是我脑海中的实际值,但无论哪种方式,它都是允许的值,因此不会引发错误。

顺便说一句,您可能希望将参数设置为DbNull.Value而不是Nothing

If MyObject.MyTimestamp <> Nothing Then
   cmd.Parameters.Item("@MyTimestamp").Value = MyObject.MyTimestamp
Else
   cmd.Parameters.Item("@MyTimestamp").Value = DbNull.Value
End If
于 2013-10-29T18:17:30.067 回答