Pergunta

Eu tenho um arquivo xml amostra criado usando Editplus (no 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>

Meu objetivo aqui é conseguir que esta informação na tabela de banco de dados Oracle. Como sugerido aqui https://stackoverflow.com/questions/998055?sort=newest#sort-top, eu tentei executar os comandos SQL. Mas não poderia ter sucesso,

========================= 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

Na saída, vejo metade do arquivo xml ficou truncado. E o tipo de codificação de saída é visto como o Windows-1252. Alguém poderia explicar por que é que acontece assim?

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

=============================== sql consulta 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

=============================================== ====================== A mesma consulta estava trabalhando aqui https://stackoverflow.com/questions/998055?sort=newest#sort- superior. Mas para mim isso não acontece. Tenho Oracle 10g instalado na minha máquina. Alguém poderia sugerir as correções para fazer a consultas de trabalho.

Graças.

Foi útil?

Solução

Considerando o seu primeiro ponto, a saída só é truncado em exibição. Você pode alterar o número de bytes são exibidos em SQL * Plus com 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 você observou, o seu conjunto de caracteres será modificado por seus parâmetros de sessão NLS (i-e: o arquivo será traduzido para o conjunto de caracteres de seu cliente).

Para o segundo ponto:

  • Qual versão do SQL * Plus você está usando? Pode ser mais velho do que o banco de dados e não reconhecendo o synthax
  • você pode postar a consulta exata como digitada no SQL * Plus (Utilize o recurso de código de SO)

porque eu não posso reproduzir com a 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

Update: (. 10.2 *) Esta synthax XMLTable deve ser um novo recurso do 10gR2 (confirmação necessidades)

No entanto, pode usar outro método de acesso de dados XML (descrito em outra 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

Outras dicas

Eu tinha exatamente o mesmo problema, eu estava me perguntando por:

encoding="UTF-8"

alterado para

encoding="WINDOWS-1250"

no meu caso (após o carregamento).

Então eu percebi o que a Oracle faz aqui: ele converte o xml codificado utf-8 para o conjunto de caracteres padrão do seu banco de dados, a fim de ser capaz de armazená-lo. É por isso que muda o valor de 'codificação'. Se o conjunto de caracteres padrão de sua databse é utf-8, em seguida, 'encodig' não vai mudar.

Se o seu xml realmente tem utf-8 caracteres codificados, em seguida, tentar carregá-lo no banco de dados com nls_charset_id('WINDOWS-1252') irá lançar um erro.

Então, para colocá-lo curto:. Você não deve se preocupar com encoding="UTF-8" mudar para encoding="WINDOWS-1252", simplesmente ignorá-la - o banco de dados está fazendo seu trabalho

Obrigado pela ajuda. 'Set Longo 4000' corrigiu o problema de truncagem.

Mas ainda estou lutando para obter a segunda consulta em execução. Minha versão sqlplus é "SQL * Plus: Lançamento 10.1.0.2.0". Você acha que essa versão é a questão.

Aqui está o código que eu tentei.

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top