我有以下变量和 CASE 语句:
DECLARE @DATE_VALUE VARCHAR(20) = '4/29/2021'
DECLARE @CONVERT_CODE VARCHAR(1) = 'I'
SELECT CASE @CONVERT_CODE WHEN 'I' THEN DATEDIFF(day, '04/21/2021', @DATE_VALUE)
END AS ConvertedValue
它没有什么特别之处。它按照我的预期返回 8 (int)。
但是,只要我在 CASE 语句中添加一个返回日期时间数据类型的条件,我就不再得到 8 (int),尽管继续使用“I”作为 @CONVERT_CODE 值。
DECLARE @DATE_VALUE VARCHAR(20) = '4/29/2021'
DECLARE @CONVERT_CODE VARCHAR(1) = 'I'
SELECT CASE @CONVERT_CODE WHEN 'I' THEN DATEDIFF(day, '04/21/2021', @DATE_VALUE)
WHEN 'D' THEN GETDATE()
END AS ConvertedValue
相反,我得到“1900-01-09 00:00:00.000”的日期时间值
我认为“D”根本不应该被评估,因为在 SQL Server 中,一旦条件评估为真(在本例中为“I”),它应该脱离 CASE 语句——所以我不确定为什么“D”的数据类型会影响整体返回数据类型。此外,如果我颠倒条件的顺序并仍然使用“I”也没关系:
DECLARE @DATE_VALUE VARCHAR(20) = '4/29/2021'
DECLARE @CONVERT_CODE VARCHAR(1) = 'I'
SELECT CASE @CONVERT_CODE WHEN 'D' THEN GETDATE()
WHEN 'I' THEN DATEDIFF(day, '04/21/2021', @DATE_VALUE)
END AS ConvertedValue
我错过了什么吗?
与所有列一样,由表达式定义的列
CASE
具有数据类型。SQL Server 以通常的方式确定结果类型,利用数据类型优先级。该类型
datetime
的优先级高于integer
。您可能期望
CASE
表达式在不同的路径上返回不同的类型,但这是不可能的(sql_variant
旁白)。“1900-01-09 00:00:00.000”是日期编号 8。您面临的问题取决于 case 仅返回一种数据类型这一事实。它将评估每个案例表达式,选择数据类型并将每个结果隐式转换为该数据类型。
在您的情况下,一种情况返回 int (datediff),另一种返回 datetime,因此 sql 决定使用 datetime,然后将 8 转换为您找到的 datetime。
在将 case 语句应用于所选的每一行之前,会评估此数据类型决策。
我认为“D”根本不应该被评估,因为在 SQL Server 中,一旦条件评估为真(在本例中为“I”),它应该脱离 CASE 语句
太多的应该 - 尝试关注Aaron Bertrand的 CASE 表达式的肮脏秘密。