2014-02-24 88 views
1

我想通過SQL Server 2008 R2中的XML進行解析,並遇到一些問題。我試圖解析每個父節點的項目,但我似乎無法獲得準確的數據。 XML數據如下:在SQL Server 2008 R2中查詢複雜的XML

<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Project.xsd" Name="Job"> 
    <Design> 
    <Catalog> 
     <Identification> 
     <Name>Group1</Name> 
     </Identification> 
     <FeatureSet ID="IDFS-1" Type="Style"> 
     <Description>Style1</Description> 
     </FeatureSet> 
     <Item ID="IDI-1-2730"> 
     <UserCode>Item1</UserCode> 
     <LineItemNumber>1</LineItemNumber> 
     </Item> 
     <Item ID="IDI-1-1595"> 
     <UserCode>Item2</UserCode> 
     <LineItemNumber>2</LineItemNumber> 
     </Item> 
    </Catalog> 
    <Catalog> 
     <Identification> 
      <Name>Group2</Name> 
     </Identification> 
     <FeatureSet ID="IDFS-1" Type="Style"> 
     <Description>Style2</Description> 
     </FeatureSet> 
     <Item ID="IDI-1-2730"> 
     <UserCode>Item3</UserCode> 
     <LineItemNumber>1</LineItemNumber> 
     </Item> 
    </Catalog> 
    </Design> 
</Project> 

這是我到目前爲止的SQL,但似乎沒有工作。

select 
    x.d.query('./UserCode').value('.','char(40)') as UserCode 
    ,x.d.query('./LineItemNumber').value('.','char(40)') as lineitemnumber 
    ,i.d.query('./Name').value('.','nvarchar(200)') as [Group] 
    ,u.d.query('./Description').value('.','nvarchar(200)') as Style 
from 
    @xml.nodes('/Project/Design/Catalog/Item') as x(d) 
outer apply 
    @xml.nodes('/Project/Design/Catalog/Identification') as i(d) 
outer apply 
    @xml.nodes('/Project/Design/Catalog/FeatureSet') as u(d) 

很明顯,我將@xml設置爲上面的XML數據類型的XML數據。

下面是我得到的結果:

UserCode lineitemnumber Group Style 
Item1  1    Group1 Style1 
Item1  1    Group1 Style2 
Item1  1    Group2 Style1 
Item1  1    Group2 Style2 
Item2  2    Group1 Style1 
Item2  2    Group1 Style2 
Item2  2    Group2 Style1 
Item2  2    Group2 Style2 
Item3  1    Group1 Style1 
Item3  1    Group1 Style2 
Item3  1    Group2 Style1 
Item3  1    Group2 Style2 

我所尋找的是:

UserCode lineitemnumber Group Style 
Item1  1    Group1 Style1 
Item2  2    Group1 Style1 
Item3  1    Group2 Style2 

每個目錄將只有一個識別/說明,也只會有一個FEATURESET /說明

回答

1

正如@Backs所述,父節點查詢可以執行b ADLY,這樣你就可以通過交叉避免它從父應用到孩子,那麼你可以根據需要指代部分:

select 
    -- these 2 are from the child (Item) 
    c.i.value('(UserCode/text())[1]', 'char(40)') as UserCode, 
    c.i.value('(LineItemNumber/text())[1]', 'char(40)') as lineitemnumber, 

    -- these are from the parent (Catalog) 
    d.c.value('(Identification/Name/text())[1]', 'nvarchar(200)') as [Group], 
    d.c.value('(FeatureSet/Description/text())[1]', 'nvarchar(200)') as Style 
from 
    @xml.nodes('/Project/Design/Catalog') d(c) -- the parent node 
    cross apply d.c.nodes('Item') c(i) -- the Item nodes under the Catalog parent 

這有一個更好的估計計劃相比

1
select 
    x.d.query('./UserCode').value('.','char(40)') as UserCode 
    ,x.d.query('./LineItemNumber').value('.','char(40)') as lineitemnumber 
    ,x.d.query('../Identification/Name').value('.','nvarchar(200)') as [Group] 
    ,x.d.query('../FeatureSet/Description').value('.','nvarchar(200)') as Style 
from @xml.nodes('/Project/Design/Catalog/Item') as x(d) 
+0

這正是我在尋找。謝謝你回來! –

+0

@FredPhillips,不客氣。但我應該注意到,返回父節點(如'query('../ Identification/Name')')是一種冒險行爲,它會導致大數據的性能問題 – Backs