【问题标题】:How to delete node from XML column in DB如何从 DB 中的 XML 列中删除节点
【发布时间】:2021-11-16 16:25:09
【问题描述】:

我正在尝试从我的 SQL 表中的 XML 列中删除特定的“节点”。 下面是 XML 列内容之一的示例。

<GodBrandConfig>
  <AppSecret>hello</AppSecret>
  <WebClientUrl>url</WebClientUrl>
  <AllowableIpAddresses>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>.*</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>178.160.245.88</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>178.160.245.88</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
  </AllowableIpAddresses>
  <GameplaySummaryUrl>about:blank</GameplaySummaryUrl>
</GodBrandConfig>

我正在尝试删除此处的重复记录 - 例如“178.160.245.88”

我一直在尝试“删除”语句的许多变体 - 请我对此提供一些帮助。 set column.modify('delete /GodBrandConfig/AllowableIpAddresses/"178.160.245.88")') where idcolumn= 1125;

【问题讨论】:

  • (1) 000.000.000.000 不被认为是重复的吗?它出现了几十次。 (2) 你如何处理像.* 这样的值?
  • 忽略它们——我只是在“屏蔽”这些 IP。我已剥离 XML 以仅包含我要删除的值。

标签: sql-server xml tsql dml


【解决方案1】:

您需要在 XPath 中选择一个 AllowableIpAddress 节点,并且由于您想要删除重复项,您可以使用以下内容删除与指定文本匹配的第二个匹配项:

update #DemoTable
set [column].modify('delete /GodBrandConfig/AllowableIpAddresses/AllowableIpAddress[text()="178.160.245.88"][2]')
where idcolumn = 1125;

这会产生更新的 XML:

<GodBrandConfig>
    <AppSecret>hello</AppSecret>
    <WebClientUrl>url</WebClientUrl>
    <AllowableIpAddresses>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>.*</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>178.160.245.88</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
        <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    </AllowableIpAddresses>
    <GameplaySummaryUrl>about:blank</GameplaySummaryUrl>
</GodBrandConfig>

【讨论】:

  • (1) 这个只清除您事先知道的特定 IP 是重复的。 (2) 这只会删除重复的第二个实体,但是如果你有两个以上的重复值怎么办?!?我看到这个答案被选为适合 OP,但我认为这是一个错误。因此,为了将来的读者:-),我将添加另一个涵盖所有情况的答案并删除具有重复值的节点
  • 注意:如果要删除除第一个节点之外的所有节点,而不仅仅是第二个节点,则可以使用[position() &gt; 1]
【解决方案2】:

检查这是否符合您的需求

DECLARE @myDoc XML
SET @myDoc = '<GodBrandConfig>
  <AppSecret>hello</AppSecret>
  <WebClientUrl>url</WebClientUrl>
  <AllowableIpAddresses>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>.*</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>178.160.245.88</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>178.160.245.88</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
    <AllowableIpAddress>000.000.000.000</AllowableIpAddress>
  </AllowableIpAddresses>
  <GameplaySummaryUrl>about:blank</GameplaySummaryUrl>
</GodBrandConfig>'  

-- Create clean node without duplication using "distinct-values"
DECLARE @AllowableIpAddress XML
SELECT @AllowableIpAddress = (
    SELECT @myDoc.query('
    <AllowableIpAddresses>
           {
                  for $x in distinct-values(//AllowableIpAddress/text())
                  return <AllowableIpAddress>{$x}</AllowableIpAddress>
           }
    </AllowableIpAddresses>
    ')
)

-- "replace node" is not supported in T-SQL (it is supported in oracle)
-- Therefore I will use modify with the actions "delete" and "insert"  
SET @myDoc.modify('delete (/GodBrandConfig/AllowableIpAddresses)')
SET @myDoc.modify('insert sql:variable("@AllowableIpAddress") after (/GodBrandConfig/WebClientUrl)[1]')
SELECT @myDoc ;

【讨论】:

  • 请注意,我删除了所有重复项,包括零 IP“000.000.000.000”,因为您说这只是为了填充数据的问题而添加的,并且它是重复的
猜你喜欢
  • 2019-04-12
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多