分割时,SQL REGEXP_SUBSTR返回null String

时间:2015-09-18 16:15:35

标签: sql regex oracle11g delimiter

我按照本文中列出的说明将分隔的字符串拆分为表格的行:

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值的无关行吗?

1 个答案:

答案 0 :(得分:0)

只需使用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

将尝试获得regexp_substr 7次出现,其中4次为NULL,最后4 NULL将被NULL压扁为DISTINCT }}