Обновление атрибутов узла xml в SQL Server, фильтрация по другому атрибуту

Я пытаюсь обновить атрибуты узла в столбце XML, и я застрял. По общему признанию, XQuery был белым шумом для меня до дня назад, и я мог продолжать еще немного, но это повредит моему клиенту. Я траул ТАК вверх и вниз, все еще так же застрял.

Итак, вот соответствующие части моей установки:

Таблица:

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

Контекст? Не спрашивайте меня, почему, это так придумано, что вы застряли, пытаясь понять это.

Для всех узлов элементов с атрибутом идентификатора "8" мне нужно увеличить атрибут PROP с 30. Когда это будет сделано, мне нужно обновить атрибут идентификатора с "8" до "7" для соответствующих узлов, эффективно объединяя элементы, сохраняя при этом их значения PROP.

Вот так близко, как я, но SQL Server (или я) не играет хорошо.

Обновить заявление:

DECLARE @newVal INT = 40

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

Результат:

XQuery [Tbl.XMLCol.modify ()]: ")" ожидался.

Кто-нибудь?

2 ответа

Решение

Вы просто должны использовать and внутри [], как это:

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

sql fiddle demo

Я столкнулся с подобной проблемой, как @nkstr. И ответ @Roman Pekar помог мне получить хорошее представление о том, как обновлять значения атрибутов, применяя фильтрацию к другим атрибутам. Вот SQL, который я использовал.

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
Другие вопросы по тегам