如何更新SQL Server中的xml字段

时间:2018-03-22 04:48:13

标签: xml sql-server-2008 tsql xquery xml-dml

我在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中提供的解决方案但似乎很复杂。

有没有人有更简单的解决方案来实现这一目标?

1 个答案:

答案 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>