繁体   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