Oracle
 sql >> Database >  >> RDS >> Oracle

Come suddividere un oggetto CLOB utilizzando , e :delimitatore in Oracle in più record

Ecco una soluzione che utilizza una sottoquery ricorsiva fattorizzata (Oracle 11.2 e versioni successive):

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

Note :

Hai detto CLOB ma nel tuo esempio hai estratto da una stringa varchar2. Ho aggiunto to_clob() per vedere se/come funziona su un CLOB.

Ho usato instr e substr , poiché spesso (di solito?) si comportano tra meglio e molto meglio del loro regexp equivalenti.

Ho salvato l '"indice" di ogni sottostringa all'interno della stringa di input; in alcuni casi l'ordine dei token nella stringa di input è importante. (Non nel tuo esempio, però, hai appena ripetuto lo stesso token cinque volte.)

Se hai bisogno di prestazioni migliori, specialmente se i tuoi CLOB sono molto grandi, potresti fare meglio a usare dbms_lob.substr e dbms_lob.instr - vedi Prestazioni di SUBSTR su CLOB , in particolare la risposta di Alex Poole e la documentazione qui:http ://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_lob.htm#BABEAJAD . Nota le differenze di sintassi rispetto al normale substr / instr .