我在Orders表中有一个名为OrderXML的xml列...
表格中有一个像这样的XML XPath ...
/Order/InternalInformation/InternalOrderBreakout/InternalOrderHeader/InternalOrderDetails/InternalOrderDetail
那里的InternalOrderDetails包含许多这样的InternalOrderDetail节点...
<InternalOrderDetails>
<InternalOrderDetail>
<Item_Number>FBL11REFBK</Item_Number>
<CountOfNumber>10</CountOfNumber>
<PriceLevel>FREE</PriceLevel>
</InternalOrderDetail>
<InternalOrderDetail>
<Item_Number>FCL13COTRGUID</Item_Number>
<CountOfNumber>2</CountOfNumber>
<PriceLevel>NONFREE</PriceLevel>
</InternalOrderDetail>
</InternalOrderDetails>
我的最终目标是在节点的Item_Number包含COTRGUID(例如'%COTRGUID')并且PriceLevel = NONFREE的情况下修改OrderXML列中的XML。如果满足该条件,我想将PriceLevel列更改为FREE。
创建xpath表达式以查找正确的节点(使用OrderXML.value或OrderXML.exist函数)以及使用OrderXML.modify函数更新XML时,都遇到了麻烦。
我为where子句尝试了以下内容:
WHERE OrderXML.value('(/Order/InternalInformation/InternalOrderBreakout/InternalOrderHeader/InternalOrderDetails/InternalOrderDetail/Item_Number/node())[1]','nvarchar(64)') like '%13COTRGUID'
那确实有效,但是在我看来,我还需要在同一个where子句中包含第二个条件(PriceLevel = NONFREE),但我不知道该怎么做。也许我可以为这样的第二个条件输入AND…
AND OrderXML.value('(/Order/InternalInformation/InternalOrderBreakout/InternalOrderHeader/InternalOrderDetails/InternalOrderDetail/PriceLevel/node())[1]','nvarchar(64)') = 'NONFREE'
但由于它是XML查询,因此恐怕它最终会像OR一样运行。
一旦正确获得WHERE子句,我将使用SET这样更新列:
UPDATE Orders SET orderXml.modify('replace value of (/Order/InternalInformation/InternalOrderBreakout/InternalOrderHeader/InternalOrderDetails/InternalOrderDetail/PriceLevel[1]/text())[1] with "NONFREE"')
但是,我在一些测试数据上运行了该语句,并且没有更新任何XML列(即使它说zz行有效)。
我在这里待了几个小时都没有结果。感谢帮助。谢谢。
最佳答案
如果在Orders表的每一行中您的条件不止一个节点,则可以使用以下方法:
update orders set
data.modify('
replace value of
(
/Order/InternalInformation/InternalOrderBreakout/
InternalOrderHeader/InternalOrderDetails/
InternalOrderDetail[
Item_Number[contains(., "COTRGUID")] and
PriceLevel="NONFREE"
]/PriceLevel/text()
)[1]
with "FREE"
');
如果一行中可以有多个节点,那么有几种可能的解决方案,可惜的是,每个解决方案都不是很优雅。
您可以重建表中的所有xml-sql fiddle demo
或者您可以在循环中进行更新-sql fiddle demo