问题描述
说我有一个字符串-'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
次一样。实现此目标的正确方法是什么?
很长一段时间后我正在执行DB脚本,因此虽然我之前已经做过,但不记得确切。所以我需要一些建议。
解决方法
- 使用“ \ 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) s1,2) s2
from xmltable(
'tokenize(.,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,8787223'
columns
s1 varchar2(10) path '@s1',s2 varchar2(10) path '@s2'
)
,
这是一个纯基于regexp_substr的解决方案。 “ d”子查询纯粹是您的数据。 Oracle不太了解\ n,因此chr(10)会解决这个问题。 lines子查询通过换行符将您的数据分成几行。最后一个查询以逗号分隔字符串。您可以通过添加其他regexp_substr实例并增加最后一个(位置)参数来扩展两列以逗号分隔的数据。
$auth.user
产生:
WITH d AS
(SELECT REPLACE('9999,8787223','\n',chr(10)) AS ata
FROM dual),lines AS
(SELECT regexp_substr(d.ata,'[^' || chr(10) || ']+',LEVEL) AS line
FROM d
CONNECT BY regexp_substr(d.ata,LEVEL) IS NOT NULL)
SELECT l.line,regexp_substr(l.line,'[^,]+',1) AS c1,2) AS c2
FROM lines l;