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;