Remplacer la valeur d'un élément xml fortement typé dans SQL Server par XQuery

10

Étant donné un élément, défini dans une collection de schémas XML comme tel:

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

Comment mettriez-vous à jour l'élément en utilisant XQuery?

L'élément se trouve dans l' espace de noms ns dans la collection de schémas. J'ai essayé de mettre à jour l'élément la requête ci-dessous:

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

mais cela génère l'erreur suivante:

Msg 9301, niveau 16, état 1, ligne 2 XQuery [cm.item.data.modify ()]: dans cette version du serveur, «cast as» n'est pas disponible. Veuillez utiliser le 'cast as?' syntaxe.

Si je supprime entièrement le casting et utilise cette requête:

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

Je reçois cette erreur:

Msg 2247, niveau 16, état 1, ligne 2 XQuery [cm.item.data.modify ()]: la valeur est de type "xs: string", qui n'est pas un sous-type du type attendu "<anonymous>".

Si j'émets cette requête:

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

Je reçois cette erreur:

Msg 9312, niveau 16, état 1, ligne 2 XQuery [cm.item.data.modify ()]: 'text ()' n'est pas pris en charge sur les types simples ou ' http://www.w3.org/2001/XMLSchema #anyType 'elements, found' (element (ns { http://www.anon.com/ }: xid, # anonyme)?) * '.

Je cible SQL Server 2008 R2.

Merci!

Mr.Brownstone
la source

Réponses:

6

Je n'ai pas trouvé de moyen simple de simplement modifier l' replace value ofinstruction pour qu'elle fonctionne avec des définitions de types simples anonymes.

Reproduction simple de ce que vous avez:

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"');

Résultat:

Msg 2247, niveau 16, état 1, ligne 25 XQuery [modify ()]: la valeur est de type "xs: string", qui n'est pas un sous-type du type attendu "<anonymous>".

Une solution consiste à modifier votre schéma pour utiliser un type simple nommé xidTypeet convertir la nouvelle valeur.

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?');

Une autre façon consiste à extraire le XML vers une variable XML non typée, à modifier la variable et à la remettre dans la table.

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
la source