重构PL / SQL

时间:2011-08-16 09:14:43

标签: oracle plsql refactoring

我在工作中遇到了以下PL / SQL代码(已修改变量):

PROCEDURE test(i_w IN a.w%type,o_result IN OUT resu_cur_type) IS
BEGIN
    IF i_w IS NULL THEN
      open o_result for SELECT a.x, b.y FROM a,b WHERE a.z=b.z;
    ELSE
      open o_result for SELECT a.x, b.y FROM a,b WHERE a.z=b.z AND a.w=i_w;
    END IF;
END test;

我认为以上内容相当于以下内容:

PROCEDURE test(i_w IN a.w%type,o_result IN OUT resu_cur_type) IS
BEGIN
      open o_result for SELECT a.x, b.y FROM a,b WHERE a.z=b.z AND NVL(a.w,1)=NVL(NVL(i_w,a.w),1);
END test;

不一样吗?有人可以解释是否有任何理由使用 原版? 请注意,原始光标是一个50行查询,因此重构可能会提高其可读性并保持简单。

编辑:

为了解决Kevin Burton的答案中的问题,我更新了WHERE条件。

2 个答案:

答案 0 :(得分:6)

正如Kevin Burton所说,你的新查询并不等同。这是:

PROCEDURE test(i_w IN a.w%type,o_result IN OUT resu_cur_type) IS
BEGIN
      open o_result for SELECT a.x, b.y FROM a,b
                        WHERE a.z=b.z 
                        AND (i_w IS NULL OR a.w=i_w);
END test;

然而,原始代码可能更有效,因为当i_w不为null时可以在a.w上使用索引但是当它为null时执行不同的操作 - 即它将查询定制为所使用的参数。

答案 1 :(得分:1)

如果a.w为null,则不会选择记录

作为

a.w=NVL(i_w,a.w); 

将是

a.w=NULL