Oracle XQuery查詢、構(gòu)建與轉(zhuǎn)換XML(2)
發(fā)表時(shí)間:2024-06-18 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]查詢 Oracle XML DB 信息庫(kù)中的 XML 數(shù)據(jù) 為訪問(wèn) Oracle XML DB 信息庫(kù)中存儲(chǔ)的 XML 數(shù)據(jù),Oracle XQuery 引入了 fn:doc 和 fn:collection XQuery 函數(shù)。使用 fn:doc,您可以查詢 XML 信息庫(kù)中存儲(chǔ)的單個(gè) XML 文...
查詢 Oracle XML DB 信息庫(kù)中的 XML 數(shù)據(jù) 為訪問(wèn) Oracle XML DB 信息庫(kù)中存儲(chǔ)的 XML 數(shù)據(jù),Oracle XQuery 引入了 fn:doc 和 fn:collection XQuery 函數(shù)。使用 fn:doc,您可以查詢 XML 信息庫(kù)中存儲(chǔ)的單個(gè) XML 文檔,而 fn:collection 使您可以訪問(wèn)同一信息庫(kù)文件夾中存儲(chǔ)的多個(gè) XML 文檔。
正如本文之前(參閱使用關(guān)系數(shù)據(jù)構(gòu)建 XML部分)介紹的示例所演示,使用 fn:doc 非常簡(jiǎn)單直接。它獲取表示信息庫(kù)文件資源 (URI) 的字符串并返回該 URI 指向的文檔。要了解 fn:collection XQuery 函數(shù)的作用,同一文件夾中至少應(yīng)有兩個(gè)信息庫(kù)文件。如果已經(jīng)運(yùn)行了列表 1 中的代碼,則已經(jīng)創(chuàng)建了 /public/employees 信息庫(kù)文件夾并在其中存儲(chǔ)了 employees.xml 文件。因此,您將需要在該文件夾中至少再創(chuàng)建一個(gè) XML 文件,然后才能試用 fn:collection。列表 2 中的 PL/SQL 代碼基于 SCOTT/TIGER 演示數(shù)據(jù)庫(kù)模式的 dept 和 emp 表存儲(chǔ)的關(guān)系數(shù)據(jù)構(gòu)建 XML,然后將生成的 XML 文檔作為 acc_dept.xml 保存到 /public/employees 信息庫(kù)文件夾。要運(yùn)行列表 2 中的 PL/SQL 過(guò)程,請(qǐng)確保以 SCOTT/TIGER 的身份登錄。
列表 2:基于關(guān)系數(shù)據(jù)構(gòu)建 XML 并將其保存到 XML 信息庫(kù)
DECLARE
XMLdoc XMLType;
BEGIN
SELECT XMLQuery(
'for $j in ora:view("SCOTT", "dept")/ROW
where $j/DEPTNO = 10
return (
{$j/DEPTNO,
$j/DNAME}
{
for $i in ora:view("SCOTT", "emp")/ROW
where $i/DEPTNO = $j/DEPTNO
return (
{$i/EMPNO,
$i/ENAME,
$i/SAL}
)}
)'
RETURNING CONTENT) INTO XMLdoc FROM DUAL;
IF(DBMS_XDB.CREATERESOURCE('/public/employees/acc_dept.xml', XMLdoc)) THEN
DBMS_OUTPUT.PUT_LINE('Resource is created');
ELSE
DBMS_OUTPUT.PUT_LINE('Cannot create resource');
END IF;
COMMIT;
END;
/ |
此時(shí),/public/employees 信息庫(kù)文件夾應(yīng)包含兩個(gè)文件:acc_dept.xml(由列表 2 中的 PL/SQL 代碼生成)和 employees.xml 文件(由列表 1 中的代碼生成)。由于這些 XML 文檔存儲(chǔ)在同一信息庫(kù)文件夾中,因此可以使用 fn:collection 函數(shù)訪問(wèn)兩個(gè) XML 文檔中存儲(chǔ)的員工信息。然而,盡管這些 XML 文檔均包含員工 XML 元素(這些元素實(shí)際上具有相同結(jié)構(gòu)),但 XML 文檔本身的結(jié)構(gòu)迥然不同。在 employees.xml 中,文檔根元素為 EMPLOYEES,而 acc_dept.xml 將 DEPARTMENT 用作根元素。要解決此問(wèn)題,可以通過(guò) XQuery 使用 XPath // 構(gòu)造,從而導(dǎo)航到 XML 文檔中的某個(gè)節(jié)點(diǎn),而不必指定該節(jié)點(diǎn)的確切路徑。以下示例演示了如何在 XQuery 表達(dá)式中使用 XPath // 構(gòu)造:
SELECT XMLQuery(
'for $i in fn:collection("/public/employees")//EMPLOYEE
where $i/SAL >= 5000
order by $i/ENAME
return;
$i'
RETURNING CONTENT) FROM DUAL; |
該構(gòu)造應(yīng)生成以下輸出:
102
De Haan
17000
7839
KING
5000
100
King
24000
101
Kochhar
17000
|
您可以看到,以上輸出包含從 employees.xml 和 acc_dept.xml 中獲取的員工 XML 元素,這些元素表示薪酬大于或等于 5,000 美元的員工。
將 XML 分解為關(guān)系數(shù)據(jù)
如果應(yīng)用程序處理關(guān)系數(shù)據(jù)而非 XML,而您需要訪問(wèn)的數(shù)據(jù)以 XML 格式存儲(chǔ),則將 XML 分解為關(guān)系數(shù)據(jù)可能會(huì)非常有用。繼續(xù)進(jìn)行上一部分的示例,您可以使用 SQL 函數(shù) XMLTable 將員工 XML 元素分解為虛擬表的單個(gè)列,如下所示:
SELECT emps.empno,emps.ename, emps.sal FROM
XMLTable(
'for $i in fn:collection("/public/employees")//EMPLOYEE
where $i/SAL >= 5000
return;
$i'
COLUMNS empno NUMBER PATH '/EMPLOYEE/EMPNO',
ename VARCHAR2(30) PATH '/EMPLOYEE/ENAME',
sal NUMBER PATH '/EMPLOYEE/SAL') emps; |
該查詢將生成以下輸出:
EMPNO ENAME SAL
----- -------------- ----------
7839 KING 5000
100 King 24000
101 Kochhar 17000
102 De Haan 17000 |