2013-04-18 19 views
0

爲什麼內置布爾函數在NULL輸入上表現不同? 例如 - 此查詢:t-sql:內置布爾函數之間的不兼容

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 - 根據Three valued logic行爲。 不應該所有布爾函數在NULL輸入上表現相同嗎? ANSI SQL標準對此有何評論?

謝謝

回答

0

我並不覺得奇怪的是,這些安全功能(IS_SRVROLEMEMBER)會表現得不同於因爲這些安全功能的系統/數據類型功能(ISNUMERIC)基本上是查詢和結果可能取決於誰是查詢更改。在MSDN Documentation中,所有這些返回值的含義(包括空值)的拼寫非常清晰。

更具體地說,對於ISNUMERICISDATE的參數,如果參數爲空或者沒有,你可以提前測試,所以我不確定返回null是否必要或具有很大的實用性。

對於安全性函數的參數,您可能有非空參數,但函數已經以有用的方式構建,以便在參數無效,未找到或未找到的情況下返回null。沒有權限知道答案。

大部分情況當然可以被看作是主觀的,因此我已經投票決定關閉這個問題,但它可能是有趣的。

+0

這個回答對於評論來說似乎太大了,所以在這裏。 –

+0

@ 0x69我覺得很有趣,你接受了這個答案,而不是我的?不建議我對答案有一個問題,只是在一天後,而是總結性地同意我的評估:a)您引用的安全功能與其他兩個不在同一「類別」中,b)爲例如ISNUMERIC和ISDATE返回NULL幾乎沒有實際用途。然而,它並沒有專門針對你的有關ANSI標準的問題作爲我的嘗試。 – Sepster

3

重新ANSI標準,後兩個函數與ANSI SQL無關;他們是MSSQL特定的安全功能。這並不是說他們在其他DBMS中沒有類似功能,只是說它們不是「典型」的UML樣式功能或標準的一部分。

我其實在this reasonably authoritative O'Reilly page關於ANSI標準函數搜索術語「布爾」返回沒有結果。可以從中推斷出,對於這種標量函數的NULL處理沒有ANSI方法。

在這些函數中需要三值邏輯,以允許NULL表示輸入不是有效。例如參考備註部分MSDN IS_MEMBER()

(的返回NULL這種形式是不是如與聚合函數可以返回一個值,或NULL,如果它的一個輸入是NULL混淆)

沒有什麼能阻止你「包裝」的功能像其他人一樣行事,如果那是你真正需要的。例如ISNULL(IS_MEMBER(someValueFromATable),0)

前兩個函數返回一個有意義的布爾值,就像您發現的那樣。

ISDATE(null),例如,因爲空是一個返回false 「有效的日期,時間或日期時間」(MSDN,我強調)。

在NULL被解釋爲意思是「未知」的情況下,如果輸入未知但在編程上不可行,則它對於ISDATE()等在語義上將有意義返回「未知」;當我們對ISNULL()已經有單獨的類型非特定測試時,需要將結果(從所有這些布爾函數)「轉換」爲三態到布爾邏輯。

在比較你已經識別的兩種函數類型的情況下,後者的返回值在這種情況下不應該爲NULL,因爲儘管NULL不是日期,但仍然肯定是有效的可以通過此功能正確檢查的數據。

+0

我希望IS_DATE(null)應該返回NULL。因爲NULL意味着UNKNOWN/MISSING值。而且我們不能假設未知/缺失值肯定不是日期,是的?還有,你的邏輯'select LEN(null)'可能返回0 - 爲什麼它不能假定無效輸入是零長度的字符串? –

+0

這不是_my_邏輯:-)是的,根據數據庫已定義的上下文,NULL可能意味着__或兩者__未知和/或丟失。或者它可能意味着,例如「我們知道沒有一個」,這又不同了。例如,Oracle(直到最近,我認爲)不能存儲一個空字符串,它表示爲NULL(這意味着你必須決定_which_意味着你需要一個NULL字符串,並且圍繞你的設計選擇進行編碼)。如果您希望ISDATE(NULL)返回NULL,那麼使用CASE或IIF返回NULL,如果值爲NULL,則應用該函數。 – Sepster

+0

@ 0x69 PS你剛剛投票給我解釋邏輯如何工作,因爲你希望它的工作方式不同? :-)你問「爲什麼內置的布爾函數在NULL輸入方面表現不同?」我解釋了爲什麼。 – Sepster

相關問題