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

时间:2016-12-04 22:04:26

标签: sql-server xml replace 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)的价格?

2 个答案:

答案 0 :(得分:1)

我假设您的表包含多个具有相同结构的行。你想在一行中改变价格,或者 - 可能是危险的 - 在所有行中?

为此,我假设您要更改一行。因此,我将在末尾添加WHERE - 子句。如果您必须全部更改,可以使用CART_DATA.exist(...)=1进行更改。这是基于XML的方法,只获取真正包含给定ItemId的行。

但是:为什么这个XML?

设计通过物理定义的表格来呼唤经典的1:n关系。 XML适用于最终存储(归档),接口,Web服务(通常是数据传输),但不适用于大量移动的数据,或者您希望使用过滤器或统计问题查看的数据。

解决方案

然而,这是代码:

@YourTableYourXMLColumn更改为实际名称。

- 两个变量:

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

- 这将显示价格 as-is

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;

答案 1 :(得分:0)

我们假设xml字段在名为GM_CART的表中称为CART_DATA。

我们也将使用sql-variables,因为在大多数情况下,您需要使用参数运行查询。

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 update语句