2

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

  < ?xml 版本="1.0" 编码="UTF-8" ?>
  <徽章>
    <row UserId="3714" Name="教师" Date="2008-09-15T08:55:03.923"/>
    <row UserId="994" Name="Teacher" Date="2008-09-15T08:55:03.957"/>
  </ 徽章>

我的目标是将这些信息放入 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 从双), 5 XMLTable('for $i in /badges/row 6 返回$i' 7 传递xml_data 8 列 UserId NUMBER 路径 '@UserId', 9 名称 VARCHAR2(50) 路径 '@Name', 10 dt VARCHAR2(25) 路径 '@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-top。但对我来说不是。我的机器上安装了 oracle 10g。有人可以建议进行更正以使查询正常工作。

谢谢。

4

3 回答 3

1

考虑到您的第一点,您的输出仅在显示时被截断。您可以使用以下命令更改 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 中键入的确切查询(请使用 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
于 2009-08-05T09:47:20.620 回答
1

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

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

于 2011-06-27T14:52:05.367 回答
0

谢谢您的帮助。'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
于 2009-08-05T10:56:21.073 回答