Oto rozwiązanie wykorzystujące podzapytanie z podziałem na czynniki rekurencyjne (Oracle 11.2 i nowsze):
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
Notatki :
Powiedziałeś CLOB, ale w twoim przykładzie wyodrębniłeś z ciągu varchar2. Dodałem to_clob()
aby zobaczyć, czy/jak to działa w CLOB.
Użyłem instr
i substr
, ponieważ często (zazwyczaj?) działają od lepszej do znacznie lepszej niż ich regexp
odpowiedniki.
Zapisałem „indeks” każdego podciągu w ciągu wejściowym; w niektórych przypadkach kolejność tokenów w ciągu wejściowym jest ważna. (Chociaż nie w twoim przykładzie, po prostu ten sam token został powtórzony pięć razy).
Jeśli potrzebujesz lepszej wydajności, zwłaszcza jeśli twoje CLOB są bardzo duże, możesz lepiej użyć dbms_lob.substr
i dbms_lob.instr
- zobacz Wydajność SUBSTR w CLOB
, zwłaszcza odpowiedź Alexa Poole'a i dokumentacja tutaj:http ://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_lob.htm#BABEAJAD
. Zwróć uwagę na różnice w składni w porównaniu ze zwykłymi substr
/ instr
.