【问题标题】:"Cannot construct data type datetime" when filtering data, but all values filtered DO have valid dates过滤数据时“无法构造数据类型日期时间”,但过滤的所有值都具有有效日期
【发布时间】:2023-02-11 03:27:17
【问题描述】:

我相信这个问题不是以下问题的重复: Cannot construct data type datetime, some of the arguments have values which are not valid

在那种情况下,过去的值显然无效。而在这种情况下,可以预期调用函数的值全部有效。

我知道实际问题是什么,这不会帮助大多数人找到其他问题。但在 SO 上可以找到它是件好事。

请阅读答案,并理解为什么它与链接的问题不同,然后再投票关闭该问题。


我运行了一些错误消息的 SQL:Cannot construct data type datetime, some of the arguments have values which are not valid.

我的 SQL 使用 DATETIMEFROMPARTS,但在选择中评估该函数很好 - 只有当我过滤所选值时才会出现问题。

它还展示了奇怪的、不可能发生的行为 w.r.t.对查询的其他更改。

我的查询大致如下所示:

WITH FilteredDataWithDate (
    SELECT *, DATETIMEFROMPARTS(...some integer columns representing date data...) AS Date
    FROM Table
    WHERE <unrelated pre-condition filter>
)
SELECT * FROM FilteredDataWithDate
  WHERE Date > '2020-01-01'

如果我运行该查询,则会出现 invalid data 错误。 但是,如果我省略最后的 Date &gt; 过滤器,那么它会愉快地呈现每个结果记录,因此很明显它过滤的值都不是无效的。

我还手动检查了Table WHERE &lt;unrelated pre-condition filter&gt; 的内容并验证了所有内容都是有效日期。

它还具有大量其他行为:

  • 如果我将所有...some integer columns representing date data... 替换为硬编码数字,就可以了。
  • 如果我更换一些该数据的一部分具有硬编码值,可以修复它,但其他部分则不能。我没有发现有什么帮助或没有帮助的任何特定模式。
  • 如果我从 Table 选择中删除大部分 * 列。然后又开始好了。
    • 具体来说,每当我在 CTE 中包含 nvarchar(max) 列时,它似乎都会中断。
  • 如果我向 CTE 添加一个附加过滤器,将结果限制为以下范围内的 Id 值,则结果为:
    • 130,000 和 140,000。错误。
    • 130,000 和 135,000。美好的。
    • 135,000 和 140,000。美好的。!!!!
  • Date 列过滤会破坏所有内容……但ORDER BY Date 没问题。(并确认所有日期都在完全合理的范围内。)
  • 添加TOP 1000000 使其工作......即使只有大约 1000 行。

... WTAF?

【问题讨论】:

    标签: sql datetime


    【解决方案1】:

    这花了我一段时间来解码,但事实证明,SS 编译器不一定将其函数的执行限制为与结果集相关或可能相关的行。

    根据它到达的执行计划,该函数可能会被调用任何记录在Table,即使不满足WHERE &lt;unrelated pre-condition filter&gt;

    这是另一个用户找到的,用于另一个功能,over here

    所以它可以在没有过滤器的情况下返回所有结果的事实实际上并不能证明函数的每个输入都是有效的。确实表中有一些记录不在结果集中,但仍然有无效数据。

    这实际上意味着即使您要添加一个显式的 WHERE 过滤器来排除包含无效日期组件数据的行......实际上也不能保证修复它,因为该函数可能仍然针对“排除的”行调用。

    我所做的每一件随机的其他事情都会以一种或另一种方式影响查询计划,而这些方式恰好会修复/破坏事情。

    解决方案自然是修复底层表数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-04
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-30
      • 1970-01-01
      • 2023-03-16
      相关资源
      最近更新 更多