【问题标题】:Updating Xml attributes with new values in a SQL Server 2008 table使用 SQL Server 2008 表中的新值更新 Xml 属性
【发布时间】:2012-09-14 18:53:44
【问题描述】:

我在 SQL Server 2008 中有一个表,它有一些列。这些列之一是 Xml 格式 我想更新一些属性。

例如,我的 Xml 列的名称是 XmlText,它在前 5 行中的值如下:

 <Identification Name="John"  Family="Brown"     Age="30" /> 
 <Identification Name="Smith" Family="Johnson"   Age="35" /> 
 <Identification Name="Jessy" Family="Albert"    Age="60" />
 <Identification Name="Mike"  Family="Brown"     Age="23" />
 <Identification Name="Sarah" Family="Johnson"   Age="30" />

我想将所有 30 到 40 的 Age 属性更改如下:

 <Identification Name="John"  Family="Brown"     Age="40" /> 
 <Identification Name="Smith" Family="Johnson"   Age="35" /> 
 <Identification Name="Jessy" Family="Albert"    Age="60" />
 <Identification Name="Mike"  Family="Brown"     Age="23" />
 <Identification Name="Sarah" Family="Johnson"   Age="40" />

【问题讨论】:

  • 嗨,卡皮尔·坎德尔瓦尔。非常感谢您的编辑。
  • SQL = 结构化查询语言 - 它不是产品。我们需要知道您使用的是哪个数据库系统(以及哪个版本)——SQL Server、Oracle、IBM DB2、PostgreSQL 等。

标签: sql xml sql-server-2008 xquery


【解决方案1】:

从您问题的早期版本看来,您的 XML 实际上位于表中的不同行上。如果是这种情况,您可以使用它。

update YourTable set
  XMLText.modify('replace value of (/Identification/@Age)[1] with "40"')
where XMLText.value('(/Identification/@Age)[1]', 'int') = 30

使用表变量的工作示例。

declare @T table(XMLText xml)

insert into @T values('<Identification Name="John"  Family="Brown"   Age="30" />')
insert into @T values('<Identification Name="Smith" Family="Johnson" Age="35" />') 
insert into @T values('<Identification Name="Jessy" Family="Albert"  Age="60" />')
insert into @T values('<Identification Name="Mike"  Family="Brown"   Age="23" />')
insert into @T values('<Identification Name="Sarah" Family="Johnson" Age="30" />')

update @T set
  XMLText.modify('replace value of (/Identification/@Age)[1] with "40"')
where XMLText.value('(/Identification/@Age)[1]', 'int') = 30

select *
from @T 

【讨论】:

    【解决方案2】:

    修改方法是您的响应。但是如果你需要一个条件,你可以在这个方法的 with 部分使用 if 表达式。

    DECLARE @t TABLE (RecordXML XML);
    Declare @xml XML
    SET @xml = '<Root>
             <Identification Name="John"  Family="Brown"     Age="30" /> 
             <Identification Name="Smith" Family="Johnson"   Age="35" /> 
             <Identification Name="Jessy" Family="Albert"    Age="60" />
             <Identification Name="Mike"  Family="Brown"     Age="23" />
             <Identification Name="Sarah" Family="Johnson"   Age="30" />
             </Root>'
    INSERT @t VALUES (@xml);
    
    
    Declare @value nvarchar(50)
    DECLARE @oldvalue nvarchar(50)
    SET @value = '40'
    SET @oldvalue = '30'
    
    Declare @update_count xml
    select @update_count = @xml.query('count(/Root/Identification/@Age[.=sql:variable("@oldvalue")])')
    Declare @number int
    select @number = convert(int, (convert(nvarchar(50), @update_count)))
    
    declare @Node int
    set @Node = 1
    
    while @Node <= @number
    begin
    UPDATE
      @t
    SET
       RecordXML.modify('replace value of 
       (/Root/Identification/@Age[.=sql:variable("@oldvalue")])[1] with sql:variable("@value")')
    WHERE
      RecordXML.exist('/Root/Identification[@Age=sql:variable("@oldvalue")]') = 1;
    
    set @Node = @Node + 1
    end
    
    SELECT * FROM @t;
    

    【讨论】:

    • 您好 EMAI,感谢您的回答。但是您的答案并不完全正确,因为它只更改了第一行,但我需要一个将所有年龄属性更改为 30 的查询,因此最后一行也必须更改。如果您使用循环编写查询,那将非常好。
    【解决方案3】:

    试试这个:

    declare @xml XML
    
    SET @xml = '<Root>
             <Identification Name="John"  Family="Brown"     Age="30" /> 
             <Identification Name="Smith" Family="Johnson"   Age="35" /> 
             <Identification Name="Jessy" Family="Albert"    Age="60" />
             <Identification Name="Mike"  Family="Brown"     Age="23" />
             <Identification Name="Sarah" Family="Johnson"   Age="30" />
             </Root>'
    
     DECLARE @nodeCount int
    DECLARE @i int
    
    SET @i = 1
    
    SELECT @nodeCount = @xml.value('count(/Root/Identification/@Age)','int') 
    
    PRINT 'Number of nodes found: ' + STR(@nodeCount)
    
    WHILE (@i <= @nodeCount)
    BEGIN
    Set @xml.modify('replace value of (/Root/Identification/@Age)[.=30][1] with "40"')
    
    SET @i = @i + 1
    END
    
    SELECT @xml
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多