Да, но вы должны добавить фильтр в качестве предиката:
Ваш макет . Я добавил столбец идентификатора и три случая
- Один "efg"
- Нет "efg"
- Множественные вхождения "efg"
- Проверить это
DECLARE @xmlTable table (ID INT IDENTITY, xmlfield xml)
INSERT INTO @xmlTable (xmlfield)
VALUES (
'<ArrayOfFieldInfo>
<FieldInfo>
<Name>abc</Name>
<FriendlyName>friend2</FriendlyName>
</FieldInfo>
<FieldInfo>
<Name>efg</Name>
<FriendlyName>friend1</FriendlyName>
</FieldInfo>
</ArrayOfFieldInfo>'
)
,(
'<ArrayOfFieldInfo>
<FieldInfo>
<Name>abc</Name>
<FriendlyName>friend2</FriendlyName>
</FieldInfo>
<FieldInfo>
<Name>xyz</Name>
<FriendlyName>friend1</FriendlyName>
</FieldInfo>
</ArrayOfFieldInfo>'
)
,(
'<ArrayOfFieldInfo>
<FieldInfo>
<Name>efg</Name>
<FriendlyName>friend2</FriendlyName>
</FieldInfo>
<FieldInfo>
<Name>efg</Name>
<FriendlyName>friend1</FriendlyName>
</FieldInfo>
</ArrayOfFieldInfo>'
)
- Давайте использовать некоторые переменные, чтобы получить более общий
DECLARE @SearchName NVARCHAR(100)=N'efg';
DECLARE @ReplaceWith NVARCHAR(100)=N'ABCDEFG';
- Запрос
UPDATE @xmlTable
SET xmlfield.modify('replace value of
(/ArrayOfFieldInfo
/FieldInfo[Name=sql:variable("@SearchName")]
/FriendlyName/text())[1]
with sql:variable("@ReplaceWith")')
WHERE xmlfield.exist('/ArrayOfFieldInfo
/FieldInfo[Name=sql:variable("@SearchName")]')=1;
--Проверьте результат
SELECT *
FROM @xmlTable t
ORDER BY t.ID;
В первом случае будет заменено значение.
Во втором случае нет замен.
Только ОДИН (первый) в третьем случае заменяется.
Идея вкратце:
XML-DML-метод replace value of
нуждается в одиночном коде. Вы пытались отфильтровать с помощью WHERE
извне, но вы должны указать движку , какой узел в XML вы хотите адресовать. Это <FieldInfo>
, где целое число <Name>
равно вашей поисковой фразе. Ниже этого <FieldInfo>
мы выбираем <FriendlyName>
и заменяем первый найденный нами.
Я добавил WHERE
, используя .exist()
. Это ускорит / может ускорить процесс, поскольку сократит число .modify()
до строк, в которых есть хотя бы один подходящий целевой элемент.
И вы можете видеть, что .modify()
ограничено только одним изменением ввызов. Это может быть очень раздражающим ... Обходным путем может быть уничтожение и воссоздание XML или использование XQuery-FLWOR.