2023年7月13日 星期四

SQL Server DateTime 型別注意事項

最近撈取資料並且使用 DateTime 型別欄位排序,但發現怎麼沒有跟預期的有差,想說資料新增進去應該

會差個幾毫秒,應該排序不是這樣的結果,想了想後,發現又忘了一個細節



以下建立一張 table,並且塞入若干資料,大概描述的一下狀況


圖片中可看出 TimeKey 最後的尾數都是 7,0,3 結尾,若再隨意塞更多資料呢,看起來還是一樣



這是因為 DateTime 的精準度會被四捨五入為 .000、.003、.007 (參考),或許有人稱 0.00333 秒(1/300)



而對應的四捨五入表如下,可以看出為何尾數都是 0,3,7,值得注意若尾數剛好是 999 則會進位


由以上可以看出對應的區間以及小數,所以若是以程式或是 SP 來塞入資料,那就很高的機率,會出現

整批尾數都是一樣,而這一點點差異,就會造成排序並非預期


為了解決這樣的狀況,現在都是使用 datetime2 型別,datetime2 有 100 奈秒,小數點後7位,能如實呈現

毫秒的差距,而資料再新增上可使用 SYSDATETIME() 函數


以下是資料原本資料表 TimeKey 欄位的型別為 datetime2



新增資料


呈現結果


若是使用EF新增,同樣使用 DateTime.Now 即可



若使用 Dapper 須注意,Dapper 會預設對應使用 DateTime 型別而非 DateTime2,新增時結果

會如下


而需要加入 SqlMapper.AddTypeMap(typeof(DateTime), System.Data.DbType.DateTime2) 特別指定




【參考】

沒有留言:

張貼留言