如何从 Oracle 中的字符串中循环标记?
Posted
技术标签:
【中文标题】如何从 Oracle 中的字符串中循环标记?【英文标题】:How to loop over tokens from a string in Oracle? 【发布时间】:2020-12-03 15:25:36 【问题描述】:假设我有一个字符串 - '9999,34244324324\n88888,131321323\n77777,8787223'
,
我希望将由\n
分隔的每一对中的每个逗号分隔数字插入到表格的两列中。
例如,如下所示:
9999 |34244324324
88888|131321323
77777|8787223
使用 REGEXP_SUBSTR,我可以将这些对组合在一起:
REGEXP_SUBSTR(str, '((\d+),(\d+)\n?)',1,i, null, j)
其中i
找到num,num
匹配项,j
是第一个或第二个数字的 1 或 2。
我可以想象循环这个 i
次,我可以从 REGXP_COUNT
得到,但这似乎重复同样的事情 n
次。实现这一目标的正确方法是什么?
很长一段时间后我正在做数据库脚本,所以虽然我之前做过,但我不记得确切了。所以我需要这方面的建议。
【问题讨论】:
【参考方案1】:-
以“\n”作为分隔符将整个字符串分割成行:
select *
from xmltable(
'tokenize(., "\\n")'
passing '9999,34244324324\n88888,131321323\n77777,8787223'
columns
s varchar2(100) path '.'
)
结果:
S
---------------------
9999,34244324324
88888,131321323
77777,8787223
-
用“,”作为分隔符将每一行拆分为子字符串:
2.1 使用regexp_substr:
select
s,
regexp_substr(s,'^([^,]*),([^,]*)',1,1,'',1) s1,
regexp_substr(s,'^([^,]*),([^,]*)',1,1,'',2) s2
from xmltable(
'tokenize(., "\\n")'
passing '9999,34244324324\n88888,131321323\n77777,8787223'
columns
s varchar2(100) path '.'
)
结果:
S S1 S2
-------------------- ------------ ------------
9999,34244324324 9999 34244324324
88888,131321323 88888 131321323
77777,8787223 77777 8787223
或 2.2 使用相同的 xmltable:
select *
from xmltable(
'for $r in tokenize(., "\\n")
return element R
attribute s1 tokenize($r, ",")[1],
attribute s2 tokenize($r, ",")[2]
'
passing '9999,34244324324\n88888,131321323\n77777,8787223'
columns
s1 varchar2(10) path '@s1',
s2 varchar2(10) path '@s2'
)
【讨论】:
【参考方案2】:这是一个纯粹的基于 regexp_substr 的解决方案。 “d”子查询纯粹是您的数据。 Oracle 不能很好地理解 \n,因此 chr(10) 会处理这个问题。行子查询将您的数据按换行符拆分为行。最后一个查询以逗号分隔字符串。您可以通过添加额外的 regexp_substr 实例并增加最后一个(位置)参数来扩展两列逗号分隔的数据。
WITH d AS
(SELECT REPLACE('9999,34244324324\n88888,131321323\n77777,8787223',
'\n',
chr(10)) AS ata
FROM dual),
lines AS
(SELECT regexp_substr(d.ata,
'[^' || chr(10) || ']+',
1,
LEVEL) AS line
FROM d
CONNECT BY regexp_substr(d.ata,
'[^' || chr(10) || ']+',
1,
LEVEL) IS NOT NULL)
SELECT l.line,
regexp_substr(l.line,
'[^,]+',
1,
1) AS c1,
regexp_substr(l.line,
'[^,]+',
1,
2) AS c2
FROM lines l;
生产:
line c1 c2
---------------- ----- -----------
9999,34244324324 9999 34244324324
88888,131321323 88888 131321323
77777,8787223 77777 8787223
【讨论】:
以上是关于如何从 Oracle 中的字符串中循环标记?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Oracle 循环中的 select 语句中执行 alter 命令?