【问题标题】:SQL REGEXP_SUBSTR returns null String when splittingSQL REGEXP_SUBSTR 拆分时返回空字符串
【发布时间】:2015-09-18 16:15:34
【问题描述】:

我按照这篇文章中概述的说明将分隔字符串拆分为表格的行:

Splitting string into multiple rows in Oracle

适用于该特定分隔字符串的答案在此小提琴中表示:

Demo1

with temp as
(
    select 108 Name, 'test' Project, 'Err1, Err2, Err3' Error  from dual
    union all
    select 109, 'test2', 'Err1' from dual
)
select distinct
  t.name, t.project,
  trim(regexp_substr(t.error, '[^,]+', 1, levels.column_value))  as error
from 
  temp t,
  table(cast(multiset(select level from dual connect by  level <= length (
        regexp_replace(t.error, '[^,]+'))  + 1) as sys.OdciNumberList)) levels
order by name;

不幸的是,我的字符串不是逗号分隔的。它由子字符串 ':::' 分隔。我试图通过在以下小提琴中编写 SQL 来改变答案以适应我的情况:

Demo2

with temp as
(
    select 108 Name, 'test' Project, 'Err1:::Err2:::Err3' Error  from dual
    union all
    select 109, 'test2', 'Err1' from dual
)
select distinct
  t.name, t.project,
  trim(regexp_substr(t.error, '[^:::]+', 1, levels.column_value))  as error
from 
  temp t,
  table(cast(multiset(select level from dual connect by  level <= length (
        regexp_replace(t.error, '[^:::]+'))  + 1) as sys.OdciNumberList)) levels
order by name

如您所见,我将测试字符串更改为由 ':::' 分隔并更改正则表达式以匹配,但查询生成了一个无关行,其中返回的子字符串为 Null 值。

谁能帮我理解为什么我所做的更改会产生带有 Null 值的无关行?

【问题讨论】:

    标签: sql regex oracle11g delimiter


    【解决方案1】:

    只需使用REPLACE, 的标准代码

    SqlFiddleDemo

     with temp as
    (
        select 108 Name, 'test' Project, 'Err1:::Err2:::Err3' Error  from dual
        union all
        select 109, 'test2', 'Err1' from dual
    )
    select distinct
      t.name, t.project,
      trim(regexp_substr(REPLACE(t.error, ':::', ', '), '[^,]+', 1, levels.column_value))  as error
    from 
      temp t,
      table(cast(multiset(select level from dual connect by  level <= length (regexp_replace(REPLACE(t.error, ':::', ', '), '[^,]+'))  + 1) as sys.OdciNumberList)) levels
    order by name
    

    或者你需要除以分隔符的长度:

    SqlFiddle

    with temp as
    (
        select 108 Name, 'test' Project, 'Err1:::Err2:::Err3' Error  from dual
        union all
        select 109, 'test2', 'Err1:::Err2' from dual
    )
    select distinct
      t.name, t.project,
      trim(regexp_substr(t.error, '[^:::]+', 1, levels.column_value))  as error
    from 
      temp t,
      table(cast(multiset(select level from dual connect by  level <= length (
           regexp_replace(t.error, '[^:::]+'))/3  + 1) as sys.OdciNumberList)) levels
    order by name
    

    你可以看到为什么执行:

    SELECT length (regexp_replace('Err1:::Err2:::Err3', '[^:::]+')) + 1 AS l
    FROM dual
    

    这将返回 7 和你的:

    SELECT DISTINCT  t.name, t.project,
    trim(regexp_substr(t.error, '[^:::]+', 1, levels.column_value))  as error
    

    将尝试在 7 次出现时获取 regexp_substr,其中 4 次为 NULL,最后 4 次 NULL 将被 DISTINCT 压缩为 1 次 NULL

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      • 2013-07-13
      • 2022-11-24
      • 2015-10-17
      • 2013-09-01
      相关资源
      最近更新 更多