Här är en lösning som använder en rekursiv faktoriserad underfråga (Oracle 11.2 och högre):
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
Anteckningar :
Du sa CLOB men i ditt exempel extraherade du från en varchar2-sträng. Jag lade till to_clob()
för att se om/hur detta fungerar på en CLOB.
Jag använde instr
och substr
, eftersom de ofta (vanligtvis?) presterar mellan bättre och mycket bättre än deras regexp
motsvarigheter.
Jag sparade "index" för varje delsträng inom inmatningssträngen; i vissa fall är ordningen på tokens i inmatningssträngen viktig. (Men inte i ditt exempel, du fick bara samma token upprepad fem gånger.)
Om du behöver bättre prestanda, särskilt om dina CLOB:er är mycket stora, kan det vara bättre att använda dbms_lob.substr
och dbms_lob.instr
- se Prestandan av SUBSTR på CLOB
, speciellt Alex Pooles svar, och dokumentation här:http ://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_lob.htm#BABEAJAD
. Observera syntaxskillnaderna jämfört med vanlig substr
/ instr
.