【问题标题】:Update SQL column data by adding text in between data in Oracle SQL通过在 Oracle SQL 中的数据之间添加文本来更新 SQL 列数据
【发布时间】:2025-11-22 14:35:01
【问题描述】:

我有两列

ID XML
1 <a id='1'></a>
2 <a id='2'></a>

现在我想搜索以 标记开头的数据并更新 xml 条目,我想在所有行的 标记之间添加额外的标记。

注意:这是示例数据。我需要 下存在的所有子节点都在 下,并且子节点会因每一行而异。

示例:

如何使用更新语句来获取该数据并在 xml 之间添加 标记并保存它。

【问题讨论】:

标签: sql oracle plsql oracle10g


【解决方案1】:

您可以使用 XQuery 更新:

update your_table
set xml = xmlquery('
  copy $i := $p1
  modify (
    for $j in $i/a
    return insert node $p2 into $j
  )
  return $i'
  passing xml as "p1", xmltype('<b></b>') as "p2"
  returning content)
where xmlexists('$p/a' passing xml as "p")

或者用这样一个简单的新节点(如果真的是的话):

update your_table
set xml = xmlquery('
  copy $i := $p1
  modify (
    for $j in $i/a
    return insert node $p2 into $j
  )
  return $i'
  passing xml as "p1", xmlelement("b", null) as "p2"
  returning content)
where xmlexists('$p/a' passing xml as "p")

db<>fiddle

在文档中阅读有关updating XML data 的更多信息。


我需要 下的所有子节点都在

您仍然可以通过 XQuery 更新来做到这一点;不禁想到它可以做得更简单,但这会创建b节点的副本,然后将a下的所有其他节点复制到其中,直接删除a下的那些节点,然后插入新的b - 包括复制的孩子 - 在a 下:

update your_table
set xml = xmlquery('
  copy $i := $p1
  modify (
    for $j in $i/a
    return insert node (
      copy $k := $p2
      modify (
        for $l in $j/*
        return (
          insert node $l into $k/b
        )
      )
      return $k
    )
    into $j,
    delete nodes $i/a/*
  )
  return $i'
  passing xml as "p1", xmltype('<b></b>') as "p2"
  returning content)
where xmlexists('$p/a' passing xml as "p");

db<>fiddle 带有一些扩展的样本数据,有和没有子节点。


可以也可以使用regexp_replace 执行此操作,作为对巴巴罗斯在 cmets 中建议的推进;至少对于小型 XML 文档:

update your_table t
set xml = xmltype(regexp_replace(t.xml.getstringval(), '(<a.*?>)(.*?)(</a>)',
  '\1<b>\2</b>\3', 1, 0, 'n'))
where xmlexists('$p/a' passing xml as "p");

db<>fiddle

但由于某种原因,它不适用于getclobval() - 不确定在这个特定版本中这是否很重要。但是,除非该结构非常知名并受到控制,否则这可能会在某些时候做一些奇怪的事情,所以它真的只是为了兴趣。将 XML 作为 XML而不是作为字符串进行操作更安全。

还有 XLST……但其他人可以使用它提出建议。

【讨论】: