2012年9月2日

.net datatable 的 select 敘述使用 SQLSERVER datetime

如果你找到這一篇想必您有遇到從SQL Server把資料A撈到DateTable dtA時,怎麼樣把SQL Server資料表B撈到dtB的datetime欄位rowB(“dtcol”)當作dtA的select條件?

首先我們要來了解一下SQL SERVER和.net的datetime,
1. SQL SERVER datetime,詳見MSDN
Datetime在sql server,最小單位是1/300 秒,1/300秒表示精確度最後一位是毫秒(1/1000),只有三個數字.000、.003、.007變化,也就是會把你的毫秒進行四捨五入成這三個數字。 儲存資料是以2個4Byte來儲存一串數字,這數字表示你的時間數值和1900 年 1 月 1 日以最小精確度為單位計算出的間隔數,我們可以作以下測試
declare @dt as datetime
a.  
set @dt = convert(datetime,'1900-01-01 00:00:00.000')
SELECT CAST(@dt AS BINARY(8)) AS WhatIsReallyStored
SELECT @dt
>>0x0000000000000000
>>1900-01-01 00:00:00.000

b.
set @dt = convert(datetime,'1900-01-01 00:00:00.001')
SELECT CAST(@dt AS BINARY(8)) AS WhatIsReallyStored
SELECT @dt
>>0x0000000000000000
>>1900-01-01 00:00:00.000
c.
set @dt = convert(datetime,'1900-01-01 00:00:00.002')
SELECT CAST(@dt AS BINARY(8)) AS WhatIsReallyStored
SELECT @dt
>>0x0000000000000001 >>1900-01-01 00:00:00.003 以上可以看出當c的.002秒,就過一個刻度,被四捨五入成.003
到這裡,我們的已經了解sqlserver的datetime儲存方式和精確度。
2. .net datetime  詳見MSDN
簡單說就是以100 nano second為單位,儲存目前時間和 0001 年元月 1 日午夜 12:00:00 的間隔數,看起來比SQL SERVER精確很多,所以從SQLSERVER把datetime欄位抓到.net,一般是以datetime去接是沒問題的,這裡有資料對照表(.net 2)
開始進行我們的程式
如果在DataTable要以select比對從Sqlserver查詢出的欄位?
我們一般會下以下語法把資料放到datatable,然後利用Select把需要的資料放到DataRow 陣列:
我們有一個資料表tbA (dtCol: datatime, name:varchar(100))

//select * from tbA where dtCol between '2012/8/1'and ‘2012/8/31’ 的資料 
DataTable dtA = tbABiz.Inq('2012/8/1','2012/8/31'); 
//select dtCol from tbA group by dtCol 
DataTable dtB = tbABiz.InqGroupByDtCol(); //以dtCol欄位為群組 查詢 
//接者我們要以dtB的資料去找dtA的資料

string filterExpression = null; 
foreach (DataRow dr in dtB.Rows) { 
    string strDT = dr("dtRow"); 
    filterExpression = " dtRow = #" + strDT.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK") + "#";

    DataRow[] rowsSelect = null; 
    rowsSelect= dtA.Select(filterExpression); 
} 



//以上可以看到在轉換strDT是以最精確的方式(100ns最小單位1/10000000秒,7個f)轉換,當然你用ss.fff也是OK,因為SQL Server精確度只有 1/300,若你只是toString()或ToString(DateTimeFormatInfo.InvariantInfo)那可抓不到資料。


到這邊討論可以告一段落了。 以下是一常見的日期格式轉換


DateTime dt = DateTime.Now;
String strDate="";
strDate = dt.ToString("MM/dd/yyyy");   // 07/21/2007 
strDate = dt.ToString("dddd, dd MMMM yyyy");   //Saturday, 21 July 2007
strDate = dt.ToString("dddd, dd MMMM yyyy HH:mm"); // Saturday, 21 July 2007 14:58
strDate = dt.ToString("dddd, dd MMMM yyyy hh:mm tt"); // Saturday, 21 July 2007 03:00 PM
strDate = dt.ToString("dddd, dd MMMM yyyy H:mm"); // Saturday, 21 July 2007 5:01 
strDate = dt.ToString("dddd, dd MMMM yyyy h:mm tt"); // Saturday, 21 July 2007 3:03 PM
strDate = dt.ToString("dddd, dd MMMM yyyy HH:mm:ss"); // Saturday, 21 July 2007 15:04:10
strDate = dt.ToString("MM/dd/yyyy HH:mm"); // 07/21/2007 15:05
strDate = dt.ToString("MM/dd/yyyy hh:mm tt"); // 07/21/2007 03:06 PM
strDate = dt.ToString("MM/dd/yyyy H:mm"); // 07/21/2007 15:07
strDate = dt.ToString("MM/dd/yyyy h:mm tt"); // 07/21/2007 3:07 PM
strDate = dt.ToString("MM/dd/yyyy HH:mm:ss"); // 07/21/2007 15:09:29
strDate = dt.ToString("MMMM dd"); // July 21
strDate = dt.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK"); // 2007-07-21T15:11:19.1250000+05:30    
strDate = dt.ToString("ddd, dd MMM yyyy HH':'mm':'ss 'GMT'"); // Sat, 21 Jul 2007 15:12:16 GMT
strDate = dt.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss"); // 2007-07-21T15:12:57
strDate = dt.ToString("HH:mm"); // 15:14
strDate = dt.ToString("hh:mm tt"); // 03:14 PM
strDate = dt.ToString("H:mm"); // 5:15
strDate = dt.ToString("h:mm tt"); // 3:16 PM
strDate = dt.ToString("HH:mm:ss"); // 15:16:29
strDate = dt.ToString("yyyy'-'MM'-'dd HH':'mm':'ss'Z'"); // 2007-07-21 15:17:20Z
strDate = dt.ToString("dddd, dd MMMM yyyy HH:mm:ss"); // Saturday, 21 July 2007 15:17:58
strDate = dt.ToString("yyyy MMMM"); // 2007 July





參考


datetime (Transact-SQL)


Demystifying the SQL Server DATETIME Datatype


http://goddaughter.iteye.com/blog/255483

沒有留言:

張貼留言