0

私は Oracle PL/SQL は初めてですが、Sql Server の経験があり、その詳細を学ぼうとしています。入門として、C# 文字列として生成され、テキスト SqlCommand として実行されるクエリを最適化することにしました。そのため、ストアド プロシージャを作成しようとしていますが、where 句を生成する方法のすべてのバリエーションを含めるには、C# で生成された文字列が 3 秒以内に実行されるのに対し、40 秒以内に実行されます。where句のバリエーションで私が意味するものの例を次に示します...

declare  
searchType nvarchar2(3); -- options are 'x', 'y', 'z'  
searchDesc nvarchar2(4); -- options are '1', '2', '3'  
searchValue nvarchar2(5);

begin  

select count(*)  
from tbl_A a
where ((searchType = 'x' 
    and ((a.desc_X = searchDesc and a.value_1 = searchValue)
      or (a.desc_X = searchDesc and a.value_2 = searchValue)
      or (a.desc_X = searchDesc and a.value_3 = searchValue)
    )
  )
  or (searchType = 'y' 
    and ((a.desc_Y = searchDesc and a.value_1 = searchValue)
      or (a.desc_Y = searchDesc and a.value_2 = searchValue)
      or (a.desc_Y = searchDesc and a.value_3 = searchValue)
    )
  )
  or (searchType = 'z' 
    and ((a.desc_Z = searchDesc and a.value_1 = searchValue)
      or (a.desc_Z = searchDesc and a.value_2 = searchValue)
      or (a.desc_Z = searchDesc and a.value_3 = searchValue)
    )
  )
)

end;

だから私が疑問に思っているのは、where句で動的SQLを実行できるselectステートメントを持つことは可能かということです。または、ステートメント全体を動的 SQL にする必要がありますか。以下は、私が質問しているものの例です...

declare
whereClause varchar2(500);  
searchType nvarchar2(3); -- options are 'x', 'y', 'z'  
searchDesc nvarchar2(4); -- options are '1', '2', '3'  
searchValue nvarchar2(5);  

begin

select case
    when searchType = 'x' then 'a.desc_X = :desc and a.value_1 = :val'
    when searchType = 'y' then 'a.desc_Y = :desc and a.value_2 = :val'
    when searchType = 'z' then 'a.desc_Z = :desc and a.value_3 = :val'
    end
into whereClause
from dual;

select count(*)
from tbl_A a
where (
    execute immediately whereClause using searchDesc, searchValue
)

end;

すべての動的SQLとして実行しようとしても、実行に約15秒かかりました。そのため、多くの where 句のバリエーションを処理するより良い方法を誰かが持っている場合は、提案を受け付けています。

4

1 に答える 1

2

そのように使用される OR が多すぎると、パフォーマンスが低下する傾向があります。常に固定のパラメーター セットを使用する場合は、次のようにすることができます。

declare

    stmt varchar2(1500);  
    searchType nvarchar2(3); -- options are 'x', 'y', 'z'  
    searchDesc nvarchar2(4); -- options are '1', '2', '3'  
    searchValue nvarchar2(5);  

    n pls_integer;

begin

    stmt := 'select count(*) from tbl_A a where (';

     case
        when searchType = 'x' then stmt := stmt || 'a.desc_X = :desc and a.value_1 = :val';
        when searchType = 'y' then stmt := stmt || 'a.desc_Y = :desc and a.value_2 = :val';
        when searchType = 'z' then stmt := stmt || 'a.desc_Z = :desc and a.value_3 = :val';
    end case;

    stmt := stmt ||')';


    execute immediately stmt using searchDesc, searchValue
    into n;

end;

T-SQL とは異なり、PL/SQL では結果セットを変数に選択する必要があることに注意してください。サンプル コードは SELECT COUNT(*) であるため、整数を提案しました。実際のクエリには、クエリ プロジェクションに一致する変数 (おそらくレコード タイプまたはコレクション) が必要です。

于 2013-06-18T16:02:35.150 に答える