“以CSV列表中的任何值开头”的条件

时间:2012-09-19 20:00:38

标签: oracle csv plsql oracle10g stringtokenizer

  

可能重复:
  how to convert csv to table in oracle

我在PL / SQL中有一个查询,用于处理变量中的输入作为“启动”过滤器:

WHERE product_group LIKE strProductGroup || '%'

作为新的“功能”,输入变量可以包含逗号分隔值。所以,在我期待像“ART”这样的东西之前,我现在可以看到“ART,DRM”。

如果可能的话,我想避免将此查询构建为字符串并使用EXECUTE IMMEDIATE。任何人都可以想到一种方法来编写一个WHERE条件,相当于在Oracle 10g中说“以CSV列表中的任何值开头”吗?

2 个答案:

答案 0 :(得分:1)

假设您对创建其他几个对象(集合类型和函数)没有任何限制,您可以将列表解析为可在查询中引用的集合。 Tom Kyte在variable "IN" list主题中对此进行了很好的讨论。

如果您使用Tom的myTableTypein_list功能,例如

SQL> create or replace type myTableType as table 
     of varchar2 (255);
  2  /

Type created.


ops$tkyte@dev8i> create or replace 
     function in_list( p_string in varchar2 ) return myTableType
  2  as
  3      l_string        long default p_string || ',';
  4      l_data          myTableType := myTableType();
  5      n               number;
  6  begin
  7    loop
  8        exit when l_string is null;
  9        n := instr( l_string, ',' );
10         l_data.extend;
11         l_data(l_data.count) := 
                 ltrim( rtrim( substr( l_string, 1, n-1 ) ) );
12         l_string := substr( l_string, n+1 );
13    end loop;
14
15    return l_data;
16  end;
17  /

然后你可以相对容易地搜索平等。

WHERE product_group IN (SELECT column_value 
                          FROM TABLE( in_list( strProductGroup )))

但是你想要做一个LIKE这更具挑战性,因为你不能在列表中做LIKE。但是,您可以执行类似

的操作
select *
  from emp e,
       (select '^' || column_value search_regexp
          from table( in_list( 'KIN,BOB' ))) a
 where regexp_like( e.ename, a.search_regexp )

这将在EMP表中搜索ENAMEKINBOB开头的所有员工。在默认的SCOTT.EMP表中,这将只返回一行,即ENAME为“KING”的行

答案 1 :(得分:0)

我发现另一个post给了我一个主意。在我的特定情况下,输入中的值将全部为3个字符,因此我可以执行以下操作:

AND SUBSTR(product_group, 0, 3) IN
    (SELECT regexp_substr(strProductGroup, '[^,]+', 1, LEVEL)
      FROM dual
      CONNECT BY LEVEL <= length(regexp_replace(strProductGroup, '[^,]+')) + 1)

我喜欢这个解决方案,因为它不需要其他类型或功能,但仅限于我的具体情况。