在表中读取XML

时间:2012-07-22 10:39:27

标签: sql xml tsql xpath xquery

我有一个存储过程,它将XML作为参数传递,然后我必须读取该xML并进行一些更新。 XML的格式是

<Requests>
    <RequestReference>R12345</RequestReference>
    <Inventory InventoryId="1" InventoryName="I1">
        <RequestCodes>
            <Code>AAA</Code>
        </RequestCodes>
    </Inventory>
    <Inventory InventoryId="2" InventoryName="I2">
        <RequestCodes>
            <Code>BBB</Code>
            <Code>CCC</Code>
        </RequestCodes>
    </Inventory>
    <Inventory InventoryId="3" InventoryName="I3">
        <RequestCodes>
            <Code>DDD</Code>
            <Code>EEE</Code>
            <Code>FFF</Code>
        </RequestCodes>
    </Inventory>
</Requests>

现在我需要在像

这样的表中读取XML
RequestReference    InventoryId InventoryName           Code
R12345                    1           I1            AAA
R12345                    2           I2            BBB
R12345                    2           I2            CCC
R12345                    3           I3            DDD
R12345                    3           I3            EEE
R12345                    3           I3            FFF

我正在尝试像

这样的东西
SELECT 
    T.Item.value('@InventoryId', 'VARCHAR(3)')  AS InventoryId,
    T.Item.value('@InventoryName', 'VARCHAR(3)')    AS InventoryName,
    T.Item.value('RequestCodes[1]/Code[1]', 'VARCHAR(5)')   AS Code
FROM   
   @xmlDoc.nodes('Requests/Inventory') 
   AS T(Item)

它产生的结果是

InventoryId InventoryName   Code
1                 I1    AAA
2                 I2    BBB
3                 I3    DDD

所以这似乎有效但不能完全产生预期的结果。

2 个答案:

答案 0 :(得分:2)

使用:

select *
from
(
SELECT
    T.Item.value('../../../RequestReference[1]', 'VARCHAR(20)')  AS RequestReference,
    T.Item.value('../../@InventoryId', 'VARCHAR(3)')  AS InventoryId,
    T.Item.value('../../@InventoryName', 'VARCHAR(3)')    AS InventoryName,
    T.Item.value('.', 'VARCHAR(5)')   AS Code
FROM   
   @xmlDoc.nodes('//Code') 
   AS T(Item)
)t
order by InventoryId, InventoryName, Code

答案 1 :(得分:2)

试试这个。你可以使用外部或交叉应用

select
--ref.query('.'),
rr.rr.value('(.)[1]','varchar(20)') as RequestReference,
--inv.inv.query('.'),
inv.inv.value('(./@InventoryId)[1]','int') as InventoryId ,
inv.inv.value('(./@InventoryName)[1]','Varchar(20)') as InventoryName ,
rc.rc.value('(.)[1]','varchar(20)') as Codes
from 
@xml.nodes('Requests') rq(ref)
cross apply rq.ref.nodes('./Inventory') inv(inv)
cross apply inv.inv.nodes('./RequestCodes/Code') rc(rc)
cross apply rq.ref.nodes('./RequestReference') rr(rr)