2017-01-27 3 views
3

데이터를 가져올 수천 개의 XML 파일이 있습니다. 이를 달성하기 위해 교차 적용 방법을 사용했습니다.노드가 항상 존재하지 않는 경우에도 모든 행 가져 오기

그러나 문제는 일부 노드가 xml 파일에 항상 존재하지 않는다는 것입니다. 이 예에서는 노드 'valueX'(제품 노드 내부)입니다. 그리고이 노드는 마지막 사람에게만 존재합니다.

<invoice> 
    <person> 
     <name>John</name> 
     <product> 
      <id>abc</id> 
      <price>100</price> 

     </product> 
     <product> 
      <id>def</id> 
      <price>99</price> 

     </product> 
    </person> 

    <person> 
     <name>Mary</name> 
     <product> 
      <id>abc</id> 
      <price>200</price> 

     </product> 
    </person> 

    <person> 
     <name>Peter</name> 
     <product> 
      <id>abc</id> 
      <price>300</price> 

     </product> 
    </person> 

    <person> 
     <name>Sue</name> 
     <product> 
      <id>abc</id> 
      <price>400</price> 
      <valueX> 
       <name>test</name> 
      </valueX> 
     </product> 
    </person> 

</invoice> 

내가 쿼리 경우 지금 십자가와 XML 파일이 'valueX'노드를 사용하여 적용,이 노드를 포함하는 단지 하나 개의 레코드를 얻을.

declare @tab table (
          id int 
         , xmlData xml 
        ) 

declare @xml nvarchar(max) 

set @xml = ' 
       <invoice> 
        <person> 
         <name>John</name> 
         <product> 
          <id>abc</id> 
          <price>100</price> 

         </product> 
         <product> 
          <id>def</id> 
          <price>99</price> 

         </product> 
        </person> 

        <person> 
         <name>Mary</name> 
         <product> 
          <id>abc</id> 
          <price>200</price> 

         </product> 
        </person> 

        <person> 
         <name>Peter</name> 
         <product> 
          <id>abc</id> 
          <price>300</price> 

         </product> 
        </person> 

        <person> 
         <name>Sue</name> 
         <product> 
          <id>abc</id> 
          <price>400</price> 
          <valueX> 
           <name>test</name> 
          </valueX> 
         </product> 
        </person> 

       </invoice> 
      ' 


insert into @tab (id, xmlData) 
values (
       1 
      , @xml 
     ) 


select t.id 
     , Person.ref.value('name[1]','nvarchar(255)') as PersonName 
     , Product.ref.value('id[1]','nvarchar(3)')  as ProductID 
     , Product.ref.value('price[1]','int')   as ProductPrice 
     , ValueX.ref.value('name[1]','nvarchar(255)') as ValueXName 

from @tab as t 

cross apply t.xmlData.nodes('invoice/person') Person(ref) 
    cross apply Person.ref.nodes('product') Product(ref) 
     cross apply Product.ref.nodes('valueX') ValueX(ref)  

그러나 노드가없는 경우에도 모든 레코드가 있어야합니다.

어떻게하면됩니까?

답변

1

그냥

from @tab as t 

outer apply t.xmlData.nodes('invoice/person') Person(ref) 
    outer apply Person.ref.nodes('product') Product(ref) 
     outer apply Product.ref.nodes('valueX') ValueX(ref) 

CROSS APPLY에 마지막 부분을 변경은 OUTER APPLY

+0

LEFT JOIN 같은 동안 INNER JOIN처럼 정말 감사합니다! 정말 빠른 배송! – gbr