xml 到 oracle 数据库表:遇到问题
题
我有一个使用 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-top. 。但对我来说却不然。我的机器上安装了oracle 10g。有人可以建议更正以使查询有效吗?
谢谢。
解决方案
考虑到您的第一点,您的输出仅在显示时被截断。您可以更改 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
其他提示
我有完全相同的问题,我想知道为什么:
encoding="UTF-8"
改变为
encoding="WINDOWS-1250"
在我的情况下(后装)。
然后我意识到甲骨文在这里所做的:它转换UTF-8编码XML的默认字符集数据库中,以便能够存储它。这就是为什么它改变“编码”的值。如果设置你的DATABSE的默认字符是utf-8,然后“encodig”不会改变。
如果你的XML的真正的有UTF-8编码的字符,然后试图加载它与nls_charset_id('WINDOWS-1252')
数据库将抛出一个错误。
所以把它简称:你不应该担心encoding="UTF-8"
更改为encoding="WINDOWS-1252"
,只是忽略它 - 数据库正在做自己的工作。
感谢您的帮助。 “设置长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