2016-12-28 5 views
4

私はXMLデータ構造を持っていますが、XML_STLDテーブルに保存されています(私は変更できません)。同じ名前の兄弟である要素を含むOpenXMLの解析

<rootnode> 
    <group id="00001" status="online"> 
     <order OrdId="42" Type="Sale"> 
      <Item code="1234" qty="1" unitprice="38.00" rank="0" level="0"> 
       <Item code="5678" qty="1" unitprice="11.00" rank="0" level="1"> 
        <Item code="9876" qty="1" unitprice="8.00" rank="0" level="2"> 
        <Tax percent="12"/></Item> 
       <Tax percent="12"/></Item> 
      <Tax percent="12"/></Item> 
      <Item code="7654" qty="1" unitprice="98.00" rank="1" level="0"> 
       <Item code="3211" qty="1" unitprice="8.00" rank="1" level="1"> 
       <Tax percent="12"/></Item> 
      <Tax percent="12"/></Item> 
     </order> 
    </group> 
</rootnode> 

マイOpenXMLのクエリは次のようになります。

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX) 

SELECT @XML = XMLData FROM XML_STLD 

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML 

SELECT GroupId, GroupStatus, OrdId, OrdType, ICode, IQty, IPrice, 
IRank, ILevel, ITax 

FROM OPENXML(@hDoc, 'rootnode/group/order/Item/Tax') 
WITH 
(
GroupId int '../../../@id', 
GroupStatus [varchar](100) '../../../@status', 
OrdId int '../../@OrdId', 
OrdType [varchar](100) '../../@Type', 
ICode int '../@code', 
IQty int '../@qty', 
IPrice numeric(18,2) '../@unitprice', 
IRank int '../@rank', 
ILevel int '../@level', 
ITax int '@percent' 
) 

EXEC sp_xml_removedocument @hDoc 
GO 

が今私のクエリは本当によく動作しますが、それはそれが唯一の最初の項目とそれに関連する税務上の兄弟を返し、大きな問題があります。要素の簡単な説明を入力する:

各項目にはランクとレベルがあります。あなたが見ることができる最初の3つはお互いの兄弟であり、ランクは "0"です。しかし、祖父母は「0」のレベル、「1」の親などを有する。これらの項目は、それぞれの兄弟がより大きなパッケージ(その親)の一部としてネストされます。注文上の2番目のスタンドアローンアイテムはランクが「1」であり、レベルは再び「0」で始まります。

私の現在の出力は次のとおりです。

GroupId | GroupStatus | OrdId | OrdType | ICode | IQty | IPrice | IRank | ILevel | ITax 
------- | ----------- | ----- | ------- | ----- | ---- | ------ | ----- | ------ | ---- 
1  | online  | 42 | Sale | 1234 | 1 | 38.00 | 0  | 0  | 12 
1  | online  | 42 | Sale | 7654 | 1 | 98.00 | 1  | 0  | 12 

私に必要な出力は次のようになります。

GroupId | GroupStatus | OrdId | OrdType | ICode | IQty | IPrice | IRank | ILevel | ITax 
------- | ----------- | ----- | ------- | ----- | ---- | ------ | ----- | ------ | ---- 
1  | online  | 42 | Sale | 1234 | 1 | 38.00 | 0  | 0  | 12 
1  | online  | 42 | Sale | 5678 | 1 | 11.00 | 0  | 1  | 12 
1  | online  | 42 | Sale | 9876 | 1 | 8.00 | 0  | 2  | 12 
1  | online  | 42 | Sale | 7654 | 1 | 98.00 | 1  | 0  | 12 
1  | online  | 42 | Sale | 3211 | 1 | 8.00 | 1  | 1  | 12 

誰かは、XQueryの回避策を支援することができれば私もうれしいです。現在SQL Server 2012を使用しています。

答えて

3

XQueryを使用すると、XMLはgroup要素に、そしてItem要素は、groupのどこにでも細断できます。そして、あなたは、これらの2つの要素から始めて必要な値を選択することができます。

select 
    grp.value('@id', 'int') AS GroupId, 
    grp.value('@status', 'varchar(100)') AS GroupStatus, 
    grp.value('(order/@OrdId)[1]', 'varchar(100)') AS OrdId, 
    grp.value('(order/@Type)[1]', 'varchar(100)') AS OrdType, 
    item.value('@code', 'int') AS ICode, 
    item.value('@qty', 'int') AS IQty 
from @xml.nodes('rootnode/group') A(grp) 
outer apply grp.nodes('.//Item') AS B(item) 

@xmlは、次のように宣言したXML変数であると仮定します

declare @xml AS XML = '<rootnode> 
    <group id="00001" status="online"> 
     <order OrdId="42" Type="Sale"> 
      <Item code="1234" qty="1" unitprice="38.00" rank="0" level="0"> 
       <Item code="5678" qty="1" unitprice="11.00" rank="0" level="1"> 
        <Item code="9876" qty="1" unitprice="8.00" rank="0" level="2"> 
         <Tax percent="12" /> 
        </Item> 
        <Tax percent="12" /> 
       </Item> 
       <Tax percent="12" /> 
      </Item> 
      <Item code="7654" qty="1" unitprice="98.00" rank="1" level="0"> 
       <Item code="3211" qty="1" unitprice="8.00" rank="1" level="1"> 
        <Tax percent="12" /> 
       </Item> 
       <Tax percent="12" /> 
      </Item> 
     </order> 
    </group> 
</rootnode>' 

出力:の

enter image description here

セレクション列IPrice,IRankILevelおよびITaxは練習問題として残っています。

+0

ありがとうございました!これは非常に役に立ちました。簡単な質問ですが、OpenXMLよりもはるかに遅く実行されているようです。これには理由がありますか?それとも私の側にあるの?私が扱っているXMLファイルは約1.5GB /日です。 –

関連する問題