【问题标题】:how to delete a duplicate field in xml如何删除xml中的重复字段
【发布时间】:2016-11-08 20:45:51
【问题描述】:

我有一个列类型为 XML 的表,该列中的 xml 文件有我想要删除的重复字段。请让我知道如何相应地更新该列。

<Material_NOI>
<Field> -------- ? I want to delete this duplicate one.
  <Field>
    <id>Type</id>
    <value>Initial</value>
    <tag />
    <visible>true</visible>
    <history>10/8/2015|</history>
    <description />
    </Field>
    </Field>
 </Material_NOI>

【问题讨论】:

  • 如果&lt;Field&gt; 出现两次,而结束的&lt;/Field&gt; 标记只出现一次,你可能会认为这是XML,但这不是XML!!! 这是如何产生的?
  • 来自 shnugo 的好点子。这似乎更像是 XML 的语法错误而不是重复。此外,即使字段重复,您首先需要确定如何定义重复的值。为此,我认为一个好方法是从 DB 读取 XML 进行操作,然后将新的 xml 更新到数据库中。通常,您总是需要定义重复性指标。
  • 感谢不错的收获。我在之前的帖子中错过了它。字段正在生成两次。目前我只想删除它而不是再次运行整个 xml。有可能吗?
  • 有趣的是,您可能会在此处看到另一篇显示为相关问答的帖子stackoverflow.com/questions/2411401/…
  • @wwidhoo Btw:日期 within XML 应该是 ISO8601。你真的应该避免像10/8/2015这样的文化特定日期格式!在一台机器上,这被视为 8 月 10 日,另一个系统将在 10 月 8 日返回......其他系统可能会完全崩溃......

标签: sql sql-server xml tsql xquery


【解决方案1】:

最简单的方法是使用 .query() 获取所需的节点并重建 XML

DECLARE @XML XML=
N'<Material_NOI>
  <Field>
    <Field>
      <id>Type</id>
      <value>Initial</value>
      <tag />
      <visible>true</visible>
      <history>10/8/2015|</history>
      <description />
    </Field>
  </Field>
</Material_NOI>';

 SELECT @XML.query('/Material_NOI/Field/Field')
 FOR XML PATH('Material_NOI')

更新:与表数据相同

您可以像这样使用可更新的 CTE

DECLARE @tbl TABLE(XmlColumn XML);
INSERT INTO @tbl VALUES
(N'<Material_NOI>
  <Field>
    <Field>
      <id>Type</id>
      <value>Initial</value>
      <tag />
      <visible>true</visible>
      <history>10/8/2015|</history>
      <description />
    </Field>
  </Field>
</Material_NOI>')
,(N'<Material_NOI>
  <Field>
    <Field>
      <id>Another id</id>
      <value>One more</value>
      <tag />
      <visible>false</visible>
      <history>10/8/2015|</history>
      <description />
    </Field>
  </Field>
</Material_NOI>');

WITH UpdateableCTE AS
(
    SELECT XmlColumn
          ,(SELECT XmlColumn.query('/Material_NOI/Field/Field') FOR XML PATH('Material_NOI'),TYPE) AS NewValue
    FROM @tbl
)
UPDATE UpdateableCTE SET XmlColumn=NewValue;

SELECT * FROM @tbl;

更新 2:使用 FLWOR 查询的简短版本

UPDATE @tbl SET XmlColumn=XmlColumn.query(N'<Material_NOI>
                                            {
                                            for $f in /Material_NOI/Field/Field 
                                                return $f
                                            }
                                            </Material_NOI>');

【讨论】:

  • 挖掘 FLWOR 查询
【解决方案2】:

使用 XQuery。此脚本仅在所有行都具有额外元素时才起作用。确保在运行之前复制表格,你永远不会知道。

DECLARE @xml_table TABLE (x XML);
INSERT INTO @xml_table(x)VALUES(
'<Material_NOI>
  <Field>
  <Field>
    <id>Type</id>
    <value>Initial</value>
    <tag />
    <visible>true</visible>
    <history>10/8/2015|</history>
    <description />
    </Field>
    </Field>
 </Material_NOI>');

UPDATE
    @xml_table
SET
    x=x.query('<Material_NOI>{for $p in Material_NOI/Field/Field return $p}</Material_NOI>');

SELECT * FROM @xml_table;

【讨论】:

  • 这一秒我发布了与更新 2 相同的内容 :-) 无论如何值得一票!
  • @Shnugo 你也是;)
猜你喜欢
  • 1970-01-01
  • 2015-09-29
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 2011-02-05
  • 2018-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多