最近使用 Case When
判斷踩到了一個資料型態的雷,特此紀錄。
問題在此,情況大概是做完一系列 case when 的判斷後,最後有 else 給 default 值,但這個值的型態和前面條件式返回的型態不同。
出現了我給定空字串他卻給我 0 的問題。
如果是這樣就沒什麼問題。
查了一下 Microsoft 的 SQL 文件看到了傳回類型的說明。
傳回類型
從 result_expressions 和選擇性 else_result_expression 的類型集傳回優先順序最高的類型。
SQL Server 會使用下列資料類型優先順序:
- 使用者自訂資料類型 (最高)
- sql_variant
- xml
- datetimeoffset
- datetime2
- datetime
- smalldatetime
- date
- time
- float
- real
- decimal
- money
- smallmoney
- bigint
- int
- smallint
- tinyint
- bit
- ntext
- text
- image
- timestamp
- uniqueidentifier
- nvarchar (包含 nvarchar(max))
- nchar
- varchar (包含 varchar(max))
- char
- varbinary (包含 varbinary(max))
- binary (最低)
在我的例子中,尋找全部的 result expression 後會發現最高的優先權就是 int (排第 16 名,相對於 varchar 的第 27),所以空字串會被強迫自動轉為 int 類型後回傳。
所以建議所有的返回值應該要保持同樣的資料型態,以我的例子來說,則建議使用 CONVERT
將 INT 轉為 VARCHAR 型別,這樣就可以讓 then 及 else 的返回值均為 VARCHAR 型別,以減少這類錯誤發生的機會。