sql >> データベース >  >> RDS >> Oracle

'where value in ...'句でパラメータを使用する方法は?

    動的SQLの使用は、コーディングの観点から最も単純なアプローチです。ただし、動的SQLの問題は、クエリのすべての個別のバージョンをハード解析する必要があることです。これは、CPUに負担をかける可能性があるだけでなく、共有プールを共有できないSQLステートメントでいっぱいにしてプッシュする可能性があります。キャッシュしたいステートメントを出力すると、よりハードな解析と共有プールの断片化エラーが発生します。これを1日1回実行している場合、それはおそらく大きな問題ではありません。何百人もの人々が1日に何千回もそれを実行している場合、それはおそらく大きな懸念事項です。

    動的SQLアプローチの例

    SQL> ed
    Wrote file afiedt.buf
    
      1  declare
      2    l_deptnos  varchar2(100) := '10,20';
      3    l_rc       sys_refcursor;
      4    l_dept_rec dept%rowtype;
      5  begin
      6    open l_rc for 'select * from dept where deptno in (' || l_deptnos || ')';
      7    loop
      8      fetch l_rc into l_dept_rec;
      9      exit when l_rc%notfound;
     10      dbms_output.put_line( l_dept_rec.dname );
     11    end loop;
     12    close l_rc;
     13* end;
    SQL> /
    ACCOUNTING
    RESEARCH
    
    PL/SQL procedure successfully completed.
    

    または、コレクションを使用することもできます。これには、単一の共有可能なカーソルを生成するという利点があるため、共有プールのハードな解析やフラッディングについて心配する必要はありません。しかし、おそらくもう少しコードが必要です。コレクションを処理する最も簡単な方法

    SQL> ed
    Wrote file afiedt.buf
    
      1  declare
      2    l_deptnos  tbl_deptnos := tbl_deptnos(10,20);
      3  begin
      4    for i in (select *
      5                from dept
      6               where deptno in (select column_value
      7                                  from table(l_deptnos)))
      8    loop
      9      dbms_output.put_line( i.dname );
     10    end loop;
     11* end;
    SQL> /
    ACCOUNTING
    RESEARCH
    
    PL/SQL procedure successfully completed.
    

    一方、実際に値のコンマ区切りリストから開始する必要がある場合は、使用する前にその文字列を解析してコレクションにする必要があります。区切られた文字列を解析するにはさまざまな方法があります。私の個人的なお気に入りは、階層クエリで正規表現を使用することですが、手続き型のアプローチを作成することもできます。

    SQL> ed
    Wrote file afiedt.buf
    
      1  declare
      2    l_deptnos     tbl_deptnos;
      3    l_deptno_str  varchar2(100) := '10,20';
      4  begin
      5    select regexp_substr(l_deptno_str, '[^,]+', 1, LEVEL)
      6      bulk collect into l_deptnos
      7      from dual
      8   connect by level <= length(replace (l_deptno_str, ',', NULL));
      9    for i in (select *
     10                from dept
     11               where deptno in (select column_value
     12                                  from table(l_deptnos)))
     13    loop
     14      dbms_output.put_line( i.dname );
     15    end loop;
     16* end;
     17  /
    ACCOUNTING
    RESEARCH
    
    PL/SQL procedure successfully completed.
    


    1. 連想テーブルを使用するよりも、フラグをビットマスクとして保存する方がよいのはいつですか。

    2. OracleSQLでデュアルから10,000の一意のIDのリストを選択する方法

    3. MySQLで日付で注文する方法

    4. IRIソフトウェアをOracleに接続する