必须在变换表达式的 modify 子句中使用 DB2® XQuery 更新表达式。更新表达式会作用于变换表达式 copy 子句创建的复制节点。
下列表达式是更新表达式:
DB2 XQuery 会对无效更新表达式返回错误。例如,如果条件表达式的一个分支包含更新表达式,而另一个分支包含并非空序列的非更新表达式,那么 DB2 XQuery 会返回错误。
变换表达式并非更新表达式,原因是它不会修改任何现有节点。变换表达式会创建现有节点的修改副本。变换表达式的结果可能包括通过更新变换表达式 modify 子句中的表达式创建的节点以及先前存在的节点。
在变换表达式中,modify 子句可指定多个更新。例如,modify 子句可包含两个更新表达式,一个表达式用于替换现有值,另一个表达式用于插入新元素。modify 子句包含多个更新表达式时,每个更新表达式会独立求值,并生成由变换表达式 copy 子句创建的特定节点的关联更改操作列表。
在 modify 子句中,更新表达式不能修改由其他更新表达式添加的新节点。例如,如果一个更新表达式添加了新的元素节点,那么另一个更新表达式不能更改新创建节点的名称。
应用更改操作的顺序应确保一系列多个更改将生成确定的结果。有关更新操作的执行顺序如何保证一系列多个更改生成确定结果的示例,请参阅示例中的最后一个 XQuery 表达式。
包含的元素的两个属性同名就是一个无效 XDM 实例的示例。
下面是不一致的名称空间绑定的示例:
在以下示例中,变换表达式的 copy 子句将变量 $product 绑定至元素节点的副本,而变换表达式的 modify 子句使用两个更新表达式来更改复制节点:
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
以下示例在 SQL UPDATE 语句中使用 XQuery 变换表达式来修改 CUSTOMER 表中的 XML 数据。SQL UPDATE 语句会作用于 CUSTOMER 表的某行。变换表达式会根据该行的 INFO 列创建 XML 文档的副本,并将 status 元素添加至文档副本。UPDATE 语句会将该行 INFO 列中的文档替换为变换表达式修改后的文档副本:
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
以下示例使用 DB2 SAMPLE 数据库中的 CUSTOMER 表。在 CUSTOMER 表中,XML 列 INFO 包含客户地址和电话信息。
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
对 SAMPLE 数据库运行时,该语句将返回以下结果:
<custinfo>
<Cid>1003</Cid>
<name>Robert Shoemaker</name>
<phone type="work">905-555-7258</phone>
<country>Canada</country>
</custinfo>
在以下示例中,XQuery 表达式会说明更新操作的顺序如何保证一系列多个更改将生成确定的结果。插入表达式会在 phone 元素后添加 status 元素,而替换表达式会将 phone 元素替换为 email 元素:
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
在 modify 子句中,替换表达式在插入表达式之前。但是,更新复制节点序列 $mycust 时,会在替换更新操作之前执行插入更新操作,以确保生成确定的结果。对 SAMPLE 数据库运行时,该表达式将返回以下结果:
<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>
如果先执行替换操作,那么 phone 元素不会在节点序列中,而用于在 phone 元素后插入 status 元素的操作没有任何意义。
有关更新操作的顺序的信息,请参阅处理 XQuery 更新操作。