2013-03-24 24 views
0

请看看下面的数据库结构:DateValue和SQL DATETIME - 30/12/1899转换为01/01/01?

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溢出。必须是1753年1月1日12:00:00 AM和12/31/9999之间下午11:59:59

我可以通过注释掉线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?

+0

两种可能性:由'objDR'产生的日期时间值超出范围,或在'DateValue'转换期间变为无效。 DateValue(objDR(“StartDate”))产生什么值?你有没有尝试通过编写'objDR.GetDateTime(objDR.GetOrdinal(“StartDate”))'来替换'DateValue'函数? – stakx 2013-03-24 13:06:28

+0

@stakx,我编辑了这个问题,请再看一下。 – w0051977 2013-03-24 13:12:03

+0

用'1899年日期功能'检查这个链接的一些历史记录:http://stackoverflow.com/questions/3963617/why-is-1899-12-30-the-zero-date-in-access-sql -server-instead-of-12-31 – 2013-03-24 13:20:16

回答

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的转化率。但是,您正在向函数(objDR("StartDate"),请参见上面)传递DateTime值,强制进行另一次转换。

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

让我们注意到,这两个转换是完全没有必要的。

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

在这个版本中,没有任何转换,从DateTimeStringDateTime。而且,由于它有效(根据你所说的),我的假设是所有这些转换都会出现问题。

+0

谢谢。我想我需要找出转换如何导致这个问题或等待回答者解释。 – w0051977 2013-03-24 13:53:27

+0

@ w0051977:这些转换可能取决于您的文化/日历设置。所以我建议你** 1。**阅读DateValue函数的MSDN文档,然后** 2。**取得您的DateTime样本值,将其提供给DateValue函数,并查看函数的返回值。这可能会对解释您遇到的问题有很大的帮助。 – stakx 2013-03-24 13:56:20