我在SQL Server表xmlValue
中有一个名为tbl1
的XML列,其数据类型为nvarchar(max)
。
此列中的xml值如下所示:
<?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>
目前,名称'xyz'的地址值是'add xyz'。我需要将其更新为其他名称'add xyz updated'。
有没有简单的方法可以做到这一点。
我尝试使用How to Update XML in SQL based on values in that XML中提供的解决方案但似乎很复杂。
有没有人有更简单的解决方案来实现这一目标?
答案 0 :(得分:0)
您已经被告知,您的XML应该存储为原生XML。
您的问题是多方面的
NVARCHAR(MAX)
而不是XML
)NVARCHAR
编码UTF-8
转换为XML
.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>