Her er en løsning, der bruger en rekursiv faktoriseret underforespørgsel (Oracle 11.2 og nyere):
with inputs ( str ) as (
select to_clob('ABCDEF:PmId12345RmLn1VlId0,ABCDEF:PmId12345RmLn1VlId0,ABCDEF:PmId12345RmLn1VlId0,ABCDEF:PmId12345RmLn1VlId0,ABCDEF:PmId12345RmLn1VlId0')
from dual
),
prep ( s, n, token, st_pos, end_pos ) as (
select ',' || str || ',', -1, null, null, 1
from inputs
union all
select s, n+1, substr(s, st_pos, end_pos - st_pos),
end_pos + 1, instr(s, ',', 1, n+3)
from prep
where end_pos != 0
)
select n as idx, token as column_name
from prep
where n > 0;
IDX COLUMN_NAME
------ ----------------------------
1 ABCDEF:PmId12345RmLn1VlId0
2 ABCDEF:PmId12345RmLn1VlId0
3 ABCDEF:PmId12345RmLn1VlId0
4 ABCDEF:PmId12345RmLn1VlId0
5 ABCDEF:PmId12345RmLn1VlId0
Noter :
Du sagde CLOB, men i dit eksempel udtog du fra en varchar2-streng. Jeg tilføjede to_clob()
for at se om/hvordan dette virker på en CLOB.
Jeg brugte instr
og substr
, da de ofte (normalt?) klarer sig mellem bedre og meget bedre end deres regexp
ækvivalenter.
Jeg gemte "indekset" for hver understreng i inputstrengen; i nogle tilfælde er rækkefølgen af tokens i inputstrengen vigtig. (Men ikke i dit eksempel, du har lige fået gentaget den samme token fem gange.)
Hvis du har brug for bedre ydeevne, især hvis dine CLOB'er er meget store, kan du være bedre stillet ved at bruge dbms_lob.substr
og dbms_lob.instr
- se Ydeevne af SUBSTR på CLOB
, især Alex Pooles svar, og dokumentation her:http ://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_lob.htm#BABEAJAD
. Bemærk syntaksforskellene i forhold til almindelig substr
/ instr
.