SQL-запрос для объединения таблицы с XML-элементом и получения свойств вложенного элемента - PullRequest
0 голосов
/ 03 мая 2019

У меня есть 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

Я хочу объединить xml и таблицу со свойствами PartNumber и мне нужен следующий вывод

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 Ответ

3 голосов
/ 03 мая 2019

Вы были близки. Вот как я бы сделал это с предоставленными вами образцами данных:

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 на более подходящие для ваших реальных данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...