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

DB2 9 基礎 (730) 認證指南第 7 部分:XQuery 入門實戰 - 從路徑表達式到 FLWOR、XML 轉換與混合查詢

     編輯:DB2 教學

XQuery 核心觀念

  • 資料模型: 輸入/輸出皆為 序列,項目可為原子值、XML 節點 (元素/屬性/文本)、完整 XML 文件。
  • 大小寫敏感 (與 SQL 不同),/Client/Address ≠ /client/address。
  • 無 NULL:XML 缺失節點直接不存在,不佔位;SQL 需用 NULL 表示未知。
  • 結果型別: 序列 (XML 片段/文件) vs SQL 結果集 (關係列)。

兩大核心表達式

表達式用途對應 SQL 概念
Path Expression (路徑表達式)在 XML 階層導航、過濾、取值WHERE 條件 + 選取欄位
FLWOR Expression迭代、過濾、排序、建構輸出SELECT-FROM-WHERE-ORDER BY

路徑表達式速查表 (以範例文件為準)

<Client id="123">
  <Address><street>9999 Elm St.</street><city>San Jose</city><state>CA</state><zip>95141</zip></Address>
  <email>any@yahoo.com</email><email>another@yahoo.com</email>
</Client>
表達式結果
/Client/email所有 email 元素
/Client/email[1]第一個 email 元素
/Client[@id='123']/email[1]id=123 的 Client 第一個 email
/Client/Address[state="CA"]/zip州=CA 的 zip 元素
/Client/*/cityClient 任一直接子元素下的 city
/Client/Address/city精確導航到 city
//email文件任意深度的 email
/Client/email[1]/text()第一個 email 的文本值
/Client/data(@id)id 屬性值 "123"
/Client/Address[state="CA"]/../email州=CA 的 Client 所有 email (.. 返回父節點)

FLWOR 子句詳細解析

for $i in (1,2,3) return $i                    → 1 2 3 (逐項綁定)
let $i := (1,2,3) return {$i} → 1 2 3 (整體綁定)
for $i in (1,2,3) where $i < 3 return $i       → 1 2 (過濾)
for $i in (5,1,2,3) order by $i descending return $i → 5 3 2 1 (排序)
  • for:逐項迭代序列,每次綁定一項。
  • let:一次綁定整個序列 (可為空/單項/多項)。
  • where:過濾條件 (XPath 謂詞)。
  • order by:排序,支援 ascending/descending、empty greatest/least。
  • return:建構輸出,**必須存在**,否則語法不完整。

DB2 執行 XQuery 環境

  • 頂層語言用 XQuery:xquery 表達式 (關鍵字 xquery 告知剖析器)。
  • 嵌入 SQL 中:無需 xquery 前綴,直接用 XMLQUERY/XMLEXISTS。
  • 範例資料表 clients:id, name, status, contactinfo XML。
  • CLP 參數 db2 -i -d:輸出縮排格式化 XML,易讀不影響實際資料。

實戰範例:針對 clients.contactinfo 查詢

1. 擷取完整 XML 文件

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

2. 擷取特定元素 (傳真號)

xquery for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax return $y
-- 等價路徑表達式
xquery db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax

輸出:<fax>4087776666</fax> <fax>4085555555</fax>

3. 取文本值而非 XML 片段

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

輸出:4087776666 4085555555

4. 擷取複雜型別 (Address 完整結構)

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

5. 依 XML 值過濾 (單一謂詞)

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

6. 多條件過濾並投影不同分支

xquery for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
       where $y/Address/zip="95032" or $y/Address/city="San Jose"
       return $y/email
-- 路徑表達式版
xquery db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client[Address/zip="95032" or Address/city="San Jose"]/email

輸出 3 筆 email (兩筆屬同一 Client)。

7. 只取每位客戶第一個 email

xquery db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client[Address/zip="95032" or Address/city="San Jose"]/email[1]

XML 輸出轉換與條件邏輯

轉 HTML 列表 (依 zip 排序)

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

{...} 大括號指示「計算運算式」而非字串字面值。

包裝輸出以表達缺失/重複元素

xquery for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
       where $y/Address[zip="95032"] or $y/Address[city="San Jose"]
       return {$y/email}

輸出:有 email 者含 <email>...、無 email 者輸出 <emailList/>、多 email 者全部保留,完美保留文件邊界語意。

條件邏輯:優先聯絡管道 (email → 家用電話 → 郵寄地址)

xquery for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
       return (
         if ($y/email) then $y/email[1]
         else if ($y/phone/home) then {$y/phone/home/text()}
         else $y/Address
       )

確保每位客戶恰好回傳一種聯絡資訊。

混合查詢:SQL + XQuery 雙向嵌入

XQuery 嵌入 SQL (以 SQL 為主)

SELECT name, status,
       XMLQUERY('$c/Client/phone/home' PASSING contactinfo AS "c")
FROM clients
WHERE XMLEXISTS('$y/Client/Address[zip="95032"]' PASSING contactinfo AS "y");
  • XMLQUERY:從 XML 擷取片段放入 SQL 結果集欄位。
  • XMLEXISTS:在 WHERE 子句中依 XML 條件過濾列。
  • 變數 $c, $y 綁定 contactinfo 欄位。

結果:Lisa Hansen | Silver | <home>4083332222</home>

SQL 嵌入 XQuery (以 XQuery 為主)

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 {$y/email}
    else $y/Address
  )
  • db2-fn:sqlquery 執行 SQL 並回傳 XML 序列供 XQuery 後續處理。
  • SQL 字串常值內的單引號需雙寫轉義 ''Gold''。

輸出:Gold 客戶住 San Jose 者,有 email 則包裝 <emailList>,無 email 則回傳 Address。

考試重點總結

  1. XQuery 資料模型 (序列、節點、原子值)、大小寫敏感、無 NULL。
  2. Path Expression 導航語法 (/、//、@、[谓詞]、..、text()、data())。
  3. FLWOR 五子句語義差異 (for vs let、where、order by、return 必備)。
  4. DB2 執行方式:xquery 前綴、db2-fn:xmlcolumn、db2-fn:sqlquery。
  5. XML 建構:大括號計算、元素建構器、條件邏輯 (if-then-else)。
  6. 混合查詢:XMLQUERY/XMLEXISTS (SQL 主) vs db2-fn:sqlquery (XQuery 主)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved