这些片段是等价的吗? (NVL与例外)

时间:2012-10-11 12:59:30

标签: exception-handling plsql nvl no-data

我怀疑在没有找到数据时管理基于sql语句的变量赋值的情况。首先,这些块是等价的吗?如果这是真的,那两个中哪一个更好?

declare
nonsense number;
begin
  select nvl((select 1 from dual where 1 <> 1),2) into nonsense from dual;
  dbms_output.put_line(nonsense);
end;

declare
nonsense number;
begin
  begin
  select 1 into nonsense from dual where 1<>1;
  exception when no_data_found then
    nonsense := 2;
  end;
  dbms_output.put_line(nonsense);
end;

2 个答案:

答案 0 :(得分:2)

简短回答是,回答很长,在这种情况下nvl更快,如果找不到结果值就在de select里面,在异常中它首先执行select和AFTER它调用异常的过程。在这种情况下,nvl更好,因为你有一个固定的值。

如果您有“其他”,请务必选择nvl。

答案 1 :(得分:1)

两个块都输出2,因此两者都是“等效”。我认为第二种形式更标准,更容易阅读。

比较两个函数:

FUNCTION getSal (p_id NUMBER) RETURN NUMBER
IS
   l_return NUMER;
BEGIN
   SELECT sal INTO l_return FROM emp WHERE id = p_id;
   RETURN l_return;
EXCEPTION
   WHEN NO_DATA_FOUND
      THEN RETURN 0;
END;

FUNCTION getSal (p_id NUMBER) RETURN NUMBER
IS
   l_return NUMER;
BEGIN
   SELECT NVL((SELECT sal INTO l_return FROM emp WHERE id = p_id), 
              0)
     INTO l_return
     FROM DUAL;
   RETURN l_return;
END;

虽然第一行有更多行,但更容易理解,如果找不到雇员,将返回0。第二个需要花费更多时间来理解,因此会更加混乱。

我肯定会选择第一个,因为它们的性能相同,可读性等于可维护性,因此非常重要。

另请注意,我的两个街区并不完全等同。如果员工的工资为NULL,我的第一个查询将返回NULL,而我的第二个查询将返回0.