【问题标题】:regexp_substr for getting correct resultregexp_substr 用于获得正确的结果
【发布时间】:2018-03-17 05:07:12
【问题描述】:

我试图使用 regexp_substr 从列列表字符串中获取每个正确的列名。

查询是这样的:

select regexp_substr(v_keep, '(^|[(,) ]*)' || r.column_name || '($|[(,) ]+)', 1, 1, 'i')
from dual;

但结果不正确。

v_keep 可以是任何列名列表,例如 abc、abc_abc、abc1 或 (abc,abc_abc,abc1)。

r.column_name 可以像 abc 或 ab。

- 如果输入 v_keep 是 (abc, abc_abc, abc1) 并且 r.column_name 是 ab,它将返回 null。

- 如果输入 v_keep 是 (abc, abc_abc, abc1) 并且 r.column_name 是 abc,它只会返回列名 abc。

任何人都可以通过修改 regexp_substr 中的模式来帮助我修复它吗?

【问题讨论】:

    标签: sql regex oracle


    【解决方案1】:

    为什么不直接使用caselike

    select (case when replace(replace(v_keep, '(', ','), '(', ',')) like '%,' || r.column_name || ',%'
                 then r.column_name
            end)
    

    我不建议将列表存储在逗号分隔的字符串中,但如果是,这是识别列表中各个元素的一种方法。

    【讨论】:

    • 因为这个查询是 if 条件下代码的一部分,我是 oracle 新手,我不知道如何在该代码中实现 case。
    • @infi999 。 . .我不明白你的意思。问题中的代码在select
    【解决方案2】:

    这很简单,你只需要添加一个子表达式,你就可以拉出你想要的字符串部分。 (子表达式是括号中的正则表达式的一部分。)在这种情况下,最后一个参数是 2,因为您需要与第二组括号相对应的匹配部分。

    regexp_substr(v_keep, '(^|[(,) ]*)(' || r.column_name || ')($|[(,) ]+)', 1, 1, 'i', 2)
    

    不过,Gordon 的解决方案会有更好的性能。

    编辑:工作示例 -

    with testdata as (select '(abc, abc_abc, abc1)' as v_keep, 'abc' as column_name from dual)
    select regexp_substr(v_keep, '(^|[(,) ]*)(' || r.column_name || ')($|[(,) ]+)', 1, 1, 'i', 2)
    from testdata r;
    

    【讨论】:

    • 我有这样做的想法。我尝试将括号和空格替换为逗号,然后使用 instr(v_keep1, ',' || r.column_name || ',') > 0 检查当前名称是否在列表中。这种性能应该比使用正则表达式更好。不过还是谢谢大家!
    【解决方案3】:

    由于这是 PL/SQL 代码来查看值是否在字符串中,因此请尝试这样做,以避免访问数据库和调用 REGEXP 的开销。只需保持 SQL 即可。我讨厌嵌套的 REPLACE 调用,但我试图避免使用 REGEXP_REPLACE,尽管如果你确实使用它可以在一次调用中完成。

    set serveroutput on;
    set feedback off;
    
    declare 
      v_keep  varchar2(50) := '(abc, abc_abc, abc1)';
      compare varchar2(10) := 'abc_';
    begin
      if instr(',' || replace(replace(replace(v_keep, ' '), '('), ')') || ',', ',' || compare || ',') > 0 then
        dbms_output.put_line('Column ''' || compare ||''' IS in the keep list');
      else
        dbms_output.put_line('Column ''' || compare ||''' IS NOT in the keep list');
      end if;  
    end;
    

    【讨论】:

      猜你喜欢
      • 2020-11-09
      • 2021-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多