Вопрос

I'm trying to update node attributes in an XML column and I'm stuck. Admittedly, XQuery was white noise for me until a day ago, and I could persevere some more, but that would hurt my customer. I've trawled SO up and down, still just as stuck.

So here are the pertinent parts of my setup:

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

Context? Don't ask me why, it's so contrived, you'd get stuck trying to make sense of it.

For all item nodes with an ID attribute of "8", I need to increase the PROP attribute with 30. When that's done, I need to update the ID attribute from "8" to "7" for matching nodes, effectively merging the items, while keeping their PROP values apart.

Here's as close as I've got, but SQL Server (or me) is not playing nice.

Update statement:

DECLARE @newVal INT = 40

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

Result:

XQuery [Tbl.XMLCol.modify()]: ")" was expected.

Anyone?

Это было полезно?

Решение

You just have to use and inside the [], like this:

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

sql fiddle demo

Другие советы

I was experiencing a similar issue like @nkstr. And the answer from @Roman Pekar helped me get a good idea on how to update attribute values, filtering on other attribute. Here is the SQL I used.

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top