基于Oracle XML Type列从View访问数据

时间:2012-04-09 10:43:01

标签: oracle xmltype

我正在尝试从XML Type列上创建的Oracle View中获取数据 例如:以下是XSD:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="MsrFact" type="MsrNode"/>
<xsd:complexType name="MsrNode">
<xsd:sequence>

<xsd:element name="shipTo" type="MsrValue"/>
<xsd:element name="billTo" type="MsrValue"/>
<xsd:element name="FormulaeItem"  type="MsrValue" maxOccurs="10"/>
</xsd:sequence>
</xsd:complexType> <xsd:complexType name="MsrValue">
<xsd:sequence>

<xsd:element name="name"   type="xsd:string"/>
<xsd:element name="street" type="xsd:integer"/>
</xsd:sequence>
</xsd:complexType> </xsd:schema>


插入的xml是:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

表: <xsd:element name="MsrFact" type="MsrNode"/>

查看:<xsd:complexType name="MsrNode">
<xsd:sequence>


<xsd:element name="shipTo" type="MsrValue"/>
<xsd:element name="billTo" type="MsrValue"/>
<xsd:element name="FormulaeItem"  type="MsrValue" maxOccurs="10"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element name="shipTo" type="MsrValue"/> <xsd:element name="billTo" type="MsrValue"/> <xsd:element name="FormulaeItem" type="MsrValue" maxOccurs="10"/>
<xsd:element name="shipTo" type="MsrValue"/>
<xsd:element name="billTo" type="MsrValue"/>
<xsd:element name="FormulaeItem" type="MsrValue" maxOccurs="10"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="MsrValue">

我不能在这个视图上写一个直接选择查询,因为它给出了错误
SQL错误:ORA-01427:单行子查询返回多行 01427. 00000 - “单行子查询返回多行”

有没有办法从这个视图中获取数据? 谢谢!

1 个答案:

答案 0 :(得分:3)

extractValue仅从给定路径中提取单个值,但由于FormulaeItem可能很多,因此您不能在此处使用extractValue。 此外,使用extractValue是一种旧的,不推荐用于查询XML的方法。您应该使用新的XMLTable方法。

create or replace view MsrFactView as
select tt.ogrid,
st.name shiptoName, st.street shiptoStreeet,
bt.name billtoName ,bt.street billtoStreet,
fi.name formulaeitemname ,fi.street formulaeitemstreet
FROM
temptab tt,
XMLTABLE(
    '/MsrFact/MsrNode'
    passing tt.xdata
    columns
        shipto  XMLTYPE path '/MsrNode/shipTo'
        billto  XMLTYPE path '/MsrNode/billTo'
        formulaeitem XMLTYPE path '/MsrNode/FormulaeItem'
) nd,
XMLTable (
    '/shipTo'
    passing nd.shipto
    columns
    name varchar2(4000) path '/shipTo/name'
    street number path '/shipTo/street'
) st,
XMLTABLE (
    '/billTo'
    passing nd.billto
    columns
    name varchar2(4000) path '/billTo/name'
    street number path '/billTo/street'
) bt,
XMLTable (
    '/FormulaeItem'
    passing nd.formulaeitem
    columns
    name varchar2(4000) path '/FormulaeItem/name'
    street number path '/FormulaeItem/street'
) fi
/

要记住的一件事是,每个'MsrNode'不会得到一行,因为每个MsrNode有1-n FormulaeItem。可以将其视为连接2个具有1-n关系的表的SQL查询。就像在这种情况下,您将在父表的每1行获得'n'行。

因此,在您的情况下,根据每个MsrNode,您将在视图中获得尽可能多的行,作为该节点中的FormulaeItem的计数。