2017-07-14 1 views
3

Compte tenu de cette XML:Insertion XML dans la table SQL Server

<Documents> 
    <Batch BatchID = "1" BatchName = "Fred Flintstone"> 
     <DocCollection> 
      <Document DocumentID = "269" KeyData = "" /> 
      <Document DocumentID = "6" KeyData = "" /> 
      <Document DocumentID = "299" KeyData = ""  ImageFile="Test.TIF" /> 
     </DocCollection>  
    </Batch>  
    <Batch BatchID = "2" BatchName = "Barney Rubble"> 
     <DocCollection> 
      <Document DocumentID = "269" KeyData = "" /> 
      <Document DocumentID = "6" KeyData = "" /> 
     </DocCollection> 
    </Batch> 
</Documents> 

je dois l'insérer dans une table dans SQL Server dans ce format:

BatchID BatchName   DocumentID 
1   Fred Flintstone  269 
1   Fred Flintstone  6 
1   Fred Flintstone  299 
2   Barney Rubble  269 
2   Barney Rubble  6 

Ce SQL:

SELECT 
     XTbl.XCol.value('./@BatchID','int') AS BatchID, 
     XTbl.XCol.value('./@BatchName','varchar(100)') AS BatchName, 
     XTbl.XCol.value('DocCollection[1]/DocumentID[1]','int') AS DocumentID 
    FROM @Data.nodes('/Documents/Batch') AS XTbl(XCol) 

obtient moi ce résultat:

BatchID BatchName  DocumentID 
1  Fred Flintstone NULL 
2  Barney Rubble NULL 

Qu'est-ce que je fais mal?

Aussi, quelqu'un peut-il recommander un bon tutoriel pour XML dans SQL Server?

Merci

Carl

Répondre

6

Vous étiez près. À l'aide d'un caractère générique et d'une application CROSS, vous pouvez générer plusieurs enregistrements.

alias Changé pour lvl1 et lvl2 pour mieux illustrer.

Declare @XML xml = ' 
<Documents> 
    <Batch BatchID = "1" BatchName = "Fred Flintstone"> 
     <DocCollection> 
      <Document DocumentID = "269" KeyData = "" /> 
      <Document DocumentID = "6" KeyData = "" /> 
      <Document DocumentID = "299" KeyData = ""  ImageFile="Test.TIF" /> 
     </DocCollection>  
    </Batch>  
    <Batch BatchID = "2" BatchName = "Barney Rubble"> 
     <DocCollection> 
      <Document DocumentID = "269" KeyData = "" /> 
      <Document DocumentID = "6" KeyData = "" /> 
     </DocCollection> 
    </Batch> 
</Documents> 
' 

Select BatchID = lvl1.n.value('@BatchID','int') 
     ,BatchName = lvl1.n.value('@BatchName','varchar(50)') 
     ,DocumentID = lvl2.n.value('@DocumentID','int') 
From @XML.nodes('Documents/Batch') lvl1(n) 
Cross Apply lvl1.n.nodes('DocCollection/Document') lvl2(n) 

Retours

BatchID BatchName  DocumentID 
1  Fred Flintstone 269 
1  Fred Flintstone 6 
1  Fred Flintstone 299 
2  Barney Rubble 269 
2  Barney Rubble 6 
+0

bonne solution, +1 de mon côté, mais pourquoi le '*' 'dans les premiers .nodes()'? – Shnugo

+0

@Shnugo Maintenant que vous le mentionnez,/Batch serait plus sûr/plus spécifique. Ou pensiez-vous quelque chose d'autre? –

+0

Non, juste pour éviter les erreurs, s'il peut y avoir plus de nœuds avec d'autres noms ... – Shnugo