Sql-Server

為什麼我的 CASE 語句中的後續未滿足條件會影響我的返回數據類型?

  • April 29, 2021

我有以下變數和 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 語句應用於所選的每一行之前,會評估此數據類型決策。

引用自:https://dba.stackexchange.com/questions/290728