在SQL中将新子树写入XML节点

时间:2011-06-16 17:32:01

标签: sql xml serialization

有没有办法在SQL中将新子树写入XML节点,特别是动态查询?我知道可以使用insertdelete语句的某种组合,但我正在寻找一种以相当隐含的方式工作的东西。 IE,我不想为每个需要的特定情况编写不同的查询。例如,假设我有这个XML层次结构:

<root>
    ...
    <node>
        <node1>
            ...
        </node1>
        <node2>
            ...
        </node2>
        ...
    </node>
    ...
</root>

如果我想替换单个节点的值,我有这个查询:

DECLARE @newVal varchar(max)
DECLARE @XPath varchar(max)
SELECT @newVal = 'newValue'
SELECT @XPath = 'root/node/node1/text()'

DECLARE @query varchar(max)

SET @query = '
    UPDATE  [dbo].[Users]
    SET     [NewSettingsXml].modify(''
        replace value of (' + @XPath + ')[1]
        with "' + @newVal + '"'')'
exec(@query)

我希望我能够做一些类似@newVal = '<newNode>foo</newNode>'的事情,其中​​新的XML将来自序列化的C#对象,但是,毫不奇怪,它将值编码为文本,将其设置为{ {1}}而是。有没有办法以类似的方式做到这一点?

3 个答案:

答案 0 :(得分:3)

您可以尝试将@newVal转换为nvarchar(max),然后执行mofify,如下所示:

DECLARE @newVal xml
SELECT @newVal = '<newNode>foo</newNode>'

DECLARE @strNewVal nvarchar(max)
SET @strNewVal = (Select (CONVERT(nvarchar(max), @newVal)))

UPDATE  [dbo].[Users]
SET     [SettingsXml].modify('
    replace value of (root/node/node1/text())[1]
    with sql:variable("@strNewVal")')

答案 1 :(得分:1)

我认为不可能用节点替换值。

这会将字符串作为值,当然会编码<>

replace value of (root/node/node1/text())[1] with "<newNode>foo</newNode>"

你可能不得不做这样的事情

replace value of (root/node/node1/text())[1] with <newNode>foo</newNode>

但是这给出了错误:

  

'替换值'的'with'子句   '不能包含构造的XML

如果您使用xml变量:

DECLARE @newVal xml
SELECT @newVal = '<newNode>foo</newNode>'

UPDATE  [dbo].[Users]
SET     [SettingsXml].modify('
    replace value of (root/node/node1/text())[1]
    with sql:variable("@newVal")')

您收到错误

  

仅支持XML实例   使用插入的直接来源   SQL:柱/ SQL:变量

所以我想当你想插入节点时,你会被迫使用insert。

答案 2 :(得分:0)

尝试使用FOR XML contruct。这可能会给你想要的结果。