1

我正在尝试从在 XML 类型列上创建的 Oracle 视图中获取数据。
例如:以下是 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是:

<MsrFact xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MsrNode>

  <shipTo>
     <name>shipTo</name>
   </shipTo>

   <billTo>
     <name>billTo</name>
   </billTo>

  <FormulaeItem>
    <name>FormulaeItem1</name>
  </FormulaeItem>

  <FormulaeItem>
     <name>FormulaeItem2</name>
     <street>100</street>
  </FormulaeItem>

  <FormulaeItem>
     <name>FormulaeItem3</name>
   </FormulaeItem>
</MsrNode> </MsrFact>

桌子: temptab( ogrid number(10), xdata xmltype);

看法: CREATE OR REPLACE VIEW
MsrFactView(orgid,shipTo,shipToR, billTo,billToR, FormulaeItem,FormulaeItemR)
AS SELECT ogrid,
extractValue(xdata, '/MsrFact/shipTo/name'),
extractValue(xdata, '/MsrFact/shipTo/street'),
extractValue(xdata, '/MsrFact/billTo/name'),
extractValue(xdata, '/MsrFact/billTo/street'),
extractValue(xdata, '/MsrFact/FormulaeItem/name'),
extractValue(xdata, '/MsrFact/FormulaeItem/street')
FROM temptab;

我无法在此视图上编写直接选择查询,因为它给出了错误
SQL 错误:ORA-01427:单行子查询返回多于一行
01427。00000 -“单行子查询返回多于一行”

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

4

1 回答 1

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,您将在视图中获得与该节点中的 FormulaeItems 数量一样多的行。

于 2012-04-09T13:08:26.600 回答