I would like to replace a value of a node in XML. The XML is stored in Oracle 12.2 database, in an XMLTYPE column. My XML:
<Warehouse>
<WarehouseId>1</WarehouseId>
<WarehouseName>Southlake, Texas</WarehouseName>
<Building>Owned</Building>
<Area>25000</Area>
</Warehouse>
The UPDATEXML function does the job, but it is slow.
select
UPDATEXML(myxmlcolumn, '/Warehouse/Building/text()','mynewvalue')
from mytable;
Oracle say that UPDATEXML is deprecated, and XMLQUERY should be used instead. So , I have tried XMLQUERY instead:
select
XMLQUERY(
'copy $t := $x modify(
replace value of node $t/Warehouse/Building with "mynewvalue"
) return $t'
from mytable;
It works much faster, but there is one little problem: if the requested node does not exist, it fails with XVM-01155: [XUDY0027] Invalid target expression
For example, this select fails with the above error(note the ZZZ fake node name):
select
XMLQUERY(
'copy $t := $x modify(
replace value of node $t/Warehouse/ZZZ with "mynewvalue"
) return $t'
from mytable;
Question: How can I change the code to ignore non-existent nodes?
IF-ELSE
statement can be helpful :)
Check example.
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;