我在PL / SQL中有一个查询,用于处理变量中的输入作为“启动”过滤器:
WHERE product_group LIKE strProductGroup || '%'
作为新的“功能”,输入变量可以包含逗号分隔值。所以,在我期待像“ART”这样的东西之前,我现在可以看到“ART,DRM”。
如果可能的话,我想避免将此查询构建为字符串并使用EXECUTE IMMEDIATE。任何人都可以想到一种方法来编写一个WHERE条件,相当于在Oracle 10g中说“以CSV列表中的任何值开头”吗?
答案 0 :(得分:1)
假设您对创建其他几个对象(集合类型和函数)没有任何限制,您可以将列表解析为可在查询中引用的集合。 Tom Kyte在variable "IN" list主题中对此进行了很好的讨论。
如果您使用Tom的myTableType
和in_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
表中搜索ENAME
以KIN
或BOB
开头的所有员工。在默认的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)
我喜欢这个解决方案,因为它不需要其他类型或功能,但仅限于我的具体情况。