DB2® XQuery updating expressions must be used in the modify clause of a transform expression. The updating expressions operate on the copied nodes created by the copy clause of the transform expression.
The following expressions are updating expressions:
DB2 XQuery returns an error for updating expressions that are not valid. For example, DB2 XQuery returns an error if one branch of a conditional expression contains an updating expression and the other branch contains a non-updating expression that is not the empty sequence.
A transform expression is not an updating expression, because it does not modify any existing nodes. A transform expression creates modified copies of existing nodes. The result of a transform expression can include nodes created by updating expressions in the modify clause of the transform expression and copies of previously existing nodes.
In a transform expression, the modify clause can specify multiple updates. For example, the modify clause can contain two updating expressions, one expression that replaces an existing value, and the other expression that inserts a new element. When the modify clause contains multiple updating expressions, each updating expression is evaluated independently and results in a list of change operations associated with specific nodes that were created by the copy clause of the transform expression.
Within a modify clause, updating expressions cannot modify new nodes that are added by other updating expressions. For example, if an updating expression adds a new element node, another updating expression cannot change the node name of the newly created node.
The order in which change operations are applied ensures that a series of multiple changes will have a deterministic result. For an example of how the order of update operations guarantees that a series of multiple changes will have a deterministic result, see the last XQuery expression in Examples.
An example of an invalid XDM instance is one that contains an element with two attributes where both attributes have the same name.
The following are examples of inconsistent namespace bindings:
In the following example, the copy clause of a transform expression binds the variable $product to a copy of an element node, and the modify clause of the transform expression uses two updating expressions to change the copied node:
xquery
transform
copy $product := db2-fn:sqlquery(
"select description from product where pid='100-100-01'")/product
modify(
do replace value of $product/description/price with 349.95,
do insert <status>Available</status> as last into $product )
return $product
The following example uses an XQuery transform expression within an SQL UPDATE statement to modify XML data in the CUSTOMER table. The SQL UPDATE statement operates on a row of the CUSTOMER table. The transform expression creates a copy of the XML document from the INFO column of the row, and adds a status element to the copy of the document. The UPDATE statement replaces the document in the INFO column of the row with the copy of the document modified by the transform expression:
UPDATE customer
SET info = xmlquery( 'transform
copy $newinfo := $info
modify do insert <status>Current</status> as last into $newinfo/customerinfo
return $newinfo' passing info as "info")
WHERE cid = 1003
The following examples use the CUSTOMER table from the DB2 SAMPLE database. In the CUSTOMER table, the XML column INFO contains customer address and phone information.
SELECT XMLQUERY( 'transform
copy $mycust := $d
modify
do delete ( $mycust/customerinfo/addr,
$mycust/customerinfo/phone[@type != "work"] )
return
<custinfo>
<Cid>{data($d/customerinfo/@Cid)}</Cid>
{$mycust/customerinfo/*}
<country>{data($d/customerinfo/addr/@country)}</country>
</custinfo>'
passing INFO as "d")
FROM CUSTOMER
WHERE CID = 1003
When run against the SAMPLE database, the statement returns the following result:
<custinfo>
<Cid>1003</Cid>
<name>Robert Shoemaker</name>
<phone type="work">905-555-7258</phone>
<country>Canada</country>
</custinfo>
In the following example, the XQuery expression demonstrates how the order of update operations guarantees that a series of multiple changes will have a deterministic result. The insert expression adds a status element after a phone element, and the replace expression replaces the phone element with an email element:
xquery
let $email := <email>jnoodle@my-email.com</email>
let $status := <status>current</status>
return
transform
copy $mycust := db2-fn:sqlquery('select info from customer where cid = 1002')
modify (
do replace $mycust/customerinfo/phone with $email,
do insert $status after $mycust/customerinfo/phone[@type = "work"] )
return $mycust
In the modify clause, the replace expression is before the insert expression. However, when updating the copied node sequence $mycust, the insert update operation is performed before the replace update operation to ensure a deterministic result. When run against the SAMPLE database, the expression returns the following result:
<customerinfo Cid="1002">
<name>Jim Noodle</name>
<addr country="Canada">
<street>25 EastCreek</street>
<city>Markham</city>
<prov-state>Ontario</prov-state>
<pcode-zip>N9C 3T6</pcode-zip>
</addr>
<email>jnoodle@my-email.com</email>
<status>current</status>
</customerinfo>
If the replace operation were performed first, the phone element would not be in the node sequence, and the operation to insert the status element after the phone element would have no meaning.
For information about the order of update operations, see Processing XQuery updating operations.