1

可能重复:
如何将 csv 转换为 oracle 中的表

我在 PL/SQL 中有一个查询,该查询旨在将变量中的输入作为“starts-with”过滤器处理:

WHERE product_group LIKE strProductGroup || '%'

作为一个新的“特征”,输入变量可以包含逗号分隔的值。所以,在我期待“ART”之类的东西之前,我现在可以看到“ART,DRM”。

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

4

2 回答 2

1

假设您对创建几个附加对象(集合类型和函数)没有任何限制,您可以将列表解析为可以在查询中引用的集合。Tom Kyte 在他的变量“IN”列表线程中对此进行了很好的讨论。

例如,如果您使用 Tom's myTableTypeandin_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的任何员工。在默认表中,这将只返回一行,即“KING”所在的行ENAMEKINBOBSCOTT.EMPENAME

于 2012-09-19T20:30:40.303 回答
0

我发现另一个帖子给了我一个想法。在我的具体情况下,输入中的值都是 3 个字符,所以我可以执行以下操作:

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

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

于 2012-09-19T20:35:23.443 回答