好的——所以这有点难以解释......
我需要发回一个 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 个过滤器的示例,但我的实际查询有更多过滤器组合。因此,如果可能,块的打开光标也应该是动态的。
我创建了一个名为 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;