SQL查询以使用XML元素联接表并获取嵌套的元素属性

时间:2019-05-03 11:18:39

标签: sql sql-server xml join

我有如下所示的XML

<Parent>  
    <BOMLine> 
    **<partnumber>abc</partnumber>**
    <SortOrder>0</SortOrder> 
    <Component>
      <PartNo>SE3008</PartNo>
      <Comp>12P6383X012</Comp>
      <CompDesc>SQ Controller</CompDesc>
      <Qty>1</Qty>
    </Component>
    <ChangeOrder>
      <Qty>10</Qty>
      <COId>AS</COId>
      <IsQtyLinked>false</IsQtyLinked>
    </ChangeOrder> 
    <ChangeOrder>
      <Qty>10</Qty>
      <COId>AS1</COId>
      <IsQtyLinked>true</IsQtyLinked>
    </ChangeOrder>
  </BOMLine>
  <BOMLine> ....
</Parent> 

和这样的临时表:

enter image description here

我想在PartNumber属性上加入xml和表,并需要以下输出

enter image description here

而且我不想使用文档句柄来处理xml,

请帮助我获得所需的输出。

我尝试过下面的代码,但是对于如何在加入时从XML中获取嵌套元素感到困惑。

DECLARE @TempTable TABLE (ID INT,
                          partnumber VARCHAR(200),
                          sortnumber INT)

INSERT INTO @TempTable (ID, partnumber, sortnumber) 
VALUES (123, 'abc', 1)



  DECLARE @xml XML ='<Parent>  
        <BOMLine> 
        <partnumber>abc</partnumber>
        <SortOrder>0</SortOrder> 
        <Component>
          <PartNo>SE3008</PartNo>
          <Comp>12P6383X012</Comp>
          <CompDesc>SQ Controller</CompDesc>
          <Qty>1</Qty>
        </Component>
        <ChangeOrder>
          <Qty>10</Qty>
          <COId>AS</COId>
          <IsQtyLinked>false</IsQtyLinked>
        </ChangeOrder> 
        <ChangeOrder>
          <Qty>10</Qty>
          <COId>AS1</COId>
          <IsQtyLinked>true</IsQtyLinked>
        </ChangeOrder>
      </BOMLine> 

     <BOMLine> 
        <partnumber>abc</partnumber>
        <SortOrder>0</SortOrder> 
        <Component>
          <PartNo>SE3008</PartNo>
          <Comp>12P6383X012</Comp>
          <CompDesc>SQ Controller</CompDesc>
          <Qty>1</Qty>
        </Component>
        <ChangeOrder>
          <Qty>10</Qty>
          <COId>AS</COId>
          <IsQtyLinked>false</IsQtyLinked>
        </ChangeOrder> 
        <ChangeOrder>
          <Qty>10</Qty>
          <COId>AS1</COId>
          <IsQtyLinked>true</IsQtyLinked>
        </ChangeOrder>
      </BOMLine> 
    </Parent> '




SELECT  TT.ID,
       TT.partnumber,
       B.CO.value('(Qty/text())[1]','int') AS Qty,
       B.CO.value('(COId/text())[1]','char(2)') AS COId,
       B.CO.value('(IsQtyLinked/text())[1]','varchar(5)') AS IsLinked
FROM @TempTable TT  
     CROSS APPLY @xml.nodes('Parent/BOMLine') P(BOM)
     CROSS APPLY P.BOM.nodes('./ChangeOrder') B(CO)
WHERE TT.partnumber = P.BOM.value('(partnumber/text())[1]','varchar(3)');

1 个答案:

答案 0 :(得分:3)

你很近。这就是我要使用您提供的示例数据进行处理的方式:

SELECT TT.ID,
       TT.partnumber,
       B.CO.value('(Qty/text())[1]','int') AS Qty,
       B.CO.value('(COId/text())[1]','char(2)') AS COId,
       B.CO.value('(IsQtyLinked/text())[1]','varchar(5)') AS IsLinked
FROM @TempTable TT
     CROSS APPLY @xml.nodes('Parent/BOMLine') P(BOM)
     CROSS APPLY P.BOM.nodes('./ChangeOrder') B(CO)
WHERE TT.partnumber = P.BOM.value('(partnumber/text())[1]','varchar(3)');

请注意,我两次使用nodes,一次是为每个BOMLine获取一行,另一次为每个ChangeOrder获取一行。然后,我使用WHERE为表(JOIN)创建一个隐式@TempTable

这是示例数据,请注意,您可能需要将返回数据类型从XML更改为更适合您的真实数据的类型。