您现在的位置是:首页 > 文章详情

NVL 与 COALESCE 不为人知的区别

日期:2020-07-07点击:360

大家都知道的区别:

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;

原文链接:https://my.oschina.net/u/3320818/blog/4339169
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章