【问题标题】:REPLACE function evaluated within an IN clause does not work in Oracle SQL 11g在 IN 子句中评估的 REPLACE 函数在 Oracle SQL 11g 中不起作用
【发布时间】:2016-03-02 18:07:17
【问题描述】:

我有一个问题,即在 in 子句中评估的替换函数在 Oracle SQL 11g 中不起作用。我需要的是一个基于 SQL 的解决方法,因为我可以控制的只是 SQL。

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

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

事实上,我没有返回任何行。替换在语法上是正确的,并且 基本上这应该解决到

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

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

我怎样才能做到这一点?

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    替换管道仍然会留下一个带有'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' || '|%';
    

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

    【讨论】:

    • 谢谢亚历克斯,但我不确定我是否理解。请问如何将其集成到单个 SQL 语句中?此条件将成为更大的单个查询的一部分。不涉及 PLSQL 或语言。干杯戴夫
    • 抱歉,刚刚看到编辑,将尝试使用 regexp_like
    • 干杯亚历克斯,regexp_like 似乎可以解决问题。非常感谢您的帮助。我会将您的答案标记为正确。干杯,戴夫
    • @MrTea - 第一个选项不涉及 PL/SQL,只是子查询分解(CTE)。您可以使用大型查询来做到这一点,但它可能会造成混淆。第二或第三个选项可能更合适;如果这是一个大查询,请检查两者的性能。
    【解决方案2】:

    我遇到了同样的问题并设法以这种方式解决:

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-20
      • 2011-06-08
      • 1970-01-01
      相关资源
      最近更新 更多