2011-08-16 27 views
2

私は仕事で次のPL/SQLコード(変数が変更された)が発生しました:私は、上記には、次のと同等だと思うリファクタリング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行のクエリであるため、リファクタリングによって読みやすさが向上し、シンプルに保たれる可能性があります。

編集:

ケビン・バートンの答えで問題に対処するために、私は、WHERE条件を更新しました。 a.wあなたはケビン・バートンが言ったように

a.w=NULL 

答えて

1

は、新しいクエリが同じではありません。これは、しかしです:i_wがnullでないときAWのインデックスを使用しますが、それがnullのときに別の何かを行うことができますよう

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; 

しかし、元のコードは、より効率的かもしれ - それが使用されるパラメータにクエリを仕立て屋すなわち。

+0

ありがとうKevin。私は質問を更新しました。 – digdug

6

になります

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

として記録

を選択しませんnullの場合

+0

トニーに感謝します。 NVL()より読みやすくなります。私はチェックし、a.w.に利用可能なインデックスはありません。ですから、後で私たちが疑っている列のインデックスを作成しない限り、それは問題ではありません。 – digdug

+0

@digdug:元のコードでは、バインド変数の覗き見を気にせず、基数推定を95%削減できます。パフォーマンスの問題のほとんどは、おそらくPL/SQLではなくSQLで発生します。この場合、PL/SQLの数行よりもSQLの1行を減らすほうがよいでしょう。動的SQLを使用する方法もあります。 PL/SQLとSQLの両方を簡略化することができますが、非常に注意深く考慮する必要がある他の多くの問題が発生します。 –

+0

@jonearles:ありがとう。 「束縛変数を見て、基数推定を95%削減する」と説明してください。 – digdug