如何更新 SQL 服务器中的 xml 字段
How to update xml field in SQL Server
我在 SQL 服务器 table tbl1
中有一个名为 xmlValue
的 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>
目前name'xyz'的地址值为'add xyz'。我需要将其更新为其他内容,比如 'add xyz updated'.
有什么简单的方法可以做到这一点。
我尝试使用 中提供的解决方案,但它似乎很复杂。
有人有更简单的解决方案吗?
你已经被告知,你的 XML 应该存储为原生 XML。
你的问题是多方面的
- 错误的数据类型(
NVARCHAR(MAX)
而不是 XML
)
- 从
NVARCHAR
到 XML 的转换不允许声明为 UTF-8
编码
.modify
不适用 即时
所以解决方法是临时 table
模型场景
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
转换你的 string-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
将原始表格更新为临时 table
UPDATE t
SET YourXmlAsString=CAST(tmp.CastedToRealXml AS NVARCHAR(MAX))
FROM @tbl AS t
INNER JOIN #tempTblKeepsCastedValue AS tmp ON t.ID=tmp.ID;
--结果(和clean-up)
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>
我在 SQL 服务器 table tbl1
中有一个名为 xmlValue
的 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>
目前name'xyz'的地址值为'add xyz'。我需要将其更新为其他内容,比如 'add xyz updated'.
有什么简单的方法可以做到这一点。
我尝试使用
有人有更简单的解决方案吗?
你已经被告知,你的 XML 应该存储为原生 XML。
你的问题是多方面的
- 错误的数据类型(
NVARCHAR(MAX)
而不是XML
) - 从
NVARCHAR
到 XML 的转换不允许声明为UTF-8
编码 .modify
不适用 即时
所以解决方法是临时 table
模型场景
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
转换你的 string-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
将原始表格更新为临时 table
UPDATE t
SET YourXmlAsString=CAST(tmp.CastedToRealXml AS NVARCHAR(MAX))
FROM @tbl AS t
INNER JOIN #tempTblKeepsCastedValue AS tmp ON t.ID=tmp.ID;
--结果(和clean-up)
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>