XQuery 針對層次化、有序的 XML 數據模型設計;SQL 面向平面、無序的關系表集合。關鍵差異包括:
基於 items(商品評論)與 clients(客戶聯系信息)兩表,均包含 XML 列(comments、contactinfo)。所有查詢在 DB2 Command Editor 或 CLP 中交互執行。
關鍵字:for(迭代)、let(變量綁定)、where(過濾)、order by(排序)、return(輸出)。
斜槓分隔的步驟導航 XML 層次,可帶謂詞過濾,如 $clients/Client/Address[state="CA"]/zip。
xquery 關鍵字開頭調用 db2-fn:xmlcolumn('TABLE.COLUMN') 獲取 XML 文檔序列。注意表名、列名需大寫以匹配 DB2 系統目錄。
xquery
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax
return $y
或簡化為路徑表達式:
xquery db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax
需文本值而非 XML 片段時,追加 /text()。
xquery
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address
return $y
返回包含所有子元素的 <Address> 片段序列。
FLWOR 寫法:
xquery
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address
where $y/zip = "95116"
return $y
路徑表達式謂詞寫法:
xquery db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address[zip="95116"]
xquery
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
where $y/Address/zip="10011" or $y/Address/city="San Jose"
return $y/email
注意:結果扁平化為 email 序列,無法直接知曉哪些 email 屬於同一客戶,也無 NULL 佔位。
xquery
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
where $y/Address/zip="10011" or $y/Address/city="San Jose"
return $y/email[1]
xquery
<ul> {
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address
order by $y/zip
return <li>{$y}</li>
} </ul>
花括號 {...} 指示計算表達式而非字面量。
xquery
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
where $y/Address[zip="10011"] or $y/Address[city="San Jose"]
return <emailList> {$y/email} </emailList>
無 email 時返回空 <emailList/>,多 email 時全部包含,完美保留文檔邊界。
xquery
for $y in db2-fn:xmlcolumn('ITEMS.COMMENTS')/Comments/Comment
return
if ($y/ResponseRequested = 'Yes')
then <action>{$y/ProductID, $y/CustomerID, $y/Message}</action>
else <info>{$y/ProductID, $y/Message}</info>
xquery
for $p in distinct-values(db2-fn:xmlcolumn('ITEMS.COMMENTS')/Comments/Comment/ProductID)
let $pc := db2-fn:xmlcolumn('ITEMS.COMMENTS')/Comments/Comment[ProductID = $p]
return <product><id>{$p}</id><comments>{count($pc)}</comments></product>
使用 db2-fn:sqlquery('SQL SELECT ...') 替代 xmlcolumn,SQL 必須返回 XML 列。
xquery
for $y in db2-fn:sqlquery('select comments from items where srp > 100')/Comments/Comment
where $y/ResponseRequested = "Yes"
return <action>{$y/ProductID, $y/CustomerID, $y/Message}</action>
xquery
for $y in db2-fn:sqlquery("select contactinfo from clients where status='Gold'")/Client
where $y/Address/city="San Jose"
return
if ($y/email) then <emailList>{$y/email}</emailList>
else $y/Address
提示:嵌入 SQL 中的字符串字面量需用雙單引號 ''Gold'' 轉義。
生產環境務必創建專用 XML 索引加速路徑表達式求值,本文因篇幅不展開,請參考 DB2 索引技術文檔。
XQuery 賦予 DB2 原生處理 XML 的能力,結合 SQL 嵌入可無縫融合關系與層次數據。後續文章將探討 Java 應用開發中如何嵌入 XQuery。