好的 - 所以这有点难以解释....
我需要发回一个refcursor
select语句需要的参数可以在每个参数中包含多个值,也可以是可选的。
所以例如声明如下:
从表A中选择*,其中Column1位于('A','B','C'),而column2位于('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;
我也知道上面的代码在“打开游标”块中是不正确的,因为它没有考虑到既没有发送参数,也没有发送两个参数。
以上是一个包含2个过滤器的示例,但我的实际查询有更多过滤器组合。因此,如果可能,块的Open Cursor也应该是动态的。
我创建了一个名为str2tbl的函数,它可以轻松地将'3#4#5'转换为表格。代码如下:
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;