2012-09-13 155 views
1

我在Oracle數據庫中調試某個過程時,遇到了令我感到意外的有關NULL值的問題。任何人都可以解釋爲什麼下面的查詢在這裏爲非等式檢查返回false?爲什麼null <>「something」返回false

DECLARE 
    vNullVariable VARCHAR2(2) := NULL; 
    vVariable VARCHAR2(2) := 'Hi'; 
BEGIN 
    IF vNullVariable <> vVariable THEN 
     dbms_output.put_line('The variables are not equal'); 
    ELSE 
     dbms_output.put_line('The variables are equal'); 
    END IF; 
END; 

回答

8

這是因爲使用了SQL三值邏輯(3VL):有TRUE,這裏FALSE並且存在NULL(未知,不真不僞)。

表達式vNullVariable <> vVariable的結果在3VL中爲NULL,而不是TRUE,因爲它認爲vNullVariable的值未知:如果在以後它變成已知值,則可能是'Hi',或者它可能不是,但是現在SQL不知道,所以它返回NULL(未知)。

所以IF表達式計算爲NULL,不正確的,所以默認ELSE路徑改爲使用 - 因爲邏輯如果IF是:

IF <expression is true> THEN 
    ... 
ELSE -- ie. if expression is FALSE or NULL 
    ... 
END IF; 

這意味着你獲得的行爲,你期待您是否以其他方式編寫了支票:

IF vNullVariable = vVariable THEN 
    dbms_output.put_line('The variables are equal'); 
ELSE 
    dbms_output.put_line('The variables are not equal'); 
END IF; 
+0

是否有這個工作的標準方法?我並不總是期望值爲NULL,但是我希望執行IF塊中的代碼。 我唯一能想到的就是添加類似(vNullVariable IS NULL和vVariable IS NOT NULL)和(.reverse。)AND(<>)。 –

+0

您可以這樣做,或者在我的更新中執行= check而不是<>檢查。 –

+0

非常感謝! –

2

NULL在Oracle上有奇怪的行爲。與空比較的東西,是更好地使用IS NULL而不是 '= NULL'

Here您對

在代碼中一個很好的解釋,你可以使用

IF vVariable IS NOT NULL THEN 
1

在Oracle中, NULL既不等於也不等於NULL。評估兩個NULL的比較條件始終爲FALSE。涉及NULL的以下條件將是有效的。

1. IF vNullVariable is NULL THEN 
2. IF vNullVariable is not NULL THEN 
3. IF NVL(vNullVariable, -1) <> NVL(vVariable, -1) THEN - 
    This condition will give you expected result even if both vNullVariabl 
    and vVariable are NULLs 
4. Oracle considers two nulls to be equal when evaluating a DECODE function 

例如下面的查詢會給你1,如果DECODE功能的第一和第二個參數是NULLs

select decode(null, null, 1) res 
     from dual; 

res 
------- 
    1 
相關問題