保存列转换以在 SELECT 中重复使用

Save a column conversion for reuse in a SELECT

存储过程中有一个 SELECT,它有一些嵌套的 case-when 块,这个东西在不同的 or 块中出现了大约 5 次:

CONVERT(DATE, ADJDOH) <= CONVERT(DATE, ADJDOT)

这些字段可以有 DATETIME、空白(空字符串)或 NULL,或者无效值,这会使 CONVERT 函数失败。有什么方法可以让我转换一次这些字段然后能够进行比较,或者比多次使用 CONVERT 函数更容易进行 null 检查?

在下面的示例中,如果日期无效,第 4 行会给出错误。

CREATE TABLE repro (
    id int,
    date1 varchar(10),
    date2 varchar(10)
)

INSERT INTO repro values
(1, '12/31/2021', '12/30/2021'),
(2, NULL, '12/14/2021'),
(3, '',''),
(4, '12/30/202', '12/30/2021')

SELECT 
    CONVERT(DATE,date1) as D1,
    CONVERT(DATE,date2) as D2
from repro 
where 
--id = 1
--id = 2
--id = 3
id = 4

drop table repro

CROSS APPLY + TRY_CONVERT就是你想要的。 CROSS APPLY 允许您在一个地方执行任何 calculations/conversions/etc 而无需重复逻辑。 TRY_CONVERT 允许您检测 and/or 从坏数据中恢复。

SELECT 
    D.Date1 AS D1
    , D.Date2 AS D2
FROM repro 
CROSS APPLY (
  -- Perform any calculations/conversions here, once
  VALUES (TRY_CONVERT(DATE,date1), TRY_CONVERT(DATE,date2))
) AS D (Date1, Date2);

你可以

尽管如此,您仍然需要以某种方式处理坏数据。但是这些中的任何一个都为您提供了一种持久的方式来提供日期转换,而无需一遍又一遍地重复逻辑。

[坦率地说,我会清理 table 中的数据,然后在该列上放置一个 check 约束以确保错误日期无法进行任何插入或更新。或者,更好的是,将该列转换为 date 并完成它 — 尽管这可能会破坏期望该列为 char/varchar.

的现有代码