方法一
今天想在預存程序比較兩個字元,但發現沒有得到預期的結果,最主要是一個問題:任何值和null比較得到的結果都是null,在網上找到了兩種方法,供大家參考一下
在ORACLE中,將Null 字元串視為NULL,任何值與NULL比較結果都為NULL。如此一來,在比較兩個字串的時候就會出現意外。請看以下的例子:
DECLARE
i VARCHAR2(10) := NULL;
v VARCHAR2(10) := 'ABC';
BEGIN
IF(i = v) THEN
DBMS_OUTPUT.PUT_LINE('相等');
ELSE
DBMS_OUTPUT.PUT_LINE('不等');
END IF;
END;
請你用你聰明的頭腦判斷一下,結果應該是什嗎?很容易就可以得出結果:'不等'。很好,你是對的。在SQLPLUS上啟動並執行結果和你想的一樣。那麼我改一下程式,你再判斷一下:
DECLARE
i VARCHAR2(10) := NULL;
v VARCHAR2(10) := 'ABC';
BEGIN
IF(i <> v) THEN
DBMS_OUTPUT.PUT_LINE('不等');
ELSE
DBMS_OUTPUT.PUT_LINE('相等');
END IF;
END;
看上去和第一個程式沒有太大的差別,很容易就得出結果:'不等'。呵呵。你確定結果就是這個嗎?那麼請你在SQLPLUS測試一下,來驗證你是正確的。很可惜,正確的結果應該是:'相等'。是不是很詫異?正如開始所說的:任何值與NULL比較結果都為NULL。即在第一個程式中的i=v比較的結果應該是NULL,而第二個程式中的i<>v比較的結果也是NULL。當IF結構中的條件為NULL時,將跳過當前的分支進入到ELSE或者是結束。不行嗎?那你運行一下以下的程式將可以等到驗證:
BEGIN
IF(NULL) THEN
DBMS_OUTPUT.PUT_LINE('NOT NULL');
ELSE
DBMS_OUTPUT.PUT_LINE('NULL');
END IF;
END;
結果輸出的是:'NULL'。
那麼應該怎樣正確的比較兩個字串呢?
首先我先說說如何確定兩個字串相等(還是用上邊的兩個變數i和v)。
1、當i和v都為NULL的時候,認為i和v相等。i IS NULL AND v IS NULL(不要寫成這樣:i = v。從上邊的分析我們可以知道這樣寫的結果為NULL)。
2、當i和v中只有一個為NULL,肯定不相等。
3、當i和v都不為NULL的時候,我們就可以用‘=’號來判斷它們是否相等。i IS NOT NULL AND v IS NOT NULL AND i = v。
根據以上三點,我們可以得出判斷i和v相等的條件運算式:i IS NULL AND v IS NULL OR i IS NOT NULL AND v IS NOT NULL AND i = v。
那麼兩個字串不相等的條件運算式只需要判斷相等的運算式為FALSE就可以了。
把判斷兩個字串是否相等的功能寫成函數:
CREATE OR REPLACE FUNCTION ISEQUAL
(
VAR1 IN VARCHAR2,
VAR2 IN VARCHAR2
)
RETURN NUMBER -- 0:不等 1:相等 -1:錯誤
IS
IF(VAR1 IS NULL AND VAR2 IS NULL OR VAR1 IS NOT NULL AND VAR2 IS NOT NULL AND VAR1 = VAR2) THEN
RETURN 1;
ELSE
RETURN 0;
ENF IF;
BEGIN
EXCEPTION
WHEN OTHERS THEN
RETURN -1;
END;
以下上測試程式:
DECLARE
VAR1 VARCHAR2(10) := NULL;
VAR2 VARCHAR2(10) := 'A';
BEGIN
IF(isequal(VAR1, VAR2) = 1) THEN
DBMS_OUTPUT.PUT_LINE('=');
ELSE
DBMS_OUTPUT.PUT_LINE('<>');
END IF;
END ;
摘自:http://www.mscto.com/Oracle/301028605.html
方法二、
另外一種方法是使用nvl方法,使用方法如下:
nvl(var1,'')!=nvl(var2,'') ,這樣就比較var1和var2字元是否不等,方法是如果var1為null的話,就轉化為""Null 字元,不為空白就還是原來的值,不過我個人測過,轉化為空白字元來比較兩個字元也出現問題,Oracle把Null 字元串認為是NUL,結果還是和null一樣的結果,所以我個人建議如果字元為null的話,就將他轉換為一個"唯一"的字元,下面是我個人對兩個字元做的比較,供大家參考
pre_remark VARCHAR2(10) := NULL;
remarks VARCHAR2(10) := 'A';
if nvl(pre_remark,'@#$%^&')!=nvl(remarks,'@#$%^&') then
DBMS_OUTPUT.PUT_LINE('true');
else
DBMS_OUTPUT.PUT_LINE('false');
end if;
返回的結果是:true