10

我有以下问题。我有一个存储在 sql 数据库中的 xml 文件。我应该通过除以 100 来更改所有 VALUE 标记值。这是 xml 结构的提取:

<HEIGHTC>
  <VALUE>15 </VALUE>
  <HEIGHTC_DATE>201110180000</HEIGHTC_DATE>
</HEIGHTC>
<HEIGHTC>
  <VALUE>15 </VALUE>
  <HEIGHTC_DATE>201110250000 </HEIGHTC_DATE>
</HEIGHTC>
<HEIGHTC>
  <VALUE>15 </VALUE>
  <HEIGHTC_DATE>201111020000 </HEIGHTC_DATE>
</HEIGHTC>
<HEIGHTC>
  <VALUE>15 </VALUE>
  <HEIGHTC_DATE>201111080000 </HEIGHTC_DATE>
</HEIGHTC>
<HEIGHTC>
  <VALUE>20 </VALUE>
  <HEIGHTC_DATE>201111150000 </HEIGHTC_DATE>
</HEIGHTC>
<HEIGHTC>
  <VALUE>15 </VALUE>
  <HEIGHTC_DATE>201111290000 </HEIGHTC_DATE>
</HEIGHTC>

我发现了以下查询:

DECLARE @var varchar(50)
set @var='HEIGHTC'
UPDATE tcdc.dbo.BADM_Xml
SET  xml_badm.modify('replace value of (/ROOT/*[local-name()=sql:variable("@var")]/VALUE/text())[1] with (/ROOT/*[local-name()=sql:variable("@var")]/VALUE)[1] * 0.01')

它一次对单个节点工作正常:有没有办法在一条指令中概括和更新所有内容?提前感谢迭戈

4

1 回答 1

20

replace value of一次只能更新一个节点。

查找要更新的所有 XML 中使用的最大节点数,并使用更新语句中的循环变量一次修改一个节点。

where 子句检查是否存在要修改的节点。否则,您将为每次迭代修改表中的每一行。

declare @I int

select @I = max(xml_badm.value('count(/ROOT/HEIGHTC/VALUE)', 'int'))
from YourTable

while @I > 0 
begin
  update YourTable
  set xml_badm.modify
    ('replace value of ((/ROOT/HEIGHTC/VALUE)[sql:variable("@I")]/text())[1]
      with ((/ROOT/HEIGHTC/VALUE)[sql:variable("@I")]/text())[1] * 0.01')
  where xml_badm.exist('(/ROOT/HEIGHTC/VALUE)[sql:variable("@I")]') = 1
  set @I = @I - 1
end
于 2013-05-23T12:14:03.887 回答