SQL小提琴
Oracle 11g R2 模式设置:
CREATE TABLE your_table ( str ) AS
SELECT '{BASICINFOxxxFyyy100x}{CONTACTxxx12345yyy20202x}' from dual
/
查询 1:
select REGEXP_SUBSTR(
t.str,
'\{([^}]*?)xxx([^}]*?)yyy([^}]*?)x\}',
1,
l.COLUMN_VALUE,
NULL,
1
) AS col1,
REGEXP_SUBSTR(
str,
'\{([^}]*?)xxx([^}]*?)yyy([^}]*?)x\}',
1,
l.COLUMN_VALUE,
NULL,
2
) AS col2,
REGEXP_SUBSTR(
str,
'\{([^}]*?)xxx([^}]*?)yyy([^}]*?)x\}',
1,
l.COLUMN_VALUE,
NULL,
3
) AS col3
FROM your_table t
CROSS JOIN
TABLE(
CAST(
MULTISET(
SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= REGEXP_COUNT( t.str,'\{([^}]*?)xxx([^}]*?)yyy([^}]*?)x\}')
) AS SYS.ODCINUMBERLIST
)
) l
结果:
| COL1 | COL2 | COL3 |
|-----------|-------|-------|
| BASICINFO | F | 100 |
| CONTACT | 12345 | 20202 |
笔记:
您的查询:
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 因此它将连接到两者并作为层次结构的深度变得更大,它将创建输出行的成倍增加的重复副本。您可以使用一些技巧来阻止这种情况,但是将行生成器放入相关的子查询中会更有效,然后可以将其CROSS JOIN
返回到原始表(它是相关的,因此它不会加入错误的行) 如果您要使用分层查询。
更好的是修复您的数据结构,这样您就不会在分隔字符串中存储多个值。