基于复合XQuery

时间:2015-06-09 16:06:47

标签: sql-server xml xquery xquery-sql xquery-update

我有一个带有XmlProperties列的db表,其中的数据采用Serialized .NET数组的形式。这是一个例子:

<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
  <KeyValueOfstringanyType>
    <Key>CompanyName</Key>
    <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">Company A</Value>
  </KeyValueOfstringanyType>
  <KeyValueOfstringanyType>
    <Key>CompanyUrl</Key>
    <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string" />
  </KeyValueOfstringanyType>
</ArrayOfKeyValueOfstringanyType>

我想更新Key = "CompanyName"Value = "Company A"以及set Value = "Company A, LLC."的所有值元素此列中还有其他键/值对,这就是我需要更新的原因仅适用于该键/值组合。

我可以使用此查询查询并获取结果:

WITH KeyValues
AS (SELECT
  Id,
  key_value.value('./*:Key[1]', 'NVARCHAR(MAX)') AS [key],
  key_value.value('./*:Value[1]', 'NVARCHAR(MAX)') AS [value]
FROM dbo.MyTable
CROSS APPLY XmlProperties.nodes('/*:ArrayOfKeyValueOfstringanyType/*:KeyValueOfstringanyType[*:Key="CompanyName" and *:Value="Company A"]') AS N (key_value))
SELECT
  *
FROM KeyValues

但是,我似乎无法弄清楚如何将相同的过滤逻辑应用于.modify语句来替换&#34;公司A&#34;与&#34;公司A,LLC。&#34;

我尝试过这样的事情无济于事:

UPDATE dbo.MyTable
SET XmlProperties.modify('replace value of (/*:ArrayOfKeyValueOfstringanyType/*:KeyValueOfstringanyType/*:Value[../*:Key="CompanyName" and ../*:Value="Company A"]) with "Company A, LLC"')

有人有一个优雅的解决方案吗?我觉得我很亲近,但还没有破解它。

1 个答案:

答案 0 :(得分:1)

您可以尝试这种方式:

declare @xml XML = '<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
  <KeyValueOfstringanyType>
    <Key>CompanyName</Key>
    <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">Company A</Value>
  </KeyValueOfstringanyType>
  <KeyValueOfstringanyType>
    <Key>CompanyUrl</Key>
    <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string" />
  </KeyValueOfstringanyType>
</ArrayOfKeyValueOfstringanyType>'

SET @xml.modify('
  replace value of 
    (/*:ArrayOfKeyValueOfstringanyType
     /*:KeyValueOfstringanyType[*:Key="CompanyName" and *:Value="Company A"]
     /*:Value
     /text()
    )[1] 
  with "Company A, LLC"
')

<强> SQL Fiddle

请注意,replace value of要求您将xpath结果限制为一个简单类型。请参阅上面的示例,尾随/text()表示xpath返回简单类型string,然后()[1]将字符串限制为仅返回一个实例。