通过在 Oracle SQL 中的数据之间添加文本来更新 SQL 列数据

Update SQL column data by adding text in between data in Oracle SQL

我有两列

ID XML
1
2

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

注意:这是示例数据。我需要 下的所有子节点都位于 下,并且每一行的子节点都会有所不同。

Sample : <a id='1'><b></b></a>

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

您可以使用 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 的更多信息。


I need all the child nodes present under <a> to come under <b>

您仍然可以通过 XQuery 更新来执行此操作;不禁想到它可以做的更简单,但是这会创建一个b节点的副本,然后将a下的所有其他节点复制到其中,删除直接在[=15=下的那些节点], 并在 a 下插入新的 b - 包括复制的子代:

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 来做这件事,作为对 Barbaros 在评论中的建议的推进;至少对于 XML 个小文档:

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

db<>fiddle

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

然后是 XLST...但其他人可以使用它提出建议。