簡體   English   中英

ISNULL vs CASE返回類型

[英]ISNULL vs CASE Return Type

我最近遇到了一個有趣的問題,即在TSQL中將CASE語句更改為ISNULL函數。 我正在使用的查詢用於獲取我工作的網站的一些用戶屬性和權限。 以前,查詢有許多類似於以下內容的CASE語句:

注意: a.column1中的a.column1是表中的bit類型。 另請注意, [CanDoSomething]結果列有時用作網站中的字符串。

SELECT
    ...
    CASE
        WHEN a.column1 IS NULL THEN 0
        ELSE a.column1
    END [CanDoSomething]
    ...
FROM
    a

DBA用ISNULL函數替換了這些CASE語句:

SELECT
    ...
    ISNULL(a.column1, 0) [CanDoSomething]
    ...
FROM
    a

這似乎是一個很好的改變,但它在C#中檢索數據時引起了一些意想不到的事情。 使用上一個查詢,從C#中的DataTable訪問時, [CanDoSomething]列的值為10 當我們改為使用ISNULL ,C#中的值隨后被更改為truefalse ,當被視為字符串時,顯然與10

這引起的錯誤已經得到解決。 我只是好奇為什么ISNULL返回的值與等效的CASE語句不同,我似乎無法在Google上找到任何答案。

答案是在ISNULL的返回類型文檔中

ISNULL ( check_expression , replacement_value )

返回與check_expression相同的類型。 如果提供了一個文字NULL作為check_expression ,則返回replacement_value的數據類型。 如果提供了一個文字NULL作為check_expression並且沒有提供replacement_value ,則返回一個int

總是返回int *的 CASE表達式不同,因為第一個分支中的零返回一個intISNULL將返回其第一個參數類型的值,即a.column1


* CASE表達式是在編輯之前, WHEN a.column1 IS NULL THEN 0 ELSE 1

要擴展@ dasblinkenlight的解釋:

真正的問題是,根據文檔case表達

從* result_expressions *和可選的* else_result_expression *中的類型集返回最高優先級類型。 有關更多信息,請參閱數據類型優先級(Transact-SQL)

isnull()

返回與* check_expression *相同的類型

在你的情況下,這是一bit 你的case表達:

CASE
  WHEN a.column1 IS NULL THEN 0
  ELSE                        a.column1
END

具有返回兩種不同數據類型的執行路徑,一個int (文字值0 )和一個bit (列的值)。 如果查看上面鏈接的數據類型優先級圖表 ,則int的優先級高於bit ,因此bit值將轉換為int

這是因為從bitint轉換擴展轉換 Sql Server的bit類型本質上是1位整數值,因此沒有數據丟失。 intbit轉換是一種縮小的轉換,並且存在數據丟失的可能性(至少在概念上)。

你不會遇到這個問題,如果DBA使用了coalesce()而不是isnull() ,這本來是我個人的選擇,因為coalesce()被定義為返回類似於case的類型。 coalesce()

返回具有最高數據類型優先級的表達式的數據類型。 如果所有表達式都不可為空,則結果將輸入為nonnullable。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM