【问题标题】:Date conversion "Out of range value" error, converting dates under WHERE clause日期转换“超出范围值”错误,在 WHERE 子句下转换日期
【发布时间】:2020-02-11 19:06:05
【问题描述】:

我正在使用一个表,该表将日期值存储为单独的“世纪”、“年”、“月”和“日”列下的整数。 (Year 列只获取年份的最后两位数字,Century 列分别为 2000 年之前和 2000 年之后的年份,取值范围为 0 到 1。)

我正在尝试过滤特定日期之后的数据。这些列必须转换为单个日期或日期时间值,以便可以更改报告参数。现在 WHERE 子句如下所示:

WHERE convert(datetime, CAST( ((19 + Table.Century) * 100 + Table.Year) as varchar) + '-' +  (Table.Month as varchar) + '-' + CAST(Table.Day as varchar), 121) > Convert(datetime,'2020-01-01', 121)

但是,当我尝试运行查询时,它总是抛出错误:

将 varchar 数据类型转换为 datetime 数据类型导致值超出范围。

问题似乎在于月份列。如果我将任何 30 天的月份(或 2 月)替换为 Table.Month 值,它将引发错误。 31 天的月份工作正常。但是,数据本身没有越界日期。此外,如果我将它放在 SELECT 语句中,该语句运行良好并且不会中断。

我得到的印象是 WHERE 语句正在评估每个可能的 Day 值与每个可能的 Year 值的每个可能的 Month 值等,并最终检查诸如“2020-02-30”之类的日期。如何让它停止这种行为?

【问题讨论】:

  • 天哪!自 Y2K 以来,我还没有看到过一个世纪指标。

标签: sql sql-server sql-server-2017


【解决方案1】:

使用datefromparts():

where datefromparts(1900 + century * 100 + year, month, day) > '2020-01-01'

也就是说,您可能有无效值。你应该调查那些:

select century, year, month, day
from t
where try_convert(concat(1900 + century * 100 + year, '-'
                         month, '-', day)
                 ) is null

这是因为 SQL Server 擅长解释日期,例如 '2020-1-1'

【讨论】:

  • 感谢您的提示。 DATEFROMPARTS 更方便。然而,使用它导致了一个荒谬的发现,即只有当我尝试将我新组装的日期与另一个日期进行比较时,才会发生超出范围的错误。它在 SELECT 中自行显示所有日期,但是当我添加过滤器(例如 > 2020-01-01)时,突然 DATEFROMPARTS 函数说它的参数无效。
  • @dhwu 。 . .您是否尝试了第二个查询来查找错误日期?
猜你喜欢
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多