xml 到 oracle DB 表:遇到问题

发布于 2024-07-30 08:42:23 字数 2206 浏览 9 评论 0原文

我有一个使用 Editplus(在 Windows 中)创建的示例 xml 文件。

  < ?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 DB 表中。 正如此处建议的https://stackoverflow.com/questions/998055?sort=newest#sort-top,我尝试执行sql命令。 但没能成功,

==========================sql查询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查询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

=================================================== =================== 同样的查询在这里工作 https://stackoverflow.com/questions/998055?sort=newest#sort-顶部。 但对我来说却不然。 我的机器上安装了oracle 10g。 有人可以建议更正以使查询有效吗?

谢谢。

I have a sample xml file created using Editplus( in 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>

My goal here is to get this information into Oracle DB table. As suggested here https://stackoverflow.com/questions/998055?sort=newest#sort-top, I tried to execute the sql commands. But couldn't succeed,

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

In the output, I see half of the xml file got truncated. And the encoding type in output is seen as WINDOWS-1252. Could someone explain why is it happening so?

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

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

=====================================================================
The same query was working here https://stackoverflow.com/questions/998055?sort=newest#sort-top. But for me it doesn't.
I have oracle 10g installed on my machine.
Could someone suggest the corrections to make the queries work.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

┈┾☆殇 2024-08-06 08:42:23

考虑到您的第一点,您的输出仅在显示时被截断。 您可以使用 SET LONG 更改 SQL*Plus 中显示的字节数:

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 中键入它时发布确切的查询吗(请使用 SO 的 CODE 功能),

因为我无法使用 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

Considering your first point, your output is only truncated on display. You can change how many bytes are displayed in SQL*Plus with 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>

As you have noticed, your character set will be modified per your NLS session parameters (i-e: the file will be translated to the character set of your client).

For the second point:

  • What version of SQL*Plus are you using ? It might be older than the database and not recognizing the synthax
  • could you post the exact query as you typed it in SQL*Plus (Please use the CODE feature of SO)

because I can not reproduce with 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: This XMLTable synthax must be a new feature of the 10gR2 (10.2.*) (needs confirmation)

You can however use another method of accessing XML Data(described in another 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
夏花。依旧 2024-08-06 08:42:23

我遇到了完全相同的问题,我想知道为什么:

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",只需忽略它 - 数据库正在做它的工作。

I had the exact same problem, I was wondering why:

encoding="UTF-8"

changed to

encoding="WINDOWS-1250"

in my case (after loading).

Then I realised what Oracle does here: it converts the utf-8 encoded xml to the default character set of your database, in order to be able to store it. That's why it changes the value of 'encoding'. If the default character set of your databse is utf-8, then 'encodig' will not change.

If your xml actually has utf-8 encoded characters, then trying to load it in the database with nls_charset_id('WINDOWS-1252') will throw an error.

So to put it short: you should not worry about encoding="UTF-8" changing to encoding="WINDOWS-1252", just ignore it - the database is doing its job.

仄言 2024-08-06 08:42:23

谢谢您的帮助。 “set Long 4000”修复了截断问题。

但我仍然在努力运行第二个查询。 我的 sqlplus 版本是“SQL*Plus:Release 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

Thanks for the help. 'set Long 4000' fixed the truncation issue.

But I am still struggling to get the second query running. My sqlplus version is "SQL*Plus: Release 10.1.0.2.0". Do you think that version is the issue.

Here is the code i have tried.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文