try_cast 和 cast 不同的结果。将日期数据类型转换为日期时间数据类型导致值超出范围
Posted
技术标签:
【中文标题】try_cast 和 cast 不同的结果。将日期数据类型转换为日期时间数据类型导致值超出范围【英文标题】:try_cast and cast differing results. The conversion of a date data type to a datetime data type resulted in an out-of-range value 【发布时间】:2021-01-13 15:08:37 【问题描述】:我有两个 SQL 2017 数据库。
数据库 1 包含表 (a),其列为 datatype "date"
数据库 2 包含表 (b),其列为 datatype "datetime"
我正在使用从"table a"
到"table b"
的基本插入语句
SELECT CAST(si.InceptionDate AS datetime).
目前因错误而失败
"The conversion of a date data type to a datetime data type resulted in an out-of-range value."
如果我将插入语句更改为
SELECT TRY_CAST(si.InceptionDate AS datetime)
现在可以使用了。这在理论上是有道理的,但是“表 b”中的日期时间列不包含任何 NULL,并且没有丢失来自 "table a"
的任何记录。 try_cast
怎么能成功地改变数据类型而强制转换却不行?
我认为这与从“表 a”中选择的数据有关,因为我在数据库 2 上创建了一个具有“日期”数据类型的虚拟表,并在插入插入“表 b”之前先将其插入其中工作没问题。
谁能想到原因???这让我很难过:(
【问题讨论】:
【参考方案1】:大概,您的查询比您显示的要复杂。
我的猜测是某些值会导致转换错误但这些行会从最终结果中过滤掉。 SQL Server 有在过滤子句之前推送表达式的习惯。一旦结果是,将被过滤掉的行上的错误会导致查询失败。
【讨论】:
有趣...以前没有遇到过这个,但感觉可能是这个原因。我在选择查询上有一些内部连接,并且插入的字段来自连接表。如果我放弃插入并使用 CAST 语句进行选择,它会做更多的摆弄,它返回整个数据集没有问题。如果我然后按 CAST(si.InceptionDate as datetime) 执行 ORDER BY CAST(si.InceptionDate as datetime),它会失败并显示相同的错误消息 @MarkDungey。 . .只需使用try_cast()
。【参考方案2】:
这里有两件事可能有所贡献,没有任何样本数据,我只能猜测是哪一个(尽管可能两者都有)。
首先,让我们解决您拥有的两个函数,TRY_CAST
和 CAST
。 TRY_CAST
无法返回您遇到的错误;如果转换失败,则返回 NULL
。这是设计使然,documentation 会告诉你。
接下来,您有 2 种不同的数据类型,datetime
和 date
。 datetime
是一种较旧的数据类型,对于基于 LOGIN's
LANGUAGE
设置的问题是可疑的。具体来说,对于datetime
(和smalldatetime
),yyyy-MM-dd
的格式不是明确的。这可以通过以下方式重现:
SET LANGUAGE ENGLISH; --American
SELECT CAST('2021-01-13' AS datetime); --Works
GO
SET LANGUAGE BRITISH; --English; we speak ENGLISH in England...
SELECT CAST('2021-01-13' AS datetime); --Fails
GO
date
不会发生这种情况:
SET LANGUAGE ENGLISH; --American
SELECT CAST('2021-01-13' AS date); --Works
GO
SET LANGUAGE BRITISH; --English; we speak ENGLISH in England...
SELECT CAST('2021-01-13' AS date); --Works
GO
同样,由于我们没有样本,因此这些因素中的一个或两个都在起作用。
【讨论】:
以上是关于try_cast 和 cast 不同的结果。将日期数据类型转换为日期时间数据类型导致值超出范围的主要内容,如果未能解决你的问题,请参考以下文章