簡體   English   中英

將 0 轉換為 DATE 和 DATETIME

[英]Casting 0 as DATE and DATETIME

我碰巧偶然發現了這個,找不到任何技術解釋:

在 SQL Server 2014 中:

SELECT CAST('' AS DATETIME);
1900-01-01 00:00:00.000

SELECT CAST(0 AS DATETIME);
1900-01-01 00:00:00.000

SELECT CAST('' AS DATE);
1900-01-01

SELECT CAST(CAST(0 AS DATETIME) AS DATE);
1900-01-01

SELECT CAST(0 AS DATE);

Msg 529, Level 16, State 2, Line 4
不允許從數據類型 int 顯式轉換為 date。

為什么從空字符串到DATEDATETIMECAST工作,但從0它只作為DATETIME

我對技術解釋感興趣

我認為這與Microsoft選擇支持的問題有關。 或多或少地歸結為以下事實:允許從數值將數據轉換為日期時間,而日期不允許從數值進行轉換。 在SQL Server中,它必須先將0轉換為0.000000000之類的數值,然后再轉換為該數字的datetime。 我的示例表明,可以將當前日期轉換為數字值,然后再轉換為日期時間。 但是,轉換為日期會引發錯誤。 我想避免如果試圖將值0.5轉換為日期時可能遇到的舍入問題。 在這種情況下,將對SQL引擎進行編程,以將0.5隱式轉換為日期1900-01-01或1900-01-02。 在這種情況下,您將不得不決定應返回哪個日期。

這有效:

--produces a numeric value like 42746.97660799
select cast(getdate() as numeric(18,8)) 

select cast(42746.97660799 as datetime)

雖然這會引發您收到的相同錯誤:

select cast(42746.97660799 as date)

消息529,級別16,狀態2,第5行,不允許從數字類型的數據類型到日期的顯式轉換。

這可能是出於時間戳行為。 您可以將0轉換為日期時間,然后將其轉換為日期。 這也是微軟的一條規則。 這不是國家規定。

除了SQL Server支持的內容外,我不確定是否有很多明確的技術說明。 SQL Server對其所有數據類型“ 數據類型優先級”進行排名 隱式轉換隨着時間的推移而發展。 有由克雷格·弗里德曼微軟博客解釋的邏輯和進化相當不錯的更多的隱式轉換 @hamid_reza hobab表示的本質上是正確的。 SQL Server支持將int轉換為datetime。 日期時間比日期具有更高的優先級,因此可傳遞的日期時間可以轉換為日期。 SQL Server不支持@dfundako在評論中發布的支持矩陣中指示的int到日期的隱式或顯式轉換。

您的第一個問題,為什么不能將 0 轉換為 Date,這是從 Int 到 Date 的非法轉換(請參閱鏈接文檔中的矩陣)

我在找到類似的代碼后發現了你的問題,並想知道為什么 cast(0 as datetime) 產生了 1900-01-01。 我想知道這是一個我可以信任的“標准”還是未定義的“在我們改變它之前它會一直這樣工作”。 我什至發現其他 SO 帖子表明 Epoch 是 1900 年,但找不到任何關於此的官方文檔。

在閱讀 Cast/Convert 文檔時,可以參考如果缺少年份或時間(盡管在 varchar 轉換部分),Cast 會做什么。 未定義時,日期默認為 1900-01-01,時間默認為 00:00:00。 (參見鏈接文檔中的下標 6)。 文章中有示例代碼將時間轉換為日期時間,並為日期部分生成 1900-01-01。

這(謝天謝地?!)產生 0(而 1753 的最小日期產生一個很大的負數)

select cast(cast('1900-01-01' as datetime) as Int)

標題為“CAST 和 CONVERT (Transact-SQL)”的 Microsoft 文檔

https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver15

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM