您已经被告知,您的 XML 应该存储为原生 XML。
你的问题是多方面的
- 错误的数据类型(
NVARCHAR(MAX)
而不是XML
)
NVARCHAR
声明UTF-8
编码时不允许转换为 XML from
.modify
不适用
所以解决方法是临时表
模拟场景
DECLARE @tbl TABLE(ID INT IDENTITY, YourXmlAsString NVARCHAR(MAX));
INSERT INTO @tbl VALUES
('<?xml version="1.0" encoding="UTF-8"?>
<main>
<sub>
<subMode>
<name>abc</name>
<address>add abc</address>
</subMode>
<subMode>
<name>xyz</name>
<address>add xyz</address>
</subMode>
</sub>
</main>');
--这将SELECT
转换您的字符串 XML 并将结果存储为真正的 XML
SELECT ID
,CAST(REPLACE(YourXmlAsString,'UTF-8','UTF-16') AS XML) CastedToRealXML
,YourXmlAsString AS OriginalValue
INTO #tempTblKeepsCastedValue
FROM @tbl
--WHERE SomeCriteria;
--您搜索xyz并将某些内容附加到现有值
DECLARE @SearchForName NVARCHAR(100)=N'xyz';
DECLARE @Append NVARCHAR(100)=N'add to the value';
UPDATE #tempTblKeepsCastedValue
SET CastedToRealXML.modify('replace value of
(/main/sub/subMode[name/text()=sql:variable("@SearchForName")]/address/text())[1]
with concat((/main/sub/subMode[name/text()=sql:variable("@SearchForName")]/address/text())[1],sql:variable("@Append"))');
INNER JOIN
--现在您使用临时表更新原始表
UPDATE t
SET YourXmlAsString=CAST(tmp.CastedToRealXml AS NVARCHAR(MAX))
FROM @tbl AS t
INNER JOIN #tempTblKeepsCastedValue AS tmp ON t.ID=tmp.ID;
--结果(和清理)
SELECT * FROM @tbl
DROP TABLE #tempTblKeepsCastedValue;
ID YourXmlAsString
1 <main><sub><subMode><name>abc</name><address>add abc</address></subMode><subMode><name>xyz</name><address>add xyzadd to the value</address></subMode></sub></main>