0

好的——所以这有点难以解释......

我需要发回一个 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;
4

0 回答 0