我遇到了在SQL Server中修改XML的问题,这对我来说似乎没有意义。我想更新一个空节点的值,但它似乎没有工作。例如,假设我有这个XML树:
<root>
<node />
</root>
我想用'foo'更新<node />
的值,所以我有XML查询:
UPDATE [Table]
SET [XmlColumn].modify('
replace value of (root/node/text())[1]
with "foo"')
出于某种原因,这不起作用。它将节点视为不存在。如果节点已经有一个值(例如<node>bar</node>
),它就可以正常工作,但是当节点为空时,它会默默地忽略该命令,甚至不会抛出任何错误。有没有办法让SQL Server在空节点上确认replace value of
?
修改
我希望此查询的最终结果是:
<root>
<node>
foo
</node>
</root>
答案 0 :(得分:5)
UPDATE [Table]
SET [XmlColumn].modify(' insert text{"foo"} into (/root/node)[1]')
为我试试这项工作
答案 1 :(得分:3)
这会有任何帮助:http://whyiamright.wordpress.com/2008/01/02/updating-xml-column-in-sql-server-2005/?
你似乎在xpath的开头就错过了斜线。
编辑:然后它似乎是这个问题的重复:
答案 2 :(得分:0)
不断创新。
提供实际答案:
您不能一口气做到这一点。
您首先需要将该值设置为空(如果存在,请替换),然后将其插入:
SET @tXML.modify('replace value of (//path[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0]/text())[1] with ""')
SET @tXML.modify('insert text{"This Works"} into (//path[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0])[1]')
使用的XML示例:
DECLARE @tXML xml = '<svg>
<g>
<path></path>
<path data-objid="0000X1">tt</path>
<path data-objid="0000X2"></path>
<path data-objid="0000X3"></path>
</g>
</svg>';
属性也一样。
在那里,您需要首先插入属性,但是您需要使用[not(@data-objid)]
来检查属性是否已经存在。将其插入所需的位置后,您可以修改值。
SET @tXML.modify('insert attribute data-objid {"1"} into (//path[not(@data-objid) and contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0])[1]')
SET @tXML.modify('replace value of (//path[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0]/@data-objid)[1] with "Test"')
因此,您在不存在该属性的地方创建了该属性(具有虚拟值),然后在该属性已经存在的地方对其进行了更新,这意味着现在所有值(包括虚拟值)都已更新。
由于修改/插入只能对单个记录进行操作,因此您不能仍然进行批量更新/插入。
有趣的是,与预期相反,您可以可以批量删除...不是很重要...我认为有人在运送垃圾时用完了这一点。