Ето решение, използващо рекурсивна факторизирана подзаявка (Oracle 11.2 и по-нова версия):
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
Бележки :
Казахте CLOB, но във вашия пример сте извлекли от низ varchar2. Добавих to_clob()
за да видите дали/как работи това на CLOB.
Използвах instr
и substr
, тъй като често (обикновено?) се представят между по-добро и много по-добро от техния regexp
еквиваленти.
Запазих "индекса" на всеки подниз във входния низ; в някои случаи редът на токените във входния низ е важен. (Не във вашия пример обаче, току-що сте имали същия знак, повторен пет пъти.)
Ако имате нужда от по-добра производителност, особено ако вашите CLOB са много големи, може да е по-добре да използвате dbms_lob.substr
и dbms_lob.instr
- вижте Ефективност на SUBSTR на CLOB
, особено отговора на Alex Poole и документация тук:http ://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_lob.htm#BABEAJAD
. Обърнете внимание на разликите в синтаксиса спрямо обикновения substr
/ instr
.