使用 XMLType 在 oracle 表中加载 XML 的过程
Posted
技术标签:
【中文标题】使用 XMLType 在 oracle 表中加载 XML 的过程【英文标题】:Procedure for loading XML in oracle table using XMLType 【发布时间】:2015-04-22 10:26:36 【问题描述】:我的灵感来自一个 xml 类型的过程,用于在此处解析和插入表中的数据。在我的情况下,表已经存在,一旦外部应用程序生成 xml,我需要在表中加载数据,所以我创建了我的程序,当我编译一切正常但在执行时我有错误。 所以这是我里面的xml程序。
CREATE OR REPLACE PROCEDURE dta_proc AS
l_xml xmltype;
l_val VARCHAR2(10000) := '<root>
<record>
<id_localisation>8PJ</id_localisation>
<data>
<id_client>50C</id_client>
<mail>1@mail.com</mail>
<adress>10 </adress>
<num_tel>001</num_tel>
<key>C</key>
<contact>
<name>toto</name>
<birth>01/30/009</birth>
<city>London</city>
</contact>
</data>
<data>
<id_client>25C</id_client>
<mail>2@gmaiil.com</mail>
<adress>20</adress>
<num_tel>02200</num_tel>
<key>D1</key>
<contact>
<name>tata</name>
<birth>02/08/2004</birth>
<city>Spa</city>
</contact>
</data>
</record>
<record>
<id_localisation>ESP31</id_localisation>
<data>
<id_client>70D</id_client>
<mail>3@gmail.com</mail>
<adress>7Bcd</adress>
<num_tel>5555</num_tel>
<key>D2</key>
<contact>
<name>titi</name>
<birth>05/07/2014</birth>
<city>StMarine</city>
</contact>
</data>
<data>
<id_client>10D</id_client>
<mail>4@gmail.com</mail>
<adress>888</adress>
<num_tel>881.0</num_tel>
<key>D3</key>
<contact>
<name>awk</name>
<birth>05/08/1999</birth>
<city>Bahrein</city>
</contact>
</data>
</record>
</root>';
statut number;
id_client varchar2(13);
date_ev date;
id_diff varchar2(13);
BEGIN
l_xml := xmltype(l_val);
FOR x IN
(SELECT VALUE(p) col_val
FROM TABLE(XMLSEQUENCE(EXTRACT(l_xml, '/begin/entry'))) p
)
loop
IF x.col_val.existsnode('/root/record/id_localisation//text()') > 0 THEN
localisation := x.col_val.extract('/root/record/id_localisation//text()').getstringval();
END IF;
if x.col_val.existsnode('/root/record/data/id_client/text()') > 0 then
id_client := x.col_val.extract('/root/record/data/id_client/text()').getstringval();
end if;
if x.col_val.existsnode('/root/record/data/num_tel/text()') > 0 then
num_tel := x.col_val.extract('/root/record/data/num_tel/text()').getstringval();
end if;
IF x.col_val.existsnode('/root/record/data/contact/city/text()') > 0 THEN
city := x.col_val.extract('/root/record/data/contact/city/text()').getstringval();
end if;
INSERT INTO Customer
(
Loca,
ID_CLT,
TEL,
Town
)
VALUES
(
localisation,
id_client,
num_tel,
city
);
localisation := null;
id_client := null;
num_tel := null;
city := null;
end loop;
commit;
end dta_proc;
执行时出错:
执行xml_procedure;
ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00245: extra data after end of document
Error at line 26
ORA-06512: at "SYS.XMLTYPE", line 310
ORA-06512: at "xml_procedure", line 58
ORA-06512: at line 1
31011. 00000 - "XML parsing failed"
*Cause: XML parser returned an error while trying to parse the document.
*Action: Check if the document to be parsed is valid.
还有一个问题。生成后如何在我的过程中自动加载 xml?
【问题讨论】:
请编辑您的问题并描述运行代码时出现的问题。提供一些你认为应该发生的事情的例子,然后告诉我们真正发生的事情。谢谢。 您在执行过程中是否遇到任何错误,如果有,请发布它们 我把执行脚本后遇到的错误放在了 【参考方案1】:我不会使用 xmlsequence 等来生成 xmltype,而是执行以下操作(在 11.2.0.3 上对我有用):
with sample_data as (select
'<root>
<record>
<id_localisation>8PJ</id_localisation>
<data>
<id_client>50C</id_client>
<mail>1@mail.com</mail>
<adress>10 </adress>
<num_tel>001</num_tel>
<key>C</key>
<contact>
<name>toto</name>
<birth>01/30/009</birth>
<city>London</city>
</contact>
</data>
<data>
<id_client>25C</id_client>
<mail>2@gmaiil.com</mail>
<adress>20</adress>
<num_tel>02200</num_tel>
<key>D1</key>
<contact>
<name>tata</name>
<birth>02/08/2004</birth>
<city>Spa</city>
</contact>
</data>
</record>
<record>
<id_localisation>ESP31</id_localisation>
<data>
<id_client>70D</id_client>
<mail>3@gmail.com</mail>
<adress>7Bcd</adress>
<num_tel>5555</num_tel>
<key>D2</key>
<contact>
<name>titi</name>
<birth>05/07/2014</birth>
<city>StMarine</city>
</contact>
</data>
<data>
<id_client>10D</id_client>
<mail>4@gmail.com</mail>
<adress>888</adress>
<num_tel>881.0</num_tel>
<key>D3</key>
<contact>
<name>awk</name>
<birth>05/08/1999</birth>
<city>Bahrein</city>
</contact>
</data>
</record>
</root>' str from dual)
-- end of mimicking your sample xml
select x.localisation,
y.id_client,
y.num_tel,
y.city
from sample_data sd,
xmltable('/root/record'
passing xmltype(sd.str)
columns localisation varchar2(20) path 'id_localisation',
subxml xmltype path '.') x,
xmltable('/record/data'
passing x.subxml
columns id_client varchar2(13) path 'id_client',
num_tel varchar2(10) path 'num_tel',
city varchar2(20) path 'contact/city') y;
LOCALISATION ID_CLIENT NUM_TEL CITY
-------------------- ------------- ---------- --------------------
8PJ 50C 001 London
8PJ 25C 02200 Spa
ESP31 70D 5555 StMarine
ESP31 10D 881.0 Bahrein
然后您可以在插入中使用该 select 语句(显然,没有 WITH
子句,因为您会将 xml 数据存储在某处(例如,传入的表或参数)。
关于你关于自动加载生成的 xml 的问题......你没有给我们足够的信息来回答这个问题。我假设生成 xml 的外部应用程序想要调用您的过程来存储它,并将 xml 作为参数传递。
【讨论】:
对不起,我不明白你在这里做什么,程序的声明在哪里?插入部分在哪里? 我给了你一个选择语句,它接受你提供的“xml”并输出结果。然后您可以将其插入到插入语句中(您知道INSERT INTO.... SELECT ...
,对吗?),然后您可以插入到过程中。你为什么不自己尝试做这件事——这样你会学到更多。如果您遇到困难,请务必编辑您的原始问题以添加您尝试过的内容,我们可以提供进一步的帮助。以上是关于使用 XMLType 在 oracle 表中加载 XML 的过程的主要内容,如果未能解决你的问题,请参考以下文章
将 oracle xmltype 表字段选择到 xmltype 变量中会导致空对象