Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment diviser un objet CLOB en utilisant , et :délimiteur dans Oracle en plusieurs enregistrements

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 .