Sybase

datetime 小數秒

  • March 8, 2017

我正在閱讀Sybase ASE 15.7 文件datetime中的數據類型描述:

datetime 列包含 1753 年 1 月 1 日到 9999 年 12 月 31 日之間的日期。在支持這種粒度級別的平台上,datetime 值精確到 1/300 秒。

我覺得上面的內容非常令人困惑。首先,這是唯一添加了“在支持這種粒度級別的平台上”的警告的數據類型。這到底是什麼意思,我如何確定我的平台是否是“支持這種粒度級別”的平台之一?

此外,我不清楚能夠有效地準確儲存 1/300 秒意味著什麼。我正在使用 JDBC 訪問數據庫,唯一可能的類型是java.sql.Timestamp。這種類型允許我檢索到納秒的精度。但是考慮到除以 300 在一般情況下需要十進制系統中的無限位,實際上需要小數納秒(具有無限十進制位)來保持表示為 1/300 秒的值。因此,這意味著我無法在不失去一些精度的情況下獲取儲存在伺服器中的值,但可以忽略不計。

最後,當我執行以下查詢時:

SELECT convert(char(32), submission_date, 139) FROM some..table

我看到如下值:

Jan  6 2014 12:36:12.420000     
Sep 12 2013 13:44:57.100000     
Sep 10 2014 13:47:02.240000     
Sep 10 2014 13:47:07.850000     
Sep 10 2014 13:47:13.346000     
Sep 10 2014 13:47:19.033000     
Sep 10 2014 13:47:24.533000     
Sep 10 2014 13:47:30.030000     
Sep 10 2014 13:47:35.636000     
Sep 10 2014 13:47:41.136000     
Sep 10 2014 13:47:46.750000     
Sep 10 2014 13:47:52.240000     
Sep 25 2014 09:01:18.426000     

這些值似乎表明只保留了整千分之一秒(而不是 1/300 秒 - 這需要千分之一的小數)。如果是伺服器內部儲存值“精確到 1/300 秒”的情況,我希望轉換為十進製表示法以使用所有可用的小數位(3/300 秒的邊緣情況除外,30/300 secs、150/300 secs 和其他一些不需要十進制系統中無限位數的數字)。

datetime在 Adaptive Server Enterprise(和 SQL Server,因為它們共享一個包含 datetime 類型的公共程式碼庫)中,使用 8 個字節進行儲存。4 個字節為日期,4 個字節為時間。您可以通過查看日期時間的二進製版本來看到這一點:

SELECT CONVERT(varbinary(8), CONVERT(datetime, '1753-01-01T00:00:00.000'), 0)
SELECT CONVERT(varbinary(8), CONVERT(datetime, '1900-01-01T00:00:00.000'), 0)
SELECT CONVERT(varbinary(8), CONVERT(datetime, '1900-01-02T00:00:00.000'), 0)
SELECT CONVERT(varbinary(8), CONVERT(datetime, '3000-12-31T23:59:59.997'), 0)

四個二進制值是:

0xFFFF2E4600000000
0x0000000000000000
0x0000000100000000
0x000622D3018B81FF

採取以下,它顯示了 1/300 秒的作用:

SELECT CONVERT(varbinary(8), CONVERT(datetime, '1900-01-01T00:00:00.000'), 0) 
SELECT CONVERT(varbinary(8), CONVERT(datetime, '1900-01-02T00:00:00.000'), 0) 
SELECT CONVERT(varbinary(8), CONVERT(datetime, '1900-01-02T00:00:00.003'), 0) 

第二個和第三個值之間的差異是一個:

0x0000000000000000
0x0000000100000000
0x0000000100000001

所以日期儲存在最重要的 4 個字節中;和時間儲存在最低有效的 4 個字節中。儘管在 4 個字節的儲存空間中移動到大於 3 毫秒(1/300 秒)的精度是可能的;這就是實際使用的所有精度。

在 SQL Server 中,您可以使用datetime2(7)數據類型將精度降至 7 位,精度為 100ns:

SELECT CONVERT(varbinary(16), CONVERT(datetime2(7), '1900-01-01T00:00:00.0000000'), 0)
SELECT CONVERT(varbinary(16), CONVERT(datetime2(7), '1900-01-01T00:00:00.0000001'), 0)
SELECT CONVERT(varbinary(16), CONVERT(datetime2(7), '1900-01-01T00:00:00.0000002'), 0)

這些值的儲存方式略有不同,但是您仍然可以看到二進制值遞增:

0x0700000000005B950A
0x0701000000005B950A
0x0702000000005B950A

我正在使用 Sybase ISQL 客戶端;Sybase CTISQL 實用程序/15.7/P-EBF20996 SP100/DRV.15.7.0.10

datetime順便說一句,Adaptive Server Enterprise (ASE) 和 SQL Server 舍入值的方式之間存在細微差別。在 SQL Server 中,毫秒被舍入為0.0000.0030.007,而在 ASE 中,它們被舍入為0.0000.0030.006- 據我所知,沒有記錄為什麼存在差異。您可以通過執行以下查詢在 ASE 上看到這一點:

SELECT CONVERT(varchar(50), CONVERT(datetime, N'2017-01-01T23:59:59.997'), 139);

返回:

Jan  1 2017 23:59:59.996000

而在 SQL Server 上,等效程式碼SELECT CONVERT(varchar(50), CONVERT(datetime, N'2017-01-01T23:59:59.997'), 109);, 返回:

Jan  1 2017 11:59:59:997PM

引用自:https://dba.stackexchange.com/questions/166370