Oracle REGEXP捕获由一组分隔符分隔的值

Oracle REGEXP捕获由一组分隔符分隔的值,oracle,regexp-substr,Oracle,Regexp Substr,我的列值如下所示:[只是我创建的一个示例] {BASICINFOxxxFyyy100x}{CONTACTxxx12345yyy20202x} 它可以包含0个或多个数据块。。。我已经创建了下面的查询来分割块 with x as (select '{BASICINFOxxxFyyy100x}{CONTACTxxx12345yyy20202x}' a from dual) select REGEXP_SUBSTR(a,'({.*?x})',1,rownum,null,1) from x c

我的列值如下所示:[只是我创建的一个示例]

{BASICINFOxxxFyyy100x}{CONTACTxxx12345yyy20202x}

它可以包含0个或多个数据块。。。我已经创建了下面的查询来分割块

with x as
 (select 
 '{BASICINFOxxxFyyy100x}{CONTACTxxx12345yyy20202x}' a from dual)
 select REGEXP_SUBSTR(a,'({.*?x})',1,rownum,null,1)
 from x
 connect by rownum <= REGEXP_COUNT(a,'x}')
分隔符始终是标准的。我未能创建一个提供所需输出的漂亮查询

提前谢谢

SQL> with x as
  2   (select  '{BASICINFOxxxFyyy100x}{CONTACTxxx12345yyy20202x}' a from dual
  3   ),
  4  y as (
  5   select REGEXP_SUBSTR(a,'({.*?x})',1,rownum,null,1) c1
  6   from x
  7   connect by rownum <= REGEXP_COUNT(a,'x}')
  8  )
  9  select
 10    substr(c1,2,instr(c1,'xxx')-2) z1,
 11    substr(c1,instr(c1,'xxx')+3,instr(c1,'yyy')-instr(c1,'xxx')-3) z2,
 12    rtrim(substr(c1,instr(c1,'yyy')+3),'x}') z3
 13  from y;

Z1              Z2              Z3
--------------- --------------- ---------------
BASICINFO       F               100
CONTACT         12345           20202
Oracle 11g R2架构设置:

问题1:

注:

您的查询:

select REGEXP_SUBSTR(a,'({.*?x})',1,rownum,null,1)
from x
connect by rownum <= REGEXP_COUNT(a,'x}')
当您有多行输入时将不起作用-在CONNECT BY子句中,分层查询没有任何限制它连接Row1-Level2到Row1-Level1或Row2-Level1,因此它将同时连接到这两行,并且随着层次结构的深度越来越大,它将创建输出行的指数级副本。您可以使用一些技巧来阻止这种情况,但将行生成器放入相关子查询,然后将其交叉连接回其相关的原始表,这样,如果您要使用分层查询,它就不会连接到错误的行,效率会更高

更好的方法是修复数据结构,这样就不会在分隔字符串中存储多个值

Oracle 11g R2架构设置:

问题1:

注:

您的查询:

select REGEXP_SUBSTR(a,'({.*?x})',1,rownum,null,1)
from x
connect by rownum <= REGEXP_COUNT(a,'x}')
当您有多行输入时将不起作用-在CONNECT BY子句中,分层查询没有任何限制它连接Row1-Level2到Row1-Level1或Row2-Level1,因此它将同时连接到这两行,并且随着层次结构的深度越来越大,它将创建输出行的指数级副本。您可以使用一些技巧来阻止这种情况,但将行生成器放入相关子查询,然后将其交叉连接回其相关的原始表,这样,如果您要使用分层查询,它就不会连接到错误的行,效率会更高


更好的方法是修复数据结构,这样就不会在分隔字符串中存储多个值。

这里是另一个解决方案,它是从您离开的位置派生出来的。您的查询已导致将一行拆分为两行。下面将分为3列:

WITH x
     AS (SELECT '{BASICINFOxxxFyyy100x}{CONTACTxxx12345yyy20202x}' a
           FROM DUAL),
-- Your query result here
     tbl
     AS (    SELECT REGEXP_SUBSTR (a,
                                   '({.*?x})',
                                   1,
                                   ROWNUM,
                                   NULL,
                                   1)
                       Col
               FROM x
         CONNECT BY ROWNUM <= REGEXP_COUNT (a, 'x}'))
--- Actual Query
SELECT col,
       REGEXP_SUBSTR (col,
                      '(.*?{)([^x]+)',
                      1,
                      1,
                      '',
                      2)
          AS COL1,
       REGEXP_SUBSTR (REGEXP_SUBSTR (col,
                                     '(.*?)([^x]+)',
                                     1,
                                     2,
                                     '',
                                     2),
                      '[^y]+',
                      1,
                      1)
          AS COL2,
       REGEXP_SUBSTR (REGEXP_SUBSTR (col,
                                     '[^y]+x',
                                     1,
                                     2),
                      '[^x]+',
                      1,
                      1)
          AS COL3
  FROM tbl;

这是另一个解决方案,它是从你离开的地方衍生出来的。您的查询已导致将一行拆分为两行。下面将分为3列:

WITH x
     AS (SELECT '{BASICINFOxxxFyyy100x}{CONTACTxxx12345yyy20202x}' a
           FROM DUAL),
-- Your query result here
     tbl
     AS (    SELECT REGEXP_SUBSTR (a,
                                   '({.*?x})',
                                   1,
                                   ROWNUM,
                                   NULL,
                                   1)
                       Col
               FROM x
         CONNECT BY ROWNUM <= REGEXP_COUNT (a, 'x}'))
--- Actual Query
SELECT col,
       REGEXP_SUBSTR (col,
                      '(.*?{)([^x]+)',
                      1,
                      1,
                      '',
                      2)
          AS COL1,
       REGEXP_SUBSTR (REGEXP_SUBSTR (col,
                                     '(.*?)([^x]+)',
                                     1,
                                     2,
                                     '',
                                     2),
                      '[^y]+',
                      1,
                      1)
          AS COL2,
       REGEXP_SUBSTR (REGEXP_SUBSTR (col,
                                     '[^y]+x',
                                     1,
                                     2),
                      '[^x]+',
                      1,
                      1)
          AS COL3
  FROM tbl;
方法列表
select REGEXP_SUBSTR(a,'({.*?x})',1,rownum,null,1)
from x
connect by rownum <= REGEXP_COUNT(a,'x}')
WITH x
     AS (SELECT '{BASICINFOxxxFyyy100x}{CONTACTxxx12345yyy20202x}' a
           FROM DUAL),
-- Your query result here
     tbl
     AS (    SELECT REGEXP_SUBSTR (a,
                                   '({.*?x})',
                                   1,
                                   ROWNUM,
                                   NULL,
                                   1)
                       Col
               FROM x
         CONNECT BY ROWNUM <= REGEXP_COUNT (a, 'x}'))
--- Actual Query
SELECT col,
       REGEXP_SUBSTR (col,
                      '(.*?{)([^x]+)',
                      1,
                      1,
                      '',
                      2)
          AS COL1,
       REGEXP_SUBSTR (REGEXP_SUBSTR (col,
                                     '(.*?)([^x]+)',
                                     1,
                                     2,
                                     '',
                                     2),
                      '[^y]+',
                      1,
                      1)
          AS COL2,
       REGEXP_SUBSTR (REGEXP_SUBSTR (col,
                                     '[^y]+x',
                                     1,
                                     2),
                      '[^x]+',
                      1,
                      1)
          AS COL3
  FROM tbl;
SQL> /

COL                                              COL1                                             COL2                                             COL3
------------------------------------------------ ------------------------------------------------ ------------------------------------------------ ------------------------------------------------
{BASICINFOxxxFyyy100x}                           BASICINFO                                        F                                                100
{CONTACTxxx12345yyy20202x}                       CONTACT                                          12345                                            20202