таблица базы данных xml to oracle: возникают проблемы - PullRequest
2 голосов
/ 05 августа 2009

У меня есть образец XML-файла, созданного с помощью Editplus (в 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>

Моя цель - перенести эту информацию в таблицу БД Oracle. Как предложено здесь https://stackoverflow.com/questions/998055?sort=newest#sort-top, Я пытался выполнить команды sql. Но не удалось,

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

В выводе я вижу, что половина XML-файла была усечена. И тип кодировки в выводе рассматривается как WINDOWS-1252. Может кто-нибудь объяснить, почему так происходит?

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

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

SQL> SELECT UserId, Name, to_timestamp(dt, 'YYYY-MM-DD"T"HH24:MI:SS.FF3') dt<br>
  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');</p>

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

=============================================== ====================== Здесь работал тот же запрос https://stackoverflow.com/questions/998055?sort=newest#sort-top. Но для меня это не так. На моей машине установлен оракул 10g. Может ли кто-нибудь предложить исправления, чтобы заставить запросы работать.

Спасибо.

Ответы [ 3 ]

1 голос
/ 27 июня 2011

У меня была точно такая же проблема, мне было интересно, почему:

encoding="UTF-8"

изменено на

encoding="WINDOWS-1250"

в моем случае (после загрузки).

Затем я понял, что Oracle делает здесь: он преобразует кодированный в utf-8 xml в набор символов по умолчанию вашей базы данных, чтобы иметь возможность хранить его. Вот почему это меняет значение «кодировка». Если набор символов по умолчанию для вашей базы данных - utf-8, то 'encodig' не изменится.

Если ваш xml на самом деле содержит символы в кодировке utf-8, то попытка загрузить его в базу данных с помощью nls_charset_id('WINDOWS-1252') приведет к ошибке.

Короче говоря: вам не нужно беспокоиться о том, что encoding="UTF-8" изменится на encoding="WINDOWS-1252", просто проигнорируйте его - база данных выполняет свою работу.

1 голос
/ 05 августа 2009

Учитывая вашу первую точку, ваш вывод только усечен на дисплее. Вы можете изменить количество отображаемых байтов в SQL * Plus с помощью 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>

Как вы заметили, ваш набор символов будет изменен в соответствии с параметрами сеанса NLS (т.е. файл будет переведен в набор символов вашего клиента).

Для второго пункта:

  • Какую версию SQL * Plus вы используете? Возможно, он старше, чем база данных, и не может распознать синтакс
  • не могли бы вы опубликовать точный запрос в том виде, в каком он был введен в SQL * Plus (используйте функцию CODE в SO)

потому что я не могу воспроизвести с 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

Обновление: Этот синтаксис XMLTable должен быть новой функцией 10gR2 (10.2. *) (Требуется подтверждение)

Однако вы можете использовать другой метод доступа к XML-данным (описан в Другой 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
0 голосов
/ 05 августа 2009

Спасибо за помощь. 'set Long 4000' исправил проблему усечения.

Но я все еще пытаюсь запустить второй запрос. Моя версия sqlplus - «SQL * Plus: выпуск 10.1.0.2.0». Как вы думаете, эта версия является проблемой.

Вот код, который я пробовал.

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