Ich habe eine XML
Spalte, die Daten mit ähnlicher Struktur enthält:
<Root>
<Elements>
<Element Code="1" Value="aaa"></Element>
<Element Code="2" Value="bbb"></Element>
<Element Code="3" Value="ccc"></Element>
</Elements>
</Root>
Wie kann ich die Daten mit SQL Server ändern, um jedes Value
Attribut in ein Element zu ändern ?
<Root>
<Elements>
<Element Code="1">
<Value>aaa</Value>
</Element>
<Element Code="2">
<Value>bbb</Value>
</Element>
<Element Code="3">
<Value>ccc</Value>
</Element>
</Elements>
</Root>
Aktualisieren:
Mein XML sieht eher so aus:
<Root attr1="val1" attr2="val2">
<Elements>
<Element Code="1" Value="aaa" ExtraData="extra" />
<Element Code="2" Value="bbb" ExtraData="extra" />
<Element Code="3" Value="ccc" ExtraData="extra" />
<Element Code="4" Value="" ExtraData="extra" />
<Element Code="5" ExtraData="extra" />
</Elements>
<ExtraData>
<!-- Some XML is here -->
</ExtraData>
</Root>
Ich möchte nur Value
Attribute verschieben und alle anderen Attribute und Elemente beibehalten.
sql-server
xml
xquery
Wojteq
quelle
quelle
<Value>
Elemente pro Element<Element>
. Wenn nicht, führt das Verschieben des Attributs in ein Element nur zu aufgeblähterem und möglicherweise weniger effizientem XML.<Value>
Elements oder stattdessen.Antworten:
Sie können das XML vernichten und mit XQuery erneut erstellen.
Ergebnis:
Wenn dies
Elements
nicht das erste Element unterRoot
der Abfrage ist, muss es geändert werden, um alle Elemente vor demElements
ersten und alle Elemente nach dem Hinzufügen hinzuzufügenElements
.quelle
Value
Element erstellt wird, wenn@Value
es leer ist oder nicht vorhanden ist? Ich habe es versucht, aber ich habe versagt.Sie können auch die Methoden des XML-Datentyps (z. B. Ändern ) und einige XQuery verwenden, um die XML zu ändern, z
Diese Methode lässt sich in der Regel nicht gut über große XML-Teile skalieren, eignet sich jedoch möglicherweise besser als ein umfassender Ersatz für XML.
Sie können diese Methode auch einfach anpassen, wenn Ihr XML in einer Tabelle gespeichert ist. Aus Erfahrung würde ich nicht empfehlen, ein einzelnes Update für eine Million Zeilentabellen auszuführen. Wenn Ihre Tabelle groß ist, ziehen Sie einen Cursor durch die Tabelle oder stapeln Sie die Aktualisierungen auf andere Weise. Hier ist die Technik:
quelle
AKTUALISIEREN:
Ich habe den Code sowie das Eingabe- und Ausgabe-XML in der folgenden Beispielabfrage aktualisiert, um die neueste Anforderung widerzuspiegeln, die in einem Kommentar zu @ Mikaels feiner Antwort angegeben ist:
Während ein einzelner Ausdruck dieser neuen Variante korrekt entsprechen kann, scheint es keine Möglichkeit zu geben, das leere
<Value/>
Element in einem einzelnen Durchgang wegzulassen , da die bedingte Logik in der Ersetzungszeichenfolge nicht zulässig ist. Daher habe ich dies als zweiteilige Modifikation angepasst: einen Durchgang, um die nicht leeren@Value
Attribute zu erhalten, und einen Durchgang, um die leeren@Value
Attribute zu erhalten. Es war nicht erforderlich, mit dem<Element>
Fehlen des@Value
Attributs umzugehen, da der Wunsch besteht, das<Value>
Element sowieso nicht zu haben .Eine Möglichkeit besteht darin, das XML als regulären String zu behandeln und basierend auf einem Muster zu transformieren. Dies kann leicht mit regulären Ausdrücken (insbesondere der Funktion "Ersetzen") erreicht werden, die über den SQLCLR-Code verfügbar gemacht werden können.
Im folgenden Beispiel wird die skalare UDF RegEx_Replace aus der SQL # -Bibliothek verwendet (deren Autor ich bin, aber diese RegEx-Funktion ist in der kostenlosen Version zusammen mit vielen anderen verfügbar):
Die
PRINT
Anweisungen dienen nur dazu, den Vergleich nebeneinander auf der Registerkarte "Nachrichten" zu vereinfachen. Die resultierende Ausgabe ist (ich habe das ursprüngliche XML ein wenig geändert, um deutlich zu machen, dass nur die gewünschten Teile berührt wurden und sonst nichts):Wenn Sie ein Feld in einer Tabelle aktualisieren möchten, können Sie Folgendes anpassen:
quelle
Es gibt wahrscheinlich bessere Möglichkeiten, dies außerhalb von SQL Server zu tun. Hier ist jedoch eine Möglichkeit, dies zu tun.
Der XML-CTE wandelt Ihre XML-Variable in eine Tabelle um.
Die Hauptauswahl wandelt dann den CTE wieder in XML um.
Dies kann auch mit erfolgen
For XML Explicit
.quelle