2016-11-02 2 views
-1

Ich habe eine komplexe verschachtelte XML (generierte aus einer C# Einheit Grafik), zum Beispiel:Wie konvertiert man verschachtelte XML in entsprechende Tabellen?

<Customers> 
    <Customer> 
    <Id>1</Id> 
    <Number>12345</Number> 
    <Addresses> 
     <Address> 
     <Id>100</Id> 
     <Street>my street </street> 
     <city>London</city> 
     </Address> 
     <Address> 
     <Id>101</Id> 
     <street>my street 2</street> 
     <city>Berlin</city> 
     </Address> 
    </Addresses> 
    <BankDetails> 
     <BankDetail> 
     <Id>222</Id> 
     <Iban>DE8439834934939434333</Iban> 
     </BankDetail> 
     <BankDetail> 
     <Id>228</Id> 
     <Iban>UK1237921391239123213</Iban> 
     </BankDetail> 
    </BankDetails> 
    <Orders> 
     <Order>   
     <OrderLine>   
     </OrderLine> 
     </Order> 
    </Orders> 
    </Customer> 
</Customers> 

Bevor die oben genannten XML-Daten in die tatsächlichen Tabellen zu speichern, ich brauche es zuerst zu verarbeiten. Aus diesem Grund habe ich entsprechende Tabellentypen angelegt. Jeder dieser Tabellentypen hat eine zusätzliche Spalte (GUID als ROWGUID), so dass ich, wenn ich neue Daten verarbeite (noch nicht zugewiesener Primärschlüssel), einen eindeutigen Schlüssel erzeuge. Ich verwende diese Spalte, um die relationale Integrität zwischen verschiedenen Tabellentypen beizubehalten.

Wie lautet die SQL-Syntax zum Konvertieren der obigen verschachtelten XML in die entsprechenden Tabellen, wobei zu beachten ist, dass untergeordnete Datensätze auf die generierte übergeordnete GUID verweisen müssen?

+0

Ihr XML ist ungültig (falsches schließendes Tag '') und da sind einige '>' Zeichen am falschen Ort ... ('* my street> *') – Shnugo

+0

Diese Frage wurde bereits beantwortet : http://stackoverflow.com/questions/3989395/convert-xml-to-table-sql-server – Penman

+0

@Shnugo Typo behoben. –

Antwort

1

es so versuchen:

DECLARE @xml XML= 
N'<Customers> 
    <Customer> 
    <Id>1</Id> 
    <AccountNumber>12345</AccountNumber> 
    <Addresses> 
     <Address> 
     <Id>100</Id> 
     <street>my street&gt;</street> 
     <city>London</city> 
     </Address> 
     <Address> 
     <Id>101</Id> 
     <street>my street&gt;</street> 
     <city>Berlin</city> 
     </Address> 
    </Addresses> 
    <BankDetails> 
     <BankDetail> 
     <Id>222</Id> 
     <Iban>DE8439834934939434333</Iban> 
     </BankDetail> 
     <BankDetail> 
     <Id>228</Id> 
     <Iban>UK1237921391239123213</Iban> 
     </BankDetail> 
    </BankDetails> 
    <Orders> 
     <Order> 
     <OrderLine /> 
     </Order> 
    </Orders> 
    </Customer> 
</Customers>'; 

--Dieser Abfrage eine Tabelle #tmpInsert mit allen Daten schaffen

SELECT cust.value('Id[1]','int') AS CustomerID 
     ,cust.value('AccountNumber[1]','int') AS CustomerAccountNumber 
     ,addr.value('Id[1]','int') AS AddressId 
     ,addr.value('street[1]','nvarchar(max)') AS AddressStreet 
     ,addr.value('city[1]','nvarchar(max)') AS AddressCity 
     ,bank.value('Id[1]','int') AS BankId 
     ,bank.value('Iban[1]','nvarchar(max)') AS BankIban 
     ,ord.value('OrderLine[1]','nvarchar(max)') AS OrderLine 
INTO #tmpInsert 
FROM @xml.nodes('/Customers/Customer') AS A(cust) 
OUTER APPLY cust.nodes('Addresses/Address') AS B(addr) 
OUTER APPLY cust.nodes('BankDetails/BankDetail') AS C(bank) 
OUTER APPLY cust.nodes('Orders/Order') AS D(ord); 

--Here Sie den Inhalt

SELECT * FROM #tmpInsert; 
überprüfen

- Aufräumen

GO 
DROP TABLE #tmpInsert 

Sobald Sie alle Ihre Daten in der Tabelle haben, können Sie einfach DISTINCT, GROUP BY, falls erforderlich ROW_NUMBER() OVER(PARTITION BY ...) verwenden, um jeden Satz separat für den richtigen Einsatz auszuwählen.

+0

Dies funktioniert, indem Sie geschachtelte Werte in Spalten der einen Tabelle platzieren. Ist es möglich, verschachtelte Knoten in separate Tabellen zu extrahieren? Und ist es möglich zu vermeiden, dass einzelne Spalten im SELECT-Teil übergeben werden? –

+0

Verwenden Sie einfach 'INSERT INOURCustomerTable (ID, Nummer) SELECT DISTINCT CustomerId, CustomerAccountNumber FROM # tmpInsert;' und ähnlich für alle anderen verschachtelten Sets. Sie können '# tmpInsert' als Quellentabelle für alle verwenden. Und nein: ich würde wirklich vermeiden, die * einzelnen Spalten wegzulassen * Im Moment wird Ihr Tisch in jedem Punkt geändert, ein einfacher 'INSERT IN MyCustomerTabLE SELECT * FROM SomeWhere' wird - sicher! - in Zukunft in Schwierigkeiten führen! – Shnugo

Verwandte Themen