自 Oracle 10g 起,Oracle 引入 XMLTable 函數,配合 XQuery/XPath,可將 XML 資料直接轉換為關聯式資料列/欄位,極大簡化 XML 解析與 ETL。本文系統介紹語法、XPath 基礎、實戰範例與進階用法。
XMLTable(
XQuery_expression
PASSING xml_data
COLUMNS
column_name datatype PATH 'xpath_expression' [DEFAULT expr],
...
) [xmltable_alias]
/Employees/Employee)。text() 取節點文本、@attr 取屬性。CREATE TABLE employees (
id NUMBER,
data XMLTYPE
);
INSERT INTO employees VALUES (1, XMLTYPE(
'
John Watson 30 johnwatson@sh.com
Sherlock Holmes 32 sherlock@sh.com
Jim Moriarty 52 jim@sh.com
Mycroft Holmes 41 mycroft@sh.com
'));
SELECT t.id, x.*
FROM employees t,
XMLTable('/Employees/Employee' PASSING t.data
COLUMNS firstname VARCHAR2(30) PATH 'firstname',
lastname VARCHAR2(30) PATH 'lastname') x
WHERE t.id = 1;
輸出:
| ID | FIRSTNAME | LASTNAME |
|---|---|---|
| 1 | John | Watson |
| 1 | Sherlock | Holmes |
| 1 | Jim | Moriarty |
| 1 | Mycroft | Holmes |
SELECT t.id, x.*
FROM employees t,
XMLTable('/Employees/Employee/firstname' PASSING t.data
COLUMNS firstname VARCHAR2(30) PATH 'text()') x
WHERE t.id = 1;
SELECT t.id, x.*
FROM employees t,
XMLTable('/Employees/Employee' PASSING t.data
COLUMNS firstname VARCHAR2(30) PATH 'firstname',
type VARCHAR2(30) PATH '@type') x;
輸出:包含 admin/user 區分。
-- 僅 emplid=2222
SELECT t.id, x.*
FROM employees t,
XMLTable('/Employees/Employee[@emplid=2222]' PASSING t.data
COLUMNS firstname VARCHAR2(30) PATH 'firstname',
lastname VARCHAR2(30) PATH 'lastname') x
WHERE t.id = 1;
SELECT t.id, x.*
FROM employees t,
XMLTable('/Employees/Employee[@type="admin" and age>40]' PASSING t.data
COLUMNS firstname VARCHAR2(30) PATH 'firstname',
lastname VARCHAR2(30) PATH 'lastname',
age VARCHAR2(30) PATH 'age') x
WHERE t.id = 1;
| 表達式 | 說明 |
|---|---|
nodename | 選擇所有該名稱節點 |
/ | 從根節點開始 |
// | 任意層級遞歸選擇 |
@attr | 選擇屬性 |
text() | 取節點文本內容 |
//Employee[@type='admin'] | 所有 type=admin 的 Employee |
/Employees/Employee[1] | 第一個 Employee |
/Employees/Employee[last()] | 最後一個 Employee |
當 XML 結構不固定或不想硬編碼欄位時,使用 XML 關鍵字:
SELECT x.column_value.getClobVal() AS xml_fragment
FROM employees t,
XMLTable('/Employees/Employee' PASSING t.data COLUMNS column_value XMLTYPE) x;
SELECT x.*
FROM employees t,
XMLTable(
XMLNAMESPACES('https://example.com/ns' AS "ns"),
'/ns:Employees/ns:Employee' PASSING t.data
COLUMNS firstname VARCHAR2(30) PATH 'ns:firstname') x;
CREATE INDEX idx_emp_xml ON employees(data) INDEXTYPE IS XDB.XMLIndex;// 遞歸下降,改用確切路徑。XMLTable 是 Oracle 內建最強大的 XML→關聯轉換工具,結合 XPath/XQuery 可實現複雜結構的解析、過濾、轉型。掌握 PASSING、COLUMNS PATH、text()/@attr、謂詞過濾 核心語法,即可應對絕大多數 XML ETL 與報表需求。配合 XMLIndex 可獲得生產級效能。