簡體   English   中英

t-sql:內置布爾函數之間不兼容

[英]t-sql: incompatibility between built-in boolean functions

為什么內置的布爾函數在NULL輸入上的行為會有所不同? 例如-此查詢:

select 'ISDATE(null)'                 as function_call, 
        ISDATE(null) as result union all
select 'ISNUMERIC(null)'              as function_call, 
        ISNUMERIC(null) as result union all
select 'IS_MEMBER(null)'              as function_call, 
        IS_MEMBER(null) as result union all
select 'IS_SRVROLEMEMBER(null, null)' as function_call, 
        IS_SRVROLEMEMBER(null, null) as result

給我們:

function_call                result
---------------------------- -----------
ISDATE(null)                 0
ISNUMERIC(null)              0
IS_MEMBER(null)              NULL
IS_SRVROLEMEMBER(null, null) NULL

看起來ISDATEISNUMERIC行為符合布爾邏輯,但IS_MEMBERIS_SRVROLEMEMBER行為符合三值邏輯 所有布爾函數在NULL輸入上的行為不應該都一樣嗎? ANSI SQL標准對此有何評論?

謝謝

對於ANSI標准,后兩個功能與ANSI SQL無關; 它們是MSSQL特定的安全功能。 這並不是說它們不是其他DBMS中的類似物,只是說明它們不是“典型的” UML樣式函數或標准的一部分。

我其實在搜索這個合理的權威O'Reilly的網頁有關的術語“布爾” ANSI標准功能不返回任何結果。 由此可以推斷出,對於這種標量函數對NULL的處理沒有ANSI方法。

這些函數中需要使用三值邏輯,以允許NULL表示輸入無效 例如,請參閱MSDN IS_MEMBER() 備注”部分。

(不要將這種形式的NULL返回與可能返回一個值的聚合函數相混淆,如果聚合函數的輸入之一為NULL,則為NULL。)

如果您真正需要的是,沒有什么能阻止您“包裝”這些功能使其像其他功能那樣運行。 例如ISNULL(IS_MEMBER(someValueFromATable),0)

如您所見,前兩個函數返回一個有意義的布爾值。

例如, ISDATE(null)返回false,因為null 不是有效的日期,時間或datetime ”( MSDN ,我強調value )。

在將NULL解釋為“未知”的情況下,當輸入未知但在編程上不可行時, ISDATE()等返回“未知”在語義上有意義。 當我們已經有一個針對ISNULL()類型非特定測試時,將(從所有這些布爾函數中)結果(從所有這些布爾函數)“轉換”為布爾邏輯的需求是完全多余的。

在比較您確定的兩種類型的函數時,在這種情況下,后一種函數的返回值不應為NULL,因為雖然NULL不是日期,但它肯定是可以正確檢查的有效數據通過此功能。

這些安全功能( IS_SRVROLEMEMBER )的行為與系統/數據類型函數( ISNUMERIC )有所不同,這並不奇怪,因為這些安全功能本質上是查詢,並且結果可以根據查詢的對象而改變。 對於所有這些, MSDN文檔中都很好地闡明了返回值(包括空值)的含義。

更具體地說,對於ISNUMERICISDATE的參數,您可以提前很好地測試參數是否為null,因此我不確定是否需要返回null或是否具有實用性。

對於安全性函數的參數,您可能具有非null參數,但是以一種有用的方式構建了這些函數,以在參數無效,未找到或您沒有權限的情況下返回null知道答案。

當然,其中很多都可以看作是主觀的,因此無論是否有趣,我都投票贊成結束這個問題。

暫無
暫無

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

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