0

OK -- これは説明するのが少し難しいです....

refcursor を送り返す必要があります

select ステートメントには、それぞれに複数の値を持つことができるパラメーターが必要であり、オプションにすることもできます。

たとえば、次のようなステートメント:

select * from Table A where Column1 in ('A', 'B', 'C') and column2 in ('3', '4', '5');

ただし、Column1 のフィルターの値は「A#B#C」のように入力パラメーターとして渡され、Column2 のフィルターの値は「3#4#5」のように入力パラメーターとして渡されます。

また、入力パラメーターが NULL の場合、そのフィルターを where 句に追加したくありません。

私のSPはそのように書かれています

PROCEDURE GET_RECS (
    p_users IN VARCHAR2,
 p_clients IN VARCHAR2
, p_CURSOR OUT SYS_REFCURSOR)

IS
v_sql varchar2(4000);
    v_crlf char(2) := chr(13) || chr(10);

begin
v_sql := 'select A.col1, A.col2 from table1 A where 1 = 1 ' || v_crlf;
if p_users is not null then
v_sql := v_SQL || ' and a.user in (SELECT * FROM TABLE ( CAST (str2tbl (:p_users ) AS     TableType) )) ' || v_crlf;
end if;
if p_clients is not null then
v_sql := v_SQL || ' and a.client in (SELECT * FROM TABLE ( CAST (str2tbl (:p_clients ) AS TableType) )) ' || v_crlf;
 end if;

if p_users is not null then
OPEN p_cursor FOR v_sql using p_users ;
 end if;
if p_clients is not null then
OPEN p_cursor FOR v_sql using p_clients ;
 end if;

end;

また、どちらのパラメーターも送信されないこと、または両方のパラメーターが送信されることを考慮していないため、「Open cursor for」ブロックで上記のコードが正しくないこともわかっています。

上記は 2 つのフィルターを使用したサンプルですが、実際のクエリにはさらに多くのフィルターの組み合わせがあります。したがって、可能であれば、ブロックの Open Cursor も動的にする必要があります。

「3#4#5」をテーブルに簡単に変換する str2tbl という関数を作成しました。そのためのコードは次のとおりです。

CREATE OR REPLACE function str2tbl
 (p_str   in varchar2,
  p_delim in varchar2 default '#')
 return      TableType
 as
 l_str      long default p_str || p_delim;
 l_n        number;
 l_data     TableType := TableType();
 begin
 loop
     l_n := instr( l_str, p_delim );
     exit when (nvl(l_n,0) = 0);
     l_data.extend;
     l_data( l_data.count ) := ltrim(rtrim(substr(l_str,1,l_n-1)));
     l_str := substr( l_str, l_n+length(p_delim) );
 end loop;
 return l_data;
 end;
4

0 に答える 0