Ich habe eine Tabelle von Werten in SQL Server 2008, aus der ich den Wert in eine XML-Spalte innerhalb einer übereinstimmenden Zeile einer anderen Tabelle einfügen möchte. Die XML-Spalte enthält möglicherweise nicht alle Tags, die zu dem Element führen, das eingefügt werden soll.Wie fügt man ein Element in die XML-Spalte ein, ohne zu wissen, ob der Baum bereits existiert?
Ich kann dies durch mehrere update/xml.modify
Anweisungen erreichen, um sicherzustellen, dass die Tags vor dem Einfügen des Elements vorhanden sind, aber das scheint wirklich ineffizient und was, wenn ich ein Element 5 oder 10 Tags tief einfügen wollte?
Hier ist ein erstelltes example in SQL fiddle
Das Setup ist, dass ich habe 2 Tabellen (vereinfachte/hier aus bis zu einem verständlichen Szenario zu machen)
CREATE TABLE tableColors (id nvarchar(100), color nvarchar(100))
CREATE TABLE xmlTable (id nvarchar(100), xmlCol xml)`
Ich brauche das Element <root><colors><color>tableColors.color</color></colors></root>
in XMLTABLE einzufügen, wo die id stimmt überein und das Element existiert noch nicht. Das xmlCol kann viel mehr Elemente enthalten oder sogar leer sein. Das Farb-Tag ist 0 oder viele und das Farb-Tag ist 0 oder 1.
Die abschließende Anweisung, das Element an der richtigen Stelle einzufügen, ist sinnvoll, funktioniert aber nicht, wenn die übergeordneten Tags nicht bereits vorhanden sind.
UPDATE xmlTable
SET xmlCol.modify(' insert <color>{sql:column("color")}</color> as first into (/root/colors)[1] ')
FROM xmlTable
INNER JOIN tableColors ON xmlTable.id = tableColors.id
WHERE xmlCol.exist('/root/colors/color[(text()[1]) = sql:column("color")]') = 0
Also, ich brauche /root/colors
existiert, um sicherzustellen, bevor Sie dieses Update-Anweisung ausgeführt wird. Bitte sagen Sie mir, dass ich etwas vermisse und ich muss nicht explizit eine Einfügung von root machen (wenn leer) und dann Farben in root einfügen.
Um weiter zu erklären, hier ist ein vor und nach dem das neue Element in/root/Farben des Einsetzens:
New Element XML before XML after
<color>blue</color> -blank- <root><colors><color>blue</color></colors></root>
<color>green</color> <root><vegitation>yes</vegitation></root> <root><vegitation>yes</vegitation><colors><color>green</color></colors></root>
<color>white</color> <root><colors><color>brown</color></colors></root> <root><colors><color>brown</color><color>white</color></colors></root>
Auch hier ist eine vollständige example in SQL fiddle wo ich erreichen, was ich will, aber es muss eine sein besserer Weg. Was vermisse ich?
Es sieht so aus, als wäre Brians Antwort so nah wie XML. d. h. mehrere if-Anweisungen innerhalb eines einzelnen Updates - ein einzelnes Update ist großartig, aber für komplexere Bäume wäre dies ein Albtraum. Ich weiß, ich sagte, ich würde keine Antwort akzeptieren, die dynamisches SQL verwendet, aber ich dachte, ich könnte Brians Antwort in eine gespeicherte Prozedur konvertieren, die dynamisches SQL verwendet, um die Wiederholung zu eliminieren und diese bis zu anderen Bäumen und Spalten zu öffnen. http://sqlfiddle.com/#!6/d8e66/1 Immer noch in der Hoffnung, jemand wird eine noch einfachere XML-Anweisung vorbringen :) –