2017-07-17 107 views
2

鑑於這種XML:插入複雜的XML到SQL Server表

<Documents> 
    <Batch BatchID="1" BatchName="Fred Flintstone"> 
    <DocCollection> 
     <Document DocumentID="269" FileName="CoverPageInstructions.xsl"> 
     <MergeFields> 
      <MergeField FieldName="A" Value="" /> 
      <MergeField FieldName="B" Value="" /> 
      <MergeField FieldName="C" Value="" /> 
      <MergeField FieldName="D" Value="" /> 
     </MergeFields> 
     </Document> 
     <Document DocumentID="6" FileName="USform8802.pdf"> 
     <MergeFields> 
      <MergeField FieldName="E" Value="" /> 
      <MergeField FieldName="F" Value="" /> 
      <MergeField FieldName="G" Value="" /> 
      <MergeField FieldName="H" Value="" /> 
      <MergeField FieldName="I" Value="" /> 
     </MergeFields> 
     </Document> 
     <Document DocumentID="299" FileName="POASIDE.TIF"> 
     <MergeFields /> 
     </Document> 
    </DocCollection> 
    </Batch> 
    <Batch BatchID="2" BatchName="Barney Rubble"> 
    <DocCollection> 
     <Document DocumentID="269" FileName="CoverPageInstructions.xsl"> 
     <MergeFields> 
      <MergeField FieldName="A" Value="" /> 
      <MergeField FieldName="B" Value="" /> 
      <MergeField FieldName="C" Value="" /> 
      <MergeField FieldName="D" Value="" /> 
     </MergeFields> 
     </Document> 
     <Document DocumentID="6" FileName="USform8802.pdf"> 
     <MergeFields> 
      <MergeField FieldName="E" Value="" /> 
      <MergeField FieldName="F" Value="" /> 
      <MergeField FieldName="G" Value="" /> 
      <MergeField FieldName="H" Value="" /> 
      <MergeField FieldName="I" Value="" /> 
     </MergeFields> 
     </Document> 
    </DocCollection> 
    </Batch> 
</Documents> 

我試圖實現這一結果:

BatchID BatchName DocumentID FieldName 
1 Fred Flintstone 269 A 
1 Fred Flintstone 269 B 
1 Fred Flintstone 269 C 
1 Fred Flintstone 269 D 
1 Fred Flintstone 6 E 
1 Fred Flintstone 6 F 
1 Fred Flintstone 6 G 
1 Fred Flintstone 6 H 
1 Fred Flintstone 6 I 
1 Fred Flintstone 299 Null 
2 Barney Rubble 269 A 
2 Barney Rubble 269 B 
2 Barney Rubble 269 C 
2 Barney Rubble 269 D 
2 Barney Rubble 6 E 
2 Barney Rubble 6 F 
2 Barney Rubble 6 G 
2 Barney Rubble 6 H 
2 Barney Rubble 6 I 

我似乎得到一個笛卡兒連接本(每個文檔有跨所有文件的MergeField的完整列表:

SELECT lvl1.n.value('@BatchID','int'), 
     lvl1.n.value('@BatchName','varchar(50)'), 
     lvl2.n.value('@DocumentID','int'), 
     lvl3.n.value('@FieldName','varchar(50)') 
FROM @Data.nodes('Documents/*') lvl1(n) 
CROSS APPLY lvl1.n.nodes('DocCollection/Document') lvl2(n) 
CROSS APPLY lvl1.n.nodes('DocCollection/Document/MergeFields/MergeField') lvl3(n) 

我想知道如何得到我需要的結果,用空值va適用於沒有MergeField元素的批1中的299 DocumentID。

任何幫助表示讚賞。

感謝

卡爾

UPDATE:以下是如何做到使用的OpenXML相同:

SELECT 
    BatchID, 
    BatchName, 
    DocumentID, 
    FileName, 
    KeyData, 
    FieldName 
    FROM OPENXML(@hdoc, '/Documents/Batch/DocCollection/Document/MergeFields/MergeField', 11) 
     WITH (BatchID varchar(100) '../../../../@BatchID', 
      BatchName varchar(100) '../../../../@BatchName', 
      DocumentID varchar(100) '../../@DocumentID', 
      FileName varchar(100) '../../@FileName', 
      KeyData varchar(100) '../../@KeyData', 
      FieldName varchar(100) '@FieldName'); 

回答

3

編輯 - 對不起,我錯過了弗雷德的NULL。只是改變了跨應用 到外部應用..其他的交叉應用可能是如果需要

通知LVL3

不清楚爲什麼沒有創建每個字段的別名的外部應用。例如,我希望像BatchID = lvl1.n.value('@BatchID','int'),

SELECT lvl1.n.value('@BatchID','int'), 
     lvl1.n.value('@BatchName','varchar(50)'), 
     lvl2.n.value('@DocumentID','int'), 
     lvl3.n.value('@FieldName','varchar(50)') 
FROM @Data.nodes('Documents/Batch') lvl1(n) 
CROSS APPLY lvl1.n.nodes('DocCollection/Document') lvl2(n) 
Outer APPLY lvl2.n.nodes('MergeFields/MergeField') lvl3(n) 

返回

enter image description here

+0

謝謝(再次)約翰。太棒了。我無法相信我在這個項目中遇到的XML問題。 – CarlGanz

+0

@CarlGanz樂於助人。我也是XML的後期用戶。我看snugo,他是xml忍者 –