我正在使用Oracle版本-11.2.0.4
我在下面以更简化的方式重现了我所面临的问题。 我有2个带有XMLTYPE列的表。 表1(在下面的示例中为base_table)具有XMLTYPE作为BINARY XML的存储模型。 表2(my_tab)具有XMLTYPE作为CLOB的存储模型。
使用base_table中的XML,我将根据特定条件提取属性的值。 反过来,此属性是my_tab中包含的xml中节点的名称,我想从my_tab中提取该节点的值。 请注意,我目前无权更改此逻辑。
在两个表中XMLTYPE列的存储模型均为CLOB之前,代码运行良好。 最近,base_table被重新创建(拖放),因此它的存储模型被修改为BINARY XML,据我所知,这是版本11.2.0.4中的默认存储模型。
这是创建表stmt和示例数据-
create table base_table(xml xmltype);
create table my_tab(xml xmltype)
xmltype column "XML" store as clob;
insert into base_table(xml)
values (xmltype('
A-Node1
A-Node2
B-Node1
B-Node2
C-Node1
C-Node2
')
);
insert into my_tab(xml)
values (xmltype('
My area of concern
Something irrelevant
Some value for this node
')
);
以下查询失败:
select extract(t.xml, sd.tag_name).getstringval()
from (select '//' || extract(value(d), '//@NAME').getstringval() || '/text()' as tag_name
from base_table b,
table(xmlsequence(extract(b.xml, '//ROOT/ELEMENT'))) d
where extract(value(d), '//NODE2/text()').getstringval() = 'B-Node2') sd,
my_tab t;
ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00601: Invalid token in: '///text()'
但是,此查询工作正常,并且能够提取我感兴趣的节点的值。可以看出,根据需要提取了tag_name,但是当在“提取”中使用它时,它的值就会丢失。
select sd.tag_name, extract(t.xml, '//NodeB/text()').getstringval()
from (select '//' || extract(value(d), '//@NAME').getstringval() || '/text()' as tag_name
from base_table b,
table(xmlsequence(extract(b.xml, '//ROOT/ELEMENT'))) d
where extract(value(d), '//NODE2/text()').getstringval() = 'B-Node2') sd,
my_tab t;
如果我将base_table的XMLTYPE存储模型更改回CLOB,则错误的查询将再次正常运行。
我想了解BINARY XML的存储模型出了什么问题。
我修改查询如下,它工作正常。 即转换为Clob并返回XMLTYPE:
select extract(t.xml, sd.tag_name).getstringval()
from (select '//' || extract(value(d), '//@NAME').getstringval() || '/text()' as tag_name
from base_table b,
table(xmlsequence(extract(XMLTYPE(b.xml.getclobval()), '//ROOT/ELEMENT'))) d
where extract(value(d), '//NODE2/text()').getstringval() = 'B-Node2') sd,
my_tab t;
谢谢,卡拉什