2013-10-12 47 views
1

鑑於這種XML片段(VIN的顯然是假的)不能一絲一毫跨XML數據應用

<VehicleFeed> 
    <Vehicle> 
    <VIN>1234</VIN> 
    <Equipment> 
     <EquipmentDesc>1.1</EquipmentDesc> 
     <EquipmentDesc>1.2</EquipmentDesc> 
     <EquipmentDesc>1.3</EquipmentDesc> 
    </Equipment> 
    </Vehicle> 
    <Vehicle> 
    <VIN>2345</VIN> 
    <Equipment> 
     <EquipmentDesc>2.1</EquipmentDesc> 
     <EquipmentDesc>2.2</EquipmentDesc> 
     <EquipmentDesc>2.3</EquipmentDesc> 
    </Equipment> 
    </Vehicle> 
</VehicleFeed> 

What I really want is this result set 

VIN EquipmentDesc 
--- ------------- 
1234 1.1 
1234 1.2 
1234 1.3 
2345 2.1 
2345 2.2 
2345 2.3 

我有一個名爲@xdata VAR XML數據。下面的代碼是我認爲可以工作的代碼,但它將所有設備值連接成單個數據列,而不是將它們拆分成行。

select t.c.value('VIN[1]', 'varchar(20)') as VIN 
    , t1.c1.value('.', 'varchar(80)') as EquipDesc 
from @xdata.nodes('//VehicleFeed/Vehicle') as t(c) 
cross apply t.c.nodes('Equipment') as t1(c1) 

也就是說,我得到

VIN EquipmentDesc 
--- ------------- 
1234 1.11.21.3 
2345 2.12.22.3 

我清楚我做錯了什麼,推測可能與交叉應用,或描述數據(或兩者)的選擇,但我不知道這是什麼。看起來這很簡單,但我沒有看到它。

回答

1

我後來意識到了答案。我只是需要添加更多水平的交叉應用,以進入EquipmentDesc元素 - 大腦受損,編碼星期六晚上。

cross apply t1.c1.nodes('EquipmentDesc') as t2(c2) 

,然後使用

, t2.c2.value('.', 'varchar(80)') as EquipDesc 

我不使用交叉應用過於頻繁的設備描述值,容易忘記它真正的意思,當我調整了一些現有的代碼。對不起,如果我浪費了任何人的時間。

ADDED

最終查詢(相關部分至少)

select t.c.value('VIN[1]', 'varchar(20)') as VIN 
    , t2.c2.value('.', 'varchar(80)') as EquipDesc 
from @xdata.nodes('//VehicleFeed/Vehicle') as t(c) 
cross apply t.c.nodes('Equipment') as t1(c1) 
cross apply t1.c1.nodes('EquipmentDesc') as t2(c2) 
+0

請張貼完整改正後的查詢。至少要糾正您在問題中發佈的金額。 –

1

可以實現用更短的語句相同:

select t.c.value('../../VIN[1]', 'varchar(20)') as VIN 
    , t.c.value('.', 'varchar(80)') as EquipDesc 
from @xdata.nodes('/VehicleFeed/Vehicle/Equipment/EquipmentDesc') as t(c); 
+0

當然,我還沒有使用中間級別。儘管我不會在最後一行重複完整的xpath。感謝提醒,但我敢打賭別人會從中學習。 +1 –