sql >> Base de Datos >  >> RDS >> Oracle

¿La función EXTRACTO de Oracle está rompiendo NOENTITYESCAPING en XMLELEMENT?

Intenta usar extractvalue() función, que elimina las entidades codificadas, en lugar de extract() . Aquí hay un ejemplo:

clear screen;
column res format a20;

-- depending on a situation, NOENTITYESCAPING might be dropped

select extractvalue(
                     xmlelement(NOENTITYESCAPING e,id,'->')
                    , '//text()'
                    ) as res
  from (select level as id 
          from dual 
       connect by level < 6)

Resultado:

RES                
--------------------
1->                  
2->                  
3->                  
4->                  
5->    

Pero el uso de extractvalue() La función puede estar limitada por el hecho de que puede devolver el valor de un solo nodo. En el caso de devolver valores de múltiples nodos, utl_i18n paquete y unescape_reference() La función de ese paquete se puede usar para eliminar las entidades codificadas:

clear screen;
column res format a20;

select utl_i18n.unescape_reference(xmlelement(root
                                             , xmlelement(node1, '>')
                                             , xmlelement(node2, '<')
                                             ).extract('//text()').getstringval()
                                   ) as res
 from dual
connect by level <= 3;

Resultado:

RES                
--------------------
><                   
><                   
>< 

Sí, como utl_i18n.unescape_reference() la función solo acepta valores de varchar2 tipo de datos y tipos que se pueden convertir implícitamente a varchar2 tipo de datos, sus manos están atadas cuando se trata de procesar grandes "cadenas ". En esta situación, puede recurrir a dbms_xmlgen paquete y convert() función en particular, que tiene una versión sobrecargada capaz de aceptar CLOB s. He aquí un ejemplo:

select dbms_xmlgen.convert(
                           xmlagg(xmlelement(root
                                             , xmlelement(node1, '>')
                                             , xmlelement(node2, '<')
                                             )
                                  ).extract('//text()').getclobval()
                          , 1) as res
 from dual
connect by level <= 3000;   -- 1 (second parameter of the convert() function)
                            -- instructs function to decode entities  

Resultado:

RES
------------------------------------------------------
><><><><><><><><><><><><><><><><><><><><><><><><><>
-- ... the rest of the CLOB