使用 (XML DML) 的替换值更新 Xml 字段

Update Xml Field with replace value of (XML DML)

我面临更新一个包含多行的 xml 字段数据的情况。

XML 看起来像这样(包含多个项目的购物车数据)

 <cart>
  <items>
    <ItemId>111613</ItemId>
    <ItemCode>P.KNT330.01.85.1.1.1</ItemCode>
    <ItemName>KANAT330 85 TEAK  PETEK  ODA PVT</ItemName>
    <THUMBNAIL>/Content/images/noimage.jpg</THUMBNAIL>
    <Quantity>1</Quantity>
    <MU>AD</MU>
    <Price_Net>143.50</Price_Net>
    <Currency>TL</Currency>
    <ExchangeRate>1</ExchangeRate>
    <Price_Net_TL>143.50</Price_Net_TL>
    <Item_Disc1_Percent>15</Item_Disc1_Percent>
    <Item_Disc2_Percent>9</Item_Disc2_Percent>
    <Item_Disc3_Percent>0</Item_Disc3_Percent>
    <Item_Disc4_Percent>0</Item_Disc4_Percent>
    <Item_Disc5_Percent>0</Item_Disc5_Percent>
    <Item_Disc6_Percent>0</Item_Disc6_Percent>
    <Price_Net_AfterDisc_TL>110.997250</Price_Net_AfterDisc_TL>
    <VAT_Percent>18.0</VAT_Percent>
    <VAT_TL>19.97950500</VAT_TL>
    <Price_Gross_TL>130.97675500</Price_Gross_TL>
    <LineDesc />
  </items>
  <items>
    <ItemId>116950</ItemId>
    <ItemCode>KS.220.S.0850.51.00</ItemCode>
    <ItemName>220 LIK D.TEAK 85 LIK KNT YÖNSÜZ KASA</ItemName>
    <THUMBNAIL>/Content/images/noimage.jpg</THUMBNAIL>
    <Quantity>1.000</Quantity>
    <MU>TK</MU>
    <Price_Net>115.20</Price_Net>
    <Currency>TL</Currency>
    <ExchangeRate>1</ExchangeRate>
    <Price_Net_TL>115.20</Price_Net_TL>
    <Item_Disc1_Percent>15</Item_Disc1_Percent>
    <Item_Disc2_Percent>9</Item_Disc2_Percent>
    <Item_Disc3_Percent>0</Item_Disc3_Percent>
    <Item_Disc4_Percent>0</Item_Disc4_Percent>
    <Item_Disc5_Percent>0</Item_Disc5_Percent>
    <Item_Disc6_Percent>0</Item_Disc6_Percent>
    <Price_Net_AfterDisc_TL>89.107200</Price_Net_AfterDisc_TL>
    <VAT_Percent>18.0</VAT_Percent>
    <VAT_TL>16.03929600</VAT_TL>
    <Price_Gross_TL>105.14649600</Price_Gross_TL>
    <LineDesc />
  </items>
  <items>
    <ItemId>112357</ItemId>
    <ItemCode>PRV.071.S.51</ItemCode>
    <ItemName>PERVAZ 70 DÜZ D.TEAK TAKIM</ItemName>
    <THUMBNAIL>/Content/images/noimage.jpg</THUMBNAIL>
    <Quantity>1.000</Quantity>
    <MU>TK</MU>
    <Price_Net>45.80</Price_Net>
    <Currency>TL</Currency>
    <ExchangeRate>1</ExchangeRate>
    <Price_Net_TL>45.80</Price_Net_TL>
    <Item_Disc1_Percent>15</Item_Disc1_Percent>
    <Item_Disc2_Percent>9</Item_Disc2_Percent>
    <Item_Disc3_Percent>0</Item_Disc3_Percent>
    <Item_Disc4_Percent>0</Item_Disc4_Percent>
    <Item_Disc5_Percent>0</Item_Disc5_Percent>
    <Item_Disc6_Percent>0</Item_Disc6_Percent>
    <Price_Net_AfterDisc_TL>35.426300</Price_Net_AfterDisc_TL>
    <VAT_Percent>18.0</VAT_Percent>
    <VAT_TL>6.37673400</VAT_TL>
    <Price_Gross_TL>41.80303400</Price_Gross_TL>
    <LineDesc />
  </items>
  <items>
    <ItemId>108561</ItemId>
    <ItemCode>34016-13030</ItemCode>
    <ItemName>IÇ ODA KAPI KILIDI NIKEL  141-45</ItemName>
    <THUMBNAIL>/Content/images/noimage.jpg</THUMBNAIL>
    <Quantity>1.000</Quantity>
    <MU>AD</MU>
    <Price_Net>10.35</Price_Net>
    <Currency>TL</Currency>
    <ExchangeRate>1</ExchangeRate>
    <Price_Net_TL>10.35</Price_Net_TL>
    <Item_Disc1_Percent>15</Item_Disc1_Percent>
    <Item_Disc2_Percent>9</Item_Disc2_Percent>
    <Item_Disc3_Percent>0</Item_Disc3_Percent>
    <Item_Disc4_Percent>0</Item_Disc4_Percent>
    <Item_Disc5_Percent>0</Item_Disc5_Percent>
    <Item_Disc6_Percent>0</Item_Disc6_Percent>
    <Price_Net_AfterDisc_TL>8.005725</Price_Net_AfterDisc_TL>
    <VAT_Percent>18.0</VAT_Percent>
    <VAT_TL>1.44103050</VAT_TL>
    <Price_Gross_TL>9.44675550</Price_Gross_TL>
    <LineDesc />
  </items>
  <items>
    <ItemId>108568</ItemId>
    <ItemCode>34026-11160</ItemCode>
    <ItemName>ADOKAPI KÖSE BIRL TKZ TAKIMI</ItemName>
    <THUMBNAIL>/Content/images/noimage.jpg</THUMBNAIL>
    <Quantity>1.000</Quantity>
    <MU>AD</MU>
    <Price_Net>1.80</Price_Net>
    <Currency>TL</Currency>
    <ExchangeRate>1</ExchangeRate>
    <Price_Net_TL>1.80</Price_Net_TL>
    <Item_Disc1_Percent>15</Item_Disc1_Percent>
    <Item_Disc2_Percent>9</Item_Disc2_Percent>
    <Item_Disc3_Percent>0</Item_Disc3_Percent>
    <Item_Disc4_Percent>0</Item_Disc4_Percent>
    <Item_Disc5_Percent>0</Item_Disc5_Percent>
    <Item_Disc6_Percent>0</Item_Disc6_Percent>
    <Price_Net_AfterDisc_TL>1.392300</Price_Net_AfterDisc_TL>
    <VAT_Percent>18.0</VAT_Percent>
    <VAT_TL>0.25061400</VAT_TL>
    <Price_Gross_TL>1.64291400</Price_Gross_TL>
    <LineDesc />
  </items>
  <items>
    <ItemId>108543</ItemId>
    <ItemCode>34006-70370</ItemCode>
    <ItemName>ADOKAPI MENTESE  10401.0000.0.2</ItemName>
    <THUMBNAIL>/Content/images/noimage.jpg</THUMBNAIL>
    <Quantity>3.000</Quantity>
    <MU>AD</MU>
    <Price_Net>1.30</Price_Net>
    <Currency>TL</Currency>
    <ExchangeRate>1</ExchangeRate>
    <Price_Net_TL>1.30</Price_Net_TL>
    <Item_Disc1_Percent>15</Item_Disc1_Percent>
    <Item_Disc2_Percent>9</Item_Disc2_Percent>
    <Item_Disc3_Percent>0</Item_Disc3_Percent>
    <Item_Disc4_Percent>0</Item_Disc4_Percent>
    <Item_Disc5_Percent>0</Item_Disc5_Percent>
    <Item_Disc6_Percent>0</Item_Disc6_Percent>
    <Price_Net_AfterDisc_TL>1.005550</Price_Net_AfterDisc_TL>
    <VAT_Percent>18.0</VAT_Percent>
    <VAT_TL>0.18099900</VAT_TL>
    <Price_Gross_TL>1.18654900</Price_Gross_TL>
    <LineDesc />
  </items>
  <items>
    <ItemId>108575</ItemId>
    <ItemCode>34026-90300</ItemCode>
    <ItemName>ADOKAPI ROZETI NIKEL 20298.0000.0.2</ItemName>
    <THUMBNAIL>/Content/images/noimage.jpg</THUMBNAIL>
    <Quantity>2.000</Quantity>
    <MU>AD</MU>
    <Price_Net>0.45</Price_Net>
    <Currency>TL</Currency>
    <ExchangeRate>1</ExchangeRate>
    <Price_Net_TL>0.45</Price_Net_TL>
    <Item_Disc1_Percent>15</Item_Disc1_Percent>
    <Item_Disc2_Percent>9</Item_Disc2_Percent>
    <Item_Disc3_Percent>0</Item_Disc3_Percent>
    <Item_Disc4_Percent>0</Item_Disc4_Percent>
    <Item_Disc5_Percent>0</Item_Disc5_Percent>
    <Item_Disc6_Percent>0</Item_Disc6_Percent>
    <Price_Net_AfterDisc_TL>0.348075</Price_Net_AfterDisc_TL>
    <VAT_Percent>18.0</VAT_Percent>
    <VAT_TL>0.06265350</VAT_TL>
    <Price_Gross_TL>0.41072850</Price_Gross_TL>
    <LineDesc />
  </items>
  <items>
    <ItemId>115240</ItemId>
    <ItemCode>34024-35016</ItemCode>
    <ItemName>TPE ADOKAPI CONTA AÇIK KAHVE</ItemName>
    <THUMBNAIL>/Content/images/noimage.jpg</THUMBNAIL>
    <Quantity>5.000</Quantity>
    <MU>MT</MU>
    <Price_Net>0.36</Price_Net>
    <Currency>TL</Currency>
    <ExchangeRate>1</ExchangeRate>
    <Price_Net_TL>0.36</Price_Net_TL>
    <Item_Disc1_Percent>15</Item_Disc1_Percent>
    <Item_Disc2_Percent>9</Item_Disc2_Percent>
    <Item_Disc3_Percent>0</Item_Disc3_Percent>
    <Item_Disc4_Percent>0</Item_Disc4_Percent>
    <Item_Disc5_Percent>0</Item_Disc5_Percent>
    <Item_Disc6_Percent>0</Item_Disc6_Percent>
    <Price_Net_AfterDisc_TL>0.278460</Price_Net_AfterDisc_TL>
    <VAT_Percent>18.0</VAT_Percent>
    <VAT_TL>0.05012280</VAT_TL>
    <Price_Gross_TL>0.32858280</Price_Gross_TL>
    <LineDesc />
  </items>
  <GenDiscPercent_1 xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" p2:nil="true" />
  <GenDiscPercent_2 xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" p2:nil="true" />
  <GenDiscPercent_3 xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" p2:nil="true" />
  <ResChar1 />
  <ResChar2>A-0201-1748</ResChar2>
  <ResChar3 />
  <ResNum1 xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" p2:nil="true" />
  <ResNum2 xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" p2:nil="true" />
  <ResNum3 xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" p2:nil="true" />
  <ResNum4 xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" p2:nil="true" />
  <ResDate1>2016-02-18T00:00:00</ResDate1>
  <ResDate2>2016-02-18T00:00:00</ResDate2>
  <ResDate3 xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" p2:nil="true" />
  <ResDate4 xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" p2:nil="true" />
</cart>

如何在此 xml 字段数据中修改(比方说)特定商品(ItemId 为 116950)的价格?

假设 xml 字段在 table 中称为 CART_DATA GM_CART。

我们还将使用 sql 变量,因为在大多数情况下您需要 运行 您的查询带有参数。

DECLARE @cartid int = 1000, @itemid int = 116950, @newprice float = 99.90    
UPDATE GM_CART 
SET CART_DATA.modify('replace value of (/cart/items/Price_Net/text()[.>>(/cart/items/ItemId[.=sql:variable("@itemid")])[1] ])[1]
 with sql:variable("@newprice")')   
    WHERE CARTID=@cartid

如果需要更新其他节点,您必须为每个节点单独调用 sql 更新语句

我假设,您的 table 包含具有相同结构的几行。您是想在一行中更改价格,还是在所有行中更改价格?

为此,我假设您想要更改一行。因此,我将在末尾添加一个 WHERE 子句。如果你必须改变所有,你可以用 CART_DATA.exist(...)=1 来改变这个。这是基于 XML 的快速方法,只获取真正包含给定 ItemId.

的行

但是:为什么会这样XML?

该设计通过物理定义的 table 呼唤经典的 1:n 关系。 XML 适用于最终存储(存档)、接口、Web 服务(一般数据传输),但不适用于大量移动的数据,或者您想要使用过滤器或统计问题查看的数据。

一个解决方案

然而,这是代码:

@YourTableYourXMLColumn改为真实姓名。

--两个变量:

DECLARE @itemID INT=116950;
DECLARE @newPrice DECIMAL(10,4)=0.99;

--这将显示价格原样

SELECT t.YourXMLColumn.value('(/cart/items[ItemId=sql:variable("@itemID")]/Price_Net/text())[1]','decimal(10,4)')
FROM @YourTable AS t
WHERE t.ID=1;

--这将修改价格

UPDATE @YourTable
SET YourXMLColumn.modify(N'replace value of (/cart/items[ItemId=sql:variable("@itemID")]/Price_Net/text())[1] with sql:variable("@newPrice")')
WHERE ID=1;

--如果操作成功,将显示新价格

SELECT t.YourXMLColumn.value('(/cart/items[ItemId=sql:variable("@itemID")]/Price_Net/text())[1]','decimal(10,4)')
FROM @YourTable AS t
WHERE t.ID=1;