2016-08-03 61 views
0

Ich habe diese innere XML, die ich an eine gespeicherte SQL Server-Prozedur übergeben.SQL Server-XML-Datei mit mehreren Knoten mit dem gleichen Namen

Sample of XML being passed to SQL Server

Wie Sie sehen können, enthält es mehr root Knoten, sondern zusätzlich kann es auch 1 bis ‚n‘ Anzahl von LotResults geordneten Knoten enthalten.

Gibt es eine Möglichkeit, dies in der gespeicherten Prozedur zu manipulieren, so dass ich alle LotResults/Result Knoten für jeden Knoten root abrufen kann?

Bisher habe ich die cursor erklärt, die mit den Knoten der obersten Ebene umgehen können:

DECLARE cur CURSOR FOR 
    SELECT tab.col.value('ID[1]','NCHAR(10)') as INT_TransactionID, 
      tab.col.value('ResultDateTime[1]','INT') as DAT_ResultDateTime, 
      tab.col.value('StandardComment[1]/ID[1]','BIT') as INT_StandardCommentID, 
      tab.col.value('ReviewComment[1]/ID[1]','BIT') as INT_ReviewCommentID 
    FROM @XML_Results.nodes('/roots/root') AS tab(col) 

    OPEN cur 
-- loop over nodes within xml document and populate declared variables 
    FETCH 
    NEXT 
    FROM cur 

    INTO @INT_TransactionID, 
      @DAT_ResultDateTime, 
      @INT_StandardCommentID, 
      @INT_ReviewCommentID 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 

    BEGIN 
    -- use my values here 

     END 

    -- fetch next record 
    FETCH 
    NEXT 
    FROM cur 
    INTO @INT_TransactionID, 
      @DAT_ResultDateTime, 
      @INT_StandardCommentID, 
      @INT_ReviewCommentID 

     END 

    CLOSE cur; 

Hinweis: ich einen Beitrag gefunden beschreibt how to extract nodes with the same name und ich fühle mich wie es ist etwas, das verwendet werden kann, was zu erreichen Ich möchte hier, aber ich brauche eine Anleitung, wie dies auf mein Szenario angewendet werden kann.

Antwort

2

Keine Cursor! Cursor werden vom Teufel geschaffen, um arme kleine db Leute vom Licht des Set-based Denkens tief in die dunklen Morgen der Verfahrensansätze zu führen ...

Bitte (für zukünftige Fragen): Keine Bilder einfügen! Musste mein Beispiel eingeben ...

Und übrigens: Deine benutze meine Werte hier macht es schwierig, die richtige Sache zu beraten. Abhängig davon, was Sie dort tun, könnte ein Cursor tatsächlich benötigt werden. Aber in diesem Fall sollten Sie den Cursor aus einer Abfrage erstellen, wie ich Ihnen zeigen, ...

Probieren Sie es wie folgt aus:

DECLARE @xml XML= 
'<roots> 
    <root> 
    <ID>5</ID> 
    <LotResults> 
     <ID>13</ID> 
     <Result> 
     <ID>5</ID> 
     <Count>2</Count> 
     </Result> 
    </LotResults> 
    <LotResults> 
     <ID>13</ID> 
     <Result> 
     <ID>5</ID> 
     <Count>2</Count> 
     </Result> 
    </LotResults> 
    <StandardComment> 
     <ID>0</ID> 
    </StandardComment> 
    <ReviewComment> 
     <ID>0</ID> 
    </ReviewComment> 
    </root> 
    <root> 
    <ID>44</ID> 
    <LotResults> 
     <ID>444</ID> 
     <Result> 
     <ID>4444</ID> 
     <Count>2</Count> 
     </Result> 
    </LotResults> 
    <LotResults> 
     <ID>555</ID> 
     <Result> 
     <ID>55</ID> 
     <Count>2</Count> 
     </Result> 
    </LotResults> 
    <StandardComment> 
     <ID>5</ID> 
    </StandardComment> 
    <ReviewComment> 
     <ID>5</ID> 
    </ReviewComment> 
    </root> 
</roots>'; 

--und Hier ist die Abfrage

SELECT r.value('ID[1]','int') AS root_ID 
     ,lr.value('ID[1]','int') AS LotResult_ID 
     ,lr.value('(Result/ID)[1]','int') AS LotResult_Result_ID 
     ,lr.value('(Result/Count)[1]','int') AS LotResult_Result_Count 
     ,r.value('(StandardComment/ID)[1]','int') AS StandardComment_ID 
     ,r.value('(ReviewComment/ID)[1]','int') AS ReviewComment_ID 
FROM @xml.nodes('/roots/root') AS A(r) 
CROSS APPLY r.nodes('LotResults') AS B(lr) 
+0

@Schnugo Dank um zurück zu kommen. Entschuldigung für den Druckbildschirm des XML, wird für zukünftige Beiträge bekannt sein. Was das Auslassen von Innercursor-Inhalten anbelangt, liegt das daran, dass ich zuerst übersortiert werden wollte. Im Grunde wird der Cursor über jeden Root-Knoten der obersten Ebene iterieren, alle relevanten Daten extrahieren und eine Anzahl von Tabellen "UPDATE". Haben Sie einen Hinweis, der in diesem Fall die Verwendung eines Cursors verhindern könnte? – Sandman

+1

Ich rate dazu: Platziere ein 'INTO # myTempResult' direkt vor dem' FROM'. Dadurch wird das gesamte Ergebnis in eine neu erstellte Tabelle mit der entsprechenden automatisch erstellten Struktur verschoben. Danach benutze 'INSERT INTO MyTable (Spalte1, Spalte2, ...) SELECT DISTINCT Spalte1, Spalte2, ... FROM # myTempResult'. Sie benötigen eine Einfügung für jede Tabelle, in die Sie schreiben. Alles Set-basiert, kein Cursor ... – Shnugo

+0

Danke für den Hinweis. Ich werde das ausprobieren und den gefürchteten Teufels-Cursor meiden;) – Sandman