DateValue和SQL DATETIME - 30/12/1899转换为01/01/01?

时间:2013-03-24 12:59:34

标签: vb.net sql-server-2008

请查看下面的数据库结构:

CREATE TABLE TestStartDate (PersonID int, StartDate datetime NOT NULL)
INSERT INTO TestStartDate VALUES(1,'1899-12-30')

以及以下代码:

Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Dim objCommand As SqlCommand, objCommand2 As SqlCommand
        Dim objCon As SqlConnection
        Try
            objCommand = New SqlCommand
            Using objCommand
                Dim strConString As String = "Data Source=IANSCOMPUTER;Initial Catalog=Test;Integrated Security=True;MultipleActiveResultSets=true"
                objCon = New SqlConnection
                Using(objCon)
                    objCon.ConnectionString = strConString
                    objCon.Open()
                    objCommand.Connection = objCon
                    objCommand.CommandText = "select startdate from TestStartDate "
                    Dim objDR As SqlDataReader = objCommand.ExecuteReader
                    If objDR.HasRows Then
                        objDR.Read()
                        Using objCon
                            objCommand2 = New SqlCommand
                            Using objCommand2
                                objCommand2.Connection = objCon
                                objCommand2.CommandText = "INSERT INTO TestStartDate (StartDate) VALUES (@StartDate)"
                                objCommand2.Parameters.AddWithValue("@StartDate", DateValue(objDR("StartDate"))) 'line 24
                                'objCommand2.Parameters.AddWithValue("@StartDate", objDR("StartDate")) 'line 25
                                objCommand2.ExecuteNonQuery() 'Line 26
                                Dim date1 As Date = objDR("startdate")
                            End Using
                        End Using
                    End If
                End Using
            End Using
        Catch ex As Exception
            Throw
        Finally

        End Try
    End Sub

代码在第26行引发异常(第26行注释):

  

SqlDateTime溢出。必须在1/1/1753 12:00:00 AM和12/31/9999 11:59:59 PM之间

我可以通过注释第24行并取消注释第25行来解决这个问题。为什么DATEVALUE导致此异常?

我查看了以下网页:http://msdn.microsoft.com/en-us/library/6d6k22a5%28v=vs.80%29.aspx。这表明DATEVALUE可能会将30/12/1899转换为01/01/01(01/01/01在SQL Server中不是可接受的值)?如果是这种情况,那么为什么30/12/1899转换为01/01/01?

1 个答案:

答案 0 :(得分:0)

Dim date1 As Date = objDR("StartDate")

鉴于您的这一行代码,我们假设objDR("StartDate")返回DateTime值。

….CommandText = "INSERT INTO TestStartDate (StartDate) VALUES (@StartDate)"
….Parameters.AddWithValue("@StartDate", DateValue(objDR("StartDate")))
….ExecuteNonQuery()

DateValue function执行从StringDateTime的转换。但是,您将DateTime值传递给函数(objDR("StartDate"),见上文),并强制进行另一次转换。

因此,这行代码采用DateTime值,隐式将其转换为String,然后显式解析该字符串以生成DateTime值。有两种可能与文化相关的转换可能会产生意想不到的结果。

让我们注意两次转换是完全没必要的。

….CommandText = "INSERT INTO TestStartDate (StartDate) VALUES (@StartDate)"
….Parameters.AddWithValue("@StartDate", objDR("StartDate"))
….ExecuteNonQuery()

使用此版本时,DateTimeStringDateTime的转化无效。既然它有效(根据你所说的话),我的假设就是所有这些转换都出了问题。