根据同级其他节点的值更新节点值XML T-SQL

Update Node Value XML T-SQL Based on Value of Other Node at Same Level

我想更新一块 ​​xml,我保存在一个变量中。我想更新 Value 的值,其中 Name 是给定值。这是 xml 的模型:

<ParameterValues>
  <ParameterValue>
    <Name>TO</Name>
    <Value>me@you.com</Value>
  </ParameterValue>
  <ParameterValue>
    <Name>CC</Name>
    <Value>bob@email.com</Value>
  </ParameterValue>
  <ParameterValue>
    <Name>Priority</Name>
    <Value>NORMAL</Value>
  </ParameterValue>
</ParameterValues>

我写了下面的内容,它总是更新第一个值,但我想更改 modify 命令,这样我就有了等同于 where 子句的内容 - 我想更新(对于instance) 同一节点中 Name = "CC" 的值。我该如何实现?

我在网上看到的所有示例都假设我在树结构中的每个节点都有一个唯一标识符,位于我要更新的值之上,而不是在同一级别。

DECLARE @Email VARCHAR(50) = 'New@email.co.uk';
DECLARE @Ext XML =
'<ParameterValues>
  <ParameterValue>
    <Name>TO</Name>
    <Value>me@you.com</Value>
  </ParameterValue>
  <ParameterValue>
    <Name>CC</Name>
    <Value>bob@email.com</Value>
  </ParameterValue>
  <ParameterValue>
    <Name>Priority</Name>
    <Value>NORMAL</Value>
  </ParameterValue>
</ParameterValues>';

SET @Ext.modify('replace value of (//Value/text())[1] with sql:variable("@Email")');

SELECT
     Col.value('./Name[1]','VARCHAR(100)')  AS [Name]
    ,Col.value('./Value[1]','VARCHAR(1000)')AS [Value]
FROM
    @Ext.nodes('//ParameterValue')  AS Tab(Col);

感谢所有帮助!

请参阅以下代码段:

SET @Ext.modify('replace value of (//Value[../Name="CC"]/text())[1] with sql:variable("@Email")');

诀窍是在方括号中应用条件。

像这样尝试

DECLARE @Ext XML =
'<ParameterValues>
  <ParameterValue>
    <Name>TO</Name>
    <Value>me@you.com</Value>
  </ParameterValue>
  <ParameterValue>
    <Name>CC</Name>
    <Value>bob@email.com</Value>
  </ParameterValue>
  <ParameterValue>
    <Name>Priority</Name>
    <Value>NORMAL</Value>
  </ParameterValue>
</ParameterValues>';

DECLARE @Email VARCHAR(50) = 'New@email.co.uk';
DECLARE @SearchFor VARCHAR(100)='CC'

SET @Ext.modify('replace value of (/ParameterValues/ParameterValue[Name=sql:variable("@Searchfor")]/Value/text())[1] with sql:variable("@Email")');

SELECT @Ext;

简而言之。

.modify() 方法每次调用只能更改一个位置。这意味着,第一个参数(replace value of 之后的 XPath)必须是单例。我们需要第二个变量来定义我们要更改的参数。我这里使用:

replace value of (/ParameterValues
                 /ParameterValue[Name=sql:variable("@Searchfor")]
                 /Value/text())[1] 
with sql:variable("@Email")

您可以将此解读为 深入 <ParameterValues>,然后进入 <ParameterValue> 并找到具有给定名称的一个。下面我们深入探讨 <Value> 和 return text().

如果多次出现,无论如何我们都会选择第一个并将其替换为给定值。