【问题标题】:How to delete a XML child node using SQL Server 2016如何使用 SQL Server 2016 删除 XML 子节点
【发布时间】:2020-06-01 13:14:35
【问题描述】:

我有以下 Xml 示例 sn-p 取自一个较大的文件:

<EntityAttributeValue>
  <Value />
  <Attribute>
    <Id>0</Id>
    <Name>Use 3</Name>
    <AttributeType>other</AttributeType>
  </Attribute>
  <AttributeValueId>999998</AttributeValueId>
  <ProductTypeId xsi:nil="true" />
</EntityAttributeValue>

我正在尝试使用 SQL 删除 &lt;ProductTypeId&gt; 节点,以便上面的内容如下所示:

<EntityAttributeValue>
  <Value />
  <Attribute>
    <Id>13</Id>
    <Name>Use 3</Name>
    <AttributeType>other</AttributeType>
  </Attribute>
  <AttributeValueId>999998</AttributeValueId>
</EntityAttributeValue>

我已使用以下 SQL 查询 XML 并隔离上面的 sn-p(第一个)

select t.c.query('.') as Attributes 
from @XMLData.nodes('/Item/ContentAttributeValues/EntityAttributeValue') t(c)
where t.c.value('(Attribute/Id)[1]','INT') = 0

我试过了

SET @XMLData.modify('delete (/Item/ContentAttributeValues/EntityAttributeValue/ProductTypeId)') 

删除所有产品ID,但无济于事,任何帮助都会得到很大的帮助。

干杯

【问题讨论】:

  • 请发布该问题的完整重现,因为xml.modify( 似乎是正确的。

标签: sql-server xml tsql sql-server-2016 xml-dml


【解决方案1】:

在您提供的 XML sn-p 中,您有一个不同的根。所以,为了让你的delete 工作,你只需要调整路径:

SET @XMLData.modify('delete /EntityAttributeValue/ProductTypeId');

【讨论】:

    【解决方案2】:

    这是一个完整的例子。我必须在根目录中添加一个命名空间来容纳xsi:nil="true" 属性。

    SQL

    -- DDL and sample data population, start
    DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML NOT NULL);
    INSERT INTO @tbl (xmldata) VALUES
    (N'<Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <ContentAttributeValues>
            <EntityAttributeValue>
                <Value/>
                <Attribute>
                    <Id>0</Id>
                    <Name>Use 3</Name>
                    <AttributeType>other</AttributeType>
                </Attribute>
                <AttributeValueId>999998</AttributeValueId>
                <ProductTypeId xsi:nil="true"/>
            </EntityAttributeValue>
            <EntityAttributeValue>
                <Value/>
                <Attribute>
                    <Id>10</Id>
                    <Name>Use 7</Name>
                    <AttributeType>other</AttributeType>
                </Attribute>
                <AttributeValueId>999770</AttributeValueId>
                <ProductTypeId xsi:nil="true"/>
            </EntityAttributeValue>
        </ContentAttributeValues>
    </Item>');
    -- DDL and sample data population, end
    
    UPDATE @tbl
    SET xmldata.modify('delete /Item/ContentAttributeValues/EntityAttributeValue/ProductTypeId');
    
    SELECT * FROM @tbl;
    

    输出 XML

    <Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ContentAttributeValues>
        <EntityAttributeValue>
          <Value />
          <Attribute>
            <Id>0</Id>
            <Name>Use 3</Name>
            <AttributeType>other</AttributeType>
          </Attribute>
          <AttributeValueId>999998</AttributeValueId>
        </EntityAttributeValue>
        <EntityAttributeValue>
          <Value />
          <Attribute>
            <Id>10</Id>
            <Name>Use 7</Name>
            <AttributeType>other</AttributeType>
          </Attribute>
          <AttributeValueId>999770</AttributeValueId>
        </EntityAttributeValue>
      </ContentAttributeValues>
    </Item>
    

    【讨论】:

      【解决方案3】:

      根据我的代码,您正在搜索 EAV 元素的 &lt;ProductTypeId&gt;,其中 &lt;Attribute&gt;&lt;Id&gt; 的值为 0

      您的问题并不完全清楚,但我认为您可能正在寻找这个:

      declare @tbl TABLE(ID INT IDENTITY, YourXml XML);
      INSERT INTO @tbl VALUES
      (N'<Item xmlns:xsi="blahblah">
        <ContentAttributeValues>
          <EntityAttributeValue>
            <Value />
            <Attribute>
              <Id>0</Id>                                     <!-- Id value = 0  -->
              <Name>Use 3</Name>
              <AttributeType>other</AttributeType>
            </Attribute>
            <AttributeValueId>999998</AttributeValueId>
            <ProductTypeId xsi:nil="true" />                 
          </EntityAttributeValue>
          <EntityAttributeValue>
            <Value />
            <Attribute>
              <Id>1</Id>                                      <!-- Other Id value!!!  -->
              <Name>Use 3</Name>
              <AttributeType>other</AttributeType>
            </Attribute>
            <AttributeValueId>999998</AttributeValueId>
            <ProductTypeId xsi:nil="true" />
          </EntityAttributeValue>
        </ContentAttributeValues>
      </Item>');
      
      UPDATE @tbl SET YourXml.modify(N'delete /Item
                                              /ContentAttributeValues
                                              /EntityAttributeValue[Attribute/Id = 0]
                                              /ProductTypeId');
      
      SELECT * FROM @tbl;
      

      XPath 代表:深入 EAV 元素并过滤元素,这些元素回答谓词。在此 EAV 元素下方找到 &lt;ProductTypeID&gt; 并将其删除。

      在结果中,您会发现仅删除了第一个 EAV 元素的节点,该元素具有 Id=0

      【讨论】:

        【解决方案4】:

        大家好,感谢您的 cmets。

        很抱歉没有让我的代码清晰,我以为它在我的脑海里,而且已经很晚了!哈哈。

        SET @XMLData.modify('delete(/Item/ContentAttributeValues/EntityAttributeValue/ProductTypeId)') 辛苦了..我之前尝试过,但我遇到了错误,我知道删除后的括号是它工作的关键哈! 再次感谢大家!!

        【讨论】:

        • 很高兴听到建议的解决方案对您有用。请将其标记为已回答。您只需将答案标记为正确(绿色检查图像)。单击解决您的问题的答案左侧的绿色轮廓复选标记。这将答案标记为“已接受”
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-24
        • 2016-01-23
        • 1970-01-01
        相关资源
        最近更新 更多