更新一个节点的值,如果不存在则忽略
Update value of a node, ignore if not exists
我想替换 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] 无效的目标表达式
例如,此 select 失败并出现上述错误(注意 ZZZ 假节点名称):
select
XMLQUERY(
'copy $t := $x modify(
replace value of node $t/Warehouse/ZZZ with "mynewvalue"
) return $t'
from mytable;
问题:
如何更改代码以忽略不存在的节点?[=15=]
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;
根据@Arkadiusz Łukasiewicz 的精彩回答,我编写了完整的解决方案,其中包括:
- 忽略 non-existent 个节点
- 能够在单个 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
我想替换 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] 无效的目标表达式
例如,此 select 失败并出现上述错误(注意 ZZZ 假节点名称):
select
XMLQUERY(
'copy $t := $x modify(
replace value of node $t/Warehouse/ZZZ with "mynewvalue"
) return $t'
from mytable;
问题: 如何更改代码以忽略不存在的节点?[=15=]
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;
根据@Arkadiusz Łukasiewicz 的精彩回答,我编写了完整的解决方案,其中包括:
- 忽略 non-existent 个节点
- 能够在单个 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