【问题标题】:How to change node value using node's current value in SQL with XQuery (SQL Server)如何使用 XQuery(SQL Server)在 SQL 中使用节点的当前值更改节点值
【发布时间】:2011-07-26 06:38:47
【问题描述】:

我该如何改变:

<data>
  <row>
    <a>A</a>
    <a>B</a>
    <a>C</a>
  </row>
</data>

到:

<data>
  <row>
    <a>Data A</a>
    <a>Data B</a>
    <a>Data C</a>
  </row>
</data>

在 SQL 中?我看过很多关于如何用静态值完全替换值的示例,但没有动态替换值的示例。

【问题讨论】:

    标签: sql sql-server xml xml-dml


    【解决方案1】:

    不知道是否可以在replace value of语句中使用xml。但你可以这样做。

    declare @xml xml = '
    <data>
      <row>
        <a>A</a>
        <a>B</a>
        <a>C</a>
      </row>
    </data>'
    
    declare @Val1 varchar(10) 
    declare @Val2 varchar(10) 
    declare @Val3 varchar(10) 
    
    select 
      @Val1 = 'Data '+r.value('a[1]', 'varchar(1)'), 
      @Val2 = 'Data '+r.value('a[2]', 'varchar(1)'), 
      @Val3 = 'Data '+r.value('a[3]', 'varchar(1)') 
    from @xml.nodes('/data/row') n(r)
    
    set @xml.modify('replace value of (/data/row/a/text())[1] with (sql:variable("@val1"))')
    set @xml.modify('replace value of (/data/row/a/text())[2] with (sql:variable("@val2"))')
    set @xml.modify('replace value of (/data/row/a/text())[3] with (sql:variable("@val3"))')
    

    第 2 版

    declare @xml xml = '
    <data>
      <row>
        <a>A</a>
        <a>B</a>
        <a>C</a>
      </row>
      <row>
        <a>1</a>
        <a>2</a>
        <a>3</a>
      </row>
    </data>'
    
    ;with cte as
    (
      select
        r.query('.') as Row,
        row_number() over(order by (select 0)) as rn
      from @xml.nodes('/data/row') n(r)
    )
    select
      (select 
         'Data '+a.value('.', 'varchar(1)')
       from cte as c2
         cross apply Row.nodes('row/a') as r(a)
       where c1.rn = c2.rn
       for xml path('a'), root('row'), type)  
    from cte as c1 
    group by rn
    for xml path(''), root('data')
    

    【讨论】:

    • 谢谢米凯尔。我在其他网站上看到过该解决方案,但它不是动态的。如果我有 1000 个“行”标签,每个标签有 1-100 个“a”标签怎么办?
    【解决方案2】:

    我遇到了同样的问题,但我找到了另一个我认为的解决方案;)

    for $n in /data/row
     return replace value of node $n with concat('Data',$n/text())
    

    真诚的

    【讨论】:

      【解决方案3】:

      这是另一种不太理想的方法。

      SET @temp.modify('replace value of (/data/row/node()/text())[1] with concat("Data ", (/data/row/node()/text())[1])')
      SET @temp.modify('replace value of (/data/row/node()/text())[2] with concat("Data ", (/data/row/node()/text())[2])')
      SET @temp.modify('replace value of (/data/row/node()/text())[3] with concat("Data ", (/data/row/node()/text())[3])')
      

      此方法的缺点是您需要为行的每个子项单独声明。这仅在您事先知道行节点将有多少个子节点时才有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-24
        • 2010-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多