Oracle Database 10g リリース 2(10.2)
XML 生成のマスター
オラクル・ホワイト・ペーパー
2005 年 9 月
Oracle Database 10g リリース 2(10.2)
XML 生成のマスター
概要 ... 3
XML SQL UTILITY(XSU)を使用したXMLの生成 ... 3
XSU Java APIを使用したXMLの生成... 4
XSU PL/SQL APIを使用したXMLの生成... 5
DBMS_XMLGENパッケージを使用したXMLの生成... 6
SYS_XMLGENおよびSYS_XMLAGG関数を使用したXMLの生成... 7
SYS_XMLGEN()関数 ... 7
SYS_XMLAGG()関数... 8
SQL/XML関数を使用したXMLの生成 ... 9
XMLElement()関数... 9
XMLAttributes()句... 10
XMLForest()関数 ... 11
XMLConcat()関数... 11
XMLAgg()関数 ... 12
XMLPI()関数... 13
XMLComment()関数 ... 14
XMLRoot()関数 ... 14
XMLSerialize()関数 ... 14
XMLParse()関数 ... 15
XMLSequence()関数... 15
XMLColAttVal()関数 ... 17
SQL/XML関数に基づいたXMLTypeビュー... 18
結論 ... 22
Oracle Database 10g リリース 2(10.2)
XML 生成のマスター
概要
リレーショナル・データを XML 形式で公開、交換する需要の拡大に対応するた
め、Oracle データベースは長年にわたり進化し続け、業界標準に基づいてより効
果的で高度な XML 生成機能を提供してきました。XML の生成アプローチが Oracle
データベースの各リリースでどのように進化してきたかを説明します。
• XML-SQL Utility: Oracle8i で導入された XML-SQL Utility の Java 実装は、
PL/SQL API (DBMS_XMLQuery パッケージ)とともに業界をリードし、初
期の XML アプリケーションのニーズに対応してきました。
• DBMS_XMLGEN: XML アプリケーションに対するワークロードの急増に伴
い、オラクル社は高パフォーマンスでスケーラブルなデータベース・ネイティ
ブの Oracle9i の DBMS_XMLGEN PL/SQL パッケージをリリースしました。
• SYS_XMLGEN and SYS_XMLAGG SQL 関数: この SQL 関数も Oracle9i から
導入され、リレーショナル・データから整形式の XML 文書の生成に活用され
てきました。
オ ラ ク ル 社 は 、 新 し く 標 準 化 さ れ た SQL/XML 機能を Oracle Database 10g リ リ ー ス 1 ( 10.1 ) と 、 今 回 の Oracle Database 10g リリース 2(10.2)に適切 に実装して、業界トップの地位を保持し ています。• SQL/XML: XML 技術の重要性を認識し、オラクル社は、革新的な XML DB
製品である Oracle9i Database リリース 2(9.2)を発売しました。XML DB の
柱の 1 つとして、XML 生成機能は最新の SQL 2003 Part 14 - SQL/XML 標準に
基づいています。オラクル社は、新しく標準化された SQL/XML 機能を Oracle
Database 10g リリース 1(10.1)と、今回の Oracle Database 10g リリース 2(10.2)
に適切に実装して、業界トップの地位を依然保持しています。
次の各項では、これらの機能の使用方法および基盤となるテクノロジについて説
明します。また、推奨される使用方法のガイドライン、および各アプローチのメ
リットとデメリットも説明します。
XML SQL UTILITY(XSU)を使用した XML の生成
XML-SQL Utility(XSU)は、リレーショナル・データベース表またはビューから
取得したデータを XML に変換し、データベースに対して XML 文書の挿入、更新、
削除を行うために必要なサービスを実装する Java クラスのコレクションです。ま
た、
Java クラスをミラー化した、
PL/SQL プログラムを開発するための PL/SQL パッ
ケージも提供されています。Oracle8i への導入以降、多数の XML アプリケーショ
ンの J2EE 環境の中間層での Oracle データベースへの接続に JDBC および XSU Java
クラスが使用されています。XML データへのアクセスに、Oracle8i データベース
を使用する PL/SQL プログラムも、対応する XSU PL/SQL パッケージに依存して
います。この項では、XSU の XML 生成を中心に説明します。
XSU は、次のインタフェースを介してアクセスできます。
• リレーショナル・データから XML を生成する oracle.xml.sql.query パッ
ケージの OracleXMLQuery Java クラス
• OracleXMLQuery Java クラスをミラー化する PL/SQL パッケージ
DBMS_XMLQuery
XSU Java API を使用した XML の生成
OracleXMLQuery クラスは、リレーショナル・データから
XML を生成する XSU
の主要クラスです。データベース接続のための JDBC とともに使用して、SQL 問
合せを発行し、その結果を XML データに変換します。次のコード(抜粋)は、
OracleXMLQuery クラスを使用して、指定の
SQL 問合せから XML データを生
成する手順を示しています。
// import the Oracle driver class
import oracle.jdbc.*;
// load the Oracle JDBC driver
DriverManager.registerDriver(new
oracle.jdbc.OracleDriver());
// create the connection
Connection conn = DriverManager.getConnection
("jdbc:oracle:oci:@","hr","hr");
// Create an OracleXMLQuery Class instance by passing
// a SQL query to the constructor.
OracleXMLQuery qry = new OracleXMLQuery (conn, "SELECT *
from EMPLOYEES");
// Invoking an OracleXMLQuery method to specify that
// only 20 rows should be included in the result set,
xmlQry.setMaxRows(20);
// Return a DOM object or string by invoking
// OracleXMLQuery methods.
XMLDocument domDoc = (XMLDocument)qry.qetXMLDOM();
// Obtain a string object.
String xmlString = qry.getXMLString();
// Perform additional processing on the string
// or DOM as needed...
XSU PL/SQL API を使用した XML の生成
DBMS_XMLQuery は、下位層の OracleXMLQuery Java クラスとやり取りする
PL/SQL パッケージです。このパッケージは、他の Java パッケージとともに Oracle
データベースにロードされ、統合された Oracle JVM 上で稼働します。XSU も、
Oracle9i 以降 XMLType データ型をサポートしています。表に XMLType 列がある
場合、XSU を使用すると有効です。
DBMS_XMLQuery は、DTD や XML スキーマを持つ XML 文書、およびそれらを
持たない XML 文書を含む CLOB を生成します。次の PL/SQL コードは、XMLQuery
を使用する基本手順を示します。
-- Declare a variable for the XML query context and a
-- variable for the generated XML.
DECLARE
v_queryCtx
DBMS_XMLQuery.ctxType;
v_result CLOB;
BEGIN
-- Obtain a context handle with a query.
v_queryCtx = DBMS_XMLQuery.newContext
('SELECT * FROM employees WHERE
employee_id =: EMPLOYEE_ID AND
first_name =: FIRST_NAME');
-- Bind values to the query.
DBMS_XMLQuery.setBindValue (v_queryCtx,
'EMPLOYEE_ID',
20);
DBMS_XMLQuery.setBindValue (v_queryCtx,
'FIRST_NAME',
'John');
-- Set optional arguments
DBMS_XMLQuery.setRowSetTag(v_queryCtx,'EMPSET');
-- Fetch the XML result as a CLOB using the
-- getXML function,
v_result := DBMS_XMLQuery.getXML(v_queryCtx);
-- Process the results of the XML generation.
v_xmlstr VARCHAR2(32767);
v_line VARCHAR2(2000);
-- Print the CLOB stored in v_result.
v_xmlstr := DBMS_LOB.SUBSTR(v_result,32767);
LOOP
EXIT WHEN v_xmlstr IS NULL;
v_line := substr(v_xmlstr,l,
INSTR
(v_xmlstr,CHR(10))-1);
DBMS_OUTPUT.PUT_LINE('| ' || v_line);
v_xmlstr := SUBSTR(v_xmlstr,
INSTR(v_xmlstr,CHR(10))+1);
END
LOOP;
-- Close the context.
DBMS_XMLQuery.closeContext(v_queryCtx);
END;
DBMS_XMLGEN パッケージを使用した XML の生成
SQL 問合せから XML を生成する際のパフォーマンスとスケーラビリティを大き
く向上させるために、Oracle9i では、DBMS_XMLQuery パッケージのかわりに
DBMS_XMLGEN PL/SQL パッケージが導入されました。このパッケージは、C 言語
で実装されたデータベース・ネイティブの XML 生成関数に関連付けられます。
DBMS_XMLGEN は、データベース問合せ結果を
XML にマップすることで、どの
SQL 問合せからでも XML 文書を生成します。また、XML 文書を CLOB または
XMLType として取得します。最大行およびスキップする行を指定できるフェッ
チ・インタフェースも提供します。これは、Web アプリケーションにおけるペー
ジ区切り要件に役立ちます。DBMS_XMLGEN は、ROW、ROWSET などのタグ名を変
更するオプションも提供します。
DBMS_XMLGen パッケージの getXML()プロシージャをコールすると、結果とし
て CLOB が出力されます。デフォルトのマッピングは次のとおりです。
• 問合せ結果の各行は、デフォルトのタグ名 ROW で XML 要素にマップされま
す。
• 結果全体は、ROWSET 要素に含まれます。これらの名前はどちらも
DBMS_XMLGen の setRowTagName()および setRowSetTagName()プロ
シージャを使用して構成できます。
• SQL 問合せ結果の各列は、ROW 要素のサブ要素としてマップされます。
• バイナリ・データは、16 進数表現に変換されます。
次の例では、リレーショナル表から従業員データを選び出し、結果として得られ
た CLOB を表に入力して XML 文書を作成します。
CREATE TABLE temp_clob_tab (result CLOB);
DECLARE
qryCtx
DBMS_XMLGEN.ctxHandle;
result
CLOB;
BEGIN
qryCtx := dbms_xmlgen.newContext('SELECT * from
scott.emp');
-- set the row header to be EMPLOYEE
DBMS_XMLGEN.setRowTag(qryCtx,
'EMPLOYEE');
-- now get the result
result := DBMS_XMLGEN.getXML(qryCtx);
INSERT INTO temp_clob_tab VALUES (result);
--close
context
DBMS_XMLGEN.closeContext(qryCtx);
END;
/
SELECT * FROM temp_clob_tab;
RESULT
---
<?xml version="1.0"?>
<ROWSET>
<EMPLOYEE>
<EMPNO>7369</EMPNO>
<ENAME>SMITH</ENAME>
<JOB>CLERK</JOB>
<MGR>7902</MGR>
<HIREDATE>17-DEC-80</HIREDATE>
<SAL>800</SAL>
<DEPTNO>20</DEPTNO>
</EMPLOYEE>
<EMPLOYEE>
<EMPNO>7499</EMPNO>
<ENAME>ALLEN</ENAME>
<JOB>SALESMAN</JOB>
<MGR>7698</MGR>
<HIREDATE>20-FEB-81</HIREDATE>
<SAL>1600</SAL>
<COMM>300</COMM>
<DEPTNO>30</DEPTNO>
</EMPLOYEE>
...
</ROWSET>
SYS_XMLGEN および SYS_XMLAGG 関数を使用した XML の
生成
DBMS_XMLGEN パッケージと同様に SYS_XMLGEN()および SYS_XMLAGG()関
数も Oracle9i から導入され、リレーショナル・データから整形式の XML 文書を生
成するために活用されてきました。
SYS_XMLGEN()関数
この Oracle データベース固有の SQL 関数は、XMLElement()と同様ですが、相
違点は、1 つの引数を受け取り、結果を XML に変換することです。他の XML 生
成関数とは違い、SYS_XMLGEN()は常に整形式の XML 文書を返します。問合せ
レベルで稼働する DBMS_XMLGEN とは異なり、SYS_XMLGEN()は行レベルで稼働
して各行に XML 文書を返します。
SYS_XMLGEN()の利点は次のとおりです。
• SQL 問合せ内で XML インスタンスの作成および問合せが可能です。
• リレーショナル・データベース・インフラストラクチャを使用して、複雑に
ネストした XML インスタンスを単純なリレーショナル表から作成できます。
たとえば、SYS_XMLGEN()を使用して XMLType ビューを作成した場合、
Oracle XML DB は(可能な場合には)問合せのリライトを実行します。
SYS_XMLGEN()は次のいずれかを基に
XML 文書を作成します。
• ユーザー定義型(UDT)インスタンス
• スカラー値
• XML
返り値は、XMLType インスタンスとなります。
SYS_XMLGEN()は、オプションで
SQL 結果をカスタマイズできる XMLFormat オ
ブジェクト型を入力します。NULL フォーマット・オブジェクトは、デフォルトの
マッピング操作を意味します。
SYS_XMLGEN()は、次のように
SQL 問合せに XML インスタンスを作成して問合
せを行います。
SELECT SYS_XMLGEN(employee_id) AS "result"
FROM employees WHERE fname LIKE 'John %';
結果の XML 文書は次のとおりです。
Result
---
<?xml version="1.0"?>
<EMPLOYEE_ID>1001</EMPLOYEE_ID>
1 row selected.
SYS_XMLAGG()関数
SYS_XMLAGG()関数は、すべての
XML 文書または expr で表現されるフラグメン
トを集計して 1 つの XML 文書を作成します。ROWSET というデフォルトの名前で
新規の囲み要素を追加します。XML 文書を異なる書式でフォーマットする場合は、
'fmt'パラメータを使用してください。
次の例では、SYS_XMLGen 関数を使用して、姓が R で始まる従業員の emp1oyees
というサンプル表の各行に XML 文書を生成し、すべての行をデフォルトの囲み
要素 ROWSET の 1 つの XML 文書に集計します。
SELECT SYS_XMLAGG(SYS_XMLGEN(last_name))
FROM
employees
WHERE last_name LIKE 'R%';
SYS_XMLAGG(SYS_XMLGEN(LAST_NAME))
---
<ROWSET>
<LAST_NAME>Raphaely</LAST_NAME>
<LAST_NAME>Rogers</LAST_NAME>
<LAST_NAME>Rajs</LAST_NAME>
<LAST_NAME>Russell</LAST_NAME>
</ROWSET>
SQL/XML 関数を使用した XML の生成
業界全体における XML の採用傾向に伴い、オラクル社は、SQL 標準化委員会の
他のデータベース・ベンダーの陣頭に立ち、新規の SQL/XML 標準の作成を開始
しました。この標準は、現在 SQL 2003 標準および SQL 2005 標準の Part 14 となっ
ています。SQL/XML 標準は、新規 XML 型の詳細な定義、XML 型の値、SQL 構
文と XML 構文のマッピング、XML を SQL データから生成する機能など、データ
ベースで SQL と XML を併用する方法を定義しています。Oracle9i Database リリー
ス 2(9.2)以降、SQL/XML 機能は、Oracle SQL エンジンの不可欠な部分としてサ
ポートされています。このエンジンは、追加の SQL 拡張機能を提供して XML デー
タの問合せ、更新、変換をサポートしています。SQL/XML 委員会の創設メンバー
として、オラクル社は、委員会による SQL 2005 標準の主要新機能定義の作業に注
力しています。
Oracle の優れた SQL エンジンに SQL/XML 関数を追加することで、
オラクル社は、
新しく標準化された SQL/XML 機能を Oracle9i Database リリース 2(9.2)、Oracle
Database 10g リリース 1(10.1)、Oracle Database 10g リリース 2(10.2)に適切に
実装して、業界トップの地位を依然保持しています。
SQL/XML 関数は、リレーショナル・データから XML を生成する最も効率的で柔
軟な手段です。Oracle XML DB では、XMLRoot()、XMLPI()、XMLComment()、
XMLElement()、XMLForest()、XMLConcat()、XMLAgg()、XML
Seria1ize()
など、XML 生成用の SQL/XML 関数が多数サポートされています。また、XML
生成用の Oracle データベース拡張関数 XMLCo1AttVa1()も用意されています。
XMLElement()関数
XMLElement()関数は、要素名、その要素のオプションの属性コレクション、お
よび要素内容を構成するための 0 個以上の引数をとり、XMLType のインスタンス
を返します。
XMLElement()は、主にリレーショナル・データから
XML インスタンスの構成
する用途に使用されます。すべての SQL 識別子が妥当な XML 名ではないため、
XML 名への SQL 識別子のマッピングを定義することが必要です。
SQL 識別子から妥当な XML 要素名を生成する際、XML 要素名に使用が禁止され
ている文字はエスケープされます。部分的なエスケープにより、XML では表現で
きない符号である「:」以外の SQL 識別子の前に、符号#を使用するエスケープ文
字が付けられ、後ろには、そのエスケープ文字の 16 進数フォーマットの Unicode
表現が付けられます。これは、生成中の要素の名前空間接頭辞を指定する際に使
用できます。完全エスケープされたマッピングでは、SQL 識別子名に含まれてい
る XML 文字以外の文字は、「:」文字を含め、すべてエスケープされます。
XMLAttributes()句
XMLElement()のオプションとして XMLAttributes()句を指定することで、そ
の要素の属性を指定します。この後に、新規作成された子要素を構成する値リス
トが続きます。XMLAttributes()句では、属性の値を取得するために値式が評
価されます。
XMLAttributes()句に続く値リストは、
XML フォーマットに変換され最上位要
素の子として構成されます。式が NULL と評価された場合は、その式に対する要
素は作成されません。
次の例では、id および name 属性により従業員ごとの Emp 要素を作成します。
SELECT XMLELEMENT ("Emp", XMLATTRIBUTES (
e.employees_id as "ID",
e.fname ||' ' || e.lname AS "name"))
AS
"result"
FROM employees e
WHERE employee_id > 200;
この問合せで、次の XML フラグメントが返されます。
result
---
<Emp ID="1001" name="John Smith"/>
<Emp ID="1206" name="Mary Martin"/>
次の例は、XML スキーマ・ベースのドキュメントを作成する際の名前空間の使用
法を示します。XML スキーマ http://www.oracle.com/Employee.xsd が存
在し、ターゲットの名前空間がないと仮定すると、次の問合せにより、そのスキー
マに基づく XMLType インスタンスが作成されます。
SELECT XMLElement("Employee", XMLAttributes
('http://www.w3.org/2001/XMLSchema' AS "xmlns:xsi",
'http://www.oracle.com/Employee.xsd'
AS
"xsi:nonamespaceSchemaLocation"),
XMLForest(employee_id, last_name, salary)) AS "RESULT"
FROM hr.employees
WHERE department_id = 10;
これで、XML スキーマに基づく次のような XML 文書が作成されます。
Employee.xsd.
RESULT
---
<Employee xmlns:xsi=http://www.w3.org/2001/XMLSchema
xsi:nonamespaceSchemaLocation="http://www.oracle.com/Emp
loyee.xsd">
<EMPLOYEE_ID>200</EMPLOYEE_ID>
<LAST_NAME>Whalen</LAST_NAME>
<SALARY>4400</SALARY>
</Employee>
1 row selected.
XMLForest()関数
XMLForest()関数では、所定の引数リストから
XML 要素のフォレストが作成さ
れます。この引数は、オプションの別名を持つ値式の場合があります。
値リストは、XML フォーマットに変換されます。AS 句が省略されている式の場
合、完全にエスケープされた列名フォームが要素のタグ名として使用されます。
オブジェクト・タイプまたはコレクションでは、AS 句は必須です。その他の型で
は、AS 句は必須ではありません。AS 句が指定されている場合は、部分的にエス
ケープされた別名のフォームが、タグ名として使用されます。式が NULL と評価
された場合、その式に対して要素は作成されません。
次の例は、各従業員の Emp 要素を生成します。name 属性およびその従業員の業
務開始日と部門がコンテンツとして持つ要素を含みます。
SELECT XMLELEMENT("Emp", XMLATTRIBUTES (e.fname | |' '| |
e.lname AS "name"),
XMLForest (e.hire, e.department AS "department"))
AS "result"
FROM employees e;
この問合せで、次の XML が作成されます。
result
---
<Emp name="John Smith">
<HIRE>24-MAY-00</HIRE>
<department>Accounting</department>
</Emp>
<Emp name="Mary Martin">
<HIRE>FEB-01-96</HIRE>
<department>Shipping</department>
</Emp>
2 rows selected.
XMLConcat()関数
XMLConcat()関数を使用すると、渡されたすべての引数が連結され、XML フラ
グメントが作成されます。XMLConcat()構文には次の 2 つの形式があります。
• 1 つ目の形式は、XMLSequenceType を取ることによって、ドキュメント・フ
ラグメントを含む XMLType を生成します。この形式は、XMLType の VARRAY
で、VARRAY の全要素が連結されたシングル XMLType インスタンスを返し
ます。この形式は、XMLType リストをシングル・インスタンスに連結する場
合に有効です。
• 2 つ目の形式は、任意の数の XMLType 値を取って連結します。値の 1 つが
NULL の場合、その値は無視されます。すべての値が NULL の場合、結果は
NULL になります。この形式は、任意の数の XMLType インスタンスを同じ行
の中で連結する際に使用されます。XMLAgg()は、複数行にまたがる XMLType
インスタンスの連結に使用できます。
次の例は、XMLConcat()が、XMLSequenceType から連結された XMLTypes を
返す方法を示します。
SELECT XMLConcat(XMLSequenceType (
xmltype('<PartNo>1236</PartNo>'),
xmltype('<PartName>Widget</PartName>'),
xmltype('<PartPrice>29.99</PartPrice>'))).getClobVal()
AS
"result"
FROM
dual;
このコードは次の形式の 1 つのフラグメントを返します。
result
---
<PartNo>1236</PartNo>
<PartName>Widget</PartName>
<PartPrice>29.99</PartPrice>
1 row selected.
XMLAgg()関数
XMLAgg()は集計関数で、XML 要素のコレクションから XML 要素のフォレスト
を作成します。XMLConcat()では、NULL の引数はすべて結果から削除されます。
この関数は、複数行にまたがる XMLType インスタンスの連結に使用できます。こ
の関数を ORDER BY 句とともに使用することで、集計される XML 値を配列でき
ます。
XMLAgg()は集計関数であるため、グループごとに
XML の集計結果を出します。
問合せの中に group by 指定がない場合は、問合せのすべての行に対して、単一
の XML 集計結果を返します。
次の例は、Employee 要素を含む Department 要素を生成する方法を示します。
要素コンテンツには、従業員のジョブ ID と姓を含みます。この例でも、名前(性)
順に部門の従業員 XML 要素が配列されています。
SELECT
XMLELEMENT("Department",XMLAGG(XMLELEMENT("Employee",
e.job||' '||e.ename) ORDER BY e.ename))
AS
"Dept_list"
FROM scott.emp e
WHERE e.deptno = 10;
Dept_list
---
<Department>
<Employee>MANAGER
CLARK</Employee>
<Employee>PRESIDENT
KING</Employee>
<Employee>CLERK
MILLER</Employee>
</Department>
1 row selected.
XMLAgg()は行を集計するため、結果は単一の行になります。GROUP BY 句を使
用して、返された一連の行を複数のグループに分けることができます。
SELECT XMLELEMENT("Department",
XMLAttributes(deptno AS "deptno"), XMLAgg(
xMLElement("Employee", e.job||' '||e.ename)))
AS
"Dept_list"
FROM scott.emp e
GROUP BY e.deptno;
Dept_list
---
<Department deptno="10">
<Employee>MANAGER
CLARK</Employee>
<Employee>PRESIDENT
KING</Employee>
<Employee>CLERK
MILLER</Employee>
</Department>
<Department deptno="20">
<Employee>CLERK
SMITH</Employee>
<Employee>ANALYST
FORD</Employee>
<Employee>CLERK
ADAMS</Employee>
<Employee>ANALYST
SCOTT</Employee>
<Employee>MANAGER
JONES</Employee>
</Department>
<Department deptno="30">
<Employee>SALESMAN
ALLEN</Employee>
<Employee>MANAGER
BLAKE</Employee>
<Employee>SALESMAN
MARTIN</Employee>
<Employee>SALESMAN
TURNER</Employee>
<Employee>CLERK
JAMES</Employee>
<Employee>SALESMAN
WARD</Employee>
</Department>
3 rows selected.
XMLPI()関数
SQL/XML 関数 XMLPI()は、
XML 処理命令
(processing instruction)を含む XMLType
インスタンスを返します。次に例を示します。
SELECT XMLPI(NAME "OrderAnalysisComp", 'imported,
reconfigured, disassembled')
AS pi FROM DUAL;
結果は次のとおりです。
PI
---
<?OrderAnalysisComp imported, reconfigured,
disassembled?>
1 row selected.
XMLComment()関数
XML コメントの生成には、SQL 関数 XMLComment を使用します。関数
XMLComment は、XMLType インスタンスを返します。string-result が NULL
の場合、この関数は NULL を返します。
SELECT XMLComment('This is a comment') AS cmnt FROM
DUAL;
この問合せ結果は次のとおりです。
CMNT
---
<!--This is a comment-->
XMLRoot()関数
SQL/XML 関数 XMLRoot()を使用することで、VERSION プロパティや
TANDALONE プロパティ(任意)を
XML 宣言に追加できます。通常この機能は、
データ・モデルへの準拠を目的として使用されます。この関数は、XMLType イン
スタンスを返します。
次の例では、VERSION プロパティおよび STANDALONE プロパティを持つ XML
文書を生成します。
SELECT XMLRoot(XMLType('<poid>143598</poid>'), VERSION
'1.0', STANDALONE YES)
AS xmlroot FROM DUAL;
結果は次のとおりです。
XMLROOT
---
<?xml version="1.0" standalone="yes"?>
<poid>143598</poid>
1 row selected.
XMLSerialize()関数
SQL/XML 関数 XMLSeria1ize()は、XML データの文字列または LOB 表現を取
得するときに使用できます。この関数による XML 値文字列の生成例を次に示し
ます。
SELECT XMLSerialize(DOCUMENT
XMLType('<poid>143598</poid>') AS CLOB)
AS xmlserialize_doc FROM DUAL;
結果は次のとおりです。
XMLSERIALIZE_DOC
---
<poid>143598</poid>
XMLParse()関数
SQL/XML 関数 XMLParse()は、XML データを含む文字列を解析し、対応する
XMLType 値の生成に使用できます。
WELLFORMED キーワードは、SQL/XML 標準に基づく Oracle XML DB 拡張機能で
す。WELLFORMED を指定すると、パーサーに XML 値式引数が整形式であること
が通知されます。WELLFORMED が指定されると、Oracle XML DB は、XML 値が
整形式であるかどうかのチェックを行いません。
XMLParse()関数の使用例を次に示します。
SELECT XMLParse(CONTENT
'124
<purchaseOrder
poNo="12435">
<customerName> Acme Enterprises</customerName>
<itemNo>32987457</itemNo>
</purchaseOrder>'
WELLFORMED)
AS po FROM DUAL d;
結果は次のとおりです。
PO
---
124 <purchaseOrder poNo="12435">
<customerName>Acme Enterprises</customerName>
<itemNo>32987457</itemNo>
</purchaseOrder>
XMLSequence()関数
XMLSequence()は、XMLType シーケンスを返します。この関数は
XMLSequenceType を返します。
これは XMLType インスタンスの VARRAY です。
この関数はコレクションを返すため、SQL 問合せの FROM 句で使用できます。
XMLSequence()は、
XMLTypes を含む
SQL 問合せを効果的に行うのに必要です。
この関数は、SQL/XML 標準関数に基づく Oracle データベースの拡張機能でもあ
ります。
XMLSequence()関数には次の
2 つの形式があります。
• 1 つ目の形式は、XMLType インスタンスを入力し、最上位のノードの
VARRAY を 1 つ返します。この形式は、XML フラグメントを複数行に分割
する際に使用できます。
• 2 つ目の形式は、XMLFormat オブジェクトのオプションのインスタンスを持
つ REFCURSOR 引数を入力として受け取り、カーソルの各行に対応する
XMLType の VARRAY を返します。この形式は、任意の SQL 問合せから
XMLType インスタンスの構成に使用できます。
次に 1 つ目の形式に相当する例を示します。次の従業員情報を含む XML 文書が
あると仮定します。
<EMPLOYEES>
<EMP>
<EMPNO>112</EMPNO>
<EMPNAME>Joe</EMPNAME>
<SALARY>50000</SALARY>
</EMP>
<EMP>
<EMPNO>217</EMPNO>
<EMPNAME>Jane</EMPNAME>
<SALARY>60000</SALARY>
</EMP>
<EMP>
<EMPNO>412</EMPNO>
<EMPNAME>Jack</EMPNAME>
<SALARY>40000</SALARY>
</EMP>
</EMPLOYEES>
次の構文で年収 50,000 ドル以上の従業員のみを含む新規の XML 文書を作成しま
す。
SELECT SYS_XMLAGG(value(e), xmlformat('EMPLOYEES'))
FROM TABLE(XMLSequence(Extract(doc, '/EMPLOYEES/EMP'))) e
WHERE EXTRACTVALUE(value(e), '/EMP/SALARY') >= 50000;
このコードは、次の XML 文書を返します。
<EMPLOYEES>
<EMP>
<EMPNO>112</EMPNO>
<EMPNAME>Joe</EMPNAME>
<SALARY>50000</SALARY>
</EMP>
<EMP>
<EMPNO>217</EMPNO>
<EMPNAME>Jane</EMPNAME>
<SALARY>60000</SALARY>
</EMP>
</EMPLOYEES>
2 rows selected.
すべての従業員を抽出するために extract()がどのように使用されたか注意し
てください。
• Extract()は EMP 要素のフラグメントを返します。
• XMLSequence()は、最上位の要素コレクションから XMLType インスタンス
に作成してそれを返します。
• コレクションから表を作成し、問合せの FROM 句内で使用するために、TABLE
関数が使用されています。
次に、XMLSequence()の 2 つ目の形式に相当する例を示します。この例では、
カーソル式の行ごとに XML 文書が作成され、XMLSequenceType として値が返
されています。XMLFormat オブジェクトは、作成される XML 文書の構造を変更
する場合に使用できます。次に例を示します。
SELECT value(e).getClobVal() AS "xmltype"
FROM TABLE(XMLSequence(Cursor(SELECT * FROM scott.emp))) e;
このコードは、次の XML を返します。
Xmltype
---
<ROW>
<EMPNO>7369</EMPNO>
<ENAME>SMITH</ENAME>
<JOB>CLERK</JOB>
<MGR>7902</MGR>
<HIREDATE>17-DEC-80</HIREDATE>
<SAL>800</SAL>
<DEPTNO>20</DEPTNO>
</ROW>
<ROW>
<EMPNO>7499</EMPNO>
<ENAME>ALLEN</ENAME>
<JOB>SALESMAN</JOB>
<MGR>7698</MGR>
<HIREDATE>20-FEB-81</HIREDATE>
<SAL>1600</SAL>
<DEPTNO>30</DEPTNO>
</ROW>
...
14 rows selected.
行ごとに使用されている ROW タグは、XMLFormat オブジェクトで変更できます。
XMLColAttVal()関数
XMLColAttval()関数は、渡される引数の値を含む
XML column 要素のフォレ
ストを生成します。この関数は、SQL/XML 標準関数の Oracle データベースの拡
張機能でもあります。
引数の名前は、column 要素の name 属性に入力されます。XMLForest()関数と
は異なり、要素名は決してエスケープされません。そのため、この関数は、SQL
列およびエスケープされた名前を持たない値のトランスポートに使用できます。
次の例は、各従業員の Emp 要素を生成する方法を示したものです。name 属性お
よびその従業員の業務開始日と部門がコンテンツとして含まれています。
SELECT XMLELEMENT("Emp",
XMLATTRIBUTES(e.fname ||' '||e.lname AS "name" ),
XMLCOLATTVAL(e.hire, e.department AS department"))
AS
"result"
この問合せで、次の XML 結果が作成されます。
result
---
<Emp name="John Smith">
<column
name="HIRE">24-MAY-00</column>
<column
name="department">Accounting</column>
</Emp>
<Emp name="Mary Martin">
<column
name="HIRE">01-FEB-96</column>
<column
name="department">Shipping</column>
</Emp>
2 rows selected.
各 XMLColAttVal()引数と関連付けられた名前は属性値の移入に使用されるた
め、完全にエスケープされたマッピングも一部エスケープされたマッピングも使
用されません。
SQL/XML 関数に基づいた XMLType ビュー
リレーショナル・データから XML を生成するための強力なメカニズムとして、
他には XMLType ビューがあります。XMLType ビューは、Oracle XML DB で提供
される充実した SQL/XML 生成関数セットを活用して作成できます。これにより、
下位層のリレーショナル表から、物理的にリレーショナル・レガシー・データを
XML に移行することなく直接 XMLType ビューを構成できます。
XMLType ビューの各行は、XMLType インスタンスに対応しています。ビュー内
の各行を一意に識別するオブジェクト識別子は、XMLType 結果に適用される
getNumberVal()を使用した extract などの関数で作成できます。問合せに
XMLType ビューを使用することで、アプリケーション固有のニーズに合わせた
XML データを返すことができます。
次の例では、多数の SQL/XML 生成関数を使用することで内部 SELECT によって
複雑な問合せから XMLType ビューを作成します。次の関数が使用されます。
XMLElement()、XMLAttributes()、XMLConcat()、XMLRoot()、XMLPI()、
XMLComment()
create or replace view DEPARTMENT_XML of xmltype
with object id
(
substr(extractValue(sys_nc_rowinfo$,'/Department/Name'),1,30)
)
as
select xmlroot(xmlConcat(xm1PI("pi", 'valid, well-formed'),
xmlElement
(
"Department",
xmlAttributes( d.DEPARTMENT_ID as "DepartmentId"),
xmlElement("Name",
d.DEPARTMENT_NAME),
xmlElement
(
xmlForest
(
STREET_ADDRESS
as
"Address",
CITY
as
"City",
STATE_PROVINCE
as
"State",
POSTAL_CODE
as
"Zip",
COUNTRY_NAME
as
"Country"
)
),
xmlElement
(
"EmployeeList",
xmlcomment('Generated from an inner select call'),
(
select
xmlAgg
(
xmlElement
(
"Employee",
xmlAttributes
(
e.EMPLOYEE_ID
as
"employeeNumber"
),
xmlForest
(
e.FIRST_NAME
as
"FirstName",
e.LAST_NAME
as
"LastName",
e.EMAIL
as
"EmailAddress",
e.PHONE_NUMBER
as
"Telephone",
e.HIRE_DATE
as
"StartDate",
j.JOB_TITLE
as
"JobTitle",
e.SALARY
as
"Salary",
m.FIRST_NAME
|| ' ' ||m.LAST_NAME
as
"Manager"
),
xmlElement
(
"Commission",
e.COMMISSION_PCT
)
)
)
from HR.EMPLOYEES e, HR.EMPLOYEES m, HR.JOBS j
where e.DEPARTMENT_ID = d.DEPARTMENT_ID
and
j.JOB_ID
=
e.JOB_ID
and
m.EMPLOYEE_ID
=
e.MANAGER_ID
)
)
)
), VERSION '1.0') as XML
from HR.DEPARTMENTS d, HR.COUNTRIES c, HR.LOCATIONS 1
where d.LOCATION_ID = l.LOCATION_ID
and l.COUNTRY_ID = c.COUNTRY_ID
SQL> select object_value from department_xml;
OBJECT_VALUE
---
<?xml version="1.0"?>
<?pi valid, well-formed?>
<Department DepartmentId="10">
<Name>Administration</Name>
<Location>
<Address>2004
Charade
Rd</Address>
<City>Seattle</City>
<State>Washington</State>
<Zip>98199</Zip>
<Country>United States of America</Country>
<EmployeeList>
<!--Generated from an inner select call-->
<Employee
employeeNumber="200">
<FirstName>Jennifer</FirstName>
<LastName>Whalen</LastName>
<EmailAddress>JWHALEN</EmailAddress>
<Telephone>515.123.4444</Telephone>
<StartDate>17-SEP-87</StartDate>
<JobTitle>Administration
Assistant</JobTitle>
<Salary>4400</Salary>
<Manager>Neena
Kochhar</Manager>
<Commission/>
</Employee>
</EmployeeList>
</Department>
<?xml version="1.0"?>
<?pi valid, well-formed?>
<Department DepartmentId="20">
<Name>Marketing</Name>
<Location>
<Address>147
Spadina
Ave</Address>
<City>Toronto</City>
<State>Ontario</State>
<Zip>M5V
2L7</Zip>
<Country>Canada</Country>
</Location>
<EmployeeList>
<!--Generated from an inner select call-->
<Employee
employeeNumber="201">
<FirstName>Michael</FirstName>
<LastName>Hartstein</LastName>
<EmailAddress>MHARTSTE</EmailAddress>
<Telephone>515.123.5555</Telephone>
<StartDate>17-FEB-96</StartDate>
<JobTitle>Marketing
Manager</JobTitle>
<Salary>13000</Salary>
<Manager>Steven
King</Manager>
<Commission/>
</Employee>
<Employee
employeeNumber="202">
<FirstName>Pat</FirstName>
<LastName>Fay</LastName>
<EmailAddress>PFAY</EmailAddress>
<Telephone>603.123.6666</Telephone>
<StartDate>17-AUG-97</StartDate>
<JobTitle>Marketing
Representative</JobTitle>
<Salary>6000</Salary>
<Manager>Michael
Hartstein</Manager>
<Commission/>
</Employee>
</EmployeeList>
</Department>
...
27 rows selected.
他の問合せ条件でこの XMLType ビューを問い合せて、XML 生成を微調整できま
す。引き続き同じ例を使用して、人事管理部門に関する情報のみを取得します。
SQL> select value(d).extract('/*') from DEPARTMENT_XML d
where
existsNode(object_value,
'/Department[Name=" Human Resources "]') = 1
/
VALUE(D).EXTRACT('/*')
---
<Department DepartmentId="40">
<Name>Human
Resources</Name>
<Location>
<Address>8204
Arthur
St</Address>
<City>London</City>
<Country>United
Kingdom</Country>
</Location>
<EmployeeList>
<!--Generated from an inner select call-->
<Employee
employeeNumber="203">
<FirstName>Susan</FirstName>
<LastName>Mavris</LastName>
<EmailAddress>SMAVRIS</EmailAddress>
<Telephone>515.123.7777</Telephone>
<StartDate>
1994-06-07</StartDate>
<JobTitle>Human
Resources
Representative</JobTitle>
<Salary>6500</Salary>
<Manager>Neena
Kochhar</Manager>
<Commission/>
</Employee>
</EmployeeList>
</Department>
結論
リレーショナル・データからの XML 生成は、XML データの公開および交換を行
う XML アプリケーションにおいて重要な役割を担っています。初期の XSU から、
その後の DBMS_XMLGEN パッケージ、最終的に SQL/XML 関数へと、Oracle デー
タベースが長年にわたりどのように進化を続け、業界標準に基づいたより効果的
で高度な XML 生成機能を提供してきたかを説明しました。新規の XML アプリ
ケーションでの XML 生成には、高パフォーマンスでスケーラブルかつ業界標準
に準拠した SQL/XML 関数を使用することが最良の選択です。XML の採用が急速
に主流となりつつあることから、オラクル社は将来のリリースで、SQL/XML 標準
に準拠した XML 生成のための新機能を導入する予定です。
新規の XML アプリケーションでの XML 生成には、高パフォーマンスでスケーラ ブルかつ業界標準に準拠した SQL/XML 関数を使用することが最良の選択です。Oracle Database 10g リリース 2(10.2)XML 生成のマスター 2005 年 9 月 著書: Geoff Lee Oracle Corporation World Headquarters 500 Oracle Parkway Redwood Shores, CA 94065 U.S.A. 海外からのお問合せ窓口: 電話: +1.650.506.7000 ファックス: +1.650.506.7200 www.oracle.com オラクル社は、インターネット上での活動を強化するソフトウェアを提供します。 Oracle はオラクル社の登録商標です。 このガイドで使用されているさまざまな製品名およびサービス名には、オラクル社の商標が含まれています。 その他のすべての製品名およびサービス名は、各社の商標です。 無断転載を禁ず この文書はあくまで参考資料であり、掲載されている情報は予告なしに変更されることがあります。 オラクル社は、本ドキュメントの無謬性を保証しません。また、本ドキュメントは、法律で明示的または暗黙的に記載されているかどうかに関係なく、商 品性または特定の目的に対する適合性に関する暗黙の保証や条件を含む一切の保証または条件に制約されません。オラクル社は、本書の内容に関していか なる保証もいたしません。また、本書により、契約上の直接的および間接的義務も発生しません。本書は、事前の書面による許可を得ることなく、電子的 または機械的に、いかなる形態または手段によっても複製または伝送することはできません。
Oracle は米国 Oracle Corporation および関連会社の登録商標です。他の製品名は、それぞれの所有者の商標です。 Copyright © 2005 Oracle Corporation