Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como dividir um objeto CLOB usando , e :delimitador no Oracle em vários registros


Aqui está uma solução usando uma subconsulta fatorada recursiva (Oracle 11.2 e acima):
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

Observações :

Você disse CLOB, mas no seu exemplo você extraiu de uma string varchar2. Eu adicionei to_clob() para ver se/como isso funciona em um CLOB.

Eu usei instr e substr , já que eles geralmente (geralmente?) têm um desempenho entre melhor e muito melhor do que seu regexp equivalentes.

Salvei o "índice" de cada substring dentro da string de entrada; em alguns casos, a ordem dos tokens na string de entrada é importante. (Não no seu exemplo, porém, você acabou de repetir o mesmo token cinco vezes.)

Se você precisar de melhor desempenho, especialmente se seus CLOBs forem muito grandes, talvez seja melhor usar dbms_lob.substr e dbms_lob.instr - consulte Desempenho de SUBSTR no CLOB , especialmente a resposta de Alex Poole e a documentação aqui:http ://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_lob.htm#BABEAJAD . Observe as diferenças de sintaxe em relação ao substr regular / instr .