联盟由subselect产生

时间:2014-12-22 11:51:00

标签: sql oracle11g

我有一个带有以下结构的SQL语句:

f(string parameter)=select * from table(parameter) ...
=> results in some table with rows.

f(字符串参数)用作更复杂的sql子查询的快捷方式。

table parameters:

|---params----|
   param1
   param2
   param3
   ....

如何将f()与表parameters结合使用,其中将为此表中的每个参数调用f()。我的问题涉及SQL语句本身。结果我期待

f(param1)
  union all
f(param2)
  union all
f(param3)
...

如果有人对f()中的住宿感兴趣,请参阅我之前的问题答案 https://stackoverflow.com/a/27599637/2023524

2 个答案:

答案 0 :(得分:1)

您可以将f定义为类似下面的函数

create or replace function f(param IN VARCHAR2) return varchar2 is
  Result varchar2(32767);
begin
  with names as(
    SELECT REGEXP_SUBSTR(regexp_replace(replace(param,
                                                chr(13) || chr(10),
                                                ','),
                                        '[[:space:]]*',
                                        ''),
                         '[^=]+',
                         1,
                         level) as name
      FROM DUAL
    CONNECT BY LEVEL <= (SELECT REGEXP_COUNT(param, '=') FROM DUAL)

     )

      select LISTAGG(nvl(regexp_substr(name, '[^,]+', 1, 2),
                         regexp_substr(name, '[^,]+', 1)),
                     ',') WITHIN
       GROUP(
       ORDER BY name)
        INTO Result
        from names;

  return(Result);
end f;

然后你可以调用你的参数,如下所示

with parameter(param) as (
    select 'aa = black' ||chr(13)||chr(10)||'bb = change'||chr(13)||chr(10)||'mmmm=no'  
    from dual union  all
   select 'aa = black' ||chr(13)||chr(10)||'bb = change'||chr(13)||chr(10)||'kkk=no' from dual
    )
    select distinct regexp_substr(f(param),'[^,]+',1,level) from parameter
    connect by level <=regexp_count(f(param),',')+1;

Update1:​​ - 仅供您参考信息您可以在匿名区块中调用功能,如下所示

DECLARE
  function f(param IN VARCHAR2) return varchar2 is
    Result varchar2(32767);
  begin
    with names as(
      SELECT REGEXP_SUBSTR(regexp_replace(replace(param,
                                                  chr(13) || chr(10),
                                                  ','),
                                          '[[:space:]]*',
                                          ''),
                           '[^=]+',
                           1,
                           level) as name
        FROM DUAL
      CONNECT BY LEVEL <= (SELECT REGEXP_COUNT(param, '=') FROM DUAL)

       )

        select LISTAGG(nvl(regexp_substr(name, '[^,]+', 1, 2),
                           regexp_substr(name, '[^,]+', 1)),
                       ',') WITHIN
         GROUP(
         ORDER BY name)
          INTO Result
          from names;


    return(Result);
  end f;
begin
  for i in 1 .. (regexp_count(f('aa = black' || chr(13) || chr(10) ||
                                'bb = change' || chr(13) || chr(10) ||
                                'kkk=no'),
                              ',') + 1) loop
    dbms_output.put_line(regexp_substr(f('aa = black' || chr(13) ||
                                         chr(10) || 'bb = change' ||
                                         chr(13) || chr(10) || 'kkk=no'),
                                       '[^,]+',
                                       1,
                                       i));
  end loop;
end;

答案 1 :(得分:0)

在Oracle 11g中,我认为您可以在from子句中执行此操作:

with params as (
      select param1 as param from dual union all
      select param2 union all
      select param3
     )
select *
from params p,
     table(f(p.param)) f;