Ersetzen Sie den Wert eines stark typisierten XML-Elements in SQL Server durch XQuery

10

Gegeben ein Element, das in einer XML-Schemasammlung als solches definiert ist:

<xsd:element name="xid">
    <xsd:simpleType>
        <xsd:restriction base="xsd:string">
            <xsd:maxLength value="32" />
        </xsd:restriction>
    </xsd:simpleType>
</xsd:element>

Wie würden Sie das Element mit XQuery aktualisieren?

Das Element befindet sich im Namespace ns in der Schemasammlung. Ich habe versucht, das Element der folgenden Abfrage zu aktualisieren:

update cm.item
   set data.modify(
    'declare namespace ns="http://www.anon.com"; 
     replace value of (/ns:*/ns:xid)[1] with "X00011793" cast as element(ns{http://www.anon.com}:xid,#anonymous) ?') 
 where id = 11793

Dies erzeugt jedoch den folgenden Fehler:

Meldung 9301, Ebene 16, Status 1, Zeile 2 XQuery [cm.item.data.modify ()]: In dieser Version des Servers ist "Cast as" nicht verfügbar. Bitte verwenden Sie die "Besetzung als?" Syntax.

Wenn ich die Besetzung vollständig entferne und diese Abfrage verwende:

update cm.item
   set data.modify(
    'declare namespace ns="http://www.anon.com"; 
     replace value of (/ns:*/ns:xid)[1] with "X00011793"') 
 where id = 11793

Ich erhalte diesen Fehler:

Meldung 2247, Ebene 16, Status 1, Zeile 2 XQuery [cm.item.data.modify ()]: Der Wert ist vom Typ "xs: string", der kein Subtyp des erwarteten Typs "<anonymous>" ist.

Wenn ich diese Abfrage stelle:

update cm.item
   set data.modify(
      'declare namespace ns="http://www.anon.com/"; 
       replace value of (/ns:*/ns:xid/text())[1] with "X00011793"')
 where id = 11793

Ich erhalte diesen Fehler:

Meldung 9312, Ebene 16, Status 1, Zeile 2 XQuery [cm.item.data.modify ()]: 'text ()' wird bei einfacher Eingabe oder ' http://www.w3.org/2001/XMLSchema ' nicht unterstützt #anyType 'Elemente gefunden' (Element (ns { http://www.anon.com/ }: xid, # anonym)?) * '.

Ich ziele auf SQL Server 2008 R2.

Vielen Dank!

Herr Brownstone
quelle

Antworten:

6

Ich habe keine einfache Möglichkeit gefunden, die replace value ofAnweisung so zu ändern , dass sie mit anonymen einfachen Typdefinitionen funktioniert.

Einfache Reproduktion von dem, was Sie haben:

drop xml schema collection dbo.SimpleTypeTest;

go

create xml schema collection dbo.SimpleTypeTest as 
N'<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="xid">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:maxLength value="30"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>';

go

declare @X xml(document dbo.SimpleTypeTest) = '<root><xid>1</xid></root>';

set @X.modify('replace value of /root/xid  with "2"');

Ergebnis:

Meldung 2247, Ebene 16, Status 1, Zeile 25 XQuery [modify ()]: Der Wert ist vom Typ "xs: string", der kein Subtyp des erwarteten Typs "<anonymous>" ist.

Eine Problemumgehung besteht darin, Ihr Schema so zu ändern, dass ein benannter einfacher Typ verwendet wird, xidTypeund den neuen Wert umzuwandeln.

drop xml schema collection dbo.SimpleTypeTest;

go

create xml schema collection dbo.SimpleTypeTest as 
N'<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="xid" type="xidType"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:simpleType name="xidType">
        <xs:restriction base="xs:string">
            <xs:maxLength value="30"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>';

go

declare @X xml(document dbo.SimpleTypeTest) = '<root><xid>1</xid></root>';

set @X.modify('replace value of /root/xid  with "2" cast as xidType?');

Eine andere Möglichkeit besteht darin, das XML in eine untypisierte XML-Variable zu extrahieren, die Variable zu ändern und sie wieder in die Tabelle aufzunehmen.

drop xml schema collection dbo.SimpleTypeTest;

go

create xml schema collection dbo.SimpleTypeTest as 
N'<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="xid">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:maxLength value="30"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>';

go

declare @X xml(document dbo.SimpleTypeTest) = '<root><xid>1</xid></root>';
declare @X2 xml = @X;

set @X2.modify('replace value of (/root/xid/text())[1]  with "2"');
set @X = @X2;
Mikael Eriksson
quelle