带有可选输入参数的Oracle Dynamic SQL,以#分隔

时间:2012-08-15 04:37:15

标签: sql oracle dynamic

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

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

0 个答案:

没有答案