Dokumentacja Oracle zaleca używanie XQuery do aktualizacji XML . Więc to pierwsza rzecz do wypróbowania.
Po pierwsze, jest to możliwe przy starym podejściu do funkcji. XQuery poniżej może być użyty zamiast wywołania XmlUpdate
:
XMLQuery(
'
declare function local:copy-replace($element as element()) {
if ($element/self::node_2) then <node_2/>
else if ($element/self::node_3) then <node_3/>
else if ($element/self::node_4) then <node_4/>
else element {node-name($element)}
{$element/@*,
for $child in $element/node()
return if ($child instance of element())
then local:copy-replace($child)
else $child
}
};
local:copy-replace($p/*)
'
passing x as "p" returning content
) as xcol_2
Kolejny, krótszy i bardziej intuicyjny wariant:
XMLQuery(
'
copy $p2 := $p
modify(
replace value of node $p2/node_root/node_2 with "",
replace value of node $p2/node_root/node_3 with "",
replace value of node $p2/node_root/node_4 with ""
)
return $p2
'
passing x as "p" returning content
) as xcol_3
Ponadto możliwe jest zwrócenie zmodyfikowanej wartości XML tylko wtedy, gdy warunek nie jest spełniony:
WITH xtbl AS
(SELECT 1 AS xtbl_id,
xmltype ('<node_root>
<node_1>12</node_1>
<node_2>233</node_2>
<node_3>223</node_3>
<node_4>234</node_4>
</node_root>') AS x
FROM Dual
UNION ALL
SELECT 2, xmltype ('<node_root>
<node_1></node_1>
<node_2>233</node_2>
<node_3>223</node_3>
<node_4>234</node_4>
</node_root>')
FROM Dual)
SELECT xtbl_id,
x,
XMLQuery(
'
for $test in $p/*
return
if( empty($p/node_root/node_1/text()) )
then $p
else (
copy $p2 := $p
modify(
replace value of node $p2/node_root/node_2 with "",
replace value of node $p2/node_root/node_3 with "",
replace value of node $p2/node_root/node_4 with ""
)
return $p2
)
'
passing x as "p" returning content
) as xcol_4
FROM xtbl
Istnieje więc wiele wariantów wykonywania operacji na wartościach XML, ale wymaga to głębszej znajomości XQuery i XPath niż stosunkowo prosta funkcja XmlUpdate ...