如何排除多个节点,因此其中一个排除将使用XML DML重新排列其属性?

时间:2017-02-10 20:46:48

标签: sql sql-server xml xml-dml

这是此发布的question的参考,因为我希望在节点<pos>内重新排列属性<est_mat>的值,因此<est_mat>的第一个节点将拥有<pos>10</pos>,然后第二个<est_mat>节点将拥有<pos>20</pos>,依此类推。 我从上述提到的参考文献中的一个用户的帮助中得到了这个查询。 因此,假设以下xml结构:

DECLARE @xml XML= 
N'<flint>
<app>
<comp>59</comp>
<signal>ORDERBOOK</signal>
<sigref>000000172</sigref>
<date>20170201</date>
<time>114954</time>
<id>SFC</id>
<revision>006</revision>
<data>
  <rec>
    <rpos>1</rpos>
    <revision>006</revision>
    <order>
      <type>SFC</type>
      <orno />
      <pono>0</pono>
      <seri>GLW</seri>
      <item>GEC1H-PCB-00081-01</item>
      <sfc_type>BTO</sfc_type>
      <revi>46</revi>
      <sel_code />
      <family />
      <qty>300</qty>
      <del_qty>0</del_qty>
      <rej_qty>0</rej_qty>
      <uom>ea</uom>
      <clot />
      <prio>999</prio>
      <wh>J59MF6</wh>
      <cdel_date>20170201</cdel_date>
      <cdel_time>114954</cdel_time>
      <prod_date>20170201</prod_date>
      <prod_time>114954</prod_time>
      <eff_date>20170201</eff_date>
      <eff_time>114954</eff_time>
      <target>0</target>
      <line />
      <status>Planned</status>
      <skit_nr />
      <pick_stat>N</pick_stat>
      <so_orno />
      <so_pono>0</so_pono>
      <est_mats>
        <est_mat>
          <pos>10</pos>
          <item>GEC1H-BTL-CARDBOARD-BOX</item>
          <revi>A</revi>
          <opno>0</opno>
          <qty>0.004</qty>
          <uom>ea</uom>
          <wh>J59JW2</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
        <est_mat>
          <pos>20</pos>
          <item>GEC1H-BTL-FD79-G007-00SA</item>
          <revi>A-002</revi>
          <opno>0</opno>
          <qty>1</qty>
          <uom>ea</uom>
          <wh>J59WP4</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
        <est_mat>
          <pos>30</pos>
          <item>GEC1H-ESC10-091-SOP-1017KXX</item>
          <revi>NR-00</revi>
          <opno>0</opno>
          <qty>1.1</qty>
          <uom>ea</uom>
          <wh>J59WP4</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
        <est_mat>
          <pos>40</pos>
          <item>GEC1J-LED-NFSL757DV1-835</item>
          <revi>NR-00</revi>
          <opno>0</opno>
          <qty>9</qty>
          <uom>ea</uom>
          <wh>J59WP4</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
        <est_mat>
          <pos>10</pos>
          <item>GEC1H-BTL-CARDBOARD-BOX</item>
          <revi>A</revi>
          <opno>0</opno>
          <qty>0.004</qty>
          <uom>ea</uom>
          <wh>J59WP4</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
        <est_mat>
          <pos>20</pos>
          <item>GEC1H-BTL-FD79-G007-00SA</item>
          <revi>A-002</revi>
          <opno>0</opno>
          <qty>1</qty>
          <uom>ea</uom>
          <wh>J59WP4</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
        <est_mat>
          <pos>30</pos>
          <item>GEC1H-ESC10-091-SOP-1017KXX</item>
          <revi>NR-00</revi>
          <opno>0</opno>
          <qty>1.1</qty>
          <uom>ea</uom>
          <wh>J59WP4</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
        <est_mat>
          <pos>40</pos>
          <item>GEC1J-LED-NFSL757DV1-835</item>
          <revi>NR-00</revi>
          <opno>0</opno>
          <qty>9</qty>
          <uom>ea</uom>
          <wh>J59WP4</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
        <est_mat>
          <pos>40</pos>
          <item>GEC1J-LED-NFSL757DV1-835</item>
          <revi>NR-00</revi>
          <opno>0</opno>
          <qty>9</qty>
          <uom>ea</uom>
          <wh>J59WP4</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
        <est_mat>
          <pos>40</pos>
          <item>TESTING2</item>
          <revi>46</revi>
          <opno>0</opno>
          <qty>0.04</qty>
          <uom>ea</uom>
          <wh>J59JW2</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
        <est_mat>
          <pos>10</pos>
          <item>TESTING</item>
          <revi>46</revi>
          <opno>0</opno>
          <qty>3</qty>
          <uom>ea</uom>
          <wh>J59JW2</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
        <est_mat>
          <pos>20</pos>
          <item>GEC1J-SW3576L11</item>
          <revi>46</revi>
          <opno>0</opno>
          <qty>3</qty>
          <uom>ea</uom>
          <wh>J59JW2</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
        <est_mat>
          <pos>30</pos>
          <item>GEC1J-SW359EL11</item>
          <revi>46</revi>
          <opno>0</opno>
          <qty>3</qty>
          <uom>ea</uom>
          <wh>J59JW2</wh>
          <backflush>Y</backflush>
          <rpl_method />
          <point_of_usage />
        </est_mat>
      </est_mats>
    </order>
  </rec>
</data>
</app>
</flint>';

和这个查询:

SELECT @xml.query(N'/flint/*[local-name()!="est_mats"]') AS [*]
  ,(
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) * 10 AS pos 
          ,em.value(N'item[1]',N'nvarchar(max)') AS item
          ,em.value(N'qty[1]',N'decimal(16,4)') AS qty 
    FROM @xml.nodes(N'flint/app/data/rec/order/est_mats/est_mat') AS A(em)
    FOR XML PATH('est_mat'),ROOT('est_mats'),TYPE
   ) 
FOR XML PATH(N'flint');

如何通过如上所述排序该属性<pos>来再次生成结构?

此时查询会抛出相同的xml结构,而不会更改<pos>

的值

1 个答案:

答案 0 :(得分:1)

您可以这样尝试:

首先在<pos>中使用愚蠢的值(减少!)样本数据来演示解决方案:

DECLARE @xml XML= 
N'<flint>
  <app>
    <comp>59</comp>
    <!--more elements-->
    <revision>006</revision>
    <data>
      <rec>
        <rpos>1</rpos>
        <revision>006</revision>
        <order>
          <type>SFC</type>
          <!--more elements-->
          <so_pono>0</so_pono>
          <est_mats>
            <est_mat>
              <pos>999</pos>
              <item>GEC1H-BTL-CARDBOARD-BOX</item>
              <!--more elements-->
            </est_mat>
            <est_mat>
              <pos>333</pos>
              <item>GEC1H-BTL-FD79-G007-00SA</item>
              <!--more elements-->
            </est_mat>
          </est_mats>
        </order>
      </rec>
    </data>
  </app>
</flint>';

- 我们不会将重新编号的<est_mats>读入暂存变量

DECLARE @est_mats XML=
(
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) * 10 AS pos 
          ,em.value(N'item[1]',N'nvarchar(max)') AS item
          --add more elements here
    FROM @xml.nodes(N'flint/app/data/rec/order/est_mats/est_mat') AS A(em)
    FOR XML PATH('est_mat'),ROOT('est_mats'),TYPE
);

- 现在我们完全删除了现有的<est_mats>

SET @xml.modify(N'delete (flint/app/data/rec/order/est_mats)[1]');

- 只需将修改过的部分插入前一个地方

SET @xml.modify(N'insert sql:variable("@est_mats") as last into (flint/app/data/rec/order)[1]');

- 这是结果

SELECT @xml;

<flint>
  <app>
    <comp>59</comp>
    <!--more elements-->
    <revision>006</revision>
    <data>
      <rec>
        <rpos>1</rpos>
        <revision>006</revision>
        <order>
          <type>SFC</type>
          <!--more elements-->
          <so_pono>0</so_pono>
          <est_mats>
            <est_mat>
              <pos>10</pos>
              <item>GEC1H-BTL-CARDBOARD-BOX</item>
            </est_mat>
            <est_mat>
              <pos>20</pos>
              <item>GEC1H-BTL-FD79-G007-00SA</item>
            </est_mat>
          </est_mats>
        </order>
      </rec>
    </data>
  </app>
</flint>