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

在IN子句中计算的REPLACE函数在Oracle SQL 11g中不起作用,sql,oracle,Sql,Oracle,我有一个问题,在in子句中计算的替换函数在Oracle SQL 11g中不起作用。我需要的是一个基于SQL的解决方案,因为我所能控制的只是SQL 我收到一个以管道分隔的值列表,例如STR1 | STR2。要将它们转换为要查询的值列表,我使用replace,如下所示,该查询的结果应为1 select 1 from dual where 'STR1' in (replace('''STR1|STR2''','|',''',''')) 事实上,我没有得到返回的行。替换在语法上是正确的,并且 本质上,

我有一个问题,在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')
这将得到我想要的结果;但它不适用于替换


我如何才能做到这一点?

替换管道仍然会留下一个带有“STR1”、“STR2”的字符串文字,而不是两个单独的列表元素。Replace只是在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_查找分隔符之间的值,允许它位于开始或结束处:

select 1 from dual where regexp_like('STR1|STR2', '(^|)' || 'STR1' || '(|$)');
或不带正则表达式,如果将值包装为分隔符:

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

您不需要所有固定值的连接,但我假设您实际上是从其他地方获取这两个字符串,这可能会更清楚它是如何构造比较的。虽然管道分隔符也会让它看起来更混乱…

替换管道仍然会留下一个带有“STR1”、“STR2”的字符串文字,而不是两个单独的列表元素。Replace只是在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_查找分隔符之间的值,允许它位于开始或结束处:

select 1 from dual where regexp_like('STR1|STR2', '(^|)' || 'STR1' || '(|$)');
或不带正则表达式,如果将值包装为分隔符:

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

您不需要所有固定值的连接,但我假设您实际上是从其他地方获取这两个字符串,这可能会更清楚它是如何构造比较的。虽然管道分隔符也让它看起来更混乱…

我也面临同样的问题,并设法以这种方式解决:

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)

我也面临同样的问题,并设法以这种方式解决:

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)

谢谢Alex,不过我不太明白。请问,如何将其集成到单个SQL语句中?此条件将是更大的单个查询的一部分。没有PLSQL或语言参与。干杯DaveSorry,刚刚看到编辑,将有一个与regexp_喜欢的人Alex,regexp_喜欢似乎做的把戏。非常感谢你的帮助。我会认为你的答案是正确的。干杯Dave@MrTea-第一个选项中没有涉及PL/SQL,只是子查询分解CTE。您可以通过一个大型查询来实现这一点,但这可能会让人感到困惑。第二种或第三种选择可能更合适;如果这是一个大问题,请检查两个问题的性能。谢谢Alex,但我不确定我是否理解这一点。请问,如何将其集成到单个SQL语句中?此条件将是更大的单个查询的一部分。没有PLSQL或语言参与。干杯DaveSorry,刚刚看到编辑,将有一个与regexp_喜欢的人Alex,regexp_喜欢似乎做的把戏。非常感谢你的帮助。我会认为你的答案是正确的。干杯Dave@MrTea-第一个选项中没有涉及PL/SQL,只是子查询分解CTE。您可以通过一个大型查询来实现这一点,但这可能会让人感到困惑。第二种或第三种选择可能更合适;如果是一个大的查询,请检查这两个查询的性能。