XQuery aktualisiert keine XML-Daten

7

Ich versuche, das Skript auszuführen, um eine XML-Spalte zu aktualisieren:

UPDATE DataImpTable
SET serviceData.modify('replace value of (/SMObjInfo/CentralData/SMData/CentralSDItem/ControlData/text())[1] with "9876"')
WHERE identifier=5
<SMObjInfo xmlns="DataService/1.0.0.0" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <CentralData>
    <SMData>
      <CentralSDItem>
        <ControlData>1234</ControlData>
      </CentralSDItem>
    </SMData>
  </CentralData>
</SMObjInfo>

Ändern Sie den Wert von ControlDatain 9876, aber der Wert scheint sich im XML für den /SMObjInfo/CentralData/SMData/CentralSDItem/ControlDataWert nicht zu ändern .

Hat das etwas mit typisiertem und untypisiertem XML zu tun?

SS
quelle

Antworten:

11

Sie müssen die Namespaces in der modifyFunktion deklarieren .

Etwas wie das:

DECLARE @xml xml = N'<SMObjInfo xmlns="DataService/1.0.0.0" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <CentralData>
    <SMData>
      <CentralSDItem>
        <ControlData>1234</ControlData>
      </CentralSDItem>
    </SMData>
  </CentralData>
</SMObjInfo>';
SET @xml.modify('
    declare default element namespace "DataService/1.0.0.0";
    replace value of (/SMObjInfo/CentralData/SMData/CentralSDItem/ControlData/text())[1]
    with "6789"
    ');
PRINT CONVERT(nvarchar(max), @xml);

In Ihrem ursprünglichen XML-Fragment haben Sie den folgenden Namespace deklariert, der niemals verwendet wird:

xmlns:i="http://www.w3.org/2001/XMLSchema-instance"

Wenn Ihre tatsächlichen XML-Dokumente diesen Namespace verwenden und Sie diese Elemente ändern möchten, müssen Sie der @xml.modifyFunktion die folgende Deklaration hinzufügen :

declare namespace i="http://www.w3.org/2001/XMLSchema-instance";

Ergebnisse (zur besseren Lesbarkeit formatiert):

<SMObjInfo xmlns="DataService/1.0.0.0" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <CentralData>
        <SMData>
            <CentralSDItem>
                <ControlData>6789</ControlData>
            </CentralSDItem>
        </SMData>
    </CentralData>
</SMObjInfo>

Ich habe einen Blog-Beitrag über die Änderungsfunktion geschrieben, zusammen mit einigen weiteren Beispielen auf SQLServerScience.com

Max Vernon
quelle
9

Wenn Sie das XML in der Tabelle haben, sollten Sie UPDATE anstelle von SET verwenden. Dort können Sie die Namespace-Deklaration mit WITH XMLNAMESPACES außerhalb des XML_DML-Ausdrucks platzieren .

with xmlnamespaces(default 'DataService/1.0.0.0')
update DataImpTable
set serviceData.modify('replace value of (/SMObjInfo/CentralData/SMData/CentralSDItem
                                            /ControlData/text())[1] with "9876"')
where identifier=5
Mikael Eriksson
quelle