[ADO.NET 2.0] 在 DateTime 欄位內只輸入時間


ADO.NET 2.0 不能明確的將時間寫入資料庫,我認為這是一個 bug ,但是我沒空發到 CSS 去確認,所以看誰要去問問看。

 繞著走的方式有兩種:

  1. 自己轉換到 Variant Date 的基準日。
  2. 自己下 SQL 命令。

先看一段測試範例:

Sub SubMain()

     Dim m_Adapter As System.Data.Odbc.OdbcDataAdapter

     Dim m_CBuilder As System.Data.Odbc.OdbcCommandBuilder

     Dim m_DataSet As New System.Data.DataSet

     Dim m_DataRow As System.Data.DataRow

     Dim strPath As String = MapPath("AddTime.mdb")

     Dim strProvider As String = "Driver={Microsoft Access Driver (*.mdb)}; dbq=" & strPath & ";"

 

     轉換到Variant Date 的基準日

     m_Adapter = New System.Data.Odbc.OdbcDataAdapter("Select * From TestTable", strProvider)

     m_Adapter.Fill(m_DataSet)

     m_DataRow = m_DataSet.Tables(0).NewRow()

     m_DataRow("DataTime") = CDate("1899/12/30 " & DateTime.Now.AddHours(-1).ToString("HH:mm:ss"))

     m_DataSet.Tables(0).Rows.Add(m_DataRow)

     m_CBuilder = New System.Data.Odbc.OdbcCommandBuilder(m_Adapter)

     m_Adapter.Update(m_DataSet)

     m_Adapter.SelectCommand.Connection.Close()

    

     SQL 命令

     Dim strInsert As String = "Insert Into TestTable (DataTime) Values(‘" & DateTime.Now.ToString("HH:mm:ss") & "’)"

     m_Adapter = New System.Data.Odbc.OdbcDataAdapter(strInsert, strProvider)

     m_Adapter.SelectCommand.Connection.Open()

     Dim nLine As Integer = m_Adapter.SelectCommand.ExecuteNonQuery()

     m_Adapter.SelectCommand.Connection.Close()

    

     m_Adapter.Dispose()

End Sub

轉換到 Variant Date 的基準日

VB6/VBA/VBScript 都是用 Variant Date(Double),在 Access/Excel/SQL Server 2000/2005 也是使用 Variant Date,因此使用相同的資料庫都可以使用相同的方法來閃避。

對於只有時間來說,比如說 00:00:00 來說,Variant Date 是指 1899/12/30 00:00:00 這個瞬間。而 .Net 的 Ticks Date (Long) 則是指 0001/01/01 00:00:00 ,亦即兩個基準日不同,Variant Date 採用 Double 來表示時間,所以在只有時間的狀況或接近 1899/12/30 下,解析度比 Ticks Date 高,但 Ticks Date 則在各種時間點都具有相同的解析度,以 2007/5/6 來說,在這種情況下是 Ticks Date 的解析度比較好。 

所以當需要寫入資料庫只有時間時,請把時間與 1899/12/30 組合,讓它寫入資料庫,就會轉換為只有時間,否則直接用時間,.Net 在轉換為 SQL 語法時,會變成 0001/01/01 ,這會造成 Variant Date 下溢位 (Overflow)。

我比較懶啦,透過 Format 輸出時間字串再用 CDate 轉回時間時間值即可。例如:

VariantDate = CDate("1899/12/30 " & DataTimeValue.ToString("HH:mm:ss"))

這種作法適用於由 .Net 幫你產生 SQL 語法,例如 CommandBuilder、InsertCommand 等。

下 SQL 命令

這比較沒什麼,讓資料庫自己去處理只有時間字串的問題。這裡要注意的就是各資料庫所用時間字串處理的分隔字元,大部分是用 ‘ ,Access 是用 # ,不過 Access 也支援用 ‘ ,用 ‘ 時,裡面必須使用 24 hr 制的時間字串,要避免地區語言出現上下午而無法辨識。 例如:

Insert Into TableName (ColumnName) Values(#HH:mm:ss#)

廣告
Categories: 資料庫 | 發表留言

文章分頁導航

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

在WordPress.com寫網誌.

%d 位部落客按了讚: