我遇到一个问题,在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')
哪会得到我想要的结果;但它不适用于替换。
我该如何做到这一点?
答案 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)