2015-04-23 38 views
3
Declare @MainXml XML = 
'<?xml version="1.0" encoding="utf-8"?> 
<result> 
<cash number="10"> 
<account amt="11.00" status="Closed"/> 
<account amt="12.00" status="Closed"/>      
</cash>   
<cash number="20"> 
<account amt="21.00" status="Closed"/> 
<account amt="22.00" status="Closed"/>      
</cash>   
</result>' 

讀取XML標籤重複我使用閱讀下面的查詢在SQL Server

Declare @Innerxml xml; 
SELECT @Innerxml = T.c.query('<result>{/result/cash}</result>') 
FROM @MainXml.nodes('result') T(c) 

SELECT 
Result.Claim.value('(./@number)[1]','varchar(max)') as C1, 
Result.Claim.value('(./@amt)[1]','varchar(max)') as C2, 
Result.Claim.value('(./@status)[1]','varchar(max)') as C3 
From @Innerxml.nodes('/result/cash/account') Result(Claim) 

我想讀在DB作爲下面的XML和存儲數據。

C1 C2  C3 
---------------- 
10 11.00 Closed 
10 12.00 Closed 
20 21.00 Closed 
20 22.00 Closed 

但我的查詢將返回只在C1列 NULL請幫我在這裏。在此先感謝

回答

2

在SQL Server你不應該使用XML查詢父軸。創建的查詢計劃將爲O(n )。對於XML中的每個節點,將檢查XML中的所有節點。

首先粉碎result/cash然後粉碎在account交叉申請。

select C.X.value('@number', 'varchar(max)') as C1, 
     A.X.value('@amt', 'varchar(max)') as C2, 
     A.X.value('@status', 'varchar(max)') as C3 
from @MainXml.nodes('result/cash') as C(X) 
    cross apply C.X.nodes('account') as A(X) 

我沒有看到創建第二個XML變量的點。直接使用@MainXML

+0

雖然這聽起來合乎邏輯,但我不確定這總是如此。我認爲我看過'..'的查詢有時表現得好於幾個這樣的應用,但我目前沒有確切的例子。也就是說,測試它會很有趣 –

+0

我也不同意計劃是'O(n^2)',它應該是線性的,因爲每個節點只有一個父親 –

+0

@RomanPekar看看http:// stackoverflow.com/questions/24196516/cross-apply-xml-query-performs-exponentially-worse-as-xml-document-grows –

2

@number<cash>屬性,但您的上下文節點是<account>。在訪問屬性之前,需要上一層XML樹以訪問節點<cash>。你可以做..到達當前節點的父XPath中:

SELECT 
Result.Claim.value('(../@number)[1]','varchar(max)') as C1, 
Result.Claim.value('(./@amt)[1]','varchar(max)') as C2, 
Result.Claim.value('(./@status)[1]','varchar(max)') as C3 
From @Innerxml.nodes('/result/cash/account') Result(Claim) 
+0

非常感謝你..你做了我的一天.. – user1893874