tabla de XML a Oracle DB: encontrar problemas
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.
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