首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

XQuery 查詢 DB2 XML 數據完全指南:從 FLWOR 到 SQL 嵌入

     編輯:DB2 教學

前言:XQuery 與 SQL 的核心差異

XQuery 針對層次化、有序的 XML 數據模型設計;SQL 面向平面、無序的關系表集合。關鍵差異包括:

  • XQuery 支持路徑表達式導航層次結構,SQL 不支持。
  • XQuery 處理有類型/無類型數據,SQL 強類型。
  • XQuery 無 NULL 概念(缺失即不存在),SQL 用 NULL 表示未知。
  • XQuery 返回 XML 序列,SQL 返回結果集。

樣本環境

基於 items(商品評論)與 clients(客戶聯系信息)兩表,均包含 XML 列(comments、contactinfo)。所有查詢在 DB2 Command Editor 或 CLP 中交互執行。

核心表達式類型

1. FLWOR 表達式(類比 SELECT-FROM-WHERE)

關鍵字:for(迭代)、let(變量綁定)、where(過濾)、order by(排序)、return(輸出)。

2. 路徑表達式

斜槓分隔的步驟導航 XML 層次,可帶謂詞過濾,如 $clients/Client/Address[state="CA"]/zip。

頂層 XQuery 必須以 xquery 關鍵字開頭

調用 db2-fn:xmlcolumn('TABLE.COLUMN') 獲取 XML 文檔序列。注意表名、列名需大寫以匹配 DB2 系統目錄。

實戰查詢場景

場景 1:檢索特定元素(傳真號)

xquery
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax
return $y

或簡化為路徑表達式:

xquery db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax

需文本值而非 XML 片段時,追加 /text()。

場景 2:檢索複雜類型(完整地址)

xquery
for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address
return $y

返回包含所有子元素的 <Address> 片段序列。

場景 3:過濾(郵編 95116 的客戶地址)

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"]

場景 4:多條件過濾並投影不同子樹(紐約 10011 或聖何塞客戶的 email)

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 佔位。

場景 5:每客戶僅取首個 email

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]

場景 6:輸出轉換為 HTML

xquery
<ul> {
  for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address
  order by $y/zip
  return <li>{$y}</li>
} </ul>

花括號 {...} 指示計算表達式而非字面量。

場景 7:條件邏輯構造不同輸出結構

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 時全部包含,完美保留文檔邊界。

場景 8:if-then-else 業務分流(評論需響應生成 action,否則 info)

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>

場景 9:let 子句聚合統計(各產品評論數)

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>

嵌入 SQL 的 XQuery:跨模型查詢利器

使用 db2-fn:sqlquery('SQL SELECT ...') 替代 xmlcolumn,SQL 必須返回 XML 列。

案例:價格 > 100 且要求響應的評論

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>

案例:Gold 客戶在聖何塞,有 email 返 email 列表,無則返地址

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 索引

生產環境務必創建專用 XML 索引加速路徑表達式求值,本文因篇幅不展開,請參考 DB2 索引技術文檔。

結語

XQuery 賦予 DB2 原生處理 XML 的能力,結合 SQL 嵌入可無縫融合關系與層次數據。後續文章將探討 Java 應用開發中如何嵌入 XQuery。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved