2016-12-28 6 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"입니다. 이러한 항목은 각 형제가 더 큰 패키지 (부모)의 일부로 중첩되어 있습니다. 주문에있는 두 번째 독립 실행 형 항목의 순위는 "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를 사용하면 group 요소에 XML을 파쇄 할 수 있으며 Item 요소는 group에 속합니다. 그럼 당신은 그 두 요소에서 시작하여 필요한 값을 선택할 수 있습니다 :

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

선택

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 변수는 다음과 같이 선언이다 열 IPrice, IRank, ILevelITax은 연습으로 남겨 둡니다.

+0

대단히 고마워요! 이것은 매우 도움이되었습니다. 간단한 질문이지만 OpenXML보다 훨씬 느리게 실행되는 것 같습니다. 이것에 대한 이유가 있습니까? 아니면 내 편이 아닐까? 내가 다루는 XML 파일은 하루에 약 1.5GB이다. –