你們都知道的區別:函數
NVL | Oracle 專屬 | 只支持兩個參數 |
COALESCE | SQL 標準 | 支持多個參數 |
可是今天偶然間還發現一個重要差異:濫用 NVL 可能致使額外的計算spa
NVL | 不管前面的參數是否爲 NULL 均會計算全部參數 |
COALESCE | 若是遇到一個不爲 NULL 的參數,則不計算後面的 |
以 PL/SQL 爲例,NVL 的表現就如同通常的函數,但 COALESCE 更像是一個語句,能夠成功避免進行耗時的運算;ci
SQL 中可能也是如此,歡迎讀者自行驗證並在評論區討論!it
DECLARE
l_n VARCHAR2(4000) := 'x';
l_s VARCHAR2(4000) := 'x';
FUNCTION Expensive_Function RETURN VARCHAR2 IS
BEGIN
Dbms_Output.Put_Line('Expensive_Function !!!');
RETURN 'x';
END Expensive_Function;
FUNCTION Common_Function(p_S1 IN VARCHAR2, p_S2 IN VARCHAR2)
RETURN VARCHAR2 IS
BEGIN
RETURN 'x';
END Common_Function;
PROCEDURE Common_Procedure(p_S1 IN VARCHAR2, p_S2 IN VARCHAR2) IS
BEGIN
RETURN;
END Common_Procedure;
BEGIN
Dbms_Output.Put_Line('Function');
l_s := Common_Function(l_n, Expensive_Function);
Dbms_Output.Put_Line('Procedure');
Common_Procedure(l_n, Expensive_Function);
Dbms_Output.Put_Line('Nvl');
l_s := Nvl(l_n, Expensive_Function); -- Nvl就像普通的函數同樣,要先計算參數
Dbms_Output.Put_Line('Coalesce');
l_s := Coalesce(l_n, Expensive_Function); -- 很是特殊的函數,行爲相似於 IF-ELSE CASE AND OR 不會進行多餘的計算
Dbms_Output.Put_Line('CASE');
l_s := CASE l_s
WHEN 'x' THEN
'xxx'
WHEN Expensive_Function THEN
'yyy'
ELSE
Expensive_Function
END;
Dbms_Output.Put_Line('AND');
IF NOT (l_n IS NULL AND Expensive_Function IS NULL) THEN
NULL;
END IF;
Dbms_Output.Put_Line('OR');
IF l_n IS NOT NULL OR Expensive_Function IS NOT NULL THEN
NULL;
END IF;
END;io