我会回答一个稍微不同的问题 - 看看是否有帮助。
在我的 cmets 中,我提出了两个问题。首先,您的clob 看起来像一个XML 文档,所以它应该存储在数据类型为xmltype 的列中,而不是clob。 (这类似于将日期存储为字符串而不是正确的 date 数据类型。)其次,您的“XML 文档”实际上不是有效的 XML 文档,因为它的序言中有两个主要错误:@ 987654325@ 在打开 < 后立即丢失,XML 应该是 xml(小写)。两者都是致命错误,不允许您将该字符串存储为xmltype。 (这也类似于将日期存储为字符串,并且有一个类似 '31 February 2020' 的字符串 - 您可以将其存储为字符串,但如果您尝试将其存储在 date 列中,Oracle 会立即告诉您一些信息错了。)
在下面的解决方案中,我将数据类型保留为CLOB - 但我将在其中存储一个有效的 XML 文档。下面是创建示例表的代码:
create table xyz (a clob);
insert into xyz values (
'<?xml version ="1.0"?>
<properties>
<property name ="tran_start_date">
<value>1/1/2021</value>
</property>
<property name ="tran_end_date">
<value>21/12/2021</value>
</property>
<property name ="accn_no">
<value>12838372882</value>
</property>
</properties>'
);
commit;
那么这是根据您的要求更新它的一种方法。我使用xmlquery作为主要工具;但是,由于您的列类型是clob,我必须先将其转换为xmltype(使用xmltype() 构造函数),并且在xmltype 更新完成后,我必须将xmltype 转换回@987654340 @;这就是xmlserialize 所做的。我将indent 选项用于xmlserialize;您的输入没有遵循任何系统缩进,因此结果的缩进将与原始内容略有不同。我希望没关系。 (作为 XML 文档,这无关紧要。)
update xyz
set a =
xmlserialize(document
xmlquery(
'copy $t := $x
modify(
(for $i in $t/properties/property[@name="tran_start_date"]/value
return replace value of node $i with "30/10/2021")
, (for $i in $t/properties/property[@name="tran_end_date"]/value
return replace value of node $i with "30/10/2022")
, (for $i in $t/properties/property[@name="accn_no"]/value
return replace value of node $i with "098765")
) return $t'
passing xmltype(a) as "x" returning content
)
indent size = 2)
;
commit;
这演示了更新值的最简单方法 - 新值直接硬编码到 xmlquery。这可以通过在xmlquery 的passing 子句中传递新值来更通用;究竟如何做到这一点取决于您首先如何将这些运行时值提供给 update 语句。
现在检查表中的内容:
select a from xyz;
A
------------------------------------------------------------
<?xml version="1.0"?>
<properties>
<property name="tran_start_date">
<value>30/10/2021</value>
</property>
<property name="tran_end_date">
<value>30/10/2022</value>
</property>
<property name="accn_no">
<value>098765</value>
</property>
</properties>