Pregunta

Tengo un archivo xml de muestra creado con Editplus (en Windows).

  < ?xml version="1.0" encoding="UTF-8" ?>
  < badges >
    < row UserId="3714" Name="Teacher" Date="2008-09-15T08:55:03.923"/>
    < row UserId="994" Name="Teacher" Date="2008-09-15T08:55:03.957"/>
  < / badges>

Mi objetivo aquí es obtener esta información en la tabla Oracle DB. Como se sugiere aquí https://stackoverflow.com/questions/998055?sort=newest#sort-top, intenté ejecutar los comandos sql. Pero no pudo tener éxito,

========================= sql query 1 =================== =========

SQL> SELECT XMLTYPE(bfilename('D', 'tmp.xml'), nls_charset_id('UTF8')) xml_data FROM dual;

  XML_DATA
  ------------------------------------------------------------
  <?xml version="1.0" encoding="WINDOWS-1252"?>
  <badges>
     <row UserId="3714" Name

En la salida, veo que la mitad del archivo xml se truncó. Y el tipo de codificación en la salida se ve como WINDOWS-1252. ¿Podría alguien explicar por qué está sucediendo así?

=============================================== ===========================

=============================== sql query 2 ============= ==================

SQL> SELECT UserId, Name, to_timestamp(dt, 'YYYY-MM-DD"T"HH24:MI:SS.FF3') dt
2 FROM (SELECT XMLTYPE(bfilename('D', 'tmp.xml'), 3 nls_charset_id('WINDOWS-1252')) xml_data 4 FROM dual), 5 XMLTable('for $i in /badges/row 6 return $i' 7 passing xml_data 8 columns UserId NUMBER path '@UserId', 9 Name VARCHAR2(50) path '@Name', 10 dt VARCHAR2(25) path '@Date');

XMLTable('for $i in /badges/row * ERROR at line 5: ORA-00933: SQL command not properly ended

=============================================== ====================== La misma consulta estaba funcionando aquí https://stackoverflow.com/questions/998055?sort=newest#sort- arriba . Pero para mí no. Tengo instalado Oracle 10g en mi máquina. ¿Podría alguien sugerir las correcciones para que las consultas funcionen?

Gracias.

¿Fue útil?

Solución

Teniendo en cuenta su primer punto, su salida solo se trunca en la pantalla. Puede cambiar cuántos bytes se muestran en SQL * Plus con SET LONG :

SQL> SELECT XMLTYPE(bfilename('D', 'test.xml'), 
  2         nls_charset_id('WINDOWS-1252')) xml_data FROM dual;

XML_DATA
--------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<badges>
  <row UserId="3714" Name=

SQL> SET LONG 4000
SQL> /

XML_DATA
--------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<badges>
  <row UserId="3714" Name="Teacher" Date="2008-09-15T08:55:03.923"/>
  <row UserId="994" Name="Teacher" Date="2008-09-15T08:55:03.957"/>
</badges>

Como ha notado, su conjunto de caracteres se modificará según los parámetros de su sesión NLS (i-e: el archivo se traducirá al conjunto de caracteres de su cliente).

Para el segundo punto:

  • ¿Qué versión de SQL * Plus está utilizando? Puede ser más antiguo que la base de datos y no reconocer el Synthax
  • ¿podría publicar la consulta exacta tal como la escribió en SQL * Plus (Utilice la función CÓDIGO de SO)

porque no puedo reproducir con Oracle 10.2.0.3:

SQL> SELECT UserId, NAME, to_timestamp(dt, 'YYYY-MM-DD"T"HH24:MI:SS.FF3') dt
  2    FROM (SELECT XMLTYPE(bfilename('D', 'test.xml'),
  3                 nls_charset_id('WINDOWS-1252')) xml_data FROM dual),
  4         XMLTable('for $i in /badges/row
  5                             return $i'
  6                   passing xml_data columns UserId NUMBER path '@UserId',
  7                   NAME VARCHAR2(50) path '@Name',
  8                   dt VARCHAR2(25) path '@Date');

    USERID NAME      DT
---------- --------- ----------------------------
      3714 Teacher   15/09/08 08:55:03,923000000
       994 Teacher   15/09/08 08:55:03,957000000

Actualización: este cuadro sintético XMLTable debe ser una nueva característica del 10gR2 (10.2. *) (necesita confirmación)

Sin embargo, puede utilizar otro método para acceder a datos XML (descrito en otro SO ):

SQL> SELECT extractvalue(column_value, '/row/@UserId') "userID",
  2         extractvalue(column_value, '/row/@Name') "Name",
  3         extractvalue(column_value, '/row/@Date') "Date"
  4    FROM TABLE(XMLSequence(XMLTYPE(bfilename('D', 'tmp.xml'),
  5                     nls_charset_id('WINDOWS-1252')).extract('/badges/row'))) t;

userID  Name      Date
------- --------- ------------------------
3718    Teacher   2008-09-15T08:55:03.923
994     Teacher   2008-09-15T08:55:03.957

Otros consejos

Tuve exactamente el mismo problema, me preguntaba por qué:

encoding="UTF-8"

cambiado a

encoding="WINDOWS-1250"

en mi caso (después de cargar).

Entonces me di cuenta de lo que Oracle hace aquí: convierte el xml codificado utf-8 al juego de caracteres predeterminado de su base de datos, para poder almacenarlo. Es por eso que cambia el valor de 'codificación'. Si el conjunto de caracteres predeterminado de su base de datos es utf-8, entonces 'encodig' no cambiará.

Si su xem en realidad tiene caracteres codificados utf-8, entonces intentar cargarlo en la base de datos con nls_charset_id ('WINDOWS-1252') arrojará un error.

Entonces, para abreviar: no debe preocuparse de que encoding = " UTF-8 " cambie a encoding = " WINDOWS-1252 " , simplemente ignórelo - la base de datos está haciendo su trabajo.

Gracias por la ayuda. 'set Long 4000' solucionó el problema de truncamiento.

Pero todavía estoy luchando para ejecutar la segunda consulta. Mi versión de sqlplus es "SQL * Plus: Release 10.1.0.2.0". ¿Crees que esa versión es el problema?

Aquí está el código que he probado.

SQL> select xmltype(bfilename('D','tmp.xml'),nls_charset_id('WINDOWS-1252')) xml_data from dual;

XML_DATA
-----------------------------------------------
<?xml version="1.0" encoding="WINDOWS-1252"?>
<badges>
  <row UserId="3714" Name


SQL> set LONG 4000
SQL> /

XML_DATA
--------------------------------------------------
<?xml version="1.0" encoding="WINDOWS-1252"?>
<badges>
 <row UserId="3714" Name="Teacher" Date="2008-09-15T08:55:03.923"/>
 <row UserId="994" Name="Teacher" Date="2008-09-15T08:55:03.957"/>
</badges>


SQL> SELECT UserId, NAME, to_timestamp(dt, 'YYYY-MM-DD"T"HH24:MI:SS.FF3') dt
2        FROM (SELECT XMLTYPE(bfilename('D', 'tmp.xml'),
3                     nls_charset_id('WINDOWS-1252')) xml_data FROM dual),
4             XMLTable('for $i in /badges/row
5                                 return $i'
6                       passing xml_data columns UserId NUMBER path '@UserId',
7                       NAME VARCHAR2(50) path '@Name',
8                       dt VARCHAR2(25) path '@Date');
       XMLTable('for $i in /badges/row
               *
ERROR at line 4:
ORA-00933: SQL command not properly ended
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top