Mettre à jour les attributes de noeud xml dans SQL Server, en filtrant sur d'autres attributes

J'essaie de mettre à jour les attributes de noeud dans une colonne XML et je suis bloqué. Certes, XQuery était un bruit blanc pour moi jusqu'à il y a un jour, et je pourrais persévérer un peu plus, mais cela nuirait à mon client. J'ai chaluté SO de haut en bas, toujours aussi coincé.

Voici donc les parties pertinentes de ma configuration:

Table:

CREATE TABLE Tbl(Id int IDENTITY, XmlCol XML) INSERT Tbl VALUES( '<root> <item ID="1">some text input</item> <item ID="7" PROP="10">1</item> </root> ' ) INSERT Tbl VALUES( '<root> <item ID="1">some other text input</item> <item ID="8" PROP="10">1</item> </root> ' ) 

Le context? Ne me requestz pas pourquoi, c'est si artificiel, vous restriez coincé à essayer de comprendre.

Pour tous les nœuds d'élément avec un atsortingbut ID de "8", j'ai besoin d'augmenter l'atsortingbut PROP à 30. Quand cela est fait, je dois mettre à jour l'atsortingbut ID de "8" à "7" pour les nœuds correspondants. , tout en gardant leurs valeurs PROP séparées.

C'est aussi proche que j'ai, mais SQL Server (ou moi) ne joue pas bien.

Mise à jour:

 DECLARE @newVal INT = 40 update Tbl set XmlCol.modify('replace value of (/root/item[@ID="8"][@PROP="10"]/@PROP)[1] with sql:variable("@newVal") ') 

Résultat:

XQuery [Tbl.XMLCol.modify ()]: ")" était attendu.

N'importe qui?

Vous avez juste à utiliser and à l'intérieur du [] , comme ceci:

 update Tbl set XmlCol.modify(' replace value of (/root/item[@ID="8" and @PROP="10"]/@PROP)[1] with sql:variable("@newVal") ') 

sql fiddle démo

Je connaissais un problème similaire à @nkstr. Et la réponse de @Roman Pekar m'a aidé à avoir une bonne idée sur la façon de mettre à jour les valeurs d'attributes, en filtrant sur d'autres attributes. Voici le SQL que j'ai utilisé.

 declare @X xml = '<root> <items> <item ItemID="100"> <obj ObjID="0001" value="val1"/> <obj ObjID="0002" value="val2"/> <obj ObjID="0003" value="val3"/> <obj ObjID="0004" value="val4"/> </item> <item ItemID="200"> <obj ObjID="0001" value="val1"/> <obj ObjID="0002" value="val2"/> <obj ObjID="0003" value="val3"/> <obj ObjID="0004" value="val4"/> </item> </items> </root>' declare @ITEMID int = 200 declare @OBJID int = 0004 declare @NEWVAL int = 8888 --update ObjID 0004 at ItemID 200 into 8888 (this is a comment) set @X.modify('replace value of (/root/items/item[@ItemID=sql:variable("@ITEMID")]/obj[@ObjID=sql:variable("@OBJID")]/@ObjID)[1] with sql:variable("@NEWVAL")') select @X