【问题标题】:SQL Server XML field swap values of two nodesSQL Server XML 字段交换两个节点的值
【发布时间】:2020-09-28 08:07:02
【问题描述】:

我有一个相当大的表,最后有一个 XML 字段。该字段包含许多 tdf 标签中的一些属性。所有标签都有一个 Field 和一个 Unit 属性以及一个 wsd 节点:

<tdf Field="DataFieldName1.FileDate" Unit="">
  <wsd Value="17.11.2015 19:25:29" />
</tdf>
<tdf Field="DataFieldName1.FormIdent" Unit="">
  <wsd Value="XXXXXX-AAAA" />
</tdf>
<tdf Field="DataFieldName2.ItemData_CycleTime" Unit="s">
  <wsd Value="70" />
</tdf>

我想要做的是交换所有记录中每个 DataFieldName1.FormIdent 和 DataFieldName2.ItemData_CycleTime 字段的值(tdf/wsd 值)。所以上面的例子应该改成这样:

<tdf Field="DataFieldName1.FileDate" Unit="">
  <wsd Value="17.11.2015 19:25:29" />
</tdf>
<tdf Field="DataFieldName1.FormIdent" Unit="">
  <wsd Value="70" />
</tdf>
<tdf Field="DataFieldName2.ItemData_CycleTime" Unit="s">
  <wsd Value="XXXXXX-AAAA" />
</tdf>

我可以在不在包含 XML 字段的表的记录上声明游标的情况下执行此操作吗?在 XML 类型字段中执行此操作的首选和最安全的方法是什么?有许多 XML 字段甚至不包含我想要交换的记录。

【问题讨论】:

    标签: sql-server xml tsql xquery


    【解决方案1】:

    您可以尝试以下 XQuery。它走在一条幸福的道路上。

    "...有许多 XML 字段甚至不包含我想要交换的记录..."。您从未提供 DDL 和样本数据总体。您始终可以在UPDATE 语句中添加WHERE 子句以过滤掉不需要的行。

    SQL

    -- DDL and sample data population, start
    DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML);
    INSERT INTO @tbl (xmldata) VALUES
    (N'<tdf Field="DataFieldName1.FileDate" Unit="">
      <wsd Value="17.11.2015 19:25:29" />
    </tdf>
    <tdf Field="DataFieldName1.FormIdent" Unit="">
      <wsd Value="XXXXXX-AAAA" />
    </tdf>
    <tdf Field="DataFieldName2.ItemData_CycleTime" Unit="s">
      <wsd Value="70" />
    </tdf>');
    -- DDL and sample data population, end
    
    -- before
    SELECT * FROM @tbl;
    
    UPDATE @tbl
    SET xmldata = xmldata.query('
    let $w1 := tdf[@Field="DataFieldName1.FormIdent"]/wsd/@Value
    let $w2 := tdf[@Field="DataFieldName2.ItemData_CycleTime"]/wsd/@Value
    for $x in tdf
    return if ($x/@Field = "DataFieldName1.FormIdent") then 
            element tdf {
                $x/@*, <wsd Value="{$w2}" />
        }
        else if ($x/@Field = "DataFieldName2.ItemData_CycleTime") then 
            element tdf {
                $x/@*, <wsd Value="{$w1}" />
        }
        else $x
    ');
    
    -- after
    SELECT * FROM @tbl;
    

    输出

    <tdf Field="DataFieldName1.FileDate" Unit="">
      <wsd Value="17.11.2015 19:25:29" />
    </tdf>
    <tdf Field="DataFieldName1.FormIdent" Unit="">
      <wsd Value="70" />
    </tdf>
    <tdf Field="DataFieldName2.ItemData_CycleTime" Unit="s">
      <wsd Value="XXXXXX-AAAA" />
    </tdf>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-22
      • 1970-01-01
      • 1970-01-01
      • 2021-05-19
      • 1970-01-01
      相关资源
      最近更新 更多