在IN子句中评估的REPLACE函数在Oracle SQL 11g中不起作用

时间:2016-03-02 18:07:18

标签: sql oracle

我遇到一个问题,在in子句中评估的替换函数在Oracle SQL 11g中不起作用。我需要的是一个基于SQL的工作,因为我可以控制的是SQL。

我收到一个由管道分隔的值列表,例如STR1|STR2。要将它们转换为要查询的值列表,我使用replace替换如下,并且应该得到1的查询结果。

select 1 from dual where 'STR1' in (replace('''STR1|STR2''','|',''','''))

实际上我没有返回任何行。替换是语法上的错误和 基本上这应该解决到

select 1 from dual where 'STR1' in ('STR1','STR2')

哪会得到我想要的结果;但它不适用于替换。

我该如何做到这一点?

2 个答案:

答案 0 :(得分:4)

更换管道仍然会为您留下一个带有'STR1','STR2'的字符串文字,而不是两个单独的列表元素。替换只是在IN子句或其他任何地方做你想做的事。 IN仍然只看到一个字符串值,并且与搜索字符串不匹配。

你可以标记你的分隔字符串;这是一种常用的方法:

with t as (
  select regexp_substr('STR1|STR2', '[^|]+', level) as str
  from dual
  connect by regexp_substr('STR1|STR2', '[^|]+', level) is not null
)
select 1 from dual where 'STR1' in (select str from t)

CTE将两个列表元素作为单独的行,然后您可以使用子查询来查看您的值是否在该列表中。

或者更简单地使用regexp_like在分隔符之间查找您的值,允许它在开头或结尾:

select 1 from dual where regexp_like('STR1|STR2', '(^|)' || 'STR1' || '(|$)');

或者没有正则表达式,如果将值包装在分隔符中:

select 1 from dual where '|' || 'STR1|STR2' || '|' like '%|' || 'STR1' || '|%';

您不需要使用固定值进行所有连接,但我认为您实际上从其他位置获取了两个字符串,这可能会使它更清晰地构建比较。 (虽然管道分隔符使它看起来更加混乱......)

答案 1 :(得分:0)

我遇到了同样的问题,并设法以这种方式工作:

SELECT 1 from dual
where 'str1' in (select distinct a.name from 
    (select  trim(substr( the_string 
         , decode( level, 1, 1, instr(the_string,',',1,level-1)+1) 
         , decode( instr(the_string,',',1,level), 0, length(the_string), instr(the_string,',',1,level) - decode( level, 1, 0, instr(the_string,',',1,level-1))-1) 
         )) name
from ( select replace('str1|str2','|',',') the_string , 
     replace('str1|srt2','|',',') the_string1 
     FROM dual ) 
     connect by level <= length(the_string)-length(replace(the_string,','))+1) a)