更新节点的值,不存在则忽略
Posted
技术标签:
【中文标题】更新节点的值,不存在则忽略【英文标题】:Update value of a node, ignore if not exists 【发布时间】:2019-07-08 13:50:53 【问题描述】:我想替换 XML 中节点的值。 XML 存储在 Oracle 12.2 数据库中的 XMLTYPE 列中。 我的 XML:
<Warehouse>
<WarehouseId>1</WarehouseId>
<WarehouseName>Southlake, Texas</WarehouseName>
<Building>Owned</Building>
<Area>25000</Area>
</Warehouse>
UPDATEXML 函数可以完成这项工作,但速度很慢。
select
UPDATEXML(myxmlcolumn, '/Warehouse/Building/text()','mynewvalue')
from mytable;
Oracle 说 UPDATEXML 是 deprecated,而应该使用 XMLQUERY。 所以,我尝试了 XMLQUERY:
select
XMLQUERY(
'copy $t := $x modify(
replace value of node $t/Warehouse/Building with "mynewvalue"
) return $t'
from mytable;
它工作快得多,但有一个小问题:如果请求的节点不存在,它会失败并显示 XVM-01155:[XUDY0027] Invalid target expression
例如,此选择失败并出现上述错误(注意 ZZZ 假节点名称):
select
XMLQUERY(
'copy $t := $x modify(
replace value of node $t/Warehouse/ZZZ with "mynewvalue"
) return $t'
from mytable;
问题: 如何更改代码以忽略不存在的节点?
【问题讨论】:
【参考方案1】:IF-ELSE
声明可能会有所帮助:)
检查示例。
with mytable as (select xmltype('<Warehouse>
<WarehouseId>1</WarehouseId>
<WarehouseName>Southlake, Texas</WarehouseName>
<Building>Owned</Building>
<Area>25000</Area>
</Warehouse>') myxmlcolumn from dual)
select
XMLQUERY(
'copy $t := . modify(
if( $t/Warehouse/WarehouseName) then
(
replace value of node $t/Warehouse/WarehouseName with "mynewvalue"
)
else ()
) return $t' passing myxmlcolumn returning content)
from mytable
union all
select
XMLQUERY(
'copy $t := . modify(
if( $t/Warehouse/ZZZZ) then
(
replace value of node $t/Warehouse/ZZZZ with "mynewvalue"
)
else ()
) return $t' passing myxmlcolumn returning content)
from mytable
union all
select
XMLQUERY(
'copy $t := . modify(
for $node in $t/Warehouse/ZZZZ
return replace value of node $node with "mynewvalue"
) return $t' passing myxmlcolumn returning content) from mytable;
【讨论】:
这个方案需要读表两次,效率不高 我又添加了一个使用 for 循环方法的示例。 @Michael 我在哪里读表两次? 我误解了“union all”的用法——正如我现在所看到的,它只是为了解释。真正的代码应该只包含 3 个选项之一。 “for 循环”的解决方案是这里最好的解决方案,因为它会自动处理不存在的节点。【参考方案2】:根据@Arkadiusz Łukasiewicz 的出色回答,我编制了完整的解决方案,其中包括:
忽略不存在的节点 能够在单个 xmlquery 调用中更改多个节点这里是:
select
xmlquery(
' copy $t := $x modify
(
(for $i in $t/Warehouse/Building
return replace value of node $i with "aaa"),
(for $i in $t/Warehouse/ZZZ
return replace value of node $i with "bbb)
)
return $t
'
passing
XMLRECORD as "x"
from mytable
【讨论】:
以上是关于更新节点的值,不存在则忽略的主要内容,如果未能解决你的问题,请参考以下文章
sql:mysql:MySql 不存在则插入,存在则更新或忽略
sql:mysql:MySql 不存在则插入,存在则更新或忽略
mysql判断一条记录是否存在,如果存在,则更新此语句,如果不存在,则插入
MySQL插入更新_ON DUPLICATE KEY UPDATE