0

我有以下XML: -從子節點OPENXML SQL返回相同節點值

<XML> 
<ProductDetail> 
    <ProductId>1</ProductId> 
    <PropertyDetail> 
     <PropertyKey>Size</PropertyKey> 
     <PropertyValue>XXL</PropertyValue> 
     <PropertyKey>ProdTaxType</PropertyKey> 
     <PropertyValue>5%</PropertyValue> 
     <PropertyKey>Incl/Excl</PropertyKey> 
     <PropertyValue>True</PropertyValue>   
     <PropertyKey>Fit</PropertyKey> 
     <PropertyValue>SLIM F/S</PropertyValue> 
    </PropertyDetail> 
</ProductDetail> 
</XML> 

但是,我得到如下結果:

ProductId PropertyKey PropertyValue 
    1   Size  XXL 

我需要使用獲得的所有PropertyDetail OPENXML。我的存儲過程小的查詢中,如下所示MS SQL 2012:

SELECT XML.ProductId, XML.PropertyKey, XML.PropertyValue FROM 
    OPENXML (@hDoc, '/XML/*', 2) WITH (
     ProductId INT 'ProductId', 
     PropertyKey VARCHAR(200) 'PropertyDetail/PropertyKey', 
     PropertyValue VARCHAR(200) 'PropertyDetail/PropertyValue' 
    ) XML 

的finall結果會看起來像如下:

ProductId PropertyKey PropertyValue 
    1   Size   XXL 
    1   ProdTaxType  5% 
    1   Incl/Excl  True 
    1   Fit   SLIM F/S  

回答

1

我會嘗試以下解決方案:

DECLARE @x XML = N'<XML> 
<ProductDetail> 
    <ProductId>1</ProductId> 
    <PropertyDetail> 
     <PropertyKey>Size</PropertyKey> 
     <PropertyValue>XXL</PropertyValue> 
     <PropertyKey>ProdTaxType</PropertyKey> 
     <PropertyValue>5%</PropertyValue> 
     <PropertyKey>Incl/Excl</PropertyKey> 
     <PropertyValue>True</PropertyValue>   
     <PropertyKey>Fit</PropertyKey> 
     <PropertyValue>SLIM F/S</PropertyValue> 
    </PropertyDetail> 
</ProductDetail> 
</XML>' 

SELECT pvt.ProductId, pvt.NodeNum, pvt.[0] AS PKey, pvt.[1] AS PValue 
FROM (
    SELECT x.XmlCol.value('(ProductId/text())[1]', 'INT')   AS ProductId, 
      (DENSE_RANK() OVER(ORDER BY y.XmlCol) + 1)/2   AS NodeNum, 
      (DENSE_RANK() OVER(ORDER BY y.XmlCol) + 1) % 2   AS NodeType, -- 0 = PropertyKey, 1 = PropertyValue 
      y.XmlCol.value('(text())[1]', 'NVARCHAR(50)')   AS NodeValue 
    FROM @x.nodes('XML/ProductDetail') x(XmlCol) 
    OUTER APPLY x.XmlCol.nodes('PropertyDetail/*') y(XmlCol) 
) AS src -- source 
PIVOT(MAX(src.NodeValue) FOR NodeType IN ([0], [1])) AS pvt 

結果:

ProductId NodeNum PKey  PValue 
--------- ------- ----------- -------- 
1   1  Size  XXL 
1   2  ProdTaxType 5% 
1   3  Incl/Excl True 
1   4  Fit   SLIM F/S 

參考:Uniquely Identifying XML Nodes with DENSE_RANK

Online Demo

注:我不知道這是否是可能的,但我會因此改變XML架構:

... 
<property name="Size" value="XXL" /> 
<property name="ProdTaxType" value="5%" /> 
... 

實際的XML模式是,不知何故,因爲它依賴於XML元素的順序PropertyKey/PropertyValue

+0

注意:請不要使用OPENXML。在某些情況下,它會導致內存泄漏。相反,我使用的是節點()方法。 –