我怎样才能粉碎xml并保留关联?

时间:2013-06-29 03:17:17

标签: sql-server sql-server-2005 xquery-sql

我有以下xml。如果你运行它,你将有3个网格结果。我正在努力处理最后的网格结果,因为我需要网格结果来获得相关的关联。换句话说,我希望网格结果#3中的网格结果#2中有相关的RowID。我怎样才能做到这一点?最终,网格结果#2将插入到具有名为SalesOrderID的主键的永久表中。网格结果#3将以SalesOrderID作为外键进入另一个表。

非常感谢!

    DECLARE @string VARCHAR(max);
DECLARE @xml XML;
SET @string ='<ShipmentConfirmationMessage>
  <ExternalCorrelationId>249801</ExternalCorrelationId>
  <ShippedItems>
    <ShipmentConfirmationLine>
      <SalesOrderNumber>SalesOrder1</SalesOrderNumber>
      <ItemId>10982</ItemId>
      <IsBackOrdered>false</IsBackOrdered>
      <TrackingNumber>Track1234</TrackingNumber>
      <Lots>
        <Lot>
          <LotNumber>789</LotNumber>
          <ExpiryDate>2013-12-20T00:00:00</ExpiryDate>
          <Quantity>1.55</Quantity>
        </Lot>

      </Lots>
    </ShipmentConfirmationLine>
    <ShipmentConfirmationLine>
      <SalesOrderNumber>SalesOrder2</SalesOrderNumber>
      <ItemId>10983</ItemId>
      <IsBackOrdered>true</IsBackOrdered>
      <TrackingNumber>Track123456789</TrackingNumber>
      <Lots>
        <Lot>
          <LotNumber>1</LotNumber>
          <ExpiryDate>2013-12-20T00:00:00</ExpiryDate>
          <Quantity>3.30</Quantity>
        </Lot>
        <Lot>
          <LotNumber>21</LotNumber>
          <ExpiryDate>2016-12-20T00:00:00</ExpiryDate>
          <Quantity>34.30</Quantity>
        </Lot>
      </Lots>
    </ShipmentConfirmationLine>
      </ShippedItems>
</ShipmentConfirmationMessage>
';
SET @xml = CONVERT(XML, @string, 1);
-- header
SELECT
@xml.value('/ShipmentConfirmationMessage[1]/ExternalCorrelationId[1]', 'varchar(50)') PurchaseOrderID
-- detail lines
SELECT IDENTITY(int, 1,1) AS RowID
 ,doc.col.value('SalesOrderNumber[1]', 'varchar(50)') SalesOrderNumber
 ,doc.col.value('ItemId[1]', 'varchar(50)') ItemId
 ,doc.col.value('IsBackOrdered[1]', 'varchar(50)') IsBackOrdered
 ,doc.col.value('TrackingNumber[1]', 'varchar(50)') TrackingNumber
 INTO #tmpDetails
FROM @xml.nodes('/ShipmentConfirmationMessage/ShippedItems/ShipmentConfirmationLine') doc(col) 
select * from #tmpDetails

-- lots associated with detail lines
SELECT
'Relevant RowID goes here',
doc.col.value('LotNumber[1]', 'varchar(50)') LotNumber
,doc.col.value('ExpiryDate[1]', 'datetime') ExpiryDate
,doc.col.value('Quantity[1]', 'decimal(13,5)') Quantity
 FROM @xml.nodes('/ShipmentConfirmationMessage/ShippedItems/ShipmentConfirmationLine/Lots/Lot') doc(col) 

 drop table #tmpDetails

1 个答案:

答案 0 :(得分:0)

Lots的XML存储在#tmpDetails.Lots

SELECT IDENTITY(int, 1,1) AS RowID
 ,doc.col.value('SalesOrderNumber[1]', 'varchar(50)') SalesOrderNumber
 ,doc.col.value('ItemId[1]', 'varchar(50)') ItemId
 ,doc.col.value('IsBackOrdered[1]', 'varchar(50)') IsBackOrdered
 ,doc.col.value('TrackingNumber[1]', 'varchar(50)') TrackingNumber
 ,doc.col.query('Lots') Lots
 INTO #tmpDetails
FROM @xml.nodes('/ShipmentConfirmationMessage/ShippedItems/ShipmentConfirmationLine') doc(col) 

使用#tmpDetails在第三个查询中使用CROSS APPLY来粉碎Lots中的XML。

SELECT
  D.RowID
 ,doc.col.value('LotNumber[1]', 'varchar(50)') LotNumber
 ,doc.col.value('ExpiryDate[1]', 'datetime') ExpiryDate
 ,doc.col.value('Quantity[1]', 'decimal(13,5)') Quantity
FROM #tmpDetails D
  CROSS APPLY D.Lots.nodes('Lots/Lot') doc(col)