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

SQL/XML 查詢 DB2 9 XML 數據實戰:從純 SQL 到 XMLTable、XMLAgg 完全指南

     編輯:DB2 教學

核心觀點

DB2 9 (Viper) 引入 原生 XML 數據類型,將 XML 以層次化格式存儲於列中。熟悉 SQL 的開發者可直接使用 SQL/XML (ISO 標準) 函數查詢、轉換、發布 XML,無需學習全新語言。

樣本表結構

CREATE TABLE items (
  id INT PRIMARY KEY NOT NULL,
  brandname VARCHAR(30),
  itemname VARCHAR(30),
  sku INT,
  srp DECIMAL(7,2),
  comments XML
);

CREATE TABLE clients (
  id INT PRIMARY KEY NOT NULL,
  name VARCHAR(50),
  status VARCHAR(10),
  contactinfo XML
);

一、純 SQL 的局限與 SQL/XML 破局

  • SELECT * FROM clients 可取整個 XML 文檔
  • 無法 在 WHERE 中按 XML 內容過濾、無法 投影 XML 片段、無法 對 XML 元素 Join/Agg/Order
  • 需用 XMLEXISTS、XMLQUERY、XMLTABLE 等 SQL/XML 函數

二、關鍵 SQL/XML 函數速查

函數用途典型子句
XMLEXISTSWHERE 中按 XPath 條件過濾行XMLEXISTS('$c/Client/Address[zip="95116"]' PASSING contactinfo AS "c")
XMLQUERYSELECT 列表中投影 XML 片段/值XMLQUERY('$c/Client/email[1]' PASSING contactinfo AS "c")
XMLTABLE將 XML 節點映射為關系結果集列COLUMNS cid INT PATH 'CommentID', msg VARCHAR(100) PATH 'Message'
XMLELEMENT關系數據構造 XML 元素XMLELEMENT(NAME "item", XMLELEMENT(NAME "id", id), ...)
XMLAGG聚合多行 XML 片段為序列XMLAGG(XMLELEMENT(...)) ORDER BY name
XMLFOREST快速構造多個同級元素XMLFOREST(name AS "fullName", status AS "status")

三、實戰場景與代碼

1. 按 XML 元素值過濾(住 95116 郵編的客戶)

SELECT name FROM clients
WHERE XMLEXISTS('$c/Client/Address[zip="95116"]'
                PASSING clients.contactinfo AS "c");

陷阱:XMLEXISTS('$c/Client/Address/zip="95116"') 語法合法但不會過濾,必須用謂詞 [zip="95116"]。

2. 投影 XML 元素值(Gold 客戶首個 email)

SELECT XMLQUERY('$c/Client/email[1]' PASSING contactinfo AS "c")
FROM clients WHERE status = 'Gold';

排除無 email 客戶:

SELECT XMLQUERY('$c/Client/email[1]' PASSING contactinfo AS "c")
FROM clients
WHERE status = 'Gold'
  AND XMLEXISTS('$c/Client/email' PASSING contactinfo AS "c");

3. XMLTable 多元素映射關系結果集(評論詳情)

SELECT t.CommentID, i.itemname, t.CustomerID, t.Message
FROM items i,
     XMLTABLE('$c/Comments/Comment' PASSING i.comments AS "c"
         COLUMNS
           CommentID  INTEGER   PATH 'CommentID',
           CustomerID INTEGER   PATH 'CustomerID',
           Message    VARCHAR(100) PATH 'Message') AS t;

結果集為純關系表格,列名自動大寫。

4. 基於 XMLTable 創建關系視圖(供傳統 SQL 應用)

CREATE VIEW commentView(itemID, itemname, commentID, message, mustRespond) AS
SELECT i.id, i.itemname, t.CommentID, t.Message, t.ResponseRequested
FROM items i,
     XMLTABLE('$c/Comments/Comment' PASSING i.comments AS "c"
         COLUMNS
           CommentID       INTEGER  PATH 'CommentID',
           Message         VARCHAR(100) PATH 'Message',
           ResponseRequested VARCHAR(100) PATH 'ResponseRequested') AS t;

性能警示:視圖上的 XML 列無索引支持,查詢時需結合關系列謂詞(如 i.id)先過濾,再應用 XML 謂詞,否則全表掃描 XML 文檔。

5. XML 與關系數據 Join(評論過的客戶姓名/狀態)

SELECT c.name, c.status
FROM items i, clients c
WHERE XMLEXISTS('$cm/Comments/Comment[CustomerID=$cid]'
                PASSING i.comments AS "cm", c.id AS "cid");

6. SQL 中嵌入 FLWOR(Gold 客戶姓名 + 首 email 轉 HTML 段落)

SELECT name,
       XMLQUERY('for $e in $c/Client/email[1]/text() return <p>{$e}</p>'
                PASSING contactinfo AS "c")
FROM clients WHERE status = 'Gold';

7. 關系數據發布為 XML(價格 < 100 的商品)

SELECT XMLELEMENT(NAME "item",
       XMLELEMENT(NAME "id", id),
       XMLELEMENT(NAME "brand", brandname),
       XMLELEMENT(NAME "sku", sku))
FROM items WHERE srp < 100;

輸出:<item><id>4272</id><brand>Classy</brand><sku>981140</sku></item>

8. 聚合分組輸出(按狀態分組客戶列表)

SELECT XMLELEMENT(NAME "customerList",
       XMLAGG(
         XMLELEMENT(NAME "customer",
           XMLFOREST(name AS "fullName", status AS "status")
         )
         ORDER BY name
       )
     )
FROM clients GROUP BY status;

生成三個 <customerList> 元素,分別包含 Gold/Silver/Standard 客戶。

四、更新與刪除 XML 數據

UPDATE:必須提供完整文檔

UPDATE clients SET contactinfo = XMLPARSE(DOCUMENT
'<Client>
  <Address><street>5401 Julio Ave.</street><city>San Jose</city><state>CA</state><zip>95116</zip></Address>
  <phone><work>4084633000</work><home>4081111111</home><cell>4082222222</cell></phone>
  <fax>4087776666</fax>
  <email>newemail@someplace.com</email>
</Client>')
WHERE id = 3227;

關鍵:僅更新 email 而省略 Address/phone 會導致舊數據丟失,且後續 XPath 查詢失效(層次結構變化)。

視圖列(來自 XMLTable)不可更新。

DELETE:支持 XML 條件

DELETE FROM clients
WHERE XMLEXISTS('$c/Client/Address[zip="95116"]'
                PASSING contactinfo AS "c");

五、索引與性能

生產環境必須創建 XML 索引加速路徑表達式,本文為入門教程不展開,請參考《DB2 pureXML 索引技術》文檔。

結語

SQL/XML 讓關系開發者以熟悉語法無縫處理 XML,結合 XMLTable、XMLELEMENT、XMLAGG 等函數可實現雙向轉換。後續文章將介紹 XQuery 原生查詢與 Java 應用開發。

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