NVL与COALESCE不为人知的区别

database

大家都知道的区别:

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 RETURNVARCHAR2IS
  BEGIN
    Dbms_Output.Put_Line("Expensive_Function !!!");
    RETURN"x";
  END Expensive_Function;
  FUNCTION Common_Function(p_S1 INVARCHAR2, p_S2 INVARCHAR2)
    RETURNVARCHAR2IS
  BEGIN
    RETURN"x";
  END Common_Function;
  PROCEDURE Common_Procedure(p_S1 INVARCHAR2, p_S2 INVARCHAR2)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");
  IFNOT(l_n ISNULLAND Expensive_Function ISNULL)THEN
    NULL;
  ENDIF;
  Dbms_Output.Put_Line("OR");
  IF l_n ISNOTNULLOR Expensive_Function ISNOTNULLTHEN
    NULL;
  ENDIF;
END;

以上是 NVL与COALESCE不为人知的区别 的全部内容, 来源链接: utcz.com/z/534494.html

回到顶部