更新sql中的XML列值

更新sql中的XML列值,xml,sql-server-2008-r2,Xml,Sql Server 2008 R2,我在sql表中有一个XML列需要更新。假设结构如下所示: <JPS> <P> <JP> <IsRequired>true</IsRequired> <Name>Folder</Name> <Value>C:\Test</Value> </JP> <JP> <IsRequired>false</IsRequire

我在sql表中有一个XML列需要更新。假设结构如下所示:

<JPS>
 <P>
  <JP>
   <IsRequired>true</IsRequired>
   <Name>Folder</Name>
   <Value>C:\Test</Value>
  </JP>
  <JP>
   <IsRequired>false</IsRequired>
   <Name>Email Addresses</Name>
   <Value>a@a.com; b@b.com</Value>      
  </JP>
</P>

真的 文件夹 C:\测试 假的 电子邮件地址 a@a.com; b@b.com

我想将表中所有行中所有XML值中的电子邮件地址更新为特定值。
如何实现同样的功能?

在标准sql中无法实现


使用标准sql,您应该一次读取一行相关的xml,更新xml并将其插回。

您不能在标准sql中执行此操作


使用标准sql,您应该一次读取一行相关的xml,更新xml并将其插回。

如果要更新具有
电子邮件地址
值的
标记的
元素的内容,则可以使用类似以下内容:

;WITH XmlEmail AS
(
SELECT 
    SomeUniqueID,  // some unique/primary key ID from your table - adapt as needed!
    JPReq = XJP.value('(IsRequired)[1]', 'varchar(20)'),
    JPName = XJP.value('(Name)[1]', 'varchar(20)'),
    JPValue = XJP.value('(Value)[1]', 'varchar(20)')
FROM 
    dbo.YourTable
CROSS APPLY
    YourXmlColumn.nodes('/JPS/P/JP[Name="Email Addresses"]') AS XTbl(XJP)
)
UPDATE dbo.YourTable
SET YourXmlColumn.modify('replace value of (/JPS/P/JP[Name="Email Addresses"]/Value/text())[1] with "newmail@test.tst"')
FROM XmlEmail xe 
WHERE dbo.YourTable.SomeUniqueID = xe.SomeUniqueID
这会将所有行和所有
/
节点更新为相同的值-这就是您要查找的吗


更新:增加了只检查和更新XML列实际包含
标记且名称为
电子邮件地址的行的支持-它要求表上有一个主键()(不确定它是什么,因为您没有说过它)。。。。我使用了
SomeUniqueID
作为列名-根据需要调整您的表如果要更新具有
电子邮件地址值的
标记的
元素的内容,则可以使用以下内容:

;WITH XmlEmail AS
(
SELECT 
    SomeUniqueID,  // some unique/primary key ID from your table - adapt as needed!
    JPReq = XJP.value('(IsRequired)[1]', 'varchar(20)'),
    JPName = XJP.value('(Name)[1]', 'varchar(20)'),
    JPValue = XJP.value('(Value)[1]', 'varchar(20)')
FROM 
    dbo.YourTable
CROSS APPLY
    YourXmlColumn.nodes('/JPS/P/JP[Name="Email Addresses"]') AS XTbl(XJP)
)
UPDATE dbo.YourTable
SET YourXmlColumn.modify('replace value of (/JPS/P/JP[Name="Email Addresses"]/Value/text())[1] with "newmail@test.tst"')
FROM XmlEmail xe 
WHERE dbo.YourTable.SomeUniqueID = xe.SomeUniqueID
这会将所有行和所有
/
节点更新为相同的值-这就是您要查找的吗


更新:增加了只检查和更新XML列实际包含
标记且名称为
电子邮件地址的行的支持-它要求表上有一个主键()(不确定它是什么,因为您没有说过它)。。。。我使用了
SomeUniqueID
作为列名-根据需要调整您的表

我使用的是sql server 2008 R2,这是一个非常糟糕的设计。。。。不要将多个值连接到一个XML标记中!使用多个标记-XML以这种方式非常灵活。。。。否则你必须求助于字符串匹配和替换正则表达式和其他丑陋的东西…谢谢Marc。我理解设计问题。但考虑到我只有一个电子邮件地址,但在那种情况下,我们如何更新。我正在使用SQL Server 2008 R2这是非常糟糕的设计…不要将多个值连接到一个XML标记中!使用多个标记-XML以这种方式非常灵活。。。。否则你必须求助于字符串匹配和替换正则表达式和其他丑陋的东西…谢谢Marc。我理解设计问题。但是,考虑到我只有一个电子邮件地址,但在这种情况下,我们如何更新。当然,你可以使用一个支持XML数据类型和XML操作的数据库系统……当然,你可以使用一个支持XML数据类型和XML操作的数据库系统……在运行更新之后,它说所有60行都被更新了。但是,当打开每个xml列值以验证它是否实际更新时,我看到了它。还注意到一些行实际上缺少xml中的电子邮件地址标记名称属性。如果电子邮件地址名称标记存在于xml行中,我们如何在update语句中进行检查,然后进行更新。我不知道您的表结构,因此很难提出任何建议。。。我试图找出哪些行包含
电子邮件地址
节点,但最终,我无法使用这些知识,因为我不知道如何唯一地标识表中的一行……运行更新后,它说所有60行都已更新。但是,当打开每个xml列值以验证它是否实际更新时,我看到了它。还注意到一些行实际上缺少xml中的电子邮件地址标记名称属性。如果电子邮件地址名称标记存在于xml行中,我们如何在update语句中进行检查,然后进行更新。我不知道您的表结构,因此很难提出任何建议。。。我试图找出哪些行包含
电子邮件地址
节点,但最后,我无法使用这些知识,因为我不知道如何唯一地标识表中的行。。。