问题描述
我有一个要求,我必须将 XML 表列选择为记录数据类型,该数据类型是静态数据类型和集合的组合。我搜索了各种来源,说 Xpath 可以返回节点列表,但我怀疑是否可以使用列的集合数据类型来存储此节点列表。
type MobileTable is Table of number Index by pls_integer;
type purchase is record (vegetables varchar2(20),fruits varchar2(30));
type food is table of purchase Index by pls_integer;
type data is record
(Name varchar2(30),Mobile_Number MobileTable,Purchases food);
<customers>
<month>July</month>
<day>Tuesday</day>
<start-time>11</start-time>
<customer>
<Name>sally</Name>
<Mobile-Number>999-256-00</Mobile-Number>
<Mobile-Number>999-256-11</Mobile-Number>
<purchase>
<vegetables>Carrot</vegetables>
<fruits>Apple</fruits>
</purchase>
<purchase>
<vegetables>broccli</vegetables>
<fruits>Orange</fruits>
</purchase>
<customer>
</customers>
about XML 只是我用来解释我的需求的一个例子,如果问题不清楚,请提出建议。
我的查询:
select Name,Mobile_Number,Purchases into data from custommers_table ct,xmltable('customers'
passing ct.cust_xml
columns Name varchar2(20) path 'Name',Mobile_Number MobileTable path 'Mobile-Number',Purchases food path '//purchase/vegetables|//purchase/fruit')
where cust_xml_id=1;
在 Mobile_Number 和 Purchases 的情况下,我收到无效的数据类型错误。
//purchase/vegetables|//purchase/fruit
我在 W3 学校的 Xpath 语法概念下发现了这个 XPath,我不确定它的正确性,但这就是我想要实现的目标。
请建议我是否还有其他方法可以实现这一点。
解决方法
作为一种相当暴力的方法,您可以将手机号码和购买作为子 xmltype 变量获取,并在循环中填充集合:
declare
type t_mobile_numbers_tab is table of varchar2(15) index by pls_integer;
type t_purchase_rec is record (
vegetables varchar2(20),fruits varchar2(30)
);
type t_purchases_tab is table of t_purchase_rec index by pls_integer;
type t_data_rec is record (
name varchar2(30),mobile_numbers t_mobile_numbers_tab,purchases t_purchases_tab
);
l_data t_data_rec;
l_mobile_numbers xmltype;
l_purchases xmltype;
begin
select name,mobile_numbers,purchases
into l_data.name,l_mobile_numbers,l_purchases
from custommers_table ct
cross apply xmltable('customers/customer'
passing ct.cust_xml
columns name varchar2(20) path 'Name',mobile_numbers xmltype path 'Mobile-Number',purchases xmltype path 'purchase/vegetables|purchase/fruits'
)
where cust_xml_id=1;
for r in (
select mobile_number
from xmltable('Mobile-Number'
passing l_mobile_numbers
columns mobile_number varchar2(15) path '.'
)
)
loop
l_data.mobile_numbers(l_data.mobile_numbers.count) := r.mobile_number;
end loop;
for r in (
select type,purchase
from xmltable('*'
passing l_purchases
columns type varchar2(10) path 'name(.)',purchase varchar2(30) path '.'
)
)
loop
if r.type = 'vegetables' then
l_data.purchases(l_data.purchases.count).vegetables := r.purchase;
elsif r.type = 'fruits' then
l_data.purchases(l_data.purchases.count).fruits := r.purchase;
end if;
end loop;
end;
/
第一个查询获取标量名称和两个子 xmltype 值。然后在游标查询中使用这些 xmltype 变量,在这些游标循环中,数字/购买被提取并分配给子集合中的记录。
db<>fiddle 显示中间值,并打印出集合的内容以查看填充的内容。
对于对象类型而不是记录,这会更简单一些;但仍然觉得可能有更有效的方法。