有没有办法在SQL中将新子树写入XML节点,特别是动态查询?我知道可以使用insert
和delete
语句的某种组合,但我正在寻找一种以相当隐含的方式工作的东西。 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}}而是。有没有办法以类似的方式做到这一点?
答案 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。这可能会给你想要的结果。