我正在尝试完全根据 Oracle 文档加载 XML 数据:[https://docs.oracle.com/cd/E11882_01/appdev.112/e23094/xdb25loa.htm#ADXDB5731]
但唯一的结果是错误:
SQL*Loader: Release 19.0.0.0.0 - Production on Mon Mar 6 11:15:26 2023
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved.
SQL*Loader-416: SDF clause for field XML_ in table FOP2 references a non existent field.
我不知道,出了什么问题,因为表 FOP2 存在,它是由以下人员创建的:
CREATE TABLE FOP2 (XML_ XMLTYPE);
加载方式:
sqlldr usr/psw loader.ctl
loader.ctl 尽量匹配Oracle文档:
load data
infile 'filenames.dat'
APPEND
into table FOP2
xmltype(XML_)
(
XML_ lobfile(filename) terminated by eof
)
filenames.dat 只包含一个文件名:
C:\Users\PP\Downloads\datafile-seznam_ds_pfo-20230302094107.xml
xml文件名是:
<box>
<id>8iedd6n</id>
<type>XXX</type>
<subtype>16</subtype>
<name>
<person>
<firstName></firstName>
<lastName></lastName>
</person>
<tradeName>BBB</tradeName>
</name>
<ico>12345678</ico>
<address>
<city>CCC</city>
<district>DDD</district>
<street>FFF</street>
<cp>GGG</cp>
<co>HHH</co>
<ce></ce>
<zip>11111</zip>
<addressPoint></addressPoint>
<state>CZ</state>
<fullAddress></fullAddress>
</address>
<pdz>false</pdz>
<ovm>true</ovm>
<hierarchy>
<isMaster>true</isMaster>
</hierarchy>
<idOVM>22222222</idOVM>
</box>
<box>
<id>9jic8np</id>
<type>XXX</type>
<subtype>20</subtype>
<name>
<person>
<firstName></firstName>
<lastName></lastName>
</person>
<tradeName>CCC</tradeName>
</name>
<ico>12345678</ico>
<address>
<city>DDD/city>
<district>EEE</district>
<street>FFF</street>
<cp>333</cp>
<co>44</co>
<ce></ce>
<zip>55555</zip>
<addressPoint>123456789</addressPoint>
<state>CZ</state>
<fullAddress></fullAddress>
</address>
<pdz>false</pdz>
<ovm>true</ovm>
<hierarchy>
<isMaster>true</isMaster>
</hierarchy>
<idOVM>33333333</idOVM>
</box>
那么,问题出在哪里?一切都像 Oracle 文档中那样,我试图在所有细节中重复它,但它不起作用。我打不通。
我试图在论坛上找到答案,我尝试了多种不同的方式来修改负载,但都没有成功。最后,我尝试编写与我在这里展示的 Oracle 文档几乎相同的代码,但仍然存在错误。我很乐意了解,出了什么问题,如何让它发挥作用。
错误消息引用的“不存在的字段”是“文件名”,文档示例中有您删除的“文件名填充字符(120)”。
总结一下我遇到的问题,以及解决方法:
控制文件,正在运行:
加载数据
字符集UTF8
infile 'datafile-seznam_ds_pfo-20230302094107.xml'
替换
进入表格 FOP2 (
虚拟填充字符(3000)由“”终止,
XML_ lobfile(常量'datafile-seznam_ds_pfo-20230302094107.xml')由“”终止
)
但是FOP2表必须是CLOB类型:
CREATE TABLE FOP2 (XML_ CLOB) ;
3 它在解析字段时产生了另一个问题。这不起作用,因为 xml_ 是 CLOB 类型。并且转换 xmltype.createxml 也不起作用,因为一些记录(有很多空记录,我没有找到如何从加载中删除它们):
SELECT x.*
FROM
FOP2
CROSS JOIN
XMLTABLE (
'BOX'
PASSING xmltype.createxml(FOP2.xml_)
COLUMNS
id varchar2(10) PATH './id' ,
type varchar2(10) PATH './type' ,
subtype varchar2(10) PATH './subtype' ,
firstName varchar2(50) PATH './name/person/firstName' ,
lastName varchar2(50) PATH './name/person/lastName' ,
tradeName varchar2(50) PATH './name/tradeName' ,
ico varchar2(10) PATH './ico' ,
city varchar2(100) PATH './address/city' ,
district varchar2(100) PATH './address/district' ,
street varchar2(100) PATH './address/street' ,
cp varchar2(10) PATH './address/cp' ,
co varchar2(10) PATH './address/co' ,
ce varchar2(10) PATH './address/ce' ,
zip varchar2(10) PATH './address/zip' ,
state varchar2(10) PATH './address/state' ,
pdz varchar2(10) PATH './pdz' ,
ovm varchar2(10) PATH './ovm' ,
isMaster varchar2(10) PATH './hierarchy/isMaster' ,
idOVM varchar2(10) PATH './idOVM'
) x
;
但是有效的代码只是手动解析。 删除空记录的条件有效(其中 instr( xml_, 'box',1) != 0;):
选择 XML_ ,
substr(XML_, instr(XML_,'',1)+4 , instr(XML_,'', (instr(XML_,'',1)+4))-(instr(XML_,'',1)+4) ) 作为 id ,
substr(XML_, instr(XML_,'',1)+6 , instr(XML_,'', (instr(XML_,'',1)+6))-(instr(XML_,'',1)+6) ) 作为类型 ,
substr(XML_, instr(XML_,'',1)+9 , instr(XML_,'', (instr(XML_,'',1)+9))-(instr(XML_,'',1)+9) ) 作为子类型 ,
substr(XML_, instr(XML_,'',1)+11 , instr(XML_,'', (instr(XML_,'',1)+11))-(instr(XML_,'',1)+11) ) 作为名字,
substr(XML_, instr(XML_,'',1)+10 , instr(XML_,'', (instr(XML_,'',1)+10))-(instr(XML_,'',1)+10) ) 作为姓氏,
substr(XML_, instr(XML_,'',1)+5 , instr(XML_,'', (instr(XML_,'',1)+5))-(instr(XML_,'',1)+5) ) 作为 ico ,
substr(XML_, instr(XML_,'',1)+6 , instr(XML_,'', (instr(XML_,'',1)+6))-(instr(XML_,'',1)+6) ) 作为城市 ,
substr(XML_, instr(XML_,'',1)+10 , instr(XML_,'', (instr(XML_,'',1)+10))-(instr(XML_,'',1)+10) ) 作为地区 ,
substr(XML_, instr(XML_,'',1)+8 , instr(XML_,'', (instr(XML_,'',1)+8))-(instr(XML_,'',1)+8) ) 作为街道 ,
substr(XML_, instr(XML_,'',1)+4 , instr(XML_,'', (instr(XML_,'',1)+4))-(instr(XML_,'',1)+4) ) 作为 cp ,
substr(XML_, instr(XML_,'',1)+4 , instr(XML_,'', (instr(XML_,'',1)+4))-(instr(XML_,'',1)+4) ) 作为 ,
substr(XML_, instr(XML_,'',1)+4 , instr(XML_,'', (instr(XML_,'',1)+4))-(instr(XML_,'',1)+4) ) 作为 ce ,
substr(XML_, instr(XML_,'',1)+5 , instr(XML_,'', (instr(XML_,'',1)+5))-(instr(XML_,'',1)+5) ) 作为 zip ,
substr(XML_, instr(XML_,'',1)+7 , instr(XML_,'', (instr(XML_,'',1)+7))-(instr(XML_,'',1)+7) ) 作为状态
来自 FOP2 在哪里 instr( xml_, 'box',1) != 0;
我注意到负载数据中还有一个问题。有一条记录满
'<<>>'
所以,显然是行
dummy FILLER CHAR(3000) TERMINATED BY "<box>",
无法正常工作。
但是手动解析CLOB是没有问题的这样一条记录。我猜 XML 解析器会有问题,因为记录的格式与其他格式不同。
问题是,为什么
dummy FILLER CHAR(3000) TERMINATED BY "<box>",
不起作用。