2017-07-17 126 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忍者 –