大家都知道的区别:
NVL | Oracle 专属 | 只支持两个参数 |
COALESCE | SQL 标准 | 支持多个参数 |
但是今天偶然间还发现一个重要差别:滥用 NVL 可能导致额外的计算
NVL | 无论前面的参数是否为 NULL 均会计算所有参数 |
COALESCE | 如果遇到一个不为 NULL 的参数,则不计算后面的 |
以 PL/SQL 为例,NVL 的表现就如同一般的函数,但 COALESCE 更像是一个语句,可以成功避免进行耗时的运算;
SQL 中可能也是如此,欢迎读者自行验证并在评论区讨论!
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;
来源:oschina
链接:https://my.oschina.net/u/3320818/blog/4339169