我只是偶然发现这件事,却找不到任何技术解释:
在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,第16级,状态2,第4行 不允许从数据类型int到日期的显式转换。
为什么从空字符串到DATE和DATETIME的DATE和DATETIME都能工作,而从0则只能作为DATETIME工作?
我对一个技术解释感兴趣
发布于 2017-01-13 23:35:17
我认为这是微软选择支持什么的问题。这或多或少地归结于这样一个事实:从数值到日期时间的数据转换是允许的,而date不允许从数字值进行转换。在SQL server中,它必须首先将0转换为类似于0.000000000的数值,然后转换为与该数字相等的日期时间。我的示例显示,可以将当前日期转换为数字值,然后返回到日期时间。但是,转换到日期会引发错误。我想,如果您尝试将值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)不允许从数据类型数值到日期的Msg 529、级别16、状态2、第5行显式转换。
发布于 2021-10-25 20:20:40
你的第一个问题,为什么你至今不能转换0,这是非法的从Int到目前为止(见链接文档中的矩阵)
在找到类似的代码之后,我找到了您的问题,并想知道为什么cast(0作为日期时间)产生了1900-01-01。我想知道这是一个我可以信任或未定义的“标准”,“在我们改变它之前,它是那样工作的。”我甚至还找到了其他这样的帖子,这些帖子暗示着这个时代是1900年,但却找不到任何关于这个时代的官方文件。
在阅读强制转换/转换文档时,引用了如果缺少年份或时间(尽管在varchar转换部分中),Cast将做什么。未定义时,日期默认为1900-01-01,时间为00:00:00。(参见链接文档中的下标6)。本文中有示例代码将时间转换为日期时间,并为日期部分生成1900-01-01。
这个(谢天谢地?!)收益率为0(而最小日期为1753,则产生大量负数)。
select cast(cast('1900-01-01' as datetime) as Int)
微软名为“强制转换(Transact-SQL)”的文档
发布于 2017-01-13 21:20:32
可能是时间戳行为造成的。您可以将0转换为datetime,然后强制转换为date。这也是微软的一条规则。一条不属于国家的规则。
https://stackoverflow.com/questions/41643454
复制相似问题