Voici une solution utilisant une sous-requête factorisée récursive (Oracle 11.2 et supérieur) :
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
Remarques :
Vous avez dit CLOB mais dans votre exemple vous avez extrait d'une chaîne varchar2. J'ai ajouté to_clob()
pour voir si/comment cela fonctionne sur un CLOB.
J'ai utilisé instr
et substr
, car ils fonctionnent souvent (généralement ?) entre mieux et bien mieux que leur regexp
équivalents.
J'ai enregistré "l'index" de chaque sous-chaîne dans la chaîne d'entrée ; dans certains cas, l'ordre des jetons dans la chaîne d'entrée est important. (Pas dans votre exemple cependant, vous venez de répéter le même jeton cinq fois.)
Si vous avez besoin de meilleures performances, en particulier si vos CLOB sont très volumineux, il peut être préférable d'utiliser dbms_lob.substr
et dbms_lob.instr
- voir Performance de SUBSTR sur CLOB
, en particulier la réponse d'Alex Poole, et la documentation ici :http ://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_lob.htm#BABEAJAD
. Notez les différences de syntaxe par rapport à substr
normal / instr
.