Oracle® XML DB

開発者ガイド

11gリリース2 (11.2)

B70200-03(原本部品番号:E23094-04)

2014年2月

このマニュアルでは、Oracle XML DBについて説明します。Oracle Database内のXMLデータの格納、生成、アクセス、検索、検証、変換、拡張および索引付けに関するガイドラインと例が記載されています。

Oracle XML DB開発者ガイド, 11gリリース2 (11.2)

B70200-03

Copyright © 2002, 2014, Oracle and/or its affiliates.All rights reserved.

原本著者:  Drew Adams

原本協力者:  Nipun Agarwal、Abhay Agrawal、Omar Alonso、David Anniss、Sandeepan Banerjee、Mark Bauer、Ravinder Booreddy、Stephen Buxton、Yuen Chan、Sivasankaran Chandrasekar、Vincent Chao、Ravindranath Chennoju、Dan Chiba、Mark Drake、Fei Ge、Janis Greenberg、Wenyun He、Shelley Higgins、Thuvan Hoang、Sam Idicula、Namit Jain、Neema Jalali、Deepti Kamal、Bhushan Khaladkar、Viswanathan Krishnamurthy、Muralidhar Krishnaprasad、Geoff Lee、Wesley Lin、Annie Liu、Anand Manikutty、Jack Melnick、Nicolas Montoya、Steve Muench、Chuck Murray、Ravi Murthy、Eric Paapanen、Syam Pannala、John Russell、Eric Sedlar、Vipul Shah、Cathy Shea、Asha Tarachandani、Tarvinder Singh、Simon Slack、Muralidhar Subramanian、Asha Tarachandani、Priya Vennapusa、James Warner

原本協力者:  Reema Al-Shaikh、Harish Akali、Vikas Arora、Deanna Bradshaw、Paul Brandenstein、Lisa Eldridge、Craig Foch、Wei Hu、Reema Koo、Susan Kotsovolos、Sonia Kumar、Roza Leyderman、Zhen Hua Liu、Diana Lorentz、Yasuhiro Matsuda、Valarie Moore、Bhagat Nainani、Visar Nimani、Sunitha Patel、Denis Raphaely、Rebecca Reitmeyer、Ronen Wolf

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs.No other rights are granted to the U.S. Government.

このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

OracleおよびJavaはOracle Corporationおよびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても一切の責任を負いかねます。

目次

例一覧

図一覧

表一覧

タイトルおよび著作権情報

はじめに

- 対象読者

- ドキュメントのアクセシビリティについて

- 関連ドキュメント

- 表記規則

- コード例

- 構文の説明

Oracle XML DBの新機能

- Oracle Database 11gリリース2 (11.2.0.3)で非推奨となったOracle XML DB構造体

- Oracle Database 11gリリース2 (11.2.0.3)でのOracle XML DBのその他の変更

- Oracle Database 11gリリース2 (11.2.0.2)でのOracle XML DBの新機能

- Oracle Database 11gリリース2 (11.2.0.2)で非推奨となったOracle XML DB構造体

- Oracle Database 11gリリース2 (11.2.0.1)でのOracle XML DBの新機能

- Oracle Database 11gリリース2 (11.2.0.1)で非推奨となったOracle XML DB構造体

- Oracle Database 11gリリース1 (11.1)でのOracle XML DBの新機能

第I部 Oracle XML DBの基礎

1 Oracle XML DBの概要

- Oracle XML DBの概要

- Oracle XML DBのアーキテクチャ

- XML用のAPI

- XML関連のカタログ・ビュー

- Oracle XML DBリポジトリの概要

- XMLサービス

- ビューRESOURCE_VIEWおよびPATH_VIEW

- Oracle XML DBリポジトリのアーキテクチャ

- ファイルおよびフォルダ

- Oracle XML DBプロトコルのアーキテクチャ

- Oracle XML DBへのプログラム・アクセス(Java、PL/SQLおよびC)

- Oracle XML DBの機能

- XMLTypeデータ型

- XML Schemaに準拠したXMLType表および列

- XMLType API

- XML Schemaのサポート

- XMLType記憶域モデル

- XMLとSQLの双対性

- SQL/XML標準関数

- XQuery式とXPath式の自動リライト

- Oracle XML DBによるXPath式の評価方法

- XQuery式とXPath式を含むSQLコードのリライト

- XPathのリライトが行われる場合

- XPathリライト処理の概要

- Oracle XML DBのメリット

- データとコンテンツの統合

- データベース機能の使用

- XML機能の活用

- 複雑なXML文書の効率的な格納および取出し

- データがXMLでない場合のXMLTypeビューの使用方法

- Oracle Textを使用したXMLデータの検索

- Oracle Streamsアドバンスト・キューイングを使用したメッセージ・アプリケーションの構築

- Oracle XML DBでサポートされている標準

- Oracle XML DBの技術サポート

- このマニュアルで使用するOracle XML DBの例

- 詳細なOracle XML DBの事例およびデモ

2 Oracle XML DBを使用する前に

- Oracle XML DBのインストール

- Oracle XML DBのユースケース

- Oracle XML DBのアプリケーション設計に関する考慮事項

- データの構造

- Oracle XML DBリポジトリへのアクセス

- アプリケーション言語

- 処理

- メッセージ機能

- 記憶域

- Oracle XML DBのパフォーマンス

- XML記憶域の要件

- XMLのメモリー管理

- XOBを使用した、XML Schemaに基づく文書に関するメモリー・オーバーヘッドの削減

- XOBによる遅延ロードされた仮想DOMの使用

- XML解析の最適化

- ノード検索の最適化

- XML Schemaの最適化

- キャッシュ済のXML Schemaを使用したロード・バランシング

- ネイティブでないコードによるボトルネックの低減

- Javaでの型変換によるボトルネックの低減

3 Oracle XML DBの使用

- XMLデータをXMLTypeとして格納

- XMLTypeの概要

- XMLTypeデータ型およびAPIのメリット

- XMLType表および列の作成

- 仮想列を使用したバイナリXMLデータのパーティション化または制約

- Oracle XML DBへのXMLコンテンツのロード

- SQLまたはPL/SQLを使用したXMLコンテンツのロード

- Javaを使用したXMLコンテンツのロード

- Cを使用したXMLコンテンツのロード

- 小規模なXML文書を含む大規模なXMLファイルのロード

- SQL*Loaderを使用した大規模なXMLファイルのロード

- DBMS_XDBを使用したリポジトリへのXML文書のロード

- プロトコルを使用したリポジトリへの文書のロード

- XML文書のキャラクタ・セット

- XMLエンコーディング宣言

- XML文書をデータベースにロードするときのキャラクタ・セットの決定

- データベースからXML文書を取り出すときのキャラクタ・セットの決定

- W3CのXML Schema勧告の概要

- XMLインスタンス・ドキュメント

- XML Schema for Schemas

- XML Schemaの編集

- XML Schemaの機能

- 発注書XML Schemaのテキスト表現

- 発注書XML Schemaのグラフィカル表現

- Oracle XML DBでのXML Schemaの使用

- XML SchemaをOracle XML DBとともに使用する理由

- XML Schemaを使用したインスタンス・ドキュメントの検証

- ビジネス・ルールまたは書式準拠に対するインスタンス・ドキュメントの制約

- データベースへのXMLTypeコンテンツの格納方法の定義

- XML文書の構造化記憶域

- ネーミング、マッピングおよび記憶域を制御するためのXML Schemaの注釈付け

- オブジェクト・リレーショナルなXMLType記憶域の場合のコレクション格納方法の制御

- Oracle XML DB名前空間の宣言

- Oracle XML DBへのXML Schemaの登録

- XML Schema登録時のSQL型および表の作成

- 大規模なXML Schemaの操作

- グローバル要素の操作

- XML Schemaに基づくXMLType列および表の作成

- デフォルト表

- XML Schemaインスタンス・ドキュメントの識別

- 属性noNamespaceSchemaLocationおよびschemaLocation

- 複数の名前空間の使用

- データベースを使用したXMLデータ整合性の規定

- XML Schemaの部分検証と全体検証の比較

- 部分検証

- 全体検証

- SQL制約を使用した参照整合性の規定

- Oracle XML DBを使用したXMLコンテンツに対するDML操作

- XPathおよびOracle XML

- Oracle XML DBに格納されたXMLコンテンツの問合せ

- XML文書PurchaseOrder

- 疑似列OBJECT_VALUEを使用したXML文書のコンテンツの取出し

- XMLQUERYを使用したXML文書のフラグメントまたはノードへのアクセス

- XMLCASTおよびXMLQUERYを使用したテキスト・ノードおよび属性値へのアクセス

- XMLEXISTS、XMLCastおよびXMLQueryを使用したXML文書の検索

- XMLTABLEを使用したXMLTypeフラグメントでのSQL操作の実行

- リレーショナル・ビューを使用したOracle XML DB内のXMLデータへのアクセス

- 単一レベルのXMLデータの分割

- 複数レベルのXMLデータの分割

- リレーショナル・データとしてのXMLコンテンツの問合せ

- Oracle XML DBに格納されたXMLコンテンツの更新

- XML Schemaに基づくXML文書および基づかないXML文書の更新

- Oracle XML DBでの名前空間のサポート

- Oracle XML DBでのXMLTypeメソッドおよびSQL関数の処理

- リレーショナル・データからのXMLデータの生成

- SQL/XML関数を使用した、リレーショナル・データからのXMLデータの生成

- DBURITYPEを使用した、リレーショナル・データからのXMLデータの生成

- XSL変換とOracle XML DB

- Oracle XML DBリポジトリの使用

- Oracle XML DBリポジトリのインストールおよび削除

- Oracle XML DBで提供される名前レベル・ロック

- プロトコルまたはSQLを使用した、リポジトリのコンテンツへのアクセスおよび処理

- 標準プロトコルを使用したデータベース・コンテンツの格納と取出し

- FTPを使用したOracle XML DBへのコンテンツのアップロード

- プログラムを使用したOracle XML DBリポジトリへのアクセス

- リポジトリ内のXMLコンテンツのアクセスおよび更新

- SQLを使用したXML文書へのアクセス

- RESOURCE_VIEWとPATH_VIEWを介して公開されるリポジトリのコンテンツ

- EXISTS_PATHとUNDER_PATHを使用した、WHERE句へのパスベースの述語の追加

- リポジトリへの非XML文書の格納も可能

- フォルダと文書の作成、削除、名前変更、移動などを実行するためのPL/SQLパッケージ

- SQLを使用した文書のコンテンツへのアクセス

- XML Schemaに基づく文書のコンテンツへのアクセス

- 結合でXMLRef要素を使用した、リソース・コンテンツへのアクセス

- リポジトリに格納された文書のコンテンツの更新

- プロトコルを使用したリポジトリのコンテンツの更新

- SQLを使用したリポジトリのコンテンツの更新

- リポジトリ内のXML Schemaに基づく文書の更新

- リポジトリ・データへのアクセスの制御

- Oracle XML DBのトランザクション・セマンティクス

- メタデータとフォルダ階層の問合せ

- RESOURCE_VIEWおよびPATH_VIEW

- RESOURCE_VIEWおよびPATH_VIEW内のリソースの問合せ

- Oracle XML DBの階層リポジトリ索引

- 文書をリポジトリに格納する方法

- ブラウザを使用した、リレーショナル・データのXMLとしての表示

- DBUri SERVLETを使用した、ブラウザからの表またはビューへのアクセス

- DBUriサーブレットを使用したXSL変換

第II部 Oracle XML DBからのXMLデータの格納および取出し

4 XMLTypeの操作

- XMLデータの選択および問合せ

- XPath式を使用したXML文書の検索

- SQL/XML関数XMLExistsおよびXMLCastを使用したXMLTypeデータの問合せ

- XMLEXISTS SQL/XML関数

- XMLCAST SQL/XML関数

- SQL/XML関数を使用したXMLデータの問合せの例

- XMLデータの更新

- XML文書全体の更新

- XMLデータを更新するためのSQL関数

- SQL関数を使用したXML要素の挿入

- UPDATEXML SQL関数

- UPDATEXMLおよびNULL値

- 同じXMLノードの複数回の更新

- UPDATEXML使用時のDOM再現性の保持

- XMLデータを更新するOracle SQL関数の最適化

- XMLデータを変更するOracle SQL関数を使用した、XMLビューの作成

- INSERTCHILDXML SQL関数

- INSERTCHILDXMLBEFORE SQL関数

- INSERTCHILDXMLAFTER SQL関数

- INSERTXMLBEFORE SQL関数

- INSERTXMLAFTER SQL関数

- APPENDCHILDXML SQL関数

- DELETEXML SQL関数

5 Oracle XML DBでのXQueryの使用

- Oracle XML DBにおけるXQueryの概要

- XQuery言語の概要

- シーケンスに基づく関数言語

- XQuery式

- FLWOR式

- SQL/XML関数XMLQUERYおよびXMLTABLE

- Oracle XML DBのXMLQUERY SQL/XML関数

- Oracle XML DBのXMLTABLE SQL/XML関数

- XQueryの用途

- 事前定義の名前空間と接頭辞

- URIスキームoradb: XQueryを使用した表またはビュー・データの問合せ

- Oracle XQuery拡張関数

- ora:contains XQuery関数

- ora:matches XQuery関数

- ora:replace XQuery関数

- ora:sqrt XQuery関数

- ora:tokenize XQuery関数

- Oracle XQuery拡張式プラグマ

- XMLQUERYおよびXMLTABLEの例

- XQueryとシーケンス

- XQueryを使用したOracle XML DBリポジトリ内でのXMLデータの問合せ

- XQueryを使用した表またはビュー・データの問合せ

- XQueryのXMLTypeデータとの使用

- XQueryでの名前空間の使用

- XQuery用のパフォーマンス・チューニング

- ルールベースおよびコストベースのXQueryの最適化

- リレーショナル・データに関するXQueryの最適化

- XML SchemaベースのXMLTypeデータに関するXQueryの最適化

- XQueryの最適化の診断: XMLOptimizationCheck

- リポジトリのデータに対するfn:docおよびfn:collectionのパフォーマンスの向上

- fn:docとfn:collectionにかわるequals_pathおよびunder_pathの使用

- Oracle XQueryプラグマora:defaultTableの使用

- Oracle XML DBにおけるXQuery静的型チェック

- SQL*Plus XQUERYコマンド

- XQueryの、PL/SQL、JDBC、およびODP.NETとの使用

- Oracle XML DBでのXQueryサポート

- XQueryとSQLのサポート

- XQuery標準で指定された実装の選択肢

- Oracle XML DBでサポートされていないXQuery機能

- XQueryのオプション機能

- XQueryの関数と演算子のサポート

- XQuery関数fn:doc、fn:collectionおよびfn:doc-available

6 XMLTypeデータの索引付け

- 索引に関連するOracle XML DBのタスク

- XMLTypeデータの索引付けの概要

- XMLIndexによるXMLデータのファイングレイン構造の対処

- Oracle Text索引

- 最適化による、使用する適切な索引の選択

- XMLデータの非推奨の索引

- ファンクション索引

- CTXXPath索引

- オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け

- 繰り返し使用しないtext()ノードまたは属性値の索引付け

- 繰り返し使用する(コレクション)要素の索引付け

- XMLIndex

- XMLIndexの利点

- 構造化XMLIndexコンポーネントと非構造化XMLIndexコンポーネント

- XMLIndex構造化コンポーネント

- 透過的な索引コンテンツ表の無視

- XMLIndex構造化コンポーネントのデータ型に関する考慮事項

- XMLIndex非構造化コンポーネント

- 表パスは透過的であり、無視

- XMLIndexパス表のVALUE列

- VALUE列に対する2次索引

- XMLIndex非構造化コンポーネントによって索引付けされないXPath式

- XMLIndex索引の作成、削除、変更、および検証

- 非構造化コンポーネントを含むXMLIndexの使用

- XMLIndexパス表に対する追加の2次索引の作成

- 構造化コンポーネントを含むXMLIndexの使用

- XMLIndexが使用されるかどうかを判別する方法

- XMLIndexの使用の無効化

- XMLIndexパスのサブセット化: 索引付けするパスの指定

- XMLIndexパスのサブセット化の例

- XMLIndexパスのサブセット化のルール

- 非構造化コンポーネントを含むXMLIndexを使用するためのガイドライン

- 構造化コンポーネントを含むXMLIndexの使用のガイドライン

- XMLIndexのパーティション化および並列度

- XMLIndex索引の非同期(遅延)メンテナンス

- コストベース・オプティマイザに対するXMLIndexオブジェクトの統計の収集

- XMLIndexに関連するデータ・ディクショナリの静的なパブリック・ビュー

- CREATE INDEXおよびALTER INDEXのPARAMETERS句

- XMLIndexの登録済パラメータ句の使用

- CREATE INDEXおよびALTER INDEXのPARAMETERS句の構文

- XMLIndex_parameters_clauseの使用

- XMLIndex_parameterの使用

- PATHS句の使用

- create_index_paths_clauseおよびalter_index_paths_clauseの使用

- pikey_clause、path_id_clauseおよびorder_key_clauseの使用

- value_clauseの使用

- async_clauseの使用

- groups_clauseおよびalter_index_group_clauseの使用

- XMLIndex_xmltable_clauseの使用

- column_clauseの使用

- XMLデータに対するOracle Text索引

- Oracle Text索引の作成および使用

- 他の索引に依存しないOracle Text索引

7 XML Schemaの格納と問合せ: 基本

- XML SchemaおよびOracle XML DBの概要

- Oracle XML DBでのXML Schemaの使用

- XML Schemaを使用する理由

- Oracle XML DBにおけるDTDのサポート

- インラインDTDの定義

- 外部DTDの定義

- DBMS_XMLSCHEMAを使用したXML Schemaの管理

- Oracle XML DBへのXML Schemaの登録

- XML Schemaを登録する前の文書の削除とリロード

- 格納とアクセスのインフラストラクチャ

- XML Schema登録の基本性質

- XML Schemaの管理および格納

- オブジェクト・リレーショナル形式で格納されたXMLデータのためのXML Schema登録のデバッグ

- 構造化記憶域に対してXML Schema登録時に作成されるSQLデータ型

- XML Schemaの登録時に作成されるデフォルト表

- XML Schemaの登録時に生成された内部構造体を使用しない

- 大/小文字が区別される生成名

- 登録されたXML Schemaに依存するデータベース・オブジェクト

- 登録されているすべてのXML Schemaのリスト

- XML Schemaの削除

- DBMS_XMLSCHEMA.DELETESCHEMAオプション

- XMLTypeのXML Schema関連メソッド

- ローカルXML SchemaおよびグローバルXML Schema

- ローカルXML Schema

- グローバルXML Schema

- DOM再現性

- DOM再現性の概要

- SYS_XDBPD$と構造化記憶域のDOM再現性

- XML変換

- 変換のためのXML SchemaとXMLインスタンス・ドキュメントの変更

- XML Schema内での変換可能な要素の指示

- XMLインスタンス・ドキュメント内での変換言語属性の指示

- XML文書を変換可能にする方法

- 変換済のドキュメントに対する操作

- XML Schemaに基づくXMLType表および列の作成

- XML Schemaに基づくデータのXMLType記憶域オプションの指定

- XML Schemaに基づくデータのバイナリXML記憶域

- XML Schemaに基づくデータの非構造化記憶域

- XML Schemaに基づくデータの構造化記憶域

- XMLType表および列に対するリレーショナル制約の指定

- OracleでのXML Schemaの注釈

- XMLスキーマ注釈の一般的な使用

- XML Schema注釈の例

- 使用できるOracle XML DBのXML Schema注釈

- 構造化記憶域に対するXML Schema注釈のガイドライン

- 未使用の最上位要素に不要な表作成の回避

- デフォルト表に対する独自の名前の提供

- 不要な場合のDOM再現性の無効化

- 順序が関係ない場合のUnordered Collection要素の使用

- タイムスタンプ・データ型を使用した時間関連要素の注釈

- 表および列のプロパティの追加

- 大規模コレクションの表外格納

- 登録されたXML Schemaの問合せによる注釈の取得

- XML Schemaデータ型のOracle XML DB記憶域へのマッピング

- XML Schemaデータ型のSQLデータ型へのマッピング

- XML Schemaデータ型のSQLへのマッピングの例

- XML Schema属性データ型のSQLへのマッピング

- 属性を宣言する際のXML Schema内のSQLType値のオーバーライド

- XML Schema要素データ型のSQLへのマッピング

- 要素を宣言する際のXML Schema内のSQLType値のオーバーライド

- SQLへのsimpleTypeのマッピング

- サポートされないNCHAR、NVARCHARおよびNCLOBのSQLType値

- simpleType: SQLのVARCHAR2またはCLOBへのXML文字列のマッピング

- タイムゾーンの操作

- SQLへのcomplexTypeのマッピング

- complexTypeのXML Schema宣言での属性の指定

8 構造化記憶域のXPathリライト

- 構造化記憶域のXPathリライトの概要

- リライトされるXPath式のサンプル

- 実行計画を使用したXPath問合せの分析および最適化

- ガイドライン: 実行計画内のXML関数に対する基礎となる表の検索

- ガイドライン: 実行計画で認識するためのデフォルト表の名前付け

- ガイドライン: 述語でターゲットとなっている列に対する索引の作成

- ガイドライン: Ordered Collection表に対する索引の作成

- ガイドライン: XMLOptimizationCheckを使用した、問合せがリライトされない理由の特定

9 XML Schemaの格納と問合せ: 高度

- DBMS_XMLSCHEMA.GENERATESCHEMAを使用したXML Schemaの生成

- 属性の親要素への一意制約の追加

- 表外に格納するための注釈属性SQLInLineのfalse設定

- 表外の表に対するXPathリライト

- 表外の表へのコレクションの格納

- オブジェクト・リレーショナル形式で格納されたXMLTypeの表および列のパーティション化

- XMLTypeデータのパーティション化の例

- パーティション・メンテナンス

- 完全修飾されたXML Schema URL

- ラージ・オブジェクト(LOB)へのXMLフラグメントのマッピング

- Oracle XML DBでのcomplexTypeの拡張および制限

- XML SchemaでのcomplexTypeの宣言: 継承の処理

- complexTypeのマッピング: simpleContentからオブジェクト型

- complexTypeのマッピング: anyおよびanyAttribute

- XML Schema: 循環依存の操作

- XML Schemaの循環依存のためのパラメータGenTablesのTRUE設定

- XML SchemaでのcomplexTypeの宣言: 循環の処理

- complexTypeによる自己参照の方法

- XML Schema間での循環参照

- 再帰的スキーマのサポート

- 一般的な表外の要素間でのdefaultTableの共有

- DOCIDが存在する場合の問合せのリライト

- DOCID列の作成の無効化

- コレクションでの大規模な文書のロードおよび取得

- xdbcoreパラメータ設定に関するガイドライン

10 XML Schemaの拡張

- XML Schemaの拡張の概要

- コピーに基づくスキーマの拡張の使用

- コピーに基づく拡張の使用例

- copyEvolveパラメータおよびエラー

- プロシージャCOPYEVOLVEの制限事項

- プロシージャCOPYEVOLVEの使用時のガイドライン

- 最上位要素名の変更

- デフォルト表以外の表のユーザー作成の仮想列

- XML Schemaとその依存が同時セッションで使用されないようにする方法

- プロシージャDBMS_XMLSCHEMA.COPYEVOLVEでのエラー発生時のロールバック

- 不十分な権限に起因するロールバックの失敗

- XML Schemaの拡張に必要な権限

- スタイルシートを使用した既存のXMLインスタンス・ドキュメントの更新

- プロシージャCOPYEVOLVEの使用時の例

- インプレースのXML Schemaの拡張の使用

- インプレースのXML Schemaの拡張の制限

- 下位互換性の制約

- インプレース拡張のその他の制限

- インプレースのXML Schema拡張でサポートされる操作

- インプレースのXML Schema拡張の使用時のガイドライン

- inPlaceEvolveパラメータ

- diffXMLパラメータのドキュメントの作成

- diffXMLの操作と例

11 XMLTypeデータの変換および検証

- XMLTypeインスタンスの変換

- SQL関数XMLTRANSFORMおよびXMLTypeメソッドTRANSFORM()

- XMLTRANSFORMおよびXMLType.transform()の例

- XMLTypeインスタンスの検証

- XMLTypeとして格納されたXMLデータの検証例

12 XMLデータの全文検索

- XMLの全文検索の概要

- 全文検索と他の検索タイプの比較

- XMLデータの検索

- 全文検索およびXML構造を使用した文書の検索

- 全文検索の例について

- ロールおよび権限

- 全文検索の例に使用するスキーマおよびデータ

- CONTAINSおよびora:containsの概要

- SQL関数CONTAINSの概要

- XPath関数ora:containsの概要

- CONTAINSおよびora:containsの比較

- CONTAINS SQL関数

- SQL関数CONTAINSを使用した全文検索

- 全文ブール演算子AND、ORおよびNOT

- 全文ステミング: $

- ブールとステミング演算子の組合せ

- SCORE SQL関数

- CONTAINS検索の範囲の限定

- WITHIN構造演算子

- INPATH構造演算子

- HASPATH構造演算子

- CONTAINS結果の投影

- CONTEXT索引を使用した索引付け

- CONTEXT索引の概要

- CONTAINSにおけるCONTEXT索引の効果

- CONTEXT索引プリファレンス

- セクション・グループの概要

- ora:contains XQuery関数

- XQuery関数ora:containsを使用した全文検索

- ora:contains問合せの範囲の限定

- ora:contains結果の投影

- ora:contains問合せのポリシー

- ora:contains問合せのポリシーの概要

- ora:containsでのポリシーの効果

- ポリシーのデフォルト

- ora:containsのパフォーマンス

- 問合せでの1次フィルタの使用

- XPathリライトおよびCONTEXT索引

- Text Path BNFの仕様

- 全文XMLのサポートの例

- 発注書のXML文書、po001.xml

- CREATE TABLE文

- 全文検索する発注書XML Schemaの例

第III部 XMLType APIの使用

13 PL/SQL APIs for XMLType

- PL/SQL API for XMLTypeの概要

- APIの機能

- XMLの遅延ロード(実体化の遅延)

- XMLTypeデータ型でのXML Schemaのサポート

- XMLTypeによる異なるキャラクタ・セットのデータのサポート

- PL/SQL DOM API for XMLType(DBMS_XMLDOM)

- W3Cのドキュメント・オブジェクト・モデル(DOM)勧告の概要

- W3C DOM標準へのOracle XML Developer's Kit拡張

- W3CのDOM勧告のサポート

- DOMとSAXの違い

- PL/SQL DOM API for XMLType(DBMS_XMLDOM): 機能

- XML Schemaのサポート

- パフォーマンスの向上

- Oracle XML Developer's KitおよびOracle XML DBを使用したエンドツーエンド・アプリケーションの設計

- PL/SQL DOM API for XMLTypeを使用するためのXMLデータの準備

- SQLオブジェクト型へのXML Schemaのマッピングの定義

- XML SchemaのマッピングのためのDOM再現性

- XMLTypeビューを使用したXMLへの既存データのラッピング

- サポートされているDBMS_XMLDOMのメソッド

- PL/SQL DOM API for XMLType: ノード型

- XML Schemaに基づくデータの操作

- DOM NodeListオブジェクトおよびNamedNodeMapオブジェクト

- PL/SQL DOM API for XMLType(DBMS_XMLDOM)の使用

- PL/SQL DOM API for XMLTypeの例

- DBMS_XMLDOMを使用した大規模ノードの処理

- Get-Pushモデル

- Get-Pullモデル

- Set-Pullモデル

- Set-Pushモデル

- バイナリ・ストリームか文字ストリームかの判断

- PL/SQL Parser API for XMLType(DBMS_XMLPARSER)

- PL/SQL Parser API for XMLTypeの機能

- PL/SQL Parser API for XMLType(DBMS_XMLPARSER)の使用

- PL/SQL XSLT Processor for XMLType(DBMS_XSLPROCESSOR)

- XSLTを使用した変換

- PL/SQL XSLT Processor for XMLType: 機能

- PL/SQL XSLT Processor API for XMLType(DBMS_XSLPROCESSOR)の使用

- PL/SQL Translation API for XMLType(DBMS_XMLTRANSLATIONS)

- DBMS_XMLTRANSLATIONSメソッド

14 PL/SQLパッケージDBMS_XMLSTORE

- PL/SQLパッケージDBMS_XMLSTOREの概要

- DBMS_XMLSTOREパッケージの使用

- DBMS_XMLSTOREを使用した挿入

- DBMS_XMLSTOREを使用した更新

- DBMS_XMLSTOREを使用した削除

15 Java DOM API for XMLType

- Java DOM API for XMLTypeの概要

- Java DOM API for XMLType

- JDBCを使用したXMLTypeデータへのアクセス

- JDBCとのXMLTypeデータの使用

- JDBCを使用してJavaアプリケーションでOracle XML DB内のXML文書にアクセスする方法

- JDBCを使用したXMLデータベース文書の操作

- JDBCを使用した、データベースへの大規模なXML文書のロード

- Java DOM API for XMLTypeの機能

- XML Schemaに基づく文書の作成

- JDBCまたはSQLJ

- Java DOM API for XMLTypeのクラス

- 推奨またはサポートされていないJavaメソッド

- Java DOM API for XMLTypeの使用

- Javaを使用した大規模ノードの処理

- Java DOMへのストリーム拡張

- Get-Pullモデル

- Get-Pushモデル

- Set-Pullモデル

- Set-Pushモデル

- バイナリXMLでのJava DOM APIおよびJDBCの使用

16 C API for XMLの使用

- C API for XMLの概要(Oracle XDKおよびOracle XML DB)

- Oracle XML DBでのOCIおよびC API for XMLの使用

- データベースに格納されているXMLTypeデータへのアクセス

- クライアントでのXMLTypeインスタンスの作成

- C DOM API関数のXMLコンテキスト・パラメータ

- OCIXmlDbInitXmlCtx()構文

- OCIXmlDbFreeXmlCtx()構文

- XMLコンテキストの初期化および終了

- バイナリXMLでのC API for XMLの使用

- Oracle XML DBでのOracle XML Developer's Kit Pull Parserの使用

- Cでの一般的なXMLType操作

17 Oracle XML DBでのOracle Data Provider for .NETの使用

- ODP.NETのXMLサポートおよびOracle XML DB

- ODP.NETのサンプル・コード

第IV部 既存データのXML表示

18 データベースからのXMLデータの生成

- Oracle DatabaseからのXMLデータ生成の概要

- SQL関数を使用したXMLの生成

- XMLELEMENTおよびXMLATTRIBUTES SQL/XML関数

- 生成されたXMLデータにおける文字のエスケープ

- XMLの日付とタイムスタンプのフォーマット

- XMLElementの例

- XMLFOREST SQL/XML関数

- XMLCONCAT SQL/XML関数

- XMLAGG SQL/XML関数

- XMLPI SQL/XML関数

- XMLCOMMENT SQL/XML関数

- XMLSERIALIZE SQL/XML関数

- XMLPARSE SQL/XML関数

- XMLROOT Oracle SQL関数

- XMLCOLATTVAL Oracle SQL関数

- XMLCDATA Oracle SQL関数

- DBMS_XMLGENを使用したXMLの生成

- PL/SQLパッケージDBMS_XMLGENの使用

- パッケージDBMS_XMLGENのファンクションおよびプロシージャ

- DBMS_XMLGENの例

- SYS_XMLGEN Oracle SQL関数

- Oracle SQL関数SYS_XMLGENを使用する利点

- XMLFormatオブジェクト型の使用

- SYS_XMLAGG Oracle SQL関数

- Oracle XML DBを使用してXMLを生成する場合のガイドライン

- XMLAGG ORDER BY句を使用して、問合せ結果を集計前に順序付けする方法

- XMLTABLEを使用して行セットを戻す方法

19 XMLTypeビュー

- XMLTypeビューの概要

- XMLTypeビューの作成: 構文

- XML Schemaに基づかないXMLTypeビューの作成

- SQL/XMLパブリッシング関数を使用した、XML Schemaに基づかないXMLTypeビューの作成

- オブジェクト型またはSYS_XMLGENを使用した、XML Schemaに基づかないXMLTypeビューの作成

- XML Schemaに基づくXMLTypeビューの作成

- SQL/XMLパブリッシング関数を使用した、XML Schemaに基づくXMLTypeビューの作成

- SQL/XMLパブリッシング関数での名前空間の使用

- オブジェクト型またはオブジェクト・ビューを使用した、XML Schemaに基づくXMLTypeビューの作成

- ネストした部門情報を使用したXMLType従業員ビューの作成

- ネストした従業員情報を使用したXMLType部門ビューの作成

- XMLType表からのXMLTypeビューの作成

- SQL関数REFを使用したXMLTypeビュー・オブジェクトの参照

- XMLTypeビューでのデータ操作言語(DML)

20 URIを介したデータのアクセス

- Oracle XML DB URLの機能の概要

- URIとURL

- URITypeとそのサブタイプ

- DBUriとXDBUri: 目的

- URITypeメソッド

- HTTPURIType PL/SQLメソッドGETCONTENTTYPE()

- DBURIType PL/SQLメソッドGETCONTENTTYPE()

- DBURIType PL/SQLメソッドGETCLOB()

- DBURIType PL/SQLメソッドGETBLOB()

- URITypeインスタンスを使用したデータ・アクセス

- XDBUris: リポジトリ・リソースへのポインタ

- XDBUri URIの構文

- XDBUriの例

- DBUris: データベース・データへのポインタ

- XMLデータ形式でのデータベース表示

- DBUri URIの構文

- データベースおよびセッションを有効範囲とするDBUri

- DBUriの例

- 表のターゲット化

- 表内の行のターゲット化

- 列のターゲット化

- 列のテキスト値の取出し

- コレクションのターゲット化

- パッケージURIFACTORYを使用したURITypeの新しいサブタイプの作成

- パッケージURIFACTORYで新しいURITypeのサブタイプを登録

- SYS_DBURIGEN SQL関数

- 列またはオブジェクト属性をSYS_DBURIGENに渡す規則

- SYS_DBURIGEN SQL関数: 例

- 部分的な結果の取得

- 挿入されたオブジェクトへのRETURNING URL

- DBUriServlet

- URLを使用したMIMEタイプのオーバーライド

- DBUriServletのカスタマイズ

- DBUriServletのセキュリティ

- DBUriを処理するためのパッケージURIFACTORYの構成

第V部 Oracle XML DBリポジトリ

21 Oracle XML DBリポジトリのデータへのアクセス

- Oracle XML DBリポジトリの概要

- Oracle XML DBリポジトリ・リソースにアクセスする2つの方法

- リポジトリの用語と提供されているリソース

- リポジトリの用語

- 提供されているファイルとフォルダ

- Oracle XML DBリポジトリ・リソース

- リポジトリ・データが格納される場所

- 生成された表の名前

- リソース用の構造化記憶域の定義

- Oracle ASM仮想フォルダ

- パス名の解決

- リンク・タイプ

- リポジトリ・リンクとドキュメント・リンク

- ハード・リンクおよび弱いリンク

- フォルダ階層の情報がない状況での弱いリンクの作成

- 複数のハード・リンクに関する制限

- リポジトリ・リソースへのナビゲーショナル・アクセスまたはパス・アクセス

- インターネット・プロトコルを使用したOracle XML DBリソースへのアクセス

- Oracle XML DBのプロトコル・アクセスを使用できる場所

- プロトコル・アクセスの使用

- Oracle XML DBリソースの取出し

- Oracle XML DBリソースの格納

- インターネット・プロトコルおよびXMLTypeの使用: ストリームへのXMLTypeの直接書込み

- プロトコルとリソースAPIを使用したOracle ASMファイルへのアクセス(DBA用)

- リポジトリ・リソースへの問合せベースのアクセス

- リポジトリ・リソースへのサーブレット・アクセス

- リポジトリ・リソースに対する操作

22 Oracle XML DBリポジトリの構成

- リソースを構成するリソース構成ファイル

- リソースの構成

- 共通の構成パラメータ

- 構成要素ResConfig

- 構成要素defaultChildConfig

- 構成要素applicationData

23 Oracle XML DBでのXLinkおよびXIncludeの使用

- XLinkおよびXIncludeの概要

- XLinkおよびXIncludeのリンク・タイプ

- XLinkリンクおよびXIncludeリンクによるドキュメント間関係のモデル化

- XLinkおよびXIncludeのリンク・タイプ

- XInclude: 複合ドキュメント

- Oracle XML DBでのXLinkの使用

- Oracle XML DBでのXIncludeの使用

- 複合ドキュメントにおける包含の展開

- 複合ドキュメントの検証

- 複合ドキュメントの更新

- 複合ドキュメントのバージョニング、ロックおよびアクセス制御

- DOCUMENT_LINKSビューを使用したXLinkリンクおよびXIncludeリンクの検証

- XLink情報に関するDOCUMENT_LINKSへの問合せ

- XInclude情報に関するDOCUMENT_LINKSへの問合せ

- XLinkおよびXIncludeのためのリソースの構成

- 未解決リンクの処理の構成: UnresolvedLink属性

- 作成するドキュメント・リンクの構成: LinkType要素

- 取得に使用するパス形式の構成: PathFormat要素

- XIncludeに関する競合解決の構成: ConflictRule要素

- XIncludeを使用したドキュメントの分解の構成: SectionConfig要素

- XLinkおよびXIncludeの構成例

- DBMS_XDB.processLinksを使用したXLinkリンクおよびXIncludeリンクの管理

24 リソースのバージョン管理

- Oracle XML DBバージョニングの概要

- バージョニングおよびリソースID

- バージョニングおよびACL

- リソースのバージョニングの例

25 RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス

- Oracle XML DBのRESOURCE_VIEWとPATH_VIEWの概要

- RESOURCE_VIEWの定義および構造

- PATH_VIEWの定義および構造

- RESOURCE_VIEWとPATH_VIEWの違いの理解

- UNDER_PATHおよびEQUALS_PATHを使用して実行できる操作

- RESOURCE_VIEWおよびPATH_VIEW SQL関数

- UNDER_PATH SQL関数

- EQUALS_PATH SQL関数

- PATH SQL関数

- DEPTH SQL関数

- RESOURCE_VIEWおよびPATH_VIEW SQL関数の使用

- リポジトリ・データ・パス、リソースおよびリンクへのアクセス: 例

- リポジトリ・リソースの削除: 例

- 空でないフォルダ・リソースの削除

- リポジトリ・リソースの更新例

- 複数のOracle XML DBリソースの操作

- Oracle XML DBリポジトリ操作のパフォーマンス・チューニング

- Oracle Textを使用したリソースの検索

26 PL/SQLを使用したリポジトリへのアクセス

- PL/SQLパッケージDBMS_XDBの概要

- DBMS_XDB: リソース管理

- DBMS_XDB: ACLベースのセキュリティ管理

- DBMS_XDB: 構成管理

27 リポジトリのアクセス制御

- アクセス制御の概念

- プリンシパル: ユーザーまたはロール

- データベース・ロールによるデータベース権限のユーザーへのマップ

- プリンシパルDAV::owner

- 権限

- アクセス制御エントリ(ACE)

- アクセス制御リスト(ACL)

- リポジトリ操作のためのデータベース権限

- 権限

- 基本権限

- 集約権限

- ACLおよびACE

- システムACL

- ACLおよびACEの評価

- ACL検証

- ACL継承

- ACE要素invertでのプリンシパルの補完

- ACE妥当性の期間

- アクセス制御リスト(ACL)の使用

- DBMS_XDB.CREATERESOURCEを使用したACLの作成

- リポジトリのパスがある場合のACL文書の取得

- リソースのACLの設定

- ACLの削除

- ACLの更新

- 指定されたリソースを保護するACL文書の取得

- 特定のリソースに対して現行ユーザーに付与された権限の取得

- 現行ユーザーがリソースに対する権限を所有しているかどうかの確認

- ユーザーがACLおよびリソース所有者を使用する権限を所有しているかどうかの確認

- 指定されたリソースを保護するACLのパスの取得

- 指定されたACLによって保護されるすべてのリソースのパスの取得

- ACLキャッシング

- リポジトリ・リソースおよびデータベース表のセキュリティ

- 最適化: 不要な場合にaclベースのセキュリティを適用しない

- Oracle XML DBのLDAPとの統合

28 プロトコルを使用したリポジトリへのアクセス

- Oracle XML DBプロトコル・サーバーの概要

- セッション・プーリング

- Oracle XML DBプロトコル・サーバーの構成管理

- プロトコル・サーバーのパラメータの構成

- セキュアHTTP(HTTPS)の構成

- HTTP ListenerによるSSLの使用の有効化

- TCPS Dispatcherの有効化

- Oracle XML DBファイル・システムのリソースとの相互作用

- プロトコル・サーバーによるXML Schemaに基づくXML文書または基づかないXML文書の処理

- イベントベース・ロギング

- FTPおよびOracle XML DBプロトコル・サーバーの使用

- Oracle XML DBプロトコル・サーバー: FTP機能

- サポートされていないFTPの機能

- サポートされているFTPクライアント・メソッド

- FTP Quoteメソッド

- Oracle ASMファイルに対するFTPの使用

- Oracle XML DBのデフォルト・ポートでなく標準ポート上でのFTP使用

- FTPでのIPv6 IPアドレスの使用

- FTPサーバーのセッション管理

- エラー421の処理(FTPセッションのデフォルトのタイムアウト値の変更)

- パッシブ・モードでのFTPクライアントの障害

- HTTP(S)およびOracle XML DBプロトコル・サーバーの使用

- Oracle XML DBプロトコル・サーバー: HTTP(S)機能

- サポートされていないHTTP(S)の機能

- サポートされているHTTP(S)クライアント・メソッド

- Oracle XML DBのデフォルト・ポートでなく標準ポート上でのHTTP(S)使用

- HTTP(S)でのIPv6 IPアドレスの使用

- HTTPS: セキュアHTTPのサポート

- URL期限切れ時間の制御

- HTTPを使用したOracle XML DBリポジトリへの匿名アクセス

- JavaサーブレットでのHTTP(S)

- 埋込みPL/SQLゲートウェイ

- クライアントからのマルチバイト・データの送信

- URL内の非ASCII文字

- HTTP(S)のキャラクタ・セットの制御

- WebDAVおよびOracle XML DBの使用

- Oracle XML DB WebDAVの機能

- サポートされていないWebDAVの機能

- サポートされているWebDAVクライアント・メソッド

- Microsoft Windows XP SP2でのWebDAVの使用

- Oracle XML DBおよびWebDAVを使用したMicrosoft WindowsでのWebフォルダの作成

29 ユーザー定義のリポジトリ・メタデータ

- メタデータとXMLの概要

- メタデータの種類 - 用語の用法

- ユーザー定義のリソース・メタデータ

- シナリオ: 写真コレクションのメタデータ

- XML Schemaによるリソース・メタデータの定義

- リソース・メタデータの追加、更新、削除

- APPENDRESOURCEMETADATAを使用したメタデータの追加

- DELETERESOURCEMETADATAを使用したメタデータの削除

- SQL DMLを使用したメタデータの追加

- WebDAV PROPPATCHを使用したメタデータの追加

- XML Schemaに基づくリソース・メタデータの問合せ

- バイナリ・イメージ・メタデータからのXMLイメージ・メタデータ

- XML Schemaに基づかないリソース・メタデータの追加

- リソース・メタデータに影響するPL/SQLプロシージャ

30 Oracle XML DBリポジトリ・イベント

- リポジトリ・イベントの概要

- リポジトリ・イベント: ユースケース

- リポジトリ・イベントとデータベース・トリガー

- リポジトリ・イベント・リスナーとイベント・ハンドラ

- リポジトリ・イベント構成

- 可能なリポジトリ・イベント

- リポジトリ操作とイベント

- リポジトリ・イベント・ハンドラの考慮事項

- リポジトリ・イベントの構成

- 構成要素event-listeners

- 構成要素listener

- リポジトリ・イベント構成の例

31 Oracle XML DB Content Connectorの使用

- JCRおよびOracle XML DB Content Connectorの概要

- Content Repository API for Java(JCR)について

- Oracle XML DB Content Connectorについて

- JCRで公開されるOracle XML DBリポジトリ

- JCRでのファイルおよびフォルダの公開例

- JCRノード型に対するOracle拡張関数

- バイナリ・コンテンツおよびXMLコンテンツ

- システム定義メタデータ

- ユーザー定義メタデータ

- ハード・リンクおよび弱いリンク

- Oracle XML DB Content Connectorの使用方法

- CLASSPATHの設定

- JCRリポジトリ・オブジェクトの取得

- ファイルのアップロードのためのサンプル・コード

- 追加コード・サンプル

- Oracle XML DB Content ConnectorのロギングAPI

- サポートされているJCRコンプライアンス・レベル

- Oracle XML DB Content Connectorの制限

- デフォルトのワークスペース名

- 特定のノード型に制限された操作

- ファイルまたはフォルダの状態の決定

- バイナリ・コンテンツとXMLコンテンツの間の相互作用

- 変更の保存順

- 未定義のプロパティ

- ノード型nt:baseは抽象

- 自動作成されるノードjcr:content

- 保存によるノードjcr:xmltextの正規化

- ノード型mix:referenceable

- 全文索引

- XML SchemaのJCRでの使用

- JCRで使用する場合にXML Schemaを登録する理由

- JCRを使用したXML Schemaの登録方法

- XML SchemaからのJCRノード型の生成方法

- 組込み単純型

- XML Schema定義単純型

- 複合型

- グローバルな要素宣言

32 JavaでのOracle XML DBアプリケーションの作成

- Oracle XML DBのJavaアプリケーションの概要

- データベース内外で使用可能なOracle XML DB API

- 設計のガイドライン: データベース内外でのJava

- HTTP(S): JavaサーブレットへのアクセスまたはXMLTypeリソースへの直接アクセス

- 多くのXMLTypeオブジェクト要素へのアクセス: JDBC XMLTypeサポートの使用

- サーブレットを使用したデータの操作およびXMLとしての迅速な書込み

- JavaでのOracle XML DB HTTPサーブレットの作成

- Oracle XML DBサーブレットの構成

- Oracle XML DBサーブレットに対するHTTPリクエストの処理

- セッション・プールおよびOracle XML DBサーブレット

- ネイティブなXMLストリームのサポート

- Oracle XML DBサーブレットのAPI

- Oracle XML DBサーブレットの例

33 ネイティブなOracle XML DB Webサービスの使用

- ネイティブなOracle XML DB Webサービスの概要

- Oracle XML DBでのWebサービスの構成と有効化

- Oracle XML DBでのWebサービスの構成

- 特定のユーザーに対するWebサービスの有効化

- Webサービスを使用したOracle XML DBの問合せ

- Webサービスを使用したPL/SQLストアド・プロシージャへのアクセス

- Webサービスを使用したPL/SQLファンクションの使用例

第VI部 Oracle XML DBをサポートするOracleツール

34 Oracle XML DBの管理

- Oracle XML DBのインストール

- Database Configuration Assistantを使用したOracle XML DBのインストール

- 動的プロトコル登録によるローカル・リスナーへのFTP、HTTPおよびHTTPSサービス

- DBCAを使用しない手動でのOracle XML DBのインストール

- インストール後

- 既存のOracle XML DBのインストールのアップグレード

- ACL文書および構成ファイルの検証

- Oracle Enterprise Managerを使用したOracle XML DBの管理

- xdbconfig.xmlを使用したOracle XML DBの構成

- Oracle XML DBの構成ファイルxdbconfig.xml

- <xdbconfig>(最上位要素)

- <sysconfig>(<xdbconfig>の子)

- <userconfig>(<xdbconfig>の子)

- <protocolconfig>(<sysconfig>の子)

- <httpconfig>(<protocolconfig>の子)

- <servlet>(<httpconfig>の子)

- Oracle XML DBの構成ファイルの例

- Oracle XML DBConfiguration API

- デフォルトの名前空間のスキーマの場所へのマッピングの構成

- XMLファイル拡張子の構成

- パッケージDBMS_XDB_ADMIN

35 SQL*Loaderを使用したXMLデータのロード

- Oracle DatabaseへのXMLTypeデータのロードの概要

- SQL*Loaderを使用したXMLTypeデータのロード

- SQL*Loaderを使用したLOB内のXMLTypeデータのロード

- 事前にサイズが決まっているフィールドのLOBデータのロード

- デリミタ付きフィールドのLOBデータのロード

- LOBFILEからのLOBデータを含んだXML列のロード

- LOBFILEの指定

- SQL*Loaderによる制御ファイルからのXMLTypeデータの直接ロード

- Oracle Databaseへの大規模なXML文書のロード

36 XMLType表のエクスポートおよびインポート

- Oracle Data Pumpの概要

- Oracle XML DBにおけるエクスポート/インポートのサポート

- XML Schemaに基づくXMLType表のエクスポート

- 階層対応(リポジトリ)表のエクスポート

- トランスポータブル表領域のエクスポートおよびインポート

- リポジトリ・リソースおよびフォルダリング・サポート

- データベースの全体エクスポート

- 異なるキャラクタ・セットでのエクスポートおよびインポート

- エクスポート/インポートの構文および例

- 表モード・エクスポート/インポートの実行

- スキーマ・モード・エクスポート/インポートの実行

37 Oracle Streams AQを使用したXMLデータの交換

- AQとXMLの相互補完

- AQおよびXMLメッセージ・ペイロード

- AQを使用するメリット

- Oracle StreamsおよびAQ

- Streamsメッセージ・キューイング

- オブジェクト型のXMLType属性

- Internet Data Access Presentation(iDAP)

- iDAPアーキテクチャ

- XMLTypeキュー・ペイロード

- XMLおよびOracle Streamsアドバンスト・キューイングを使用する場合のガイドライン

- 多くのPDFファイルを持つOracle Streams AQ XMLメッセージを1つのレコードとして格納する方法

- メッセージをエンキューした後の新しい受信者の追加

- XMLメッセージのエンキューおよびデキュー

- XMLコンテンツを持つメッセージのOracle Streams AQキューからの解析

- XML文書が処理されるまでのリスナー停止の回避

- AQでのHTTPSの使用

- Oracle Streams AQメッセージ・ペイロードへのXMLの格納

- iDAPとSOAPの比較

第VII部 付録

A Oracleが提供するXML Schemaおよび例

- XDBResource.xsd: Oracle XML DBリソースのためのXML Schema

- XDBResource.xsd

- XDBResConfig.xsd: リソース構成のためのXML Schema

- XDBResConfig.xsd

- acl.xsd: ACLのXML Schema

- acl.xsd

- xdbconfig.xsd: Oracle XML DBを構成するためのXML Schema

- xdbconfig.xsd

- xdiff.xsd: スキーマをインプレース拡張と比較するためのXML Schema

- xdiff.xsd

- 発注書XML Schema

- XSLスタイルシートの例: PurchaseOrder.xsl

- C(OCI)を使用したXMLデータのロード

- XMLコンテキスト(OCI)の初期化および終了

B Oracle XML DBの制限

索引

例一覧

- 1-1 FTPおよびHTTP(S)プロトコルがサポートされているリスナーの状態

- 3-1 XMLType列を含む表の作成

- 3-2 XMLType表の作成

- 3-3 仮想列を使用したバイナリXML表のパーティション化

- 3-4 データベース・ディレクトリの作成

- 3-5 XMLType表へのXMLコンテンツの挿入

- 3-6 Javaを使用したXMLType表へのコンテンツの挿入

- 3-7 Cを使用したXMLType表へのコンテンツの挿入

- 3-8 CREATERESOURCEを使用したリポジトリへのXMLコンテンツの挿入

- 3-9 発注書XML Schema、purchaseOrder.xsd

- 3-10 注釈付きの発注書XML Schema、purchaseOrder.xsd

- 3-11 DBMS_XMLSCHEMA.REGISTERSCHEMAを使用したXML Schemaの登録

- 3-12 XML Schemaの登録時のオブジェクトの作成

- 3-13 XML Schemaに準拠したXMLType表の作成

- 3-14 ネストしたコレクションのXMLType表の作成

- 3-15 XML Schemaに基づくXMLType表でのDESCRIBEの使用

- 3-16 不適切なXML文書を挿入しようとした場合に発生するエラー

- 3-17 不適切なXML文書の挿入時に発生するエラー(部分検証)

- 3-18 CHECK制約を使用したXML Schemaの全体検証の実施

- 3-19 BEFORE INSERTトリガーを使用したXML Schemaの全体検証の実施

- 3-20 仮想列を使用したバイナリXML表の制約

- 3-21 オブジェクト・リレーショナル形式で格納されているXMLType表の整合性制約とトリガー

- 3-22 FTPを使用してXMLをロードしたときのデータベース整合性の規定

- 3-23 XMLインスタンス・ドキュメントPurchaseOrder

- 3-24 OBJECT_VALUEを使用したXML文書全体の取出し

- 3-25 XMLQUERYを使用したXMLフラグメントへのアクセス

- 3-26 XMLCASTおよびXMLQueryを使用したテキスト・ノード値へのアクセス

- 3-27 XMLExists、XMLCastおよびXMLQueryを使用したXMLコンテンツの検索

- 3-28 XMLQueryとXMLExistsを使用したPurchaseOrderのReferenceの検索

- 3-29 XMLTABLEを使用したDescriptionノードへのアクセス

- 3-30 XMLTABLEを使用したコレクション内の要素数のカウント

- 3-31 XMLTABLEを使用した要素内の子要素数のカウント

- 3-32 XMLコンテンツのリレーショナル・ビューの作成

- 3-33 ビューを使用したコレクションの各メンバーへのアクセス

- 3-34 ビューを使用したXMLデータの問合せ

- 3-35 ビューを使用したXMLデータのビジネス・インテリジェンス問合せ

- 3-36 UPDATEXMLを使用したXMLコンテンツの更新

- 3-37 UPDATEXMLを使用した要素全体の置換

- 3-38 コレクション内で複数回出現するノードの間違った更新

- 3-39 コレクション内で複数回出現するノードの正しい更新

- 3-40 UPDATEXMLを使用したテキスト・ノード値の変更

- 3-41 SQL/XML関数を使用したXMLデータの生成

- 3-42 従来のリレーショナル表のXMLTypeビューの作成

- 3-43 XMLTypeビューの問合せ

- 3-44 DBURITypeおよびgetXML()を使用したリレーショナル表からのXMLデータの生成

- 3-45 XPath述語を使用した行の制限

- 3-46 XPath述語を使用した行と列の制限

- 3-47 XSLTスタイルシートの例: PurchaseOrder.xsl

- 3-48 TRANSFORMを使用したスタイルシートの適用

- 3-49 FTPを使用したリポジトリへのコンテンツのアップロード

- 3-50 CREATERESOURCEを使用したテキスト・ドキュメント・リソースの作成

- 3-51 PL/SQLパッケージDBMS_XDBを使用したフォルダの作成

- 3-52 XDBURITYPEを使用したリポジトリ内のテキスト・ドキュメントへのアクセス

- 3-53 RESOURCE_VIEWを使用したリソース・コンテンツへのアクセス

- 3-54 リソースと名前空間接頭辞を使用したXML文書へのアクセス

- 3-55 SQL関数REFおよび要素XMLRefを使用した、リポジトリのリソース・データの問合せ

- 3-56 メタデータ、パスおよびコンテンツに基づくXML文書のフラグメントの選択

- 3-57 リソースでUPDATEとUPDATEXMLを使用したドキュメントの更新

- 3-58 UPDATEとUPDATEXMLを使用したノードの更新

- 3-59 リポジトリ内のXML Schemaに基づく文書の更新

- 3-60 RESOURCE_VIEWおよびPATH_VIEWの構造の表示

- 3-61 EQUALS_PATHおよびRESOURCE_VIEWを使用したリソースへのアクセス

- 3-62 リポジトリに格納されたXSLスタイルシートへのパスの判別

- 3-63 パスの下に存在するリソースのカウント

- 3-64 パス内のフォルダのコンテンツのリスト

- 3-65 フォルダに含まれているリンクのリスト

- 3-66 発注書のXML文書が含まれたリソースへのパスの検索

- 3-67 フォルダ限定の問合せの実行計画の出力

- 4-1 SQL/XML関数XMLExistsを使用したノードの検索

- 4-2 XMLCASTを使用したXMLフラグメントのスカラー値の抽出

- 4-3 XMLTYPEデータの問合せ

- 4-4 PL/SQLカーソルを使用した一時XMLTYPEデータの問合せ

- 4-5 XMLTABLEを使用したXMLデータの抽出およびデータベース表への挿入

- 4-6 PL/SQLプロシージャを使用したXMLデータの抽出および表への挿入

- 4-7 SQL/XML関数を使用したXMLデータの検索

- 4-8 XMLQUERYを使用したXMLTYPEインスタンスからのフラグメントの抽出

- 4-9 SQL UPDATE文を使用したXMLTypeデータの更新

- 4-10 UPDATEおよびUPDATEXMLを使用したXMLTYPEの更新

- 4-11 UPDATEXMLを使用した、複数のテキスト・ノードと属性値の更新

- 4-12 UPDATEXMLを使用した、コレクション内で選択されたノードの更新

- 4-13 UPDATEXMLを使用したNULL更新: 要素および属性

- 4-14 UPDATEXMLを使用したNULL更新: テキスト・ノード

- 4-15 UPDATEXML式内のXPath式

- 4-16 UPDATEXML式と同等のオブジェクト・リレーショナル形式の文

- 4-17 UPDATEXMLを使用したビューの作成

- 4-18 LineItems要素へのLineItem要素の挿入

- 4-19 名前空間を使用する要素の挿入

- 4-20 最初のLineItem要素の直前にLineItem要素を挿入

- 4-21 Action要素の最後の子としてDate要素を挿入

- 4-22 LineItem要素(番号222)の削除

- 5-1 例で使用するリソースの作成

- 5-2 様々な型の項目シーケンスに適用されるXMLQuery

- 5-3 for、let、order by、where、およびreturnを使用するFLOWR式

- 5-4 組込み関数を使用したFLOWR式

- 5-5 リレーショナル表をXMLとして問い合せる

- 5-6 ネストされたFLWOR問合せでのリレーショナル・データの使用

- 5-7 XMLTableでリレーショナル表をXMLとして問い合せる

- 5-8 XMLQueryでPASSING句を使用してXMLType列を問い合せる

- 5-9 XMLTABLEでXML Schemaに基づくデータを使用する

- 5-10 XMLQUERYでXML Schemaに基づくデータを使用する

- 5-11 XMLTABLEでのPASSINGおよびCOLUMNS句の使用

- 5-12 XMLTABLEを使用してXMLコレクション要素をリレーショナル・データに分解する

- 5-13 XMLQUERYでの名前空間宣言の使用

- 5-14 XMLTABLEでのXMLNAMESPACES句の使用

- 5-15 リレーショナル・データに関するXMLQueryの最適化

- 5-16 リレーショナル・データに関するXMLTableの最適化

- 5-17 XML Schemaに基づくXMLTypeデータを含むXMLQueryの最適化

- 5-18 XML Schemaに基づくXMLTypeデータを含むXMLTableの最適化

- 5-19 fn:docを使用した、最適化されていないリポジトリの問合せ

- 5-20 EQUALS_PATHを使用した、最適化されたリポジトリの問合せ

- 5-21 Oracle XQueryプラグマora:defaultTableを使用したリポジトリの問合せ

- 5-22 XQuery式の静的型チェック: oradb URIスキーム

- 5-23 XQuery式の静的型チェック: スキーマベースのXML

- 5-24 SQL*Plus XQUERYコマンドの使用

- 5-25 XQueryをPL/SQLとともに使用する

- 5-26 XQueryをJDBCとともに使用する

- 5-27 XQueryをODP.NETおよびC#とともに使用する

- 6-1 単一の要素でXMLCASTおよびXMLQUERYを使用したCREATE INDEX

- 6-2 単一の要素でEXTRACTVALUEを使用したCREATE INDEX

- 6-3 問合せデータと索引データを対応させる: SQLのキャスト

- 6-4 問合せデータと索引データを対応させる: XQueryのキャスト

- 6-5 2つの発注書のパス表の内容

- 6-6 XMLType非構造化記憶域でのXMLIndex索引の作成

- 6-7 特定の表にあるXMLIndex索引の名前の取得

- 6-8 XMLIndex索引の名前変更と削除

- 6-9 XMLIndex索引のパス表への名前付け

- 6-10 XMLIndexパス表のシステム生成名の決定

- 6-11 XMLIndex索引の作成時における記憶域オプションの指定

- 6-12 XMLIndex非構造化コンポーネントの削除

- 6-13 XMLIndex索引の2次索引の名前付け

- 6-14 パス表のVALUE列に対するファンクション索引の作成

- 6-15 パス表のVALUE列に対する、数値索引の直接作成

- 6-16 createNumberIndexプロシージャによる、VALUE列に対する数値索引の作成

- 6-17 createDateIndexプロシージャによる、VALUE列に対する日付索引の作成

- 6-18 パス表のVALUE列に対するOracle Text CONTEXT索引の作成

- 6-19 XMLIndexのパス表上にある、すべての2次索引の表

- 6-20 XMLIndex索引: 構造化コンポーネントの追加

- 6-21 XMLIndex構造化コンポーネントの削除

- 6-22 XMLIndex索引コンテンツ表に対するBツリー索引の作成

- 6-23 XMLIndex索引コンテンツ表に対するOracle Text CONTEXT索引

- 6-24 構造化コンポーネントのみを含むXMLIndexおよび名前空間の使用

- 6-25 XMLIndex非構造化コンポーネントが使用されるかどうかの確認

- 6-26 パス表名からのXMLIndex索引名の取得

- 6-27 XMLIndexを使用したXMLフラグメントからのデータ抽出

- 6-28 2つの述語を使用する問合せに対する構造化XMLIndexコンポーネントの使用

- 6-29 マルチレベル連鎖を使用する問合せに対する構造化XMLIndexコンポーネントの使用

- 6-30 オプティマイザ・ヒントを使用したXMLIndexの無効化

- 6-31 CREATE INDEXによるXMLIndexパスのサブセット化

- 6-32 ALTER INDEXによるXMLIndexパスのサブセット化

- 6-33 名前空間接頭辞を使用したXMLIndexパスのサブセット化

- 6-34 XMLIndex索引の並列的な作成

- 6-35 XMLIndexの内部オブジェクトに対する、異なるPARALLEL度の使用

- 6-36 XMLIndexに対する遅延同期の指定

- 6-37 SYNCINDEXを使用したXMLIndex索引の手動同期化

- 6-38 XMLIndexオブジェクトに関する統計の自動収集

- 6-39 Oracle Text索引の作成

- 6-40 SQL関数CONTAINを使用したXMLデータの検索

- 6-41 Oracle Text索引およびXMLIndex索引の使用

- 7-1 XML SchemaインスタンスpurchaseOrder.xsd

- 7-2 purchaseOrder.xml: purchaseOrder.xsdに準拠する文書

- 7-3 DBMS_XMLSCHEMA.REGISTERSCHEMAを使用したXML Schemaの登録

- 7-4 XMLType表を格納するためのSQLオブジェクト型の作成

- 7-5 グローバル要素PurchaseOrderのデフォルト表

- 7-6 登録されたスキーマのデータ・ディクショナリ表

- 7-7 DBMS_XMLSCHEMA.DELETESCHEMAを使用したXML Schemaの削除

- 7-8 ローカルXML Schemaの登録

- 7-9 グローバルXML Schemaの登録

- 7-10 変換の必要があるタイトルを含むドキュメントを定義するXML Schema

- 7-11 変換されていないインスタンス・ドキュメント

- 7-12 単一値要素の属性xdb:translateを含むXML Schema

- 7-13 変換後のドキュメント

- 7-14 複数値要素の属性xdb:translateを含むXML Schema

- 7-15 複数値要素を持つXML Schemaの変換済ドキュメント

- 7-16 言語情報のないドキュメントの挿入

- 7-17 リポジトリに挿入された後のドキュメント

- 7-18 言語情報を持つドキュメントの挿入

- 7-19 挿入後のドキュメント

- 7-20 XML Schemaに基づくXMLType表および列の作成

- 7-21 XML Schemaに基づくXMLType表および列に対するCLOB記憶域の指定

- 7-22 XMLType表および列に対する構造化記憶域オプションの指定

- 7-23 STORE ALL VARRAYS ASの使用

- 7-24 一般的なスキーマ注釈の使用

- 7-25 注釈付きXML Schemaの登録

- 7-26 登録されたXML Schemaからのメタデータの問合せ

- 7-27 属性SQLTypeを使用したXML Schemaデータ型のSQLデータ型へのマッピング

- 8-1 XPathリライト

- 8-2 XPathリライトを実行しない場合に生成される実行計画

- 8-3 実行計画の分析による列と索引の対応の特定

- 8-4 述語でターゲットとなっている列に対する索引の作成

- 8-5 述語でターゲットとなっている列に対するファンクション索引の作成

- 8-6 索引が選択されていることを示す実行計画

- 8-7 述語でターゲットとなっている列に対するファンクション索引の作成

- 8-8 コレクション要素の選択の実行計画

- 8-9 Ordered Collection Tableに直接アクセスするための索引の作成

- 9-1 関数GENERATESCHEMAを使用したXML Schemaの生成

- 9-2 属性の親要素への一意制約の追加

- 9-3 表外に格納するためのSQLInLineのfalse設定

- 9-4 生成されたXMLType表および型

- 9-5 表外の表の問合せ

- 9-6 表外の表のXPathリライト

- 9-7 表外の表での索引の使用

- 9-8 コレクションの表外格納

- 9-9 生成された表外のコレクション型

- 9-10 REF値の中間表名の変更

- 9-11 表外のコレクションのXPathリライト

- 9-12 REFへの索引を使用した表外のコレクションのXPathリライト

- 9-13 XML Schemaの登録時のパーティション化情報の指定

- 9-14 表の作成時のパーティション化情報の指定

- 9-15 Oracle XML DBのXML Schema: LOBへのcomplexTypeのXMLフラグメントのマッピング

- 9-16 XML Schemaでの継承: complexTypeの拡張としてのcomplexContent

- 9-17 XML Schemaでの継承: complexTypeの制限

- 9-18 XML SchemaのcomplexType: simpleContentへのcomplexTypeのマッピング

- 9-19 XML Schema: any/anyAttributeへのcomplexTypeのマッピング

- 9-20 循環依存を使用したXML Schema

- 9-21 XML Schema: complexType間での循環

- 9-22 XML Schema: complexType間での循環、自己参照

- 9-23 存在しないXML Schemaを含むXML Schema

- 9-24 FORCEオプションを使用したXML Schema xm40.xsdの登録

- 9-25 循環するXML Schemaを使用した表作成の試行

- 9-26 FORCEオプションを使用したXML Schema xm40a.xsdの登録

- 9-27 再帰的XML Schema

- 9-28 表外の表

- 9-29 デフォルト表の無効な共有

- 10-1 修正された発注書XML Schema

- 10-2 evolvePurchaseOrder.xsl: インスタンス・ドキュメントを更新するスタイルシート

- 10-3 修正されたXML SchemaおよびXSLスタイルシートのロード

- 10-4 DBMS_XMLSCHEMA.COPYEVOLVEを使用したXML Schemaの更新

- 10-5 1つの複合型の2つの複合型への分割

- 10-6 diffXMLパラメータ・ドキュメント

- 11-1 XML Schemaの登録およびXMLデータの挿入

- 11-2 XMLTRANSFORMおよびDBURITYPEを使用したスタイルシートの取得

- 11-3 XMLTRANSFORMおよび副問合せを使用したスタイルシートの取得

- 11-4 一時スタイルシートでのメソッドTRANSFORM()の使用

- 11-5 SQLでメソッドISSCHEMAVALID()を使用したXMLの検証

- 11-6 PL/SQLでメソッドISSCHEMAVALID()を使用したXMLの検証

- 11-7 トリガー内でメソッドISSCHEMAVALID()を使用したXMLの検証

- 11-8 CHECK制約内でXMLISVALIDを使用したXMLの妥当性のチェック

- 12-1 Oracle SQL関数CONTAINSを使用した単純な問合せ

- 12-2 CONTAINSおよびWITHINを使用した問合せの制限

- 12-3 CONTAINSおよびINPATHを使用した問合せの制限

- 12-4 複雑な任意のテキスト問合せを使用したora:contains

- 12-5 単純なブール演算子を使用したCONTAINS問合せ

- 12-6 複雑なブールを使用したCONTAINS問合せ

- 12-7 ステミングを使用したCONTAINS問合せ

- 12-8 複雑な問合せ式を使用したCONTAINS問合せ

- 12-9 SCOREを使用した単純なCONTAINS問合せ

- 12-10 WITHIN

- 12-11 ネストしたWITHIN

- 12-12 属性内のWITHIN

- 12-13 WITHINおよびAND: あるコメント・セクション内の2つのワード

- 12-14 WITHINおよびAND: 同じコメント内の2つのワード

- 12-15 WITHINおよびAND: カッコを付けない場合

- 12-16 WITHINおよびAND: 演算子優先順位を示すカッコ

- 12-17 全文述語内の構造: INPATH

- 12-18 全文述語内の構造: INPATH

- 12-19 複雑なパス式を使用したINPATH(1)

- 12-20 複雑なパス式を使用したINPATH(2)

- 12-21 ネストしたINPATH

- 12-22 リライト済のネストしたINPATH

- 12-23 単純なHASPATH

- 12-24 HASPATHの等値式

- 12-25 HASPATHと他の演算子の組合せ

- 12-26 CONTAINS問合せの結果の範囲指定

- 12-27 ora:containsを使用したCONTAINS問合せ結果の投影

- 12-28 表PURCHASE_ORDERSの単純なCONTEXT索引

- 12-29 パス・セクション・グループを使用したXMLType表の単純なCONTEXT索引

- 12-30 XMLType列の単純なCONTEXT索引

- 12-31 XMLType表の単純なCONTEXT索引

- 12-32 XMLType表のCONTAINS問合せ

- 12-33 CONTAINS: デフォルトの大/小文字を区別しない一致

- 12-34 大/小文字混合のプリファレンスの作成

- 12-35 PURCHASE_ORDERS表のCONTEXT索引、大/小文字混合

- 12-36 CONTAINS: 大/小文字混合の(正確な)一致

- 12-37 パス・セクション・グループを使用したpurchase_orders表の単純なCONTEXT索引

- 12-38 XMLQueryおよびXMLExistsでのora:containsの使用

- 12-39 ora:containsで使用するポリシーの作成

- 12-40 ora:containsを使用したストップワードの検索

- 12-41 ora:containsおよびポリシーmy_nostopwords_policyを使用したストップワードの検索

- 12-42 ora:contains、デフォルトの大/小文字の区別

- 12-43 大/小文字混合のプリファレンスの作成

- 12-44 大/小文字混合の(大/小文字が区別されない)ポリシーの作成

- 12-45 ora:contains、大/小文字の区別(1)

- 12-46 ora:contains、大/小文字の区別(2)

- 12-47 大規模な表のora:contains

- 12-48 IDのBツリー索引

- 12-49 大規模な表のora:contains(追加の述語を使用)

- 12-50 ora:containsでの"electric"の検索

- 12-51 XQueryプラグマora:use_text_indexをora:containsとともに使用する

- 12-52 発注書のXML文書、po001.xml

- 12-53 表PURCHASE_ORDERSの作成

- 12-54 表PURCHASE_ORDERS_XMLTYPEの作成

- 12-55 表PURCHASE_ORDERS_XMLTYPE_TABLEの作成

- 12-56 全文検索する発注書XML Schemaの例

- 13-1 DOM文書の作成および操作

- 13-2 要素ノードの作成および関連情報の取得

- 13-3 ユーザー定義サブタイプSYS.util_BinaryOutputStream()の作成

- 13-4 ユーザー定義ストリームによるノード値の取得

- 13-5 バイナリ・データのGet-Pull

- 13-6 文字データのGet-Pull

- 13-7 バイナリ・データのSet-Pull

- 13-8 バイナリ・データのSet-Push

- 13-9 XML文書の解析

- 13-10 XSLスタイルシートを使用したXML文書の変換

- 14-1 指定した列でのデータの挿入

- 14-2 キー列を使用したデータの更新

- 14-3 DBMS_XMLSTORE.DELETEXMLの例

- 15-1 JDBCを使用したXMLType表の問合せ

- 15-2 getStringVal()およびgetCLOB()を使用したXMLTypeデータの選択

- 15-3 getObject()を使用してXMLTypeデータを戻す方法

- 15-4 出力パラメータを使用してXMLTypeデータを戻す方法

- 15-5 SQL UPDATEとコンストラクタXMLTypeを使用したXMLTypeデータの更新

- 15-6 SQL UPDATEとsetObject()を使用したXMLTypeデータの更新

- 15-7 JDBCを使用したXMLTypeデータに関するメタデータの取得

- 15-8 JDBCを使用したXMLType列の要素の更新

- 15-9 更新済の発注書

- 15-10 JDBCを使用したXMLType列の操作

- 15-11 JavaメソッドinsertXML()

- 15-12 JavaメソッドgetCLOB()

- 15-13 Java DOM APIを使用したDOMオブジェクトの作成

- 15-14 バイナリXMLでのJava DOM APIの使用

- 16-1 OCIXMLDBINITXMLCTX()およびOCIXMLDBFREEXMLCTX()の使用

- 16-2 バイナリXMLでのC API for XMLの使用

- 16-3 Oracle XML DB Pull Parserの使用

- 16-4 DOMを使用した発注部品のカウント

- 17-1 .NETへのXMLTypeデータの取出し

- 18-1 XMLELEMENT: 日付のフォーマット

- 18-2 XMLELEMENT: 各従業員の要素の生成

- 18-3 XMLELEMENT: ネストされたXMLの生成

- 18-4 XMLELEMENT: IDおよびname属性を持つ従業員要素の生成

- 18-5 XMLELEMENT: 生成されたXMLにおける文字がエスケープされない

- 18-6 XMLELEMENTと名前空間を使用したXML Schemaに基づく文書の作成

- 18-7 XMLELEMENT: ユーザー定義のデータ型インスタンスからの要素の生成

- 18-8 XMLFOREST: 属性と子要素を持つ要素の生成

- 18-9 XMLFOREST: ユーザー定義のデータ型インスタンスからの要素の生成

- 18-10 XMLCONCAT: 順序で使用されるXMLTypeインスタンスの連結

- 18-11 XMLCONCAT: XML要素の連結

- 18-12 XMLAGG: 子の従業員要素を含む部門要素の生成

- 18-13 XMLAGG: GROUP BYを使用した複数の部門要素の生成

- 18-14 XMLAGG: ネストされた要素の生成

- 18-15 SQL/XML関数XMLPIの使用

- 18-16 SQL/XML関数XMLCOMMENTの使用

- 18-17 SQL/XML関数XMLSERIALIZEの使用

- 18-18 SQL/XML関数XMLPARSEの使用

- 18-19 Oracle SQL関数XMLRootの使用

- 18-20 XMLCOLATTVAL: 属性と子要素を持つ要素の生成

- 18-21 Oracle SQL関数XMLCDATAの使用

- 18-22 DBMS_XMLGEN: 単純なXMLの生成

- 18-23 DBMS_XMLGEN: ページ区切りを使用した単純なXMLの生成(フェッチ)

- 18-24 DBMS_XMLGEN: オブジェクト型を使用したXMLの生成

- 18-25 DBMS_XMLGEN: ユーザー定義のデータ型インスタンスを使用したXMLの生成

- 18-26 DBMS_XMLGEN: XML発注書の生成

- 18-27 DBMS_XMLGEN: REFカーソルからの新規コンテキスト・ハンドルの生成

- 18-28 DBMS_XMLGEN: NULL処理の指定

- 18-29 DBMS_XMLGEN: 階層問合せを使用した再帰XMLの生成

- 18-30 DBMS_XMLGEN: SETBINDVALUE()を使用した問合せ変数のバインド

- 18-31 SYS_XMLGENを使用したXMLデータの作成

- 18-32 SYS_XMLGEN: データベース列からのXML要素の生成

- 18-33 SYS_XMLGEN: スカラー値のXML要素コンテンツへの変換

- 18-34 SYS_XMLGEN: デフォルトの要素名ROW

- 18-35 SYS_XMLGENとXMLFormatを使用したデフォルトの要素名のオーバーライド

- 18-36 SYS_XMLGEN: ユーザー定義のデータ型インスタンスのXMLへの変換

- 18-37 SYS_XMLGEN: XMLTypeインスタンスの変換

- 18-38 オブジェクト・ビューでのSYS_XMLGENの使用

- 18-39 XMLAGG ORDER BY句の使用

- 18-40 XMLTABLEを使用して行セットを戻す方法

- 19-1 XMLELEMENTを使用したXMLTypeビューの作成

- 19-2 オブジェクト型およびSYS_XMLGENを使用したXMLTypeビューの作成

- 19-3 XML Schema emp_simple.xsdの登録

- 19-4 SQL/XMLパブリッシング関数を使用したXMLTypeビューの作成

- 19-5 XMLTypeビューの問合せ

- 19-6 SQL/XMLパブリッシング関数での名前空間接頭辞の使用

- 19-7 ターゲットの名前空間が存在しないXML Schema

- 19-8 ターゲットの名前空間が存在しないXML Schemaのビューの作成

- 19-9 XML Schemaに基づくXMLTypeビューでのSQL/XML関数の使用

- 19-10 XML Schemaに基づくXMLTypeビューに対応するオブジェクト型の作成

- 19-11 DBMS_XMLSCHEMA.GENERATESCHEMAによるXML Schemaの生成

- 19-12 XML Schema emp_complex.xsdの登録

- 19-13 XMLTypeビューemp_xmlの作成

- 19-14 オブジェクト・ビューの作成と、そのオブジェクト・ビューへのXMLTypeビューの作成

- 19-15 オブジェクト型の作成

- 19-16 XML Schema dept_complex.xsdの登録

- 19-17 オブジェクト型dept_tを使用したXMLTypeビューdept_xmlの作成

- 19-18 リレーショナル・データを直接使用したXMLTypeビューdept_xmlの作成

- 19-19 XMLType表の行の制限によるXMLTypeビューの作成

- 19-20 XMLType表の変換によるXMLTypeビューの作成

- 19-21 暗黙的に更新可能なXMLTypeビューの識別

- 20-1 HTTPURIType PL/SQLメソッドGETCONTENTTYPE()

- 20-2 URI列の作成と問合せ

- 20-3 各種の方法で作成された様々な種類のURIの使用

- 20-4 XDBUriを使用した、URIによるリポジトリ・リソースへのアクセス

- 20-5 XMLCASTおよびXMLQUERYでのPL/SQLメソッドGETXML()の使用

- 20-6 DBUriを使用した完全な表のターゲット化

- 20-7 DBUriを使用した表内の個別行のターゲット化

- 20-8 DBUriを使用した特定の列のターゲット化

- 20-9 DBUriを使用した、特定の属性値を持つオブジェクト列のターゲット化

- 20-10 DBUriを使用したノードのテキスト値のみの取出し

- 20-11 DBUriを使用したコレクションのターゲット化

- 20-12 URIFACTORY: ECOMプロトコルの登録

- 20-13 SYS_DBURIGEN: 列をターゲットとするDBUriの生成

- 20-14 SYS_DBURIGENへの単一の引数を持つ列の送信

- 20-15 SYS_DBURIGENを使用したデータベース参照の挿入

- 20-16 旅行体験記の表の作成

- 20-17 最初の20文字のみを戻す関数

- 20-18 SYS_DBURIGENで使用するための旅行体験記ビューの作成

- 20-19 RETURNING句でのSYS_DBURIGENの使用によるURLの取得

- 20-20 DBUriServletのインストール先の変更

- 20-21 サーブレット・アクセスのデータベース・ロールへの制限

- 20-22 DBUri接頭辞用のハンドラの登録

- 21-1 PATH_VIEWへの問合せによるリンク・タイプの特定

- 21-2 リソースのOIDパスの取得

- 21-3 OIDパスを使用した弱いリンクの作成

- 22-1 リソース構成ファイル

- 22-2 applicationData要素

- 23-1 本のドキュメントに部および章を含めるためのXIncludeの使用方法

- 23-2 XDBURITypeによるドキュメントの包含の展開

- 23-3 XLinkリンクからマップされたドキュメント・リンクの問合せ

- 23-4 XIncludeリンクからマップされたドキュメント・リンクの問合せ

- 23-5 OIDによる取得時のXIncludeリンクからハード・ドキュメント・リンクへのマッピング

- 23-6 名前付きパスによる取得時のXLinkリンクから弱いリンクへのマッピング

- 23-7 XIncludeを使用したドキュメントの分解の構成

- 23-8 生成されたxi:include要素を表示するリポジトリ・ドキュメント

- 24-1 リポジトリ・リソースの作成

- 24-2 バージョン管理されたリソースの作成

- 24-3 リソースIDの参照によるリソース・コンテンツの取出し

- 24-4 バージョン管理されたリソースのチェックアウト

- 24-5 リソース・コンテンツの更新

- 24-6 バージョン管理されたリソースのチェックイン

- 24-7 XDBURITYPEおよびCREATEOIDPATHを使用したリソース・バージョン・コンテンツの取出し

- 24-8 GETCONTENTSCLOBBYRESIDを使用したリソース・バージョン・コンテンツの取出し

- 24-9 GETRESOURCEBYRESIDを使用したリソース・バージョン・メタデータの取出し

- 24-10 UNCHECKOUTを使用したチェックアウトのキャンセル

- 25-1 あるパスの下にあるパスの判別: 相対

- 25-2 あるパスの下にあるパスの判別: 絶対

- 25-3 あるパスの下にないパスの判別

- 25-4 複数のcorrelationを使用したパスの判別

- 25-5 3レベルのリソースの相対パス名

- 25-6 UNDER_PATHを使用したリソース・メタデータの抽出

- 25-7 関数PATHとDEPTHのPATH_VIEWでの使用

- 25-8 リンクおよびリソース情報のPATH_VIEWからの抽出

- 25-9 特定の深さまでの、あるパス以下のすべてのリポジトリ・パス

- 25-10 EQUALS_PATHを使用したリポジトリ・パスの特定

- 25-11 指定したリソースのリソースIDの取得

- 25-12 RESIDからのリソースのパス名の取得

- 25-13 指定したパスの下にあるフォルダ

- 25-14 RESOURCE_VIEWのXMLType表への結合

- 25-15 リソースの削除

- 25-16 リソースへのリンクの削除

- 25-17 空でないフォルダの削除

- 25-18 リソースの更新

- 25-19 PATH_VIEW内のパスの更新

- 25-20 属性に基づいたリソースの更新

- 25-21 フォルダ内のリソースの検索

- 25-22 リソースのコピー

- 25-23 「Paper」を含むすべてのリソースの検索

- 25-24 特定のパスの下にあり、「Paper」を含むすべてのリソースの検索

- 26-1 DBMS_XDBを使用したリソースの管理

- 26-2 DBMS_XDB.GETACLDOCUMENTの使用

- 26-3 DBMS_XDB.SETACLの使用

- 26-4 DBMS_XDB.CHANGEPRIVILEGESの使用

- 26-5 DBMS_XDB.GETPRIVILEGESの使用

- 26-6 DBMS_XDB.CFG_GETの使用

- 26-7 DBMS_XDB.CFG_UPDATEの使用

- 27-1 権限を付与する単純なアクセス制御エントリ(ACE)

- 27-2 権限を付与する単純なアクセス制御リスト(ACL)

- 27-3 要素extends-from

- 27-4 要素constrained-with

- 27-5 要素invertを使用したプリンシパル・セットの補完

- 27-6 開始日と終了日が指定されたACE

- 27-7 CREATERESOURCEを使用したACLの作成

- 27-8 リポジトリのパスがある場合のACL文書の取得

- 27-9 リソースのACLの設定

- 27-10 ACLの削除

- 27-11 アクセス制御リストの更新(置換)

- 27-12 アクセス制御リストへのACEの追加

- 27-13 アクセス制御リストからのACEの削除

- 27-14 リソースのACL文書の取得

- 27-15 特定のリソースに対して現行ユーザーに付与された権限の取得

- 27-16 あるリソースに対してユーザーが特定の権限を所有しているかどうかの確認

- 27-17 ACLCheckPrivilegesを使用したユーザー権限の確認

- 27-18 特定のリソースを保護するACLのパスの取得

- 27-19 特定のACLによって保護されたすべてのリソースのパスの取得

- 27-20 LDAPユーザーを参照するACL

- 27-21 LDAPグループを参照するACL

- 28-1 Oracle ASMフォルダのナビゲート

- 28-2 FTP proxyメソッドによる、Oracle ASMファイルのデータベース間転送

- 28-3 IPv6を使用したFTP接続

- 28-4 FTPセッションのデフォルトのタイムアウト値の変更

- 29-1 写真の技術情報を扱うXML Schemaの登録

- 29-2 写真のカテゴリを扱うXML Schemaの登録

- 29-3 メタデータのリソースへの追加 - 写真の技術情報

- 29-4 メタデータのリソースへの追加 - 写真のコンテンツ・カテゴリ

- 29-5 リソースからの特定のメタデータの削除

- 29-6 RESOURCE_VIEWでのDMLの使用によるリソースへのメタデータの追加

- 29-7 WebDAV PROPPATCHによるメタデータの追加

- 29-8 XML Schemaに基づくリソース・メタデータの問合せ

- 29-9 XML Schemaに基づかないメタデータのリソースへの追加

- 30-1 前提条件のあるJavaイベント・リスナーのリソース構成ファイル

- 30-2 前提条件のないPL/SQLイベント・リスナーのリソース構成ファイル

- 30-3 イベント・リスナーを実装するPL/SQLコード

- 30-4 イベント・リスナーを実装するJavaコード

- 30-5 イベント・ハンドラの起動

- 31-1 MyFolderのJCRノード表現

- 31-2 リポジトリ・オブジェクトの取得方法を示すコード・フラグメント

- 31-3 Oracle XML DB Content Connectorを使用したファイルのアップロード

- 31-4 コマンドラインを使用したファイルのアップロード

- 31-5 XML Schemaに基づくコンテンツを持つXML文書

- 31-6 XML Schema

- 31-7 JCRで使用するために登録されていないXMLコンテンツのJCR表現

- 31-8 JCRで使用するために登録されているXMLコンテンツのJCR表現

- 31-9 Oracle XML DBで使用するためのXML Schemaの登録

- 31-10 JCRで使用するためのXML Schemaの登録

- 32-1 Oracle XML DBサーブレット

- 32-2 Oracle XML DBサーブレットの登録およびマッピング

- 33-1 Webサービス構成サーブレットの追加

- 33-2 Webサービス構成サーブレット追加の検証

- 33-3 Webサービスで処理されるデータベース問合せのXML Schema

- 33-4 問合せWebサービスを使用したSQL問合せの入力XML文書

- 33-5 問合せWebサービスを使用したSQL問合せの出力XML文書

- 33-6 Webサービス・アクセスに使用するPL/SQLファンクションの定義

- 33-7 ストアドPL/SQLファンクションに対応するWSDLドキュメント

- 33-8 Webサービスを使用したPL/SQL問合せの入力XML文書

- 33-9 Webサービスを使用したPL/SQL問合せの出力XML文書

- 34-1 Oracle XML DBの構成ファイル

- 34-2 CFG_UPDATEおよびCFG_GETを使用した構成ファイルの更新

- 35-1 データ・ファイルfilelist.dat: ロードするXMLファイルのリスト

- 35-2 発注書XML文書のロードに使用する制御ファイルload_datra.ctl

- 35-3 シェル・コマンドsqlldrを使用したXMLデータのロード

- 36-1 表モードでのXMLTypeデータのエクスポート

- 36-2 表モードでのXMLTypeデータのインポート

- 36-3 表po2の作成

- 36-4 スキーマ・モードでのXMLTypeデータのエクスポート

- 36-5 スキーマ・モードでのXMLTypeデータのインポート

- 36-6 スキーマ・モードでのXMLTypeデータのインポート、スキーマの再マップ

- 37-1 キュー表およびキューの作成

- 37-2 メッセージ・データをXMLに変換するための変換の作成

- 37-3 メッセージを海外に送信する前の変換の適用

- 37-4 XMLTypeおよびAQ: メッセージのデキュー

- A-1 注釈付き発注書XML SchemaのpurchaseOrder.xsd

- A-2 改訂された発注書XML Schema

- A-3 PurchaseOrder.xslスタイルシート

- A-4 Cを使用したXMLType表へのXMLデータの挿入

- A-5 Using OCIXmlDbInitXmlCtx()およびOCIXmlDbFreeXmlCtx()

図一覧

- 1-1 XMLType記憶域およびOracle XML DBリポジトリ

- 1-2 XMLType記憶域

- 1-3 Oracle XML DBリポジトリのアーキテクチャ

- 1-4 Webブラウザに表示されたOracle XML DBリポジトリ

- 1-5 XMLのユースケースとXMLType記憶域モデル

- 1-6 Oracle XML DBのメリット

- 1-7 データとコンテンツの統合: 一般的なXMLアーキテクチャ

- 2-1 XMLデータに対するOracle XML DBの記憶域オプション

- 2-2 Oracle XML DBのApplication Program Interface(API)スタック

- 3-1 Windows Explorerを使用したリポジトリへのコンテンツのロード

- 3-2 XML Schema PurchaseOrderのXMLSpyによるグラフィカル表現

- 3-3 XMLSpyにおけるOracle XML DBスキーマ注釈のサポート

- 3-4 Oracle XML DBリポジトリへのファイルのコピー

- 3-5 HTTPとURLを使用したパスベースのアクセス

- 3-6 Microsoft Wordを使用した、Oracle XML DBに格納されたコンテンツの更新および編集

- 3-7 DBUriサーブレットを使用したPurchaseOrderのデータベースXSL変換

- 3-8 DBUriサーブレットを使用したDepartments表のデータベースXSL変換

- 4-1 XMLExistsの構文

- 4-2 XMLCastの構文

- 4-3 UPDATEXMLの構文

- 4-4 INSERTCHILDXMLの構文

- 4-5 INSERTCHILDXMLBEFOREの構文

- 4-6 INSERTCHILDXMLAFTERの構文

- 4-7 INSERTXMLBEFOREの構文

- 4-8 INSERTXMLAFTERの構文

- 4-9 APPENDCHILDXMLの構文

- 4-10 DELETEXMLの構文

- 5-1 XMLQUERYの構文

- 5-2 XMLTABLEの構文

- 6-1 XMLのユースケースとXML索引付け

- 7-1 XMLType表の作成: CREATE TABLE

- 7-2 XMLType表の作成: XMLType_table

- 7-3 XMLType表の作成: table_properties

- 7-4 XMLType表の作成: XMLType_virtual_columns

- 7-5 Oracle XML DBによるXML Schemaに基づくXMLType表のマッピング方法

- 7-6 simpleTypeのマッピング: XML文字列からSQLのVARCHAR2またはCLOB

- 9-1 表外に格納するためのSQLへのcomplexTypeのマッピング

- 9-2 キャラクタ・ラージ・オブジェクト(CLOB)へのcomplexTypeのXMLフラグメントのマッピング

- 9-3 同じXML Schemaの異なるcomplexType間での相互参照

- 9-4 XML Schema内での複合型の自己参照

- 9-5 XML Schema間での循環参照

- 11-1 XMLTRANSFORMの構文

- 11-2 XMLTRANSFORMの使用

- 13-1 PL/SQL DOM API for XMLTypeの使用

- 13-2 PL/SQL Parser API for XMLTypeの使用

- 13-3 PL/SQL XSLT Processor for XMLTypeの使用

- 15-1 Java DOM API for XMLTypeの使用

- 18-1 XMLELEMENTの構文

- 18-2 XMLAttributes句の構文(XMLATTRIBUTES)

- 18-3 XMLFORESTの構文

- 18-4 XMLCONCATの構文

- 18-5 XMLAGGの構文

- 18-6 XMLPIの構文

- 18-7 XMLCommentの構文

- 18-8 XMLSerializeの構文

- 18-9 XMLParseの構文

- 18-10 XMLRootの構文

- 18-11 XMLCOLATTVALの構文

- 18-12 XMLCDATAの構文

- 18-13 PL/SQLパッケージDBMS_XMLGENの使用

- 18-14 SYS_XMLGENの構文

- 18-15 SYS_XMLAGGの構文

- 19-1 XMLTypeビューの作成の句: 構文

- 20-1 リレーショナル・データのXMLビジュアル化に対応するDBUri

- 20-2 SYS_DBURIGENの構文

- 21-1 リポジトリの階層構造を示すフォルダ・ツリー

- 21-2 WindowsエクスプローラでのOracle XML DBのフォルダ

- 21-3 HTTPやWebDAVおよびナビゲーショナル・アクセスを使用した、IEブラウザからリポジトリ・データへのアクセス: Webフォルダの参照

- 21-4 Oracle ASM仮想フォルダの階層

- 25-1 RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリ・リソースへのアクセス

- 25-2 RESOURCE_VIEWとPATH_VIEWの構造

- 25-3 RESOURCE_VIEWとPATH_VIEWの解説

- 25-4 UNDER_PATHの構文

- 25-5 EQUALS_PATHの構文

- 25-6 PATHの構文

- 28-1 Oracle XML DBのアーキテクチャ: プロトコル・サーバー

- 28-2 Microsoft WindowsでのWebフォルダの作成

- 37-1 Oracle Streamsアドバンスト・キューイングおよびXMLメッセージ・ペイロード

- 37-2 HTTPまたはHTTPSを使用してAQ操作を実行するためのiDAPアーキテクチャ

表一覧

- 1-1 XMLに関連するAPI

- 1-2 XMLに関連するカタログ・ビュー

- 1-3 XMLType記憶域モデル: 相対的なメリット

- 3-1 SQL*Loaderの従来型パスおよびダイレクト・パスによるロード・モード

- 4-1 XPathの共通構造体

- 5-1 事前定義の名前空間と接頭辞

- 5-2 oradb式: 比較用の列の型

- 6-1 基本的なXML索引付けタスク

- 6-2 構造化コンポーネントを含むXMLIndex索引に関連するタスク

- 6-3 非構造化コンポーネントを含むXMLIndex索引に関連するタスク

- 6-4 XMLIndex索引に関連するその他のタスク

- 6-5 XMLIndexでのXMLデータ型とSQLデータ型の対応

- 6-6 XMLIndexのパス表

- 6-7 索引の同期化

- 6-8 XMLIndexの静的なパブリック・ビュー

- 7-1 XMLTypeのXML Schema関連メソッド

- 7-2 バイナリXMLのためのCREATE TABLEエンコード・オプション

- 7-3 要素内の注釈

- 7-4 グローバルなcomplexType要素を宣言する要素内の注釈

- 7-5 XML Schema宣言内の注釈

- 7-6 SQLへのXML Schema文字列データ型のマッピング

- 7-7 SQLへのXML Schemaバイナリ・データ型(hexBinary/base64Binary)のマッピング

- 7-8 SQLへのXML Schema数値基本型のデフォルトのマッピング

- 7-9 XML Schema日時データ型のSQLへのマッピング

- 7-10 SQLへのその他のXML Schema基本および派生データ型のデフォルトのマッピング

- 8-1 基礎となるSQL構造体にリライトされるXPath式のサンプル

- 10-1 プロシージャDBMS_XMLSCHEMA.COPYEVOLVEのパラメータ

- 10-2 プロシージャDBMS_XMLSCHEMA.COPYEVOLVEに関連するエラー

- 10-3 XML Schemaの拡張: XMLType表の一時表の列

- 10-4 XML Schemaの拡張: XMLType列の一時表の列

- 10-5 プロシージャcopyEvolveのマッピング表

- 10-6 プロシージャDBMS_XMLSCHEMA.INPLACEEVOLVEのパラメータ

- 13-1 XMLおよびHTMLのDOMノード型およびその子ノード型

- 15-1 Java DOM API for XMLType: クラス

- 16-1 OCIXmlDbInitXMlCtx()パラメータ

- 16-2 Cでの一般的なXMLType操作

- 18-1 DBMS_XMLGENのファンクションおよびプロシージャ

- 18-2 XMLFormatオブジェクトの属性

- 20-1 URIType PL/SQLメソッド

- 20-2 URIFACTORY PL/SQLメソッド

- 20-3 DBUriServlet: オプションの引数

- 21-1 Oracle XML DBリポジトリの用語の同義語

- 21-2 PATH_VIEWとRESOURCE_VIEWの違い

- 21-3 Oracle XML DBリポジトリへのアクセス: APIオプション

- 24-1 Oracle XML DBバージョニングの用語

- 24-2 パッケージDBMS_XDB_VERSIONのPL/SQLファンクションおよびプロシージャ

- 25-1 RESOURCE_VIEWの構造

- 25-2 PATH_VIEWの構造

- 25-3 UNDER_PATH SQL関数のシグネチャ

- 26-1 DBMS_XDBのリソース管理用ファンクションおよびプロシージャ

- 26-2 DBMS_XDB: セキュリティ管理用のファンクションおよびプロシージャ

- 26-3 DBMS_XDB: 構成管理用のファンクションおよびプロシージャ

- 27-1 Oracle XML DBリソースの操作に必要なデータベース権限

- 27-2 基本権限

- 27-3 集約権限

- 28-1 共通プロトコルの構成パラメータ

- 28-2 FTP固有の構成パラメータ

- 28-3 HTTP(S)またはWebDAV固有の構成パラメータ(サーブレット・パラメータを除く)

- 30-1 事前定義リポジトリ・イベント

- 30-2 Oracle XML DBリポジトリ操作とイベント

- 31-1 Oracle XML DBリソースとJCRのマッピング

- 31-2 JCRプロパティ値型にマップされるXML Schema組込み型

- 32-1 サーブレット・デプロイメント・ディスクリプタに対して定義されたXML要素

- 32-2 未実装のJavaサーブレット2.2メソッド

- 33-1 XMLデータ型とSQLデータ型とのWebサービスによるマッピング

- 34-1 DBMS_XDB_ADMIN管理プロシージャ

- 36-1 表の中のXMLType列の形式とそれに対応するダンプ・ファイルの形式

はじめに

このマニュアルでは、Oracle XML DBについて説明します。Oracle XML DBを使用して、データベースでXMLデータの格納、生成、操作、管理および問合せを実行する方法を説明します。

XMLTypeフレームワークおよびOracle XML DBリポジトリというOracle XML DBの主要部分の概要を説明した後、Oracle XML DBアプリケーションを計画するときに考慮する設計基準について簡単に説明します。Oracle XML DBの使用方法および使用可能な場所の例も示します。

次に、Oracle XML DBを使用したXMLデータの格納および取出し方法、XMLTypeデータを操作するためのAPI、および既存のXMLデータの表示、生成、変換および検索方法も説明します。さらに、バージョニングおよびセキュリティを含むOracle XML DBリポジトリの使用方法、プロトコル、SQL、PL/SQLまたはJavaを使用したリポジトリ・リソースへのアクセスし、操作する方法、およびOracle Enterprise Managerを使用してOracle XML DBアプリケーションを管理する方法についても説明します。また、XMLメッセージングおよびOracle Streamsアドバンスト・キューイングによるXMLTypeのサポートについても説明します。

ここでは、次の項目について説明します。

- 対象読者

- ドキュメントのアクセシビリティについて

- 関連ドキュメント

- 表記規則

対象読者

『Oracle XML DB開発者ガイド』は、Oracle Database上でXMLアプリケーションを構築する開発者を対象としています。

このマニュアルを使用するには、XML、XML Schema、XQuery、XPathおよびXSLを理解していることが理想です。

このマニュアルに示されている多くの例は、SQL、PL/SQL、JavaまたはCで記述されています。これらのうち1つの言語の実用経験があることが前提となります。

ドキュメントのアクセシビリティについて

Oracleのアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWeb サイト(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc)を参照してください。

Oracle Supportへのアクセス

Oracleサポート・サービスでは、My Oracle Supportを通して電子支援サービスを提供しています。詳細情報は(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info) か、聴覚に障害のあるお客様は (http://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs)を参照してください。

関連ドキュメント

詳細は、次のOracleドキュメントを参照してください。

- Oracle Database 11gとOracle Database 11g Enterprise Editionの違い、および使用可能な機能とオプションの詳細は、『Oracle Database新機能ガイド』を参照してください。このマニュアルでは、Oracle Database 11gリリース2(11.2)の新機能についても説明しています。

- 『Oracle Database XML Java API Reference』

- 『Oracle XML Developer's Kitプログラマーズ・ガイド』

- 『Oracle Databaseエラー・メッセージ』。Oracle Databaseエラー・メッセージのドキュメントは、HTML形式でのみ提供されています。出力されたまたはPDFのOracle Databaseドキュメントにのみアクセスできる場合は、エラー・メッセージを範囲で検索できます。特定の範囲を検出した後、Webブラウザの検索機能を使用してメッセージを検索してください。インターネットに接続している場合、Oracle Databaseオンライン・マニュアルのエラー・メッセージ検索機能を使用すると、特定のエラー・メッセージを検索できます。

- 『Oracle Textアプリケーション開発者ガイド』

- 『Oracle Textリファレンス』

- 『Oracle Database概要』

- 『Oracle Database Java開発者ガイド』

- 『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』

- 『Oracle Streamsアドバンスト・キューイング・ユーザーズ・ガイド』

- 『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

このマニュアルの多くの例では、Oracle Databaseのインストール時に「基本インストール」オプションを選択するとデフォルトでインストールされるサンプル・スキーマを使用しています。これらのスキーマの作成方法およびその使用方法の詳細は、『Oracle Databaseサンプル・スキーマ』を参照してください。

リリース・ノート、インストール関連ドキュメント、ホワイト・ペーパーまたはその他の関連ドキュメントは、OTN(Oracle Technology Network)から、無償でダウンロードできます。OTN-Jを使用するには、オンラインでの登録が必要です。登録は、次のWebサイトから無償で行えます。

http://www.oracle.com/technetwork/community/join/overview/index.html

OTNのユーザー名とパスワードをすでにお持ちの場合は、次のURLでOTN Webサイトのドキュメント・セクションに直接アクセスできます。

http://www.oracle.com/technetwork/indexes/documentation/

詳細は、次のURLを参照してください。

- http://www.w3.org/TR/xml/ - XML(言語)

- http://www.xml.com/pub/a/98/10/guide0.html - XML概要

- http://www.w3.org/XML/Schema - XML Schema

- http://www.w3.org/2001/XMLSchema - XML Schema

- http://www.w3.org/TR/xmlschema-0/ - XML Schema: 手引き

- http://www.w3.org/TR/xmlschema-1/ - XML Schema: 構造

- http://www.w3.org/TR/xmlschema-2/ - XML Schema: データ型

- http://www.oasis-open.org/cover/schemas.html - XML Schema

- http://www.xml.com/pub/a/2000/11/29/schemas/part1.html - XML Schema

- http://xml.coverpages.org/xmlMediaMIME.html - media/MIMEタイプ

- http://www.w3.org/TR/xptr/ - XPointer

- http://www.w3.org/TR/xpath - XPath 1.0

- http://www.w3.org/TR/xpath20/ - XPath 2.0

- http://www.zvon.org/xxl/XPathTutorial/General/examples.html - XPath

- 『XML In a Nutshell』Elliotte Rusty Harold、W.Scott Means、O'Reilly、2001年1月、http://www.oreilly.com/catalog/xmlnut/chapter/ch09.html

- http://www.w3.org/TR/2002/NOTE-unicode-xml-20020218/ - XMLでのUnicode

- http://www.w3.org/TR/xml-names/ - XML名前空間

- http://www.w3.org/TR/xml-infoset/ - 情報セット

- http://www.w3.org/DOM/ - ドキュメント・オブジェクト・モデル(DOM)

- http://www.w3.org/TR/xslt - XSLT

- http://www.w3.org/TR/xsl - XSL

- http://www.oasis-open.org/cover/xsl.html - XSL

- http://www.zvon.org/xxl/XSLTutorial/Output/index.html - XSL

- http://www.w3.org/2002/ws/Activity.html - Webサービス

- http://www.ietf.org/rfc/rfc959.txt - RFC 959: FTPプロトコル仕様

- ISO/IEC 13249-2:2000、「Information technology - Database languages - SQL Multimedia and Application Packages - Part 2: Full-Text」、International Organization For Standardization、2000

- http://java.sun.com/xml/tutorial_intro.html - XMLおよびJava

注意:
このマニュアルでは、XML Schemaとは、XML Schema 1.0勧告(http://www.w3.org/XML/Schema)のことを指します。

表記規則

このマニュアルでは次の表記規則を使用します。

規則

意味

太字

太字は、操作に関連するGraphical User Interface要素、または本文中で定義されている用語および用語集に記載されている用語を示します。

イタリック体

イタリックは、ユーザーが特定の値を指定するプレースホルダ変数を示します。

固定幅フォント

固定幅フォントは、段落内のコマンド、URL、サンプル内のコード、画面に表示されるテキスト、または入力するテキストを示します。

コード例

このマニュアルのコード例は、説明のためのみに使用しています。しかし多くの場合、例の一部をコピー・アンド・ペーストし、自分の環境で実行できます。

標準データベース・スキーマ

このマニュアルの例の多くは、データベースに含まれている標準データベース・スキーマを使用しています。特に、データベース・スキーマOEはXML発注書をXMLType表purchaseorderに、ウェアハウス情報を記載したXML文書を表warehousesのXMLType列warehouse_specに含んでいます。

発注書はリポジトリ・パス/home/OE/PurchaseOrders/2002/のOracle XML DBリポジトリにも入っています。これらのドキュメントを制御するXML Schemaはファイルpurchaseorder.xsdで、リポジトリの場所/home/OE/purchaseorder.xsdに格納されています。いくつかの例で発注書を変換するために使用されているXSLスタイルシートはファイルpurchaseorder.xslで、リポジトリの場所/home/OE/purchaseorder.xslに格納されています。このXML Schemaとスタイルシートも付録A「Oracleが提供するXML Schemaおよび例」に記載されています。

関連項目:

- データベース・スキーマHRの詳細は、『Oracle Databaseサンプル・スキーマ』を参照してください。

- データベース・スキーマOEの詳細は、『Oracle Databaseサンプル・スキーマ』を参照してください。

XMLデータのフォーマット出力

特に長かったり複雑なXMLデータを読みやすくするため、コード例では、出力をフォーマット出力で示す場合があります。

実行計画

このマニュアルのコード例には、実行計画を表しているものがあります。これらは、説明のためのみに使用しています。ここで示している例を自分の環境で実行すると、示された内容とは異なる実行計画になる可能性があります。

大/小文字の区別に関する注意

このマニュアルの例については、次の点に注意してください。

- SQLでは大/小文字が区別されますが、SQLコード内の名前は、二重引用符で囲まないかぎり、暗黙的に大文字であるとみなされます。

- XMLでは大/小文字が区別されます。XMLコード内では大文字と小文字を正確に使い分けてSQL名を表記する必要があります(大文字のSQL名は大文字で記述する必要があります)。

たとえば、SQLで二重引用符を使用せずにmy_tableという名前の表を作成する場合、XMLコードではこの名前をMY_TABLEとして表記する必要があります。

構文の説明

このマニュアルでは、様々なSQL、PL/SQL、その他のコマンドラインの構造体の構文を、図形式またはバッカス・ナウア(BNF)記法で説明しています。これらの説明の解釈方法は、『Oracle Database SQL言語リファレンス』を参照してください。

Oracle XML DBの新機能

この章では、Oracle Database 11gのOracle XML DBに追加された新機能、拡張機能、APIおよび製品統合サポートについて説明します。

また、非推奨になったOracle XML DBの特定の構造体についても説明します。

Oracle Database 11gリリース2(11.2.0.3)で非推奨となったOracle XML DB構造体

次のOracle XML DB構造体は、Oracle Database 11gリリース2(11.2.0.3)で非推奨になりました。これらは、下位互換用として11.2.0.3でもサポートされますが、新しいアプリケーションでは使用しないことをお薦めします。

- PL/SQLプロシージャDBMS_XDB_ADMIN.createRepositoryXMLIndex

- PL/SQLプロシージャDBMS_XDB_ADMIN.XMLIndexAddPath

- PL/SQLプロシージャDBMS_XDB_ADMIN.XMLIndexRemovePath

- PL/SQLプロシージャDBMS_XDB_ADMIN.dropRepositoryXMLIndex

- XMLスキーマの注釈(属性)csx:encodingType

- ハイブリッドXMLType記憶域のCLOB部分(オブジェクト・リレーショナル記憶域内に埋込みのCLOBデータ)上のXMLIndex索引

Oracle Database 11gリリース2 (11.2.0.3)でのOracle XML DBのその他の変更

次のPL/SQLプロシージャは、Oracle Database 11gリリース2 (11.2.0.3)でパッケージDBMS_XDBからパッケージDBMS_XDB_ADMINに移動されました。

- moveXDB_tablespace

- rebuildHierarchicalIndex

Oracle Database 11gリリース2(11.2.0.2)でのOracle XML DBの新機能

Oracle Database 11gリリース2(11.2.0.2)では、Oracle XML DBの次の機能が新たに導入されました。

XMLTypeのデフォルト記憶域モデル

XMLType表または列の作成時に記憶域モデルを指定しないと、XMLTypeのデフォルト記憶域モデルが使用されます。Oracle Database 11gリリース2(11.2.0.2)まで、デフォルトで非構造化(CLOB)記憶域が使用されていました。デフォルト記憶域モデルはバイナリXML記憶域に変更されました。

注意:
バイナリXML記憶域を使用する表を新たに作成し、CLOB記憶域を使用して格納されている既存のXMLTypeデータをその中に移入できます。CREATE TABLE AS SELECT...を使用して、既存のデータから選択します。

この機能は、Oracle Database 11gリリース2(11.2.0.2)から使用できます。

バイナリXMLのデフォルトLOB記憶域

バイナリXML記憶域モデルを使用するXMLTypeデータは、内部的にはラージ・オブジェクト(LOB)を使用して格納されます。Oracle Database 11gリリース2(11.2.0.2)まで、バイナリXMLデータはデフォルトでBasicFile LOB記憶域オプションを使用して格納されていました。今後、バイナリXMLデータのLOB記憶域では、デフォルトでSecureFile LOB記憶域オプションが可能なかぎり使用されます。

SecureFile LOB記憶域が使用できない場合は、デフォルトでBasicFile LOB記憶域が使用されます。これが起こるのは、次のいずれかに当てはまる場合です。

- XMLType表の表領域で、自動セグメント領域管理が使用されていない。

- ファイルinit.oraの設定により、SecureFile LOB記憶域を使用できない。例として、パラメータDB_SECUREFILEを参照してください。

関連項目:

- 自動セグメント領域管理の詳細は、『Oracle Database管理者ガイド』を参照してください。

- パラメータDB_SECUREFILEの詳細は、『Oracle Databaseリファレンス』を参照してください。

- 「Oracle Database 11gリリース2(11.2.0.2)で非推奨となったOracle XML DB構造体」

この機能は、Oracle Database 11gリリース2(11.2.0.2)から使用できます。

リポジトリの問合せパフォーマンスを高めるXQueryプラグマora:defaultTable

これまで、Oracle XML DBリポジトリ・リソースに対してfn:docとfn:collectionを使用するXQuery式のパフォーマンスを最適化するには、RESOURCE_VIEWとの明示的な結合を実行する必要がありました。今後は、新しいXQuery拡張式プラグマora:defaultTableにより、必要な結合が自動的に実行されます。

この機能は、Oracle Database 11gリリース2(11.2.0.2)から使用できます。

XML診断能力モード: SQL*Plusのシステム変数XMLOptimizationCheck

SQL*Plus SETコマンドで新しいシステム変数XMLOptimizationCheckを使用すると、SQLのXML診断能力モードを有効にすることができます。このモードを有効にすると、実行計画に対してXPathリライトのチェックが自動的に行われます。計画が最適でない場合は、エラーが発生し、リライトされていない演算子を示す診断情報がトレース・ファイルに書き込まれます。

この機能は、Oracle Database 11gリリース2(11.2.0.2)から使用できます。

関連項目:
「XQueryの最適化の診断: XMLOptimizationCheck」

Oracle Database 11gリリース2(11.2.0.2)で非推奨となったOracle XML DB構造体

次のOracle XML DB構造体は、Oracle Database 11gリリース2(11.2.0.2)で非推奨になりました。これらは、下位互換用として11.2.0.2でもサポートされますが、新しいアプリケーションでは使用しないことをお薦めします。

- BasicFile LOB記憶域を使用してバイナリXMLとして格納されているXMLTypeデータ。新機能「バイナリXMLのデフォルトLOB記憶域」を参照してください。

- Oracle XQuery関数ora:view: かわりに、XQuery関数fn:docおよびfn:collectionを使用してください。第5章「Oracle XML DBでのXQueryの使用」を参照してください。

Oracle Database 11gリリース2(11.2.0.1)でのOracle XML DBの新機能

Oracle Database 11gリリース2(11.2.0.1)では、Oracle XML DBの次の機能が新たに導入されました。

XMLType表および列のパーティション化

オブジェクト・リレーショナル形式で格納されたXMLTypeデータの場合、XMLType実表またはXMLType列を持つ実表をパーティション化すると、ヒープに基づく表記憶域を使用するすべてのコレクション表に対しても、デフォルトで自動的に同一レベル・パーティション化が行われるようになりました。同一レベル・パーティション化とは、実表のパーティションごとに、対応するコレクション表パーティションが存在するということです。子要素は、その親要素の実表パーティションに対応するコレクション表パーティションに格納されます。

関連項目:
「オブジェクト・リレーショナル形式で格納されたXMLTypeの表および列のパーティション化」

アクセス制御の拡張

アクセス制御リスト(ACL)が様々な方法で拡張され、カスタマイズ可能なファイングレイン・アクセス制御を行うことができます。独自の権限を定義して、柔軟な方法でそれらの権限をユーザーおよびロールに関連付けることができます。ACLで継承を使用できます。アクセス制御エントリ(ACE)では、開始日と終了日を指定できます。アプリケーションのユーザーおよびロールのアクセスを制御できます。これらは必ずしも、データベースのユーザーおよびロールと同じとはかぎりません。

関連項目:
第27章「リポジトリのアクセス制御」

リポジトリの読取りおよび書込みパフォーマンスの拡張

Oracle XML DBリポジトリの読取りおよび書込み操作のパフォーマンスが向上しました。

バイナリXMLのパフォーマンス拡張およびパーティション化

バイナリXML表に対する問合せおよびDML操作のパフォーマンスが向上しました。また、仮想列をパーティション化キーとして使用して、バイナリXML表をパーティション化できるようになりました。

XMLIndexの拡張

XMLIndexを使用すると、通常は構造化されていないコンテンツに埋め込まれた構造化XMLコンテンツのアイランドに索引を付けることができます。このためXMLIndex索引では、構造化XMLコンテンツと非構造化XMLコンテンツのどちらにも索引を付けることができます。

パーティション化されたXMLType表のデータに対して、ローカルのXMLIndex索引を作成できます。

関連項目:
「XMLIndex」

コストベースのXPathリライト

新しいオプティマイザ・ヒントを使用して、XQuery式のコストベースの最適化を要求できます。

Oracle Database 11gリリース2(11.2.0.1)で非推奨となったOracle XML DB構造体

次のOracle XML DB構造体は、Oracle Database 11gリリース2(11.2.0.1)で非推奨になりました。これらは、下位互換用として11.2.0.1でもサポートされますが、新しいアプリケーションでは使用しないことをお薦めします。

- Oracle SQL関数extract: かわりに、SQL/XML関数XMLQueryを使用してください。「Oracle XML DBのXMLQUERY SQL/XML関数」を参照してください。

- Oracle SQL関数extractValue: かわりに、SQL/XML関数XMLTable、またはSQL/XML関数XMLCastおよびXMLQueryを使用してください。

- 関数XMLTableの使用方法の詳細は、「SQL/XML関数XMLQUERYおよびXMLTABLE」を参照してください。

- 関数XMLCastおよびXMLQueryの使用方法の詳細は、「XMLCAST SQL/XML関数」を参照してください。

- Oracle SQL関数existsNode: かわりに、SQL/XML関数XMLExistsを使用してください。「XMLEXISTS SQL/XML関数」を参照してください。

- Oracle SQL関数XMLSequence: かわりに、SQL/XML関数XMLTableを使用してください。「Oracle XML DBのXMLTABLE SQL/XML関数」を参照してください。

- Oracle XPath関数ora:instanceof: かわりに、XQuery演算子instance ofを使用してください。

- Oracle XPath関数ora:instanceof-only: かわりに、XML Schema属性xsi:typeを使用してください。

- PL/SQL XMLTypeメソッドgetStringVal()、getCLOBVal()およびgetBLOBVal(): かわりに、SQL/XML関数XMLSerializeを使用してください。「XMLSERIALIZE SQL/XML関数」を参照してください。

- PL/SQL XMLTypeメソッドgetNamespace(): かわりに、XQuery関数fn:namespace-uriを使用してください。

- PL/SQL XMLTypeメソッドgetRootElement(): かわりに、XQuery関数fn:local-nameを使用してください。

- XMLTypeのファンクション索引 - かわりに、構造化コンポーネントが含まれるXMLIndexを使用してください。「ファンクション索引」を参照してください。

Oracle Database 11g リリース1(11.1)でのOracle XML DBの新機能

バイナリXML

バイナリXMLは、抽象データ型であるXMLTypeの新たな記憶域モデルであり、構造化記憶域(オブジェクト・リレーショナル)と非構造化(CLOB)記憶域の既存の記憶域モデルを結合します。バイナリXMLはXML Schemaを認識しますが、XML Schemaに基づいていないXMLデータでも使用できます。詳細は、「XMLType記憶域モデル」を参照してください。

関連項目:

- バイナリXMLとして保存されるXMLTypeデータの概要は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

- バイナリXMLとして保存されるXMLType表および列の作成の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- Javaを使用してバイナリXMLデータを操作する方法の詳細は、『Oracle Database XML Java API Reference』を参照してください。

- Cを使用してバイナリXMLデータを操作する方法の詳細は、『Oracle Database XML C APIリファレンス』を参照してください。

XMLIndex

XMLType用の新たな索引タイプXMLIndexが提供されています。これにより、XML Schemaに基づくかどうかにかかわらず、XPathに基づく述語のパフォーマンスおよびXMLTypeデータのフラグメント抽出を大幅に向上します。新しい索引タイプは(論理的な)ドメイン索引であり、基礎となる物理表と2次索引によって構成されます。第6章「XMLTypeデータの索引付け」を参照してください。

注意:
CTXSYS.CTXXPath索引は、Oracle Database 11gリリース1(11.1)で非推奨になりました。CTXXPathによって提供されていた機能は、XMLIndexで提供されるようになります。
CTXXPath索引をXMLIndex索引に置換することをお薦めします。今後リリースされるデータベースでは、CTXXPathはサポートされなくなります。

関連項目:

- 新規ビューXIDX_USER_PENDINGの詳細は、『Oracle Databaseリファレンス』を参照してください。

- 新規PL/SQLパッケージDBMS_XMLINDEXの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

XMLType OCTでのIOTに代わるヒープ記憶域の使用

XML要素のコレクションをOrdered Collections in Tables(OCT)として収集することができます。OCTでは、デフォルトでヒープ記憶域が使用されるようになりました。以前のリリースでのOCTは、デフォルトでは索引構成表(IOT)でした。新しいXML Schema登録オプション、REGISTER_NT_AS_IOTを使用すると、強制的にIOTが使用されます。

関連項目:
「オブジェクト・リレーショナルなXMLType記憶域の場合のコレクション格納方法の制御」

XML Schema注釈storeVarrayAsTableのデフォルト値をtrueに変更

以前のリリースでは、XMLスキーマ注釈storeVarrayAsTableのデフォルト値はfalseでしたが、trueに変更されました。これは、XMLコレクションがOrdered Collections in Tables(OCT)内に一連の行として格納されることを意味します。各行がコレクション内の要素に対応します。注釈がstoreVarrayAsTable = "false"となっている場合、コレクション全体がかわりにシリアライズされてLOB列にvarrayとして格納されます。

storeVarrayAsTable = "true"を使用すると、コレクションを効率的に使用して問合せ、更新、およびBツリー索引の作成を行うことができます。

関連項目:
XMLコレクションをオブジェクト・リレーショナルに格納する方法の詳細は、「オブジェクト・リレーショナルなXMLType記憶域の場合のコレクション格納方法の制御」を参照してください。

リポジトリのイベント

アプリケーションでは、リソースの作成、削除、更新など、Oracle XML DBリポジトリに関するイベントのハンドラによって、リスナーを登録できるようになりました。第30章「Oracle XML DBリポジトリ・イベント」を参照してください。

関連項目:

- 新規Javaメソッドの詳細は、『Oracle Database XML Java API Reference』を参照してください。

- 新規PL/SQLパッケージDBMS_XEVENTの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- 新規PL/SQLパッケージDBMS_RESCONFIGの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- 新規PL/SQLパッケージDBMS_XDBRESOURCEの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

Content Repository API for Javaのサポート(JCR: JSR-170)

Oracle XML DBでは、新たにContent Repository API for Java(JCR)とJSR-170標準をサポートします。JCRのAPIを使用し、Oracle XML DBリポジトリにアクセスできるようになります。第31章「Oracle XML DB Content Connectorの使用」を参照してください。

関連項目:
新規Javaメソッドの詳細は、『Oracle Database XML Java API Reference』を参照してください。

リポジトリ・リソースの新しいリンク・タイプ

弱いフォルダ・リンクを作成し、Oracle XML DBリポジトリのフォルダと子の関係を表せるようになりました。ハード・リンクも引き続き使用できます。「リンク・タイプ」を参照してください。

関連項目:

- PL/SQLパッケージDBMS_XDBの最新情報は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- under_path関数の最新情報は、『Oracle Database SQL言語リファレンス』を参照してください。

WebDAV権限と新規Oracle XML DB権限のサポート

Oracle XML DBリポジトリで、すべてのWebDAV権限がサポートされるようになりました。さらに、Oracle XML DB固有の基本権限もいくつか新たに用意されています。第27章「リポジトリのアクセス制御」を参照してください。

関連項目:

- 新規PL/SQLパッケージDBMS_NETWORK_ACL_ADMINの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- 新規PL/SQLパッケージUTL_TCPの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- 新規PL/SQLパッケージUTL_INADDRの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

Webサービス

Webサービスを通じてOracle Databaseにアクセスできるようになりました。SQLまたはXQueryを使用し、データベースに問い合せるWebサービスを作成およびデプロイするか、保存されたPL/SQL関数やプロシージャにアクセスできます。第33章「ネイティブなOracle XML DB Webサービスの使用」を参照してください。

インプレースXML Schemaの拡張

ほとんどのケースで、対応するXMLインスタンス・ドキュメントをコピーせずに、XML Schemaを拡張できるようになりました。第10章「XML Schemaの拡張」を参照してください。

関連項目:
PL/SQLパッケージDBMS_XMLSCHEMAの最新情報は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

再帰的なXML Schemaのサポート

Oracle XML DBでは、XMLデータが再帰的XML schemaに準拠する場合でも、複数または任意の深さのノード上で、XPath式に'//'を使用する一部の問合せに対してXPathリライトを実行できるようになりました。「再帰的スキーマのサポート」を参照してください。

関連項目:
PL/SQLパッケージDBMS_XMLSCHEMAの最新情報は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

XLinkおよびXIncludeのサポート

Oracle XML DBでは現在、XLinkとXInclude標準をサポートしています。第23章「Oracle XML DBでのXLinkおよびXIncludeの使用」を参照してください。

XML変換のサポート

自然言語の変換情報を、XML schemaおよび対応するインスタンス・ドキュメントに関連付けられるようになりました。これには、標準属性xml:langとxml:srclangのサポートも含まれます。「XML変換」を参照してください。

関連項目:
新規PL/SQLパッケージDBMS_XMLTRANSLATIONSの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

大規模なXMLノードのサポート

テキスト・ノードおよび属性値に対する64Kの制限が解除されました。テキスト・ノードと属性値は、それぞれ64Kバイトの制限は受けなくなります。PL/SQL、Java、およびCで使用可能な、プッシュ型およびプル型のストリーミングAPIにより、実質的に無制限のノード・サイズが可能になります。PL/SQLで大規模なノードを扱う方法の詳細は、「DBMS_XMLDOMを使用した大規模ノードの処理」、および「Javaを使用した大規模ノードの処理」を参照してください。

関連項目:

- バイナリXMLとして保存されるXMLType表および列の作成の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- 新規Javaメソッドの詳細は、『Oracle Database XML Java API Reference』を参照してください。

- 新規PL/SQLパッケージDBMS_SDAの詳細、およびPL/SQLパッケージDBMS_XMLDOMの最新情報は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

Java APIの統合

Oracle XML DBおよびOracle XML Developer's KitのJava XML APIが統合されました。

関連項目:

- 『Oracle XML Developer's Kitプログラマーズ・ガイド』

- 『Oracle Database XML Java API Reference』のoracle.xml.parser.v2パッケージに関する項

Oracle Data PumpによるXMLTypeサポート

XMLTypeデータのインポートおよびエクスポートの方法として、Oracle Data Pumpをお薦めします。第36章「XMLType表のエクスポートおよびインポート」を参照してください。

Oracle Streamsおよびロジカル・スタンバイによるXMLTypeのサポート

Oracle Streamsおよびロジカル・スタンバイでは現在、CLOBとして保存されるXMLTypeがサポートされています。XML Schemaに基づくデータと基づかないデータの両方がサポートされています。

関連項目:

- 『Oracle Streams概要および管理』

- 『Oracle Data Guard概要および管理』

- 『Oracle Databaseユーティリティ』

- ビューDBA_STREAMS_UNSUPPORTEDおよびDBA_STREAMS_COLUMNSの詳細は、『Oracle Databaseリファレンス』を参照してください。

Oracle XML Developer's Kit Pull-Parser API(XMLイベント、JSR-173)

Oracle XML DBでは、新しいOracle XML Kit(XDK)のPull Parser APIを使用できます。「Oracle XML DBでのOracle XML Developer's Kit Pull Parserの使用」を参照してください。

関連項目:

- 新規Cメソッドおよび型の詳細は、『Oracle Database XML C APIリファレンス』を参照してください。

- 『Oracle XML Developer's Kitプログラマーズ・ガイド』

XQueryの標準準拠

Oracle XML DBによるXQuery言語のサポートが更新され、XQuery標準の最新バージョン、W3C XQuery 1.0勧告が反映されています。

関連項目:

- 『Oracle XML Developer's Kitプログラマーズ・ガイド』

- XQuery言語の詳細は、http://www.w3.orgを参照してください。

PL/SQLを使用した、ネットワーク・サービスへのファイングレイン・アクセス

アクセス制御エントリ(ACE)に、新しい基本権限が提供されます。これらの権限は、ネットワーク・サービスへのファイングレインPL/SQLアクセスで使用されます。

SQL/XML標準準拠とパフォーマンスの拡張

Oracle XML DBによるSQL/XML標準のサポートが更新され、最新バージョンの標準が反映されています。これには、標準的なSQL関数XMLExistsおよびXMLCastのサポートなどがあります。「SQL/XML関数XMLExistsおよびXMLCastを使用したXMLTypeデータの問合せ」および「SQL関数を使用したXMLの生成」を参照してください。

関連項目:
SQL/XML関数XMLExists、XMLCast、XMLQuery、XMLTableおよびXMLForestの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

XML-Updateのパフォーマンス拡張

XMLデータの更新に使用されるSQL関数のパフォーマンスが、オブジェクト・リレーション形式で保存されるXML Schemaに基づくデータ向けに強化されました。これには、SQL関数updateXML、insertChildXMLおよびdeleteXMLのXPathリライトが含まれます。

XQueryおよびSQL/XMLパフォーマンスの拡張

XQueryとSQL/XMLにあるパフォーマンス拡張機能には、次に示す項目の処理などがあります。

- ユーザー定義のXQuery関数

- XQueryプロローグ変数

- SQL/XML生成関数を使用した結果に適用されるXQuery count関数

- XPath述語の位置指定式

- XQuery計算済コンストラクタ

- SQL/XML関数XMLAgg

XSLTパフォーマンス拡張機能

SQL関数XMLTransformおよびXMLTypeメソッドtransform()を使用したXSLT変換のパフォーマンスが強化されました。

第I部

Oracle XML DBの基礎

このマニュアルの第I部では、Oracle XML DBについて説明します。次の章で構成されます。

- 第1章「Oracle XML DBの概要」

- 第2章「Oracle XML DBを使用する前に」

- 第3章「Oracle XML DBの使用」

1 Oracle XML DBの概要

この章では、Oracle XML DBの機能およびアーキテクチャについて説明します。内容は次のとおりです。

- Oracle XML DBの概要

- Oracle XML DBのアーキテクチャ

- Oracle XML DBの機能

- Oracle XML DBのメリット

- Oracle Textを使用したXMLデータの検索

- Oracle Streamsアドバンスト・キューイングを使用したメッセージ・アプリケーションの構築

- Oracle XML DBでサポートされている標準

- Oracle XML DBの技術サポート

- このマニュアルで使用するOracle XML DBの例

- 詳細なOracle XML DBの事例およびデモ

Oracle XML DBの概要

Oracle XML DBは、XMLデータの格納、生成、アクセス、検索、検証、変換、拡張および索引付けなどの高パフォーマンスの処理に関連する一連のOracle Databaseテクノロジです。SQLとXMLの両方のデータ・モデルの相互運用を可能にすることで、ネイティブなXMLサポートを提供します。Oracle XML DBは、Oracle9iリリース2 (9.2)以上のOracle Databaseに組み込まれています。

Oracle XML DBには、次のような機能があります。

- XMLデータの抽象SQLデータ型であるXMLTypeが用意されています。

- XMLコンテンツの信頼性、可用性、拡張性、堅牢なセキュリティなど、企業レベルのOracle Database機能を提供します。XML固有のメモリーを管理および最適化します。

- 業界標準の方法で、XMLデータをアクセスおよび更新できます。標準には、SQL/XML標準や、World Wide Web Consortium(W3C)が公開したXPathやXQuery用のXMLおよびXML Schemaのデータ・モデルと勧告などがあります。FTP、HTTP(S)およびWebDAVを使用して、XMLコンテンツをOracle Databaseの内外に移動できます。業界標準のAPIにより、Java、CおよびPL/SQLを使用してXMLコンテンツのプログラム・アクセスおよび操作を行うことができます。

- SQLを使用してXMLデータにアクセスし、同時にそのデータを格納、更新および変換できます。

- SQLデータに対してXML操作を実行できます。

- 単純で軽量なリポジトリであるOracle XML DBリポジトリが備わっています。このリポジトリによって、ファイル/フォルダ/URL隠喩を使用して、XMLコンテンツを含むデータベース・コンテンツを編成および管理できます。

- 異なるシステムのデータにゲートウェイを介してアクセスし、1つの共通のデータ・モデルとして組み合せることができます。これによって、異なるストアのデータを処理する必要があるアプリケーション開発の複雑さが低減されます。

- Oracle XML DBをOracle XML Developer's Kit(XDK)と組み合せて使用し、Oracle Application ServerまたはOracle Databaseの中間層で動作するアプリケーションを構築できます。

関連項目:

- 「XMLTypeデータ型」

- http://www.oracle.com/technetwork/database-features/xmldb/overview/index.htmlのOracle XML DBに関する最新情報およびホワイト・ペーパー

- 『Oracle XML Developer's Kitプログラマーズ・ガイド』

Oracle XML DBのアーキテクチャ

図1-1および図1-2に、Oracle XML DBのソフトウェア・アーキテクチャを示します。主な特徴は次のとおりです。

- XMLType表およびビューの記憶域。

- XMLType表およびビューは、XMLIndex、BツリーおよびOracle Text索引を使用して索引付けできます。

- XMLTypeビュー内のデータは、ローカル表またはリモート表に格納できます。リモート表には、データベース・リンクを使用してアクセスできます。

- Oracle XML DBリポジトリ。Oracle XML DBに登録されるXML Schemaに関連付けられたXML文書など、任意の種類のドキュメントをリポジトリに格納できます。リポジトリ内のドキュメントには、次のいずれかの方法でアクセスできます。

- HTTPプロトコル・ハンドラを介したHTTP(S)

- WebDAVおよびFTPプロトコル・ハンドラを介したWebDAVおよびFTP

- Java Database Connectivity(JDBC)などのOracle Net Servicesを介したSQL

- Oracle Streamsアドバンスト・キューイング(AQ)およびWebサービスを使用したXMLデータのメッセージ機能がサポートされています。

図1-1 XMLType記憶域およびOracle XML DBリポジトリ

図1-2 XMLType記憶域

関連項目:

- 第II部「Oracle XML DBからのXMLデータの格納および取出し」

- 第28章「プロトコルを使用したリポジトリへのアクセス」

- 第37章「Oracle Streams AQを使用したXMLデータの交換」

XML用のAPI

表1-1に、XMLデータの操作に使用できるPL/SQL、CおよびC++のApplication Programming Interface(API)の参照ドキュメントを示します。PL/SQL、CおよびC++のAPIの主なリファレンスは、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』です。

関連項目:
Java APIs for XMLの詳細は、『Oracle Database XML Java API Reference』を参照してください。

表1-1 XMLに関連するAPI

API

ドキュメント

説明

XMLType

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「XMLType」の章、『Oracle Database XML C APIリファレンス』および『Oracle Database XML C++ APIリファレンス』

XMLTypeデータのXML操作(検証、変換)で使用するPL/SQL、CおよびC++のAPI

データベースURIタイプ

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「データベースURIタイプ」

様々なURIタイプに使用される関数

DBMS_METADATA

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_METADATA」

データベース・ディクショナリからメタデータをXMLとして取り出す、または関連付けられているオブジェクトを再作成するために作成DDLを取り出してXMLを送信するためのPL/SQL API

DBMS_RESCONFIG

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_RESCONFIG」

リソース構成リストを操作し、リソースのリスナー情報を取り出すPL/SQL API

DBMS_XDB

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XDB」

Oracle XML DBリポジトリ・リソース、ACLベースのセキュリティ、および構成セッションを管理するためのPL/SQL API

DBMS_XDB_ADMIN

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XDB_ADMIN」

Oracle XML DBリポジトリのXMLIndex索引などのOracle XML DBの各種機能を管理するためのPL/SQL API

DBMS_XDBRESOURCE

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XDBRESOURCE」

リポジトリ・リソース・メタデータおよびコンテンツを操作するPL/SQL API

DBMS_XDBT

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XDBT」

リポジトリ・リソースにテキスト索引を作成するためのPL/SQL API

DBMS_XDB_VERSION

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XDB_VERSION」

リポジトリ・リソースのバージョン管理のためのPL/SQL API

DBMS_XDBZ

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XDBZ」

Oracle XML DBリポジトリのACLベースのセキュリティ

DBMS_XEVENT

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XEVENT」

イベント関連のタイプを提供し、インタフェースをサポートするPL/SQL API

DBMS_XMLDOM

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XMLDOM」

DOM API for XMLTypeのPL/SQL実装

DBMS_XMLGEN

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XMLGEN」

SQL問合せ結果を正規のXML形式に変換するためのPL/SQL API

DBMS_XMLINDEX

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XMLINDEX」

PL/SQL API for XMLIndex

DBMS_XMLPARSER

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XMLPARSER」

DOM Parser API for XMLTypeのPL/SQL実装

DBMS_XMLSCHEMA

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XMLSCHEMA」

Oracle Database内のXML Schemaを管理(スキーマの登録、削除)するためのPL/SQL API

DBMS_XMLSTORE

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XMLSTORE」

XMLデータをリレーショナル表に格納するためのPL/SQL API

DBMS_XSLPROCESSOR

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_XSLPROCESSOR」

XSLTプロセッサのPL/SQL実装

XML関連のカタログ・ビュー

表1-2に、XML関連のカタログ・ビューのリストを示します。特定のビューに関する情報を取得するには、SQLコマンドDESCRIBEを使用します。

DESCRIBE USER_XML_SCHEMAS

表1-2 XMLに関連するカタログ・ビュー

スキーマ

説明

USER_XML_SCHEMAS

現行ユーザーが所有する登録済のXML Schema

ALL_XML_SCHEMAS

現行ユーザーが使用できる登録済のXML Schema

DBA_XML_SCHEMAS

Oracle XML DBに存在する登録済のXML Schema

USER_XML_TABLES

現行ユーザーが所有するXMLType表

ALL_XML_TABLES

現行ユーザーが使用できるXMLType表

DBA_XML_TABLES

Oracle XML DBに存在するXMLType表

USER_XML_TAB_COLS

現行ユーザーが所有するXMLType表の列

ALL_XML_TAB_COLS

現行ユーザーが使用できるXMLType表の列

DBA_XML_TAB_COLS

Oracle XML DBに存在するXMLType表の列

USER_XML_VIEWS

現行ユーザーが所有するXMLTypeビュー

ALL_XML_VIEWS

現行ユーザーが使用できるXMLTypeビュー

DBA_XML_VIEWS

Oracle XML DBに存在するXMLTypeビュー

USER_XML_VIEW_COLS

現行ユーザーが所有するXMLTypeビューの列

ALL_XML_VIEW_COLS

現行ユーザーが使用できるXMLTypeビューの列

DBA_XML_VIEW_COLS

Oracle XML DBに存在するXMLTypeビューの列

ビューALL_XML_TABLES、DBA_XML_TABLESおよびUSER_XML_TABLESに加えて、ビューALL_OBJECT_TABLES、DBA_OBJECT_TABLESおよびUSER_OBJECT_TABLESはオブジェクト・リレーショナル形式で格納されたXMLTypeデータの表領域、その他の記憶域に関する情報を提供します。

関連項目:

- 『Oracle Databaseリファレンス』

- 『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

Oracle XML DBリポジトリの概要

Oracle XML DBリポジトリは、ファイル/フォルダ/URL隠喩を使用してXMLデータを処理するためのOracle Databaseのコンポーネントです。このリポジトリには、リソースが含まれ、これはフォルダ(ディレクトリ、コンテナ)またはファイルのいずれかです。

リソースには次のような特性があります。

- パスおよび名前で識別されます。

- これにはコンテンツ(データ)が含まれ、XMLデータの場合がありますが、そうでなくてもかまいません。

- コンテンツに加えて、OwnerやCreationDateなどのシステム定義のメタデータ(プロパティ)のセットを持ちます。Oracle XML DBでは、この情報を使用してリソースを管理します。

- ユーザー定義のメタデータを持つ場合もあります。これは、システム定義のメタデータと同様に、コンテンツの一部ではないが、コンテンツに関連付けられている情報です。

- リソースにアクセスできる人およびその目的の操作を決定するアクセス制御リストが関連付けられています。

Oracle XML DBリポジトリは特にXMLコンテンツを取り扱うものですが、リポジトリを使用してXML以外の種類のデータを格納することもできます。リポジトリを使用して、Oracle Databaseに格納されているあらゆるデータにアクセスできます。

リポジトリ内のデータには、次の方法でアクセスできます(図1-1を参照)。

- SQL: ビューRESOURCE_VIEWおよびPATH_VIEWを使用

- PL/SQL: パッケージDBML_XDBを使用

- Java: Oracle XML DB Resource API for Javaを使用

関連項目:

- 第V部「Oracle XML DBリポジトリ」

- 外部プロトコルを使用してXMLType表および列のXMLデータにアクセスする方法の詳細は、第28章「プロトコルを使用したリポジトリへのアクセス」を参照してください。

- 第29章「ユーザー定義のリポジトリ・メタデータ」

XMLサービス

Oracle XML DBは、リポジトリ・データにアクセスおよび操作するためのAPIに加えて、次のリポジトリ・サービス用のAPIも提供します。

- バージョニング: Oracle XML DBは、PL/SQLパッケージDBMS_XDB_VERSIONを使用して、Oracle XML DBリポジトリ内にあるリソースのバージョニングを行います。リソースを更新すると、新しいバージョンが作成されます。前のバージョンは保持されます。バージョニングは、IETF WebDAV標準に基づいてサポートされます。

- ACLセキュリティ: リポジトリのセキュリティは、アクセス制御リスト(ACL)に基づいています。各リソースには、そのリソースを様々な方法で使用するために必要な権限をリストしたACLが関連付けられています。リソースへのアクセスまたは操作の際に、リクエストした操作が許可されるかどうかはACLによって決まります。ACLは、一連のアクセス制御エントリ(ACE)が含まれたXML文書です。特定ユーザーまたはグループ(データベース・ロール)に対する一連の権限の付与または取消しは、ACEごとに行われます。このアクセス制御メカニズムは、WebDAV仕様に基づいています。

- フォルダリング: Oracle XML DBリポジトリでは、他のリソース(ファイルまたはフォルダ)を含むフォルダ(つまりディレクトリ)・リソースの永続階層が管理されます。プロトコル・サーバー、XML Schema Manager、Oracle XML DBのRESOURCE_VIEW APIなど、その他のOracle XML DBモジュールでは、フォルダリングを使用してリポジトリのパス名がターゲット・リソースにマップされます。

ビューRESOURCE_VIEWおよびPATH_VIEW

ビューRESOURCE_VIEWおよびPATH_VIEWでは、FTPやWebDAVなどのプロトコルを介してOracle XML DBリポジトリ内のデータにSQLでアクセスできます。ビューPATH_VIEWには、リポジトリの一意のパスごとに1つの行が存在します。ビューRESOURCE_VIEWには、リポジトリのリソースごとに1つの行が存在します。

Oracle XML DB Resource API for PL/SQLであるDBMS_XDBは、問合せおよびDML関数を提供します。これはRESOURCE_VIEWおよびPATH_VIEWに基づいています。

関連項目:

- 第25章「RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス」

- ビューPATH_VIEWの詳細は、『Oracle Databaseリファレンス』を参照してください。

- ビューRESOURCE_VIEWの詳細は、『Oracle Databaseリファレンス』を参照してください。

Oracle XML DBリポジトリのアーキテクチャ

図1-3に、Oracle XML DBリポジトリのアーキテクチャを示します。

関連項目:

- 第21章「Oracle XML DBリポジトリのデータへのアクセス」

- 第25章「RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス」

図1-3 Oracle XML DBリポジトリのアーキテクチャ

ファイルおよびフォルダ

従来、リレーショナル・データベースは、階層構造の管理や、パスまたはURLの検索には適していません。Oracle XML DBリポジトリを使用すると、データベース内のXMLコンテンツを階層構造に整理できます。ファイルやフォルダを使用して整理した場合と同様の問合せおよび管理が可能になります。

リレーショナル表/行/列隠喩は、高度に構造化されたデータの管理に効果的なモデルです。ドキュメント指向のXMLデータなど、半構造化されたデータまたは構造化されていないデータの管理には、あまり効果的ではない可能性があります。

たとえば、1冊の本を表の一連の行として表すのは容易ではありません。本は冊-章-節-段落のような階層として表すのが一般的で、その階層は一連のフォルダおよびサブフォルダとして表すことができます。

- 階層リポジトリ索引によって、フォルダとパスの検索が高速化されます。Oracle XML DBには、特許を取得した階層索引が含まれており、この階層索引によってOracle XML DBリポジトリ内のフォルダとパスの検索が高速化されます。階層リポジトリ索引はエンド・ユーザーに対して透過的で、Oracle XML DBでは、従来のファイル・システムと同等以上の速度でフォルダとパスの検索を実行できます。

- Oracle XML DBリポジトリ内のXML文書には、SQL、PL/SQL、Java、Cの各言語に加えて、FTP、HTTP(S)、WebDAVなど標準の接続アクセス・プロトコルを使用してアクセスできます。Oracle XML DBリポジトリでは、コンテンツの作成者と編集者は、Oracle Databaseに格納されたXMLコンテンツに直接アクセスできます。

- ここで説明するリソースとは、URLにより識別されるファイルまたはフォルダのことです。WebDAVは、HTTPプロトコルへの一連の拡張を定義するIETF標準です。これによりHTTPサーバーはDAV対応クライアントに対するファイル・サーバーとして機能できます。たとえば、WebDAV対応エディタは、HTTP/WebDAVサーバーがファイル・システムであるかのように対話できます。DAV標準では、ファイルやフォルダを示すためにリソースという用語が使用されます。WebDAVサーバーにより管理される各リソースは、URLで識別されます。Oracle XML DBにより、これらのプロトコルのネイティブ・サポートがOracle Databaseに追加されます。これらのプロトコルはドキュメント中心の操作用に設計されています。これらのプロトコルをサポートすることにより、Oracle XML DBでは、Microsoft Windows Explorer、Microsoft Office、およびAltovaやAdobeなどのベンダーからの製品が、Oracle XML DBリポジトリに格納されたXMLコンテンツを直接操作できます。図1-4に、Webブラウザで表示した場合のリポジトリのルート・レベルのディレクトリを示します。

図1-4 Webブラウザに表示されたOracle XML DBリポジトリ

関連項目:
第3章「Oracle XML DBの使用」

このように、Microsoft Windows ExplorerなどのWebDAVクライアントは、Oracle XML DBリポジトリに直接接続できます。Oracle Database、Microsoft社固有のソフトウェア、または他の複雑なミドルウェアを追加する必要はありません。エンド・ユーザーは、操作に慣れているツールとインタフェースを使用してOracle XML DBリポジトリを直接操作できます。

Oracle XML DBプロトコルのアーキテクチャ

Oracle XML DBアーキテクチャの主要な特徴の1つは、共有サーバー構成も含めて、HTTP(S)、WebDAVおよびFTPプロトコルがサポートされていることです。リスナーがHTTP(S)またはFTPリクエストを受信すると、サービスを提供するOracle Databaseの共有サーバー・プロセスにそのリクエストを渡し、適切な応答をクライアントに戻します。TNSリスナー・コマンドlsnrctl statusを使用すると、HTTP(S)およびFTPがサポートされていることを確認できます。例1-1に、これを示します。

例1-1 FTPおよびHTTP(S)プロトコルがサポートされているリスナーの状態

LSNRCTL for 32-bit Windows: Version 11.1.0.5.0 - Production on 20-AUG-2007 16:02:34

Copyright (c) 1991, 2007, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521))) STATUS of the LISTENER
--------------------------------------------------------------------------------------------
Alias                          LISTENER
Version                        TNSLSNR for 32-bit Windows: Version 11.1.0.5.0 - Beta
Start Date                     20-JUN-2007 15:35:40
Uptime                         0 days 16 hr. 47 min. 42 sec
Trace Level                    off
Security                       ON: Local OS Authentication
SNMP                           OFF
Listener Parameter File        C:\oracle\product\11.1.0\db_1\network\admin\listener.ora
Listener Log File              c:\oracle\diag\tnslsnr\quine-pc\listener\alert\log.xml

Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\\.\pipe\EXTPROC1521ipc)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=quine-pc.example.com)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=quine-pc.example.com)
(PORT=21))(Presentation=FTP)(Session=RAW)) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=quine-pc.example.com)
(PORT=443))(Presentation=HTTP)(Session=RAW))
Services Summary...
Service "orcl.example.com" has 1 instance(s).
Instance "orcl", status READY, has 1 handler(s) for this service...
Service "orclXDB.example.com" has 1 instance(s).
Instance "orcl", status READY, has 1 handler(s) for this service...
Service "orcl_XPT.example.com" has 1 instance(s).
Instance "orcl", status READY, has 1 handler(s) for this service...
The command completed successfully

関連項目:
第28章「プロトコルを使用したリポジトリへのアクセス」

Oracle XML DBへのプログラム・アクセス(Java、PL/SQLおよびC)

すべてのOracle XML DB機能には、C、PL/SQLおよびJavaからアクセスできます。次のような方法で、Webベースのアプリケーションを構築できます。

- サーブレットおよびJava Server Pages(JSP)を使用する方法。標準的なAPIでは、Java Database Connectivity(JDBC)を使用してデータにアクセスします。

- Extensible Stylesheet Language (XSL)とXML Server Pages (XSP)を使用する方法。一般的なAPIでは、Document Object Model (DOM) API実装を使用して処理されるXML文書の形式のデータにアクセスします。

Oracle XML DBでは、このようなスタイルのアプリケーション開発をサポートします。DOM APIのJava、PL/SQLおよびCの実装を提供します。サーブレットに基づくアプリケーションなどJDBCを使用するアプリケーションの場合は、処理対象のデータ構造を事前に理解しておく必要があります。Oracle JDBCドライバにより、XMLType表および列にアクセスおよび更新し、Oracle XML DBリポジトリにアクセスするPL/SQLプロシージャをコールできます。XSLT変換に基づくアプリケーションなどDOMを使用するアプリケーションの場合、通常、データ構造に関する理解はそれほど必要ありません。DOMベースのアプリケーションは文字列名を使用してコンテンツを識別するため、DOMツリーを動的に移動して必要な情報を検索する必要があります。このため、Oracle XML DBは、XMLType列および表にアクセスおよび更新するために、DOM APIの使用をサポートします。DOM APIへのプログラミングは、JDBCを使用したプログラミングよりも柔軟性がありますが、実行時により多くのリソースを必要とする場合があります。

Oracle XML DBの機能

XMLの管理に使用するデータベースは、XML文書を永続的に保持できる必要があります。Oracle XML DBは、それ以上の機能を備えています。トランザクション制御、データ整合性、レプリケーション、信頼性、可用性、セキュリティ、拡張性のような、標準的なデータベース機能を提供する一方で、XML中心の方法でXML文書の効果的な索引付け、問合せ、更新および検索を実行できます。

XMLの階層構造によって、従来のリレーショナル・データベースのいくつかの問題点が示されます。

- リレーショナル・データベースでは、表/行隠喩を使用してコンテンツを検索します。主キーと外部キーの関係は、コンテンツ間の関係を定義するのに有効です。コンテンツは、表/行/列隠喩を使用してアクセスおよび更新します。

- これに対してXMLでは、階層テクニックを使用して、同じ処理を実行します。つまり、URLを使用してXML文書を検索します。XML文書間の関係を定義するには、XLinkなどURLベースの標準を使用します。XML文書内に含まれるコンテンツへのアクセスと更新には、XPathなどのW3C勧告を使用します。URLとXPath式は、いずれも階層隠喩に基づいています。URLは、フォルダ階層からパスを使用してドキュメントを識別するのに対し、XPathは、XML文書のノード階層からパスを使用してXML文書の一部にアクセスします。

Oracle XML DBでは、これらの問題点に対処するために、SQL関数とメソッドが導入されています。これらによって、XQuery式やXPath式などXML中心の隠喩を使用して、XML文書を問合せおよび更新できます。

Oracle XML DBの主要な機能は次のとおりです。

- XMLTypeデータ型

- XML Schemaのサポート

- XMLType記憶域モデル

- XMLとSQLの双対性

- SQL/XML標準関数

- XQuery式とXPath式の自動リライト

- Oracle XML DBリポジトリの概要。この機能は、すでに説明しました。

XMLTypeデータ型

XMLTypeは、XMLデータの抽象ネイティブSQLデータ型です。XML Schemaの検証やXMLコンテンツのXSL変換のような操作を可能にする方法を提供します。他のSQLデータ型と同じようにXMLTypeを使用できます。たとえば、次のような操作を実行する場合、XMLTypeを使用できます。

- リレーショナル表の列の作成

- PL/SQL変数の宣言

- PL/SQLプロシージャまたはファンクションの定義とコール

XMLTypeはOracle Databaseオブジェクト型であるため、XMLTypeオブジェクト・インスタンスの表も作成できます。デフォルトでは、XMLType表または列に整形式のXML文書を含めることができます。

関連項目:
Oracle Databaseのオブジェクト型およびオブジェクト・リレーショナル形式の記憶域の詳細は、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照してください。

XML Schemaに準拠したXMLType表および列

XMLType表または列は、XML Schemaに準拠するように制約することができます。これには、次のようなメリットがあります。

- データベースでは、XML Schemaに対して検証済のXML文書のみが列または表に格納されることが保証されます。無効な文書は除外されます。

- XML Schemaに基づくデータは事前定義のXML構造に準拠しているため、Oracle XML DBでは、XML Schemaに含まれる情報を使用して、データの最適な問合せと更新処理を実行できます。

- XML Schemaに基づくデータを構造化記憶域を使用して格納すると、Oracle XML DBによって自動的に分解され、一連のオブジェクト・リレーショナル・オブジェクトとして格納されます。文書を格納するためのオブジェクト・リレーショナル・モデルは、XML Schemaから導出されます。

XMLType API

データ型XMLTypeによって、次のものが提供されます。

- XMLTypeインスタンスをVARCHAR、CLOB、BLOBまたはBFILEの値から作成するために使用できるコンストラクタ。

- XMLTypeインスタンスに対して動作するXML固有のメソッド。内容は次のとおりです。

- extract(): XMLTypeに格納されたノードのサブセットを抽出

- existsNode(): XMLTypeに特定のノードが存在するかどうかを確認

- schemaValidate(): XMLTypeインスタンスのコンテンツをXML Schemaに対して検証

- transform(): XMLTypeインスタンスのコンテンツのXSL変換

関連項目:
第4章「XMLTypeの操作」および第11章「XMLTypeデータの変換および検証」

XML Schemaのサポート

Worldwide Web Consortium (W3C)のXML Schema勧告のサポートはOracle XML DBの主要な機能の1つです。XML Schemaでは、XML文書の構造、コンテンツおよび特定のセマンティクスを指定します。詳細は、http://www.w3.org/TR/xmlschema-0/を参照してください。

W3Cのスキーマ・ワーキング・グループは、特定のXML Schema(,スキーマのスキーマと呼ばれることが多い)を公開し、これによりXML Schema言語の定義またはボキャブラリが提供されます。XML Schema定義(XSD脚注 1 )はXML Schemaとも呼ばれ、スキーマのスキーマによって定義されたボキャブラリに準拠するXML文書です。

XML Schemaでは、スキーマのスキーマで定義されたボキャブラリを使用して、XML Schema型定義のコレクションおよび要素宣言を作成します。この要素宣言は、新しいクラスのXML文書(そのXML Schemaに準拠するXMLインスタンス・ドキュメント)のコンテンツと構造を記述するボキャブラリを構成します。

注意:
このマニュアルで使用している「XML Schema」という用語は、W3CのXML Schema勧告に準拠しているスキーマを指します。XML SchemaはXML文書のクラスを定義するために使用されるため、「インスタンス・ドキュメント」という用語は、多くの場合、特定のXML Schemaに準拠するXML文書を示すために使用しています。

XML Schema言語によって、要素と属性の厳密な型指定が可能になります。多数くのスカラー・データ型を定義します。このデータ型のベース・セットは、継承および拡張などのオブジェクト指向テクニックを使用して、より複合的な型を定義するように拡張できます。また、XML Schemaボキャブラリには、複合型、代替グループ、繰返しセット、ネスト、順序付けなどを定義するために使用できる構造体が含まれます。Oracle XML DBは、XML Schema勧告で定義されたすべての構造体をサポートします(redefinesを除く)。

XML Schemaは、一般的に、XMLインスタンス・ドキュメントがそれぞれの仕様に準拠していることを確認(検証)するためのメカニズムとして使用されます。Oracle XML DBには、XMLTypeメソッドとSQL関数が含まれ、それらを使用してXML文書をXML Schemaに対して検証できます。

Oracle XML DBでは、データが構造化されているかどうかに関係なく、すべてのデータで標準データ・モデルを使用できます。XML Schemaを使用すると、XMLデータを格納するためのデータベース表を自動的に作成できます。XML Schemaに基づくデータはDOM再現性を保持し、データベースの大幅な最適化を実現します。

XML Schemaに基づくデータは、Oracle XML DBの任意のXMLType記憶域モデル(バイナリXML記憶域、構造化(オブジェクト・リレーショナル)記憶域、非構造化(CLOB)記憶域)を使用して格納できます。XML Schemaに基づかないXMLデータは、バイナリXML記憶域または非構造化記憶域を使用して格納できます。

また、既存のリレーショナル・データおよびオブジェクト・リレーショナル・データをXMLTypeビューとしてラップすることもできます(オプションでXML Schemaに基づく形式にできます)。受信したXML文書からXMLType記憶域にマップし、登録済のXML Schemaを使用してそのマッピングを指定できます。

関連項目:
Oracle XML DBでのXML Schemaの使用に関する詳細は、第7章「XML Schemaの格納と問合せ: 基本」を参照してください。

XMLType記憶域モデル

XMLTypeは、データおよびその使用を最適にするための様々な記憶域モデルを提供する抽象データ型です。抽象データ型であるため、アプリケーションおよびデータベース問合せの柔軟性が増し、同じインタフェースをすべてのXMLType操作に使用できます。異なる記憶域(永続性)モデルが使用可能であるため、パフォーマンスおよび機能を、使用するXMLデータの種類やその使用パターンに最適となるように調整できます。このため、Oracle XML DBを使用してXMLデータをXMLTypeとして永続的に保持する場合は、どの記憶域モデルをどのXMLデータに使用するかを決定する必要があります。

XMLType記憶域モデルは、データベースのインポートおよびエクスポート(第36章「XMLType表のエクスポートおよびインポート」を参照)を使用して切り替えることができます。アプリケーション・コードの変更は不要です。アプリケーションをチューニングする際に、XML記憶域オプションを変更できます。

XMLType表および列は、次に示す方法で格納できます。

- 構造化記憶域: XMLTypeデータは、一連のオブジェクトとして格納されます。これは、オブジェクト・リレーショナル記憶域およびオブジェクトベースの永続性とも呼ばれます。

- 非構造化記憶域: XMLTypeデータは、キャラクタ・ラージ・オブジェクト(CLOB)インスタンスに格納されます。これは、CLOB記憶域およびテキストベースの永続性とも呼ばれます。

- バイナリXML記憶域: XMLTypeデータは、XMLデータ専用に設計された事後解析のバイナリ形式で格納されます。バイナリXMLは、簡潔で事後解析型であり、XML Schema対応のXMLです。これは、事後解析の永続性とも呼ばれます。

Oracle Databaseには、SecureFileとBasicFileの2つのLOB記憶域オプションが用意されています。いずれも、非構造化(CLOBベースの)XMLType記憶域で使用できます。BasicFile LOB記憶域は、非構造化記憶域のデフォルトです。

バイナリXMLデータの場合、SecureFileがデフォルトの記憶域オプションです。脚注 2 ただし、次のいずれかに当てはまる場合、SecureFile LOB記憶域は使用できません。その場合は、BasicFileがバイナリXMLデータのデフォルト・オプションになります。

- XMLType表の表領域で、自動セグメント領域管理が使用されていない。

- ファイルinit.oraの設定により、SecureFile LOB記憶域を使用できない。例として、パラメータDB_SECUREFILEを参照してください。

関連項目:

- 『Oracle Database SQL言語リファレンス』のCREATE TABLEの項にあるLOB_storage_clauseの説明

- LOB記憶域オプション、SecureFileおよびBasicFileの詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照してください。

- 自動セグメント領域管理の詳細は、『Oracle Database管理者ガイド』を参照してください。

- パラメータDB_SECUREFILEの詳細は、『Oracle Databaseリファレンス』を参照してください。

記憶域モデルを組み合せて、XML文書の部分によって異なるモデルを使用できます。構造化記憶域と非構造化記憶域の組合せは、ハイブリッド記憶域と呼ばれることもあります。構造化記憶域に該当することは、ハイブリッド記憶域の構造化部分に該当します。非構造化記憶域に該当することは、ハイブリッド記憶域の非構造化部分に該当します。

XMLTypeには複数の記憶域モデルがあり、モデルには複数の方法で構成できるものもあります。各モデルには、コンテキストに応じたメリットがあります。各モデルには、それに適した1つ以上のタイプの索引があります。

XMLType記憶域モデルを選択する際の最初の考慮事項は、XMLデータの性質とそれを使用する方法です。高度に構造化されたデータのデータ中心の使用と、高度に非構造化されたデータのドキュメント中心の使用を両極とする範囲を考えることができます。最初に検討すべき項目は、ユースケースは主にデータ中心であるか、ドキュメント中心であるかです。

- データ中心: データは一般に高度に構造化されており、構造は比較的静的および予測可能で、アプリケーションはその構造を好材料として活用します。データはXMLスキーマに準拠しています。

- ドキュメント中心: 次の2つの場合があります。

- データは一般に構造がないか、可変構造を持っています。ドキュメント構造は時間経過とともに変化する可能性があります(拡張)。コンテンツは混合(半構造化)しています。つまり、多数の要素がテキスト・ノードと子要素の両方を含んでいます。多数のXML要素が欠落していたり、異なった順序で表示されたりすることがあります。ドキュメントはXML Schemaに準拠している場合もしていない場合もあります。

- データは比較的構造化されていますが、アプリケーションはその構造の長所を活用しません。つまり、構造がないかのようにデータを処理します。

注意:
記憶域オプションの解説と、格納されるXMLコンテンツの構造の解説を混同しないように、コンテキストに注意してください。このマニュアルでは、「構造化」と「非構造化」は一般にXMLType記憶域オプションを指します。データの性質を指すことはそれほど多くありません。「ハイブリッド」は、ある種の埋込みCLOB記憶域を持つオブジェクト・リレーショナル記憶域を示します。「半構造化」は、記憶域に関係なく、XMLコンテンツを指します。非構造化記憶域はCLOBベースの記憶域で、構造化記憶域はオブジェクト・リレーショナル記憶域です。

ユースケースとデータが、データ中心とドキュメント中心のどちらの側に該当するか判定できたら、高度にデータ中心(またはドキュメント中心)か、それとも両者の中間に近いかどうかを検討します。つまり、ユースケースがどの程度までデータ中心、またはドキュメント中心かということです。

- 完全にデータ中心の場合、オブジェクト・リレーショナル(構造化)記憶域を使用します。このユースケースの典型的な例は、従業員レコード(フィールドは従業員番号、氏名、アドレスなど)です。Bツリー索引とオブジェクト・リレーショナル記憶域を使用します。

- データが主に変化しないXML構造で構成されているが、多少の可変データが含まれる場合(つまり、予想可能な少数の混在コンテンツ要素が含まれる場合)は、ハイブリッド記憶域を使用します。このユースケースの典型的な例は、書式自由の履歴書を含む従業員レコードです。データの構造化済部分と非構造化部分は、各部分に適切な索引を使用して別々に索引付けを行ってください。

- 完全にドキュメント中心のユースケースでは、バイナリXML記憶域またはCLOBベース(非構造化)記憶域を使用します。ここでは、索引付け方式としてXMLIndexを選択します。

- ドキュメント中心XMLデータの一般的な索引付けでは、非構造化コンポーネントとともにXMLIndex索引を使用します。このユースケースの典型的な例は、1つのXML Webドキュメント、または書籍のうちの1章です。

- データに、頻繁に問合せされる予測可能な固定構造が含まれる場合は、その部分に対して構造化コンポーネントが含まれるXMLIndex索引を使用することができます。このユースケースの典型的な例は、作成者、日付およびタイトルのフィールドを持つ書式自由の仕様です。

1つのXMLIndex索引には、構造化と非構造化コンポーネントの両方を含めることができます。一般的に非構造化コンテンツ内の構造のアイランドを処理するためです。両方のコンポーネントを使用する可能性のあるユースケースとして、構造化データが存在するときは文書からXMLフラグメントを抽出するような問合せをサポートする場合などがあります。索引の非構造化コンポーネントは、フラグメントの抽出に使用されます。構造化コンポーネントは、構造化データがあるかを確認するSQL WHERE句に使用されます。

どのような場合でも、全文問合せに対して追加でOracle Text索引を使用することができます。これは特に、ドキュメント中心の場合に役立ちます。

これらの考慮事項を図1-5に要約します。図は、データ中心の程度が最も高いものを左端に、ドキュメント中心の程度が最も高いものを右端に置いた範囲を示しています。図の表はユースケースの分類と、それに対応する記憶域モデルと索引付けの方法を示します。

図1-5 XMLのユースケースとXMLType記憶域モデル

XMLデータの索引付けの詳細は、第6章「XMLTypeデータの索引付け」を参照してください。特に、一部のタイプの索引付けが相補的であるか、直交していて、併用可能であることに注意してください。

次のリストと表1-3に、各記憶域モデルのメリットの一部を示します。

- 構造化(オブジェクト・リレーショナル)記憶域が他の記憶域モデルより優れている点としては、リレーショナル問合せおよび更新とほぼ同じパフォーマンス、メモリー管理の最適化、必要な記憶域の削減、Bツリー索引の作成、インプレース更新などがあります。これらのメリットがあるかわりに、すべてのXMLデータの収集および取出し時のオーバーヘッドが増加し、指定したXMLType表または列で管理できるXML構造の柔軟性が低下します。構造上の柔軟性が低下するのは、データとメタデータ(列名など)がオブジェクト・リレーショナル記憶域で分離されるためです。インスタンス構造は簡単には変化できません。構造化記憶域が特に適しているのは、高度に構造化され、その構造が変化しないデータです。ただし、マップ先が管理可能な数のデータベース表および結合に抑えられている場合です。

- 非構造化(CLOB)記憶域では、XML文書全体の挿入および取得時のスループットが構造化記憶域より高くなります。データの変換が必要ないので、同じ形式をデータベース外でも使用できます。非構造化記憶域はまた、格納できるXMLの構造の柔軟性も、構造化記憶域より高くなります。非構造化記憶域は、文書中心のユースケースに特に適しています。これらのメリットがあるかわりに、特定のインテリジェントな処理を実行できない場合があります。索引付けがない場合、データベースでは、CLOBインスタンスに格納されているXMLデータの問合せまたは更新の最適化はほとんど実行できません。特に、XML解析(通常は暗黙的)のコストにより、問合せのパフォーマンスが大きく影響を受ける場合があります。XMLIndexを使用した索引付けを行うと、非構造化記憶域に対する問合せのパフォーマンスを向上できます。

- バイナリXML記憶域では、非構造化記憶域より効率的なデータベースの格納、更新、索引付けおよびフラグメントの抽出が可能です。問合せのパフォーマンスが非構造化記憶域より高く、XML解析のボトルネックもありません(この記憶域は、事後解析の永続性モデルです)。構造化記憶域と同様に、バイナリXML記憶域ではXML Schemaデータ型を認識し、ネイティブなデータベース・データ型を利用できます。構造化記憶域と同様に、バイナリXML記憶域ではピース単位の更新が可能です。バイナリXMLデータは、データベース外でも使用できるため、効率的なXML交換メディアとして機能でき、様々な状況でデータベースのワークロードを減らして全体的なパフォーマンスを向上できます。非構造化記憶域と同様に、バイナリXMLデータはドキュメント順に保持されます。また、構造化記憶域と同様に、バイナリ記憶域を使用すると、データとメタデータをデータベース・レベルで分離して効率を高めることができます。一方で、バイナリXML記憶域では、非構造化記憶域と同様に、データとメタデータの組合せが可能であり、インスタンス構造を変更できます。バイナリXML記憶域では、複雑性と可変性の高いデータを扱うことができ、このようなデータを構造化記憶域モデルで扱うには、多数のデータベース表が必要になる場合があります。他のXMLType記憶域モデルと異なり、バイナリ記憶域は、XML Schemaが事前に既知でなくても、XML Schemaに基づくデータに使用でき、複数のXML Schemaを複数の共通の要素にまたがって同じ表および問合せに格納できます。

表1-3 XMLType記憶域モデル: 相対的なメリット

品質

構造化(オブジェクト・リレーショナル)記憶域

バイナリXML記憶域

非構造化(CLOB)記憶域

スループット

- XML分解では、XML文書のコンテンツ全体の収集または取出し時のスループットが低下する場合があります。

+ 高いスループット。高速なDOMロード。バイナリXMLエンコーダ/デコーダからのオーバーヘッドが多少発生します。

++ XML文書のコンテンツ全体の収集および取出し時のスループットが高くなります。

問合せ

++ 非常に高速: リレーショナル問合せのパフォーマンス。

基礎となるオブジェクト・リレーショナル列に対してBツリー索引を作成できます。

+ ストリーム式のXPath評価により、DOMの構成が回避され、複数のXPath式をシングル・パスで評価できます。ナビゲーションによるXPath評価は、非構造化記憶域よりはるかに高速です。

XMLIndex索引付けを使用すると、XPathベースの問合せのパフォーマンスを向上できます。

- XPath操作は、CLOBデータからDOMを構成し、機能上の評価を使用して評価されます。大規模な文書または文書の大規模なコレクションに対する操作の実行時は高コストになります。

XMLIndex索引付けを使用すると、XPathベースの問合せのパフォーマンスを向上できます。

更新操作(DML)

++ 非常に高速: リレーショナル列がインプレース更新されます。

+ インプレースのピース単位更新(SecureFile LOB記憶域の場合)。

- 文書の一部を更新した場合は、文書全体をディスクに再書込みする必要があります。

領域効率(ディスク)

++ 非常に高い領域効率。

+ 高い領域効率。

- 無意味な空白やタグの繰返しにより、大量のディスク領域が消費されます。

データの柔軟性

- 柔軟性は制限されます。XML Schemaに準拠する文書のみがXMLType表または列に格納されます。

+ XMLType列または表に格納可能なXML文書の構造に柔軟性があります。

+ XMLType列または表に格納可能なXML文書の構造に柔軟性があります。

XML Schemaの柔軟性

- XMLType表に格納できるのは、同じXML Schemaに準拠する文書のみです。

一部制限がありますが、インプレースのXML Schema拡張を使用できます。

++ XML Schemaに基づく文書およびXML Schemaに基づかない文書を格納できます。XMLType表に格納できるのは、登録済のXML Schemaに準拠する文書です。

++ XML Schemaに基づく文書およびXML Schemaに基づかない文書を格納できます。同じXMLType表には複数のXML Schemaを使用できません。

XML再現性

DOM再現性: データベースに格納されているXML文書から作成されたDOMは、元の文書から作成されたDOMと同じです。ただし、無意味な空白は破棄される場合があります。

DOM再現性(構造化記憶域の説明を参照)。

+ ドキュメントの再現性: 元のXMLデータがバイト単位で保持されます。特に、元の空白がすべて保持されます。

索引付けのサポート

+ Bツリー、ビットマップ、Oracle Text、XMLIndexおよびファンクション索引。

XMLIndex、ファンクション索引およびOracle Text索引。

XMLIndex、ファンクション索引およびOracle Text索引。

メモリー管理の最適化

+ XML操作は最適化され、必要なメモリーを削減できます。

+ XML操作は最適化され、必要なメモリーを削減できます。

- 文書に対するXML操作では、文書からDOMを作成する必要があります。

挿入時の検証

XMLデータは挿入時に部分的に検証されます。

+ XML Schemaに基づくデータは挿入時に完全に検証されます。

XML Schemaに基づくデータは挿入時に部分的に検証されます。

パーティション化

+ 使用できます。脚注1

仮想列に基づいたパーティション。

パーティション化キーがリレーショナル列の場合に、XMLType列をパーティション化できます。

ストリームに基づくレプリケーション

- 使用できません。

- 使用できません。

++ 使用できます。

圧縮

++ XML要素と属性を個別に圧縮できます。

+ SecureFile LOB記憶域を使用するXMLデータを圧縮できます。

- 使用できません。

脚注1 Ordered Collection Table(OCT)のパーティション化は、最上位のXMLType表のパーティション化を反映しています。最上位の表に対するパーティション・メンテナンス操作は、関連付けられたOCTに対してカスケード処理されます。「オブジェクト・リレーショナル形式で格納されたXMLTypeの表および列のパーティション化」を参照してください。

注意:
XML Schemaに基づくデータは、バイナリXMLType列または表への挿入時には、XML Schemaと照合して完全に検証されます。データが無効な場合、挿入は失敗します。

XMLTypeがオブジェクト・リレーショナル形式で格納される場合、XMLTypeインスタンスには、SQLオブジェクト・モデルに収まらないXMLデータに関する情報を格納する非表示列が含まれます。

XMLとSQLの双対性

Oracle XML DBの主な目的は、XMLとSQLの双対性の提供にあります。XMLプログラマはXMLコンテンツの操作時にリレーショナル・モデルの機能を使用でき、SQLプログラマはリレーショナル・コンテンツの操作時にXMLの柔軟性を利用できます。このため、個別のビジネス問題に対して最適のツールを使用することができます。

XMLとSQLの双対性とは、同じデータを表内の行として公開し、SQLを使用して操作できること、または同じデータをXML文書のノードとして公開し、DOM変換やXSL変換などの方法で操作できることを意味します。アクセス方法と処理方法は、基礎となる記憶域形式とは関係がありません。

これらの機能によって、一般的なビジネス問題に対する単純なソリューションが提供されます。次に例を示します。

- Oracle XML DB SQL関数を使用して、SQL問合せから直接XMLデータを生成できます。引き続きそのXMLデータを、データベースに常駐するXSLTプロセッサを使用して、HTMLなどの他の形式に変換できます。

- SQL問合せ、オンライン分析処理(OLAP)およびビジネス・インテリジェンス/データ・ウェアハウス操作を使用して、データ形式の変換を行わずにXMLコンテンツにアクセスできます。

- テキスト、空間データおよびマルチメディア操作をXMLコンテンツで実行できます。

SQL/XML標準関数

Oracle XML DBには、SQL/XML標準で定義されたSQL関数が用意されています。SQL/XML関数は、次の2つのグループに分類されます。

- SQL問合せの結果からXMLデータの生成に使用できる関数。このマニュアルでは、このような関数をSQL/XMLパブリッシング関数と呼びます。また、SQL/XML生成関数と呼ばれることもあります。

- 通常のSQL操作の一部としてXMLコンテンツの問合せおよびアクセスに使用できる関数。このマニュアルでは、このような関数をSQL/XML問合せおよびアクセス関数と呼びます。

SQL/XML関数を使用すると、XMLコンテンツをSQL文の任意の部分に指定できます。これらの関数では、XQuery式やXPath式を使用してXML構造を検索し、操作対象のノードを識別します。XQuery式やXPath式をSQL文に埋め込む機能によって、XMLアクセスが大幅に簡略化されます。

関連項目:

- OracleによるSQL/XML標準のサポートの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- XMLデータを問い合せるためのSQL/XML標準関数の詳細は、第4章「XMLTypeの操作」および第5章「Oracle XML DBでのXQueryの使用」を参照してください。

- XMLデータを生成するためのSQL/XML標準関数の詳細は、「SQL関数を使用したXMLの生成」を参照してください。

- SQL/XML標準関数の追加の使用例は、第3章「Oracle XML DBの使用」を参照してください。

- 「Oracle XML DBでサポートされている標準」

XQuery式とXPath式の自動リライト

SQL/XML関数およびXMLTypeメソッドを使用すると、XQuery式やXPath式を使用してXML文書のコレクションを検索し、XML文書内に含まれるノードのサブセットにアクセスできます。多くの場合、Oracle XML DBではそれらの式を、基礎となるデータベース・オブジェクトに対して直接実行されるコードに自動的にリライトできます。

Oracle XML DBによるXPath式の評価方法

Oracle XML DBでは、使用されるXML格納方法に応じて、XMLType列および表で操作するXPath式を次の方法で評価できます。

- 構造化記憶域: Oracle XML DBは、SQL/XML関数のXPath式を同等のSQL問合せに変換します。SQL問合せは、スキーマに基づくXMLTypeの基礎となるオブジェクト・リレーショナル・データ構造を参照します。このプロセスは、XPathリライトと呼ばれます。問合せおよびUPDATE操作の実行時に発生する可能性があります。さらに、基礎となるオブジェクト・リレーショナル表に対するBツリー索引を使用して、構造化記憶域のXPath式が評価されます。

- 非構造化記憶域: 非構造化記憶域のXPath式の評価には、XMLIndex索引を使用できます。XMLIndexを使用することをお薦めします。

- XMLIndex索引を使用できる場合は、機能上の評価ではなくその索引が使用されます。

- XMLIndex索引もファンクション索引もない場合、Oracle XML DBは、機能上の評価を使用してXPath式を評価します。機能上の評価によって、XML文書ごとにDOMツリーが構築され、DOM APIで提供されるメソッドを使用してプログラムによってXPathが解決されます。DOMツリーの更新が含まれる操作を実行する場合は、操作の完了時にXML文書全体をディスクに再書込みする必要があります。

- バイナリXML記憶域: Oracle XML DBでは、XPath式の評価に、XMLIndexおよびシングルパス・ストリーミングを使用できます。シングルパス・ストリーミングでは、一連のXPath式が、バイナリXMLデータの単一のスキャンで評価されます。問合せのコンパイル中に、最も高速な評価メソッドの組合せがコストベース・オプティマイザによって選択されます。

関連項目:
表1-3「XMLType記憶域モデル: 相対的なメリット」

XQuery式とXPath式を含むSQLコードのリライト

オブジェクト・リレーショナルに格納されるXMLデータの場合、Oracle XML DBは、XQuery式とXPath式が含まれるSQL文を、最適に処理できる純粋なリレーショナルSQL文にリライトすることができます。このようにして、Oracle XML DBでは、データベース・オプティマイザがXQueryおよびXPathの言語やXMLデータ・モデルを認識する必要をなくしています。データベース・オプティマイザは、リライトされたSQL文を他のSQL文と同じ方法で処理します。このリライト処理を総称してXPathリライトと言います。

このように、データベース・オプティマイザは従来の関係代数に基づいて実行計画を導出できます。これはまた、Oracle XML DBが、データベースのすべての機能を使用でき、XQuery式やXPath式を含むSQL文がパフォーマンスの高い効率的な方法で実行されることが保証されることを意味します。このリライトによるオーバーヘッドはほとんどなく、Oracle XML DBは、XMLの抽象的概念を保持しながらリレーショナルSQL文とほぼ同じ速度でXQueryベースおよびXPathベースの問合せを実行できます。

XPathのリライトが行われる場合

XPathのリライトは、次のすべての条件が満たされた場合に可能です。

- 基礎となる記憶域モデルを提供するために、XMLType列または表で構造化記憶域方法が使用されている場合

- XMLType列または表が、登録済のXML Schemaに関連付けられている場合

- SQL文に、XPath式を使用して一連のXML文書内にある1つ以上のノードを参照するSQL/XML関数またはXMLTypeメソッドが含まれる場合

- XPath式が参照するノードを、XML Schemaを使用して基礎となるSQLオブジェクト・モデルの属性にマップできる場合

XPathリライト処理の概要

XPathリライトでは、次のタスクが実行されます。

1. SQL文に含まれる一連のXPath式を識別します。

2. 各XPath式を、基礎となるSQL: 1999オブジェクト・モデルの表、型および属性を参照するオブジェクト・リレーショナルSQL式に変換します。

3. 元のSQL文を同等のオブジェクト・リレーショナルSQL文にリライトします。

4. 新しいSQL文をデータベース・オプティマイザに渡し、計画を生成して問合せを実行します。

XPathリライトを実行できない場合もあります。これは、通常、XPath式に対して同等のSQLがない場合に発生します。この場合、Oracle XML DBは、XPath式に対して機能上の評価を実行します。

一般的に、SQL文の機能上の評価は、特に処理対象となる文書の数が多い場合にXPathリライトより高コストになります。機能上の評価のメリットは、XMLTypeデータが構造化記憶域を使用して格納されているかどうか、またXPath式の複雑さなどには関係なく、常に実行可能であるということです。

必要なレベルのスケーラビリティとパフォーマンスを実現するOracle XML DBアプリケーションを開発するには、XPathのリライトの概念、およびXPathのリライトを実行できる条件を理解することが重要です。

関連項目:
第8章「構造化記憶域のXPathリライト」

Oracle XML DBのメリット

この項では、Oracle XML DBを使用するメリットについて説明します。図1-6に概要を示します。

図1-6 Oracle XML DBのメリット

データとコンテンツの統合

多くのアプリケーションのデータおよびWebコンテンツは、リレーショナル・データベースまたはファイル・システム内、あるいはその両方に格納されます。多くの場合、XMLデータはデータ交換に使用され、リレーショナル・データベースまたはファイル・システムから生成できます。交換されるXMLデータのボリュームが大きくなると、このデータを再生成するコストが増加し、XMLコンテンツの保存にはこれらの格納方法は効率的ではありません。

図1-7 データとコンテンツの統合: 一般的なXMLアーキテクチャ

多くの場合、企業は構造化データと非構造化データを異なる方法で管理しています。

- 表内の非構造化データの場合、ドキュメント・アクセスが透過的になり、表アクセスが複雑になります。

- 通常はバイナリ・ラージ・オブジェクト(BLOBインスタンスなど)の構造化データの場合、ドキュメント・アクセスが複雑になり、表アクセスが透過的になります。

Oracle XML DBでは、標準データ・モデル、標準SQLおよび標準XMLを使用して、構造化、非構造化または半構造化のデータを格納および管理できます。XML文書に対してSQL操作を実行したり、(表などの)オブジェクト・リレーショナル・データに対してXML操作を実行することができます。

データベース機能の使用

Oracle Databaseは、XML操作を目的とした、次のような重要なデータベース機能を備えています。

- 索引付けおよび検索: アプリケーションでは「2002年3月から4月までに作成されたすべての製品定義を検索」のような問合せが実行されます。問合せは通常、日付列のBツリー索引でサポートされています。Oracle XML DBを使用すると、XMLデータに対する効率的な構造化検索ができるようになるため、コンテンツ管理ベンダーは独自の問合せAPIを作成してこのような問合せを処理する必要がなくなります。

関連項目:

- 第4章「XMLTypeの操作」

- 第12章「XMLデータの全文検索」

- 第18章「データベースからのXMLデータの生成」

- 更新およびトランザクション処理: 商用のリレーショナル・データベースでは、レコードのサブパーツを高速更新することによって、更新を試行しているユーザー間の競合が最小化されています。従来、ドキュメント中心のデータは、XMLを介して協調環境を構築しているため、この要件はより重要になります。ファイル記憶域またはCLOB記憶域では、Oracle XML DBで行われる細分化された同時実行性制御を行うことができません。

関連項目:
第4章「XMLTypeの操作」

- 関係の管理: 通常、なんらかの構造を持つデータには外部キー制約があります。一般に、XMLデータを格納するシステムにはこの機能がないため、アプリケーション・コードで任意の制約を実装する必要があります。Oracle XML DBを使用すると、XML Schemaの定義に基づいてXMLデータを制約できるため、構造化データが持つ関係を制御できます。

関連項目:

- 第7章「XML Schemaの格納と問合せ: 基本」

- 第4章「XMLTypeの操作」の発注書の例

- データの複数のビュー: 多くの企業アプリケーションでは、別々のモジュール用に、それぞれ異なる方法でデータをグループ化する必要があります。そのため、これらの複数の方法でデータを組み合せることができるように、リレーショナル・ビューが必要になります。Oracle XML DBでは、XMLでビューを使用することによって、様々なアプリケーションで使用する場合など、XMLに別々の論理的な抽象概念が作成されます。

関連項目:
第19章「XMLTypeビュー」

- パフォーマンスとスケーラビリティ: データは、高速な格納、取出しおよび問合せが可能である必要があります。通常、ファイルまたはCLOB値のロードおよび解析は、リレーショナル・データのアクセスより遅くなります。Oracle XML DBでは、XMLの格納および取出しが大幅に高速化されます。

関連項目:

- 第2章「Oracle XML DBを使用する前に」

- 第3章「Oracle XML DBの使用」

- 簡単な開発: データベースは、個々のデータ要素を簡単に操作、変換および変更するための標準的な手段を提供する、最も重要なアプリケーション・プラットフォームです。一般的なXMLパーサーでは、XMLデータに対する標準的な読取りアクセスが提供されますが、個別のXML要素を簡単に変更および格納する方法は提供されません。Oracle XML DBでは、データを格納、変更および取得するための標準的な方法がいくつかサポートされています。たとえば、XML Schema、XQuery、XPath、DOMおよびJavaなどを使用できます。

関連項目:

- 第15章「Java DOM API for XMLType」

- 第25章「RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス」

- 第26章「PL/SQLを使用したリポジトリへのアクセス」

XML機能の活用

XMLファイル記憶域のデメリットが原因で、XMLをデータベース表および列に分割する必要がある場合でも、XMLには次のメリットがあります。

- 構造に非依存: XMLのオープン・コンテンツ・モデルは、表と列のみの構造には簡単に取得されません。XML Schemaによって、コンテナのみでなく、グローバルな要素宣言が可能になります。そのため、アプリケーションの進化に伴ってXML文書内でデータ項目がどこに移動するかにかかわらず、特定のデータ項目を検索できます。

関連項目:
第7章「XML Schemaの格納と問合せ: 基本」

- 記憶域に非依存: リレーショナル設計を使用する場合、クライアント・プログラムでは、データの格納場所、形式、表および表間の関係が認識されている必要があります。XMLTypeを使用すると、その情報がなくてもアプリケーションを作成でき、データベース管理者は構造化データを物理表および列の記憶域にマップできます。

関連項目:

- 第7章「XML Schemaの格納と問合せ: 基本」

- 第21章「Oracle XML DBリポジトリのデータへのアクセス」

- 簡単な表示: XMLは、Webブラウザ、多くの一般的なデスクトップ・アプリケーションおよびほぼすべてのインターネット・アプリケーションでネイティブに認識されます。一般的に、リレーショナル・データは、アプリケーションから直接アクセスできません。一般のクライアントがリレーショナル・データにアクセスできるようにするには、追加のプログラミングを行う必要があります。Oracle XML DBでは、データはXMLとして格納され、データベース外部ではXMLとして使用可能になります。データベースのコンテンツを表示するためのプログラミングは必要ありません。

関連項目:

- 第11章「XMLTypeデータの変換および検証」

- 第18章「データベースからのXMLデータの生成」

- 第19章「XMLTypeビュー」

- 簡単な交換: XMLは、Business-to-Business(B2B)のデータ交換で使用される言語です。通常、XMLを任意の表構造に格納する必要がある場合は、XMLの内容を独自の方法で解釈し、分解します。言語を分解すると、情報が失われ、交換が困難になります。Oracle XML DBでは、XMLをネイティブに認識し、格納および取出し処理でのDOM再現性を提供することによって、完全な交換が可能になります。

関連項目:

- 第11章「XMLTypeデータの変換および検証」

- 第19章「XMLTypeビュー」

複雑なXML文書の効率的な格納および取出し

現在、ユーザーは、複雑で大規模な多くのXML文書を格納および取り出す場合のパフォーマンス問題に直面しています。Oracle XML DBでは、XML操作のパフォーマンおよび拡張性が優れています。主なパフォーマンス機能は次のとおりです。

- ネイティブなXMLType。第4章「XMLTypeの操作」を参照してください。

- 遅延評価された仮想的なDOM。第13章「PL/SQL APIs for XMLType」を参照してください。

- XQuery、XPathおよびXSLTのサポート。このサポートは、第4章「XMLTypeの操作」、第11章「XMLTypeデータの変換および検証」、および第5章「Oracle XML DBでのXQueryの使用」などのいくつかの章で説明しています。

- XML Schemaキャッシュのサポート。第7章「XML Schemaの格納と問合せ: 基本」を参照してください。

- 索引付け: 全文およびXMLの両方。第6章「XMLTypeデータの索引付け」および第12章「XMLデータの全文検索」を参照してください。

- Oracle XML DBリポジトリに対する階層索引。第21章「Oracle XML DBリポジトリのデータへのアクセス」を参照してください。

データがXMLでない場合のXMLTypeビューの使用方法

XMLTypeビューでは、既存のリレーショナル・データおよびオブジェクト・リレーショナル・データをXML形式にラップする方法が提供されます。これは、XMLでないレガシー・データをXML形式に移行する必要がある場合などに特に有効です。XMLTypeビューを使用すると、アプリケーション・コードを変更する必要がありません。

関連項目:
第19章「XMLTypeビュー」

XMLTypeビューを使用するには、最初にXML Schemaデータ型と、SQLデータ型または双方向XMLエンコーディング型の間の双方向マッピングを表す注釈が付いたXML Schemaを登録する必要があります。その後、適切な型のインスタンスを構築する基礎となる問合せを指定することによって、このマッピングに準拠するXMLTypeビューを作成できます。

Oracle Textを使用したXMLデータの検索

Oracle Databaseでは、セクション検索用のOracle Text索引を含むXMLデータの特別な索引付け、XMLデータを処理するためのSQL関数、XMLデータの集計およびXMLデータを伴う問合せの特別な最適化が可能です。Oracle SQL関数hasPathおよびinPathは、XMLデータ検索を最適化するように設計され、そこでXMLテキストの部分文字列一致検索が可能です。

関連項目:

- 第12章「XMLデータの全文検索」

- 「XMLデータに対するOracle Text索引」

- 『Oracle Textアプリケーション開発者ガイド』

- 『Oracle Textリファレンス』

Oracle Streamsアドバンスト・キューイングを使用したメッセージ・アプリケーションの構築

Oracle Streamsアドバンスト・キューイングでは、次のものを使用できます。

- XML Schemaに基づくXMLTypeを含む、メッセージ型およびペイロード型としてのXMLType

- XMLTypeメッセージのキューおよびデキュー

関連項目:

- Oracle Streamsアドバンスト・キューイングとともにXMLTypeを使用する方法の詳細は、『Oracle Streamsアドバンスト・キューイング・ユーザーズ・ガイド』を参照してください。

- 第37章「Oracle Streams AQを使用したXMLデータの交換」

Oracle XML DBでサポートされている標準

Oracle XML DBでは、XML、SQL、Java、インターネットなど、すべての主要な標準がサポートされています。

- W3CのXML Schema 1.0勧告。XML Schemaの登録、XML Schemaに対する格納されたXMLコンテンツの検証、またはXML Schemaに対するサーバーに格納されたXMLの制約を行うことができます。

- W3C XQuery 1.0勧告およびW3C XPath 2.0勧告。HTTP(S)リクエストまたはSQLのいずれかから、XQueryおよびXPathを使用してデータベース内に格納されたXMLを検索できます。

- SQL/XML。

- Java Database Connectivity(JDBC)API。Javaプログラマは、XMLへJDBCアクセスできます。

- W3CのXSL 1.0勧告。XSLTを使用して、サーバーでXML文書を変換できます。

- W3CのDOMレベル1.0および2.0コア勧告。動的アクセスのために、サーバーに格納されたXMLをXML DOMとして取り出すことができます。

- プロトコル・サポート。Oracle NetまたはHTTP(S)、FTP、IETF WebDAVなどの標準プロトコルを使用すると、Oracle XML DBに対してXMLデータの格納または取出しができます。

- Javaサーブレットのバージョン2.2(ただし、サーブレットWARファイル、web.xmlはサポートされず、現在サポートされているのは、1つのServletContextおよび1つのweb-appのみです。ステートフル・サーブレットはサポートされていません)。

- Webサービス: SOAP 1.1。SOAPリクエストからサーバーに格納されたXMLにアクセスできます。WSDLおよびUDDIを介し、Oracle XML DBおよびOracle9iASを使用してWebサービスを構築、公開または検索できます。Oracle Streamsアドバンスト・キューイングIDAP(キューイング操作に対するSOAP仕様)を、Oracle Databaseに格納されたXMLに使用できます。

- W3CのXML Linking Language(Xlink)1.0勧告。XML文書間に様々なタイプのリンクを定義できます。

- W3CのXML Pointer Language(XPointer)勧告およびXPointer Framework。複数のXML文書またはXMLフラグメントのコンテンツを単一の情報セットにまとめることができます。

関連項目:

- SQL/XML関数の詳細は、「SQL/XML標準関数」を参照してください。

- OracleによるSQL/XML標準のサポートの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- XLinkおよびXPointerのサポートの詳細は、第23章「Oracle XML DBでのXLinkおよびXIncludeの使用」を参照してください。

- プロトコル・サポートの詳細は、第28章「プロトコルを使用したリポジトリへのアクセス」を参照してください。

- Javaサーブレットの使用方法の詳細は、第32章「JavaでのOracle XML DBアプリケーションの作成」を参照してください。

- SOAPの使用方法の詳細は、第37章「Oracle Streams AQを使用したXMLデータの交換」および『Oracle Streamsアドバンスト・キューイング・ユーザーズ・ガイド』を参照してください。

Oracle XML DBの技術サポート

Oracleサポート・サービスの通常のサポート・チャネルの他に、Oracle DatabaseのXML対応テクノロジの技術サポートが、Oracle Technology Network(OTN)のディスカッション・フォーラム・セクションから無償で利用できます。

http://forums.oracle.com/forums/category.jspa?categoryID=51

このマニュアルで使用するOracle XML DBの例

このマニュアルには、Oracle XML DBおよびXMLTypeの使用例を記載しています。例は、様々なデータベース・スキーマ、サンプルXML文書およびサンプルXML Schemaに基づいています。

関連項目:
付録A「Oracleが提供するXML Schemaおよび例」

詳細なOracle XML DBの事例およびデモ

OTNに接続し、Oracle XML DBの例、ホワイト・ペーパー、事例およびデモを参照してください。

http://www.oracle.com/technetwork/database-features/xmldb/overview/index.html

Oracle XML DBの使用方法に関する総合的なXMLクラスも利用できます。OTNからOracle Universityのリンクを参照してください。

OTNでは、Oracle XML DBの次のような詳細な事例を参照できます。

- ダウンロード可能なOracle XML DBのデモ。この詳細なデモでは、Oracle XML DBの多くの機能の使用方法を示します。このデモの一部は、第3章「Oracle XML DBの使用」でも説明されています。

- SAX Loaderアプリケーション。このアプリケーションは、データベース外で複数のXML文書を含む大規模ファイルを分割し、一連の個別の文書としてデータベースに挿入する効率的な方法を示します。これは、スタンドアロンでWebベースのアプリケーションとして提供されます。

- Oracle XML DBユーティリティ・パッケージ。これは、XDB_Utilitiesパッケージで提供されるサブプログラムを重点的に示します。これらのサブプログラムでは、BFILE値、CLOB値、DOMおよびOracle XML DBリソースのAPIを操作します。このパッケージを使用すると、基本的なOracle XML DBフォルダリング操作、データベースへのXMLファイルの読取りとロード、およびPL/SQLを使用した基本的なDOM操作を実行できます。

- カード支払いゲートウェイ・アプリケーション。このアプリケーションでは、Oracle XML DBを使用してすべてのデータをXML形式で格納し、SQLを使用して結果のXMLデータへアクセスできます。クレジット・カード会社が自社のアカウントとトランザクション・データをデータベースに格納し、XML再現性も保持する方法を示します。

- 調査アプリケーション。このアプリケーションは、メンバーのOracle製品に対する希望を判別します。OTNでは、オンライン調査を掲示し、応答を調査します。このOracle XML DBアプリケーションは、企業が動的で対話型のHTML形式を作成して、インターネット上にデプロイし、応答をXMLとして格納してから、XML対応のOracle Databaseを使用してその応答を解析する方法を示します。

脚注の凡例

脚注1: xsdは、XML Schema名前空間のスキーマのスキーマで使用される接頭辞のため、xsd:stringなど、XML Schemaデータ型に使用される名前空間の接頭辞にもなります。xsdは、XML Schemaファイルのファイル拡張子としてもしばしば使用されます。
脚注2: Oracle Database 11gリリース2(11.2.0.2)まで、BasicFileオプションがバイナリXML記憶域のデフォルトでした。バイナリXMLデータに対するBasicFileオプションの使用は非推奨になりました。

2 Oracle XML DBを使用する前に

この章では、Oracle XML DBのソリューションを計画する場合に考慮する基本的な設計基準について説明します。

この章の内容は次のとおりです。

- Oracle XML DBのインストール

- Oracle XML DBのユースケース

- Oracle XML DBのアプリケーション設計に関する考慮事項

- Oracle XML DBのパフォーマンス

Oracle XML DBのインストール

次の場合、Oracle XML DBは自動的にインストールされます。

- Database Configuration Assistant(DBCA)を使用して、汎用テンプレートを使用してOracle Databaseを構築する場合

- SQLスクリプトcatqmを使用してOracle Databaseをインストールする場合

Oracle XML DBがすでにインストールされているかどうかは、自分で判断できます。次の条件に当てはまる場合は、インストールされています。

- データベース・スキーマ(ユーザー・アカウント)XDBが存在する。確認するには、次の問合せを実行します。

SELECT * FROM ALL_USERS;

- ビューRESOURCE_VIEWが存在する。確認するには、次のコマンドを使用します。

DESCRIBE RESOURCE_VIEW

関連項目:

- Oracle XML DBの手動によるインストールまたは削除の詳細は、第34章「Oracle XML DBの管理」を参照してください。

- データベース・スキーマXDBの詳細は、『Oracle Database 2日でセキュリティ・ガイド』を参照してください。

Oracle XML DBのユースケース

Oracle XML DBは、アプリケーションで処理されるデータの一部または全部がXMLで表現されているアプリケーションに適しています。Oracle XML DBでは、高パフォーマンスのデータベースで、XMLデータの収集、格納、処理および取出しが実行されます。また、既存のリレーショナル・データからXMLを迅速に容易に生成できます。

Oracle XML DBが特に適しているアプリケーションは、次のとおりです。

- Business-to-Business(B2B)およびApplication-to-Application(A2A)統合

- インターネット

- コンテンツ管理

- メッセージ機能

- Webサービス

典型的なOracle XML DBアプリケーションには、次のうち1つ以上の特長があります。

- 多くのXML文書を収集または生成する必要がある。

- 大規模なXML文書を処理または生成する必要がある。

- 1つの文書内でも、多数の文書の集まりにわたっても、高パフォーマンスな検索が必要とされる。

- 高いレベルのセキュリティが必要とされる。

- ファイングレイン・セキュリティが必要とされる。

- データ処理でXML文書を使用し、データをリレーショナル表に格納する必要がある。

- プログラミングで、SQL、XML、XQuery、XPath、XSLなどのオープン標準がサポートされている必要がある。

- FTP、HTTP(S)、WebDAV、Java Database Connectivity(JDBC)などの標準インターネット・プロトコルを使用して情報にアクセスする必要がある。

- XMLデータはSQLから問い合せる必要がある。

- XMLデータに分析機能を適用する必要がある。

- XML文書をXML Schemaに基づいて検証する必要がある。

Oracle XML DBを使用すると、Oracle Database内でのXML文書の格納および処理手順を微調整できます。アプリケーションの性質に応じて、XML記憶域には次のうち1つ以上の機能が必要です。

- XML文書の高パフォーマンスな収集および取出し

- XML文書の高パフォーマンスな索引付けおよび検索

- XML文書のセクションの更新

- 構造化または非構造化されたXML文書の管理

Oracle XML DBのアプリケーション設計に関する考慮事項

この項では、Oracle XML DBアプリケーションを計画する際に考慮できる基本的な設計基準について説明します。

データの構造

高度に構造化されたデータ(主にXML)にするか、半構造化データにするか、非構造化データにするか。高度に構造化されたデータにする場合、表はXML Schemaに基づいた表にするか、XML Schemaに基づかない表にするか。

XMLデータがXML Schemaに基づいていない場合、その構造化の方法とは関係なく、XMLType表またはビューにバイナリXMLまたはCLOBインスタンスとして、またはOracle XML DBリポジトリのフォルダ内のファイルとして格納できます。

XMLデータがXML Schemaに基づいている場合は、その構造化部分に非構造化、構造化(オブジェクト・リレーショナル)またはバイナリXML記憶域を使用できます。非構造化部分には、XML Schemaに基づかないデータと同じオプションを使用できます。

関連項目:
第3章「Oracle XML DBの使用」

Oracle XML DBリポジトリへのアクセス

この項では、Oracle XML DBリポジトリにリソースとして格納されるデータに関する事項を取り上げます。

他のアプリケーションおよびユーザーが、どのようにXMLおよびその他のデータにアクセスする必要があるか。アクセスにどの程度のセキュリティ・レベルが必要か。バージョニングが必要か。

リポジトリへのアクセス方法には、主に次の2つがあります。

- ナビゲーション・ベースのアクセスまたはパス・ベースのアクセス。これはコンテンツ/ドキュメントおよびデータ指向アプリケーションの両方に適しています。Oracle XML DBでは、次の言語およびアクセスAPIが提供されています。

- リソース・ビューおよびパス・ビューを介したSQLアクセス。第25章「RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス」を参照してください。

- DBMS_XDBを介したPL/SQLアクセス。第26章「PL/SQLを使用したリポジトリへのアクセス」を参照してください。

- コンテンツ指向のアプリケーションに最適なHTTP(S)、WebDAVまたはFTPを使用したプロトコルベースのアクセス。第28章「プロトコルを使用したリポジトリへのアクセス」を参照してください。

- 問合せベースのアクセス。これはデータ指向アプリケーションに最適です。Oracle XML DBでは、次のAPIを介して、SQL問合せを使用するアクセスが可能です。

- (JDBCを介する)Javaアクセス。「Java DOM API for XMLType」を参照してください。

- PL/SQLアクセス。第13章「PL/SQL APIs for XMLType」を参照してください。

ポジトリ・データにアクセスするためのこれらのオプションについては、第21章「Oracle XML DBリポジトリのデータへのアクセス」を参照してください。

次のアクセス基準についても考慮します。

- どの程度のセキュリティ・レベルが必要か。第27章「リポジトリのアクセス制御」を参照してください。

- アプリケーションに最適な索引付けの形式は何か。Oracle Textの索引付けおよび問合せを使用する必要があるか。第4章「XMLTypeの操作」、第6章「XMLTypeデータの索引付け」および第12章「XMLデータの全文検索」を参照してください。

- データのバージョニングが必要か。必要な場合は、第24章「リソースのバージョン管理」を参照してください。

アプリケーション言語

どの言語でアプリケーションをプログラミングするか。

Oracle XML DBアプリケーションは、次の言語でプログラミングできます。

- Java(JDBC、Javaサーブレット)

関連項目:

- 第15章「Java DOM API for XMLType」

- 第32章「JavaでのOracle XML DBアプリケーションの作成」

- PL/SQL

関連項目:

- 第13章「PL/SQL APIs for XMLType」

- 第26章「PL/SQLを使用したリポジトリへのアクセス」

- 「XML用のAPI」

処理

XMLデータを生成する必要があるか。第18章「データベースからのXMLデータの生成」を参照してください。

XML文書はどれほどの頻度でアクセス、更新および操作されるか。更新の対象は文書のフラグメントか、または文書全体か。

XMLデータをHTMLやWMLなどの他の言語に変換する必要があるか。その場合は、アプリケーションによってXMLデータがどのように変換されるか。第11章「XMLTypeデータの変換および検証」を参照してください。

アプリケーションを主にデータベースに常駐させる必要があるか、またはデータベースと中間層の両方で動作させる必要があるか。

アプリケーションは、データ中心、ドキュメント(コンテンツ中心)、またはその両方のいずれであるか。

次の処理オプションは、Oracle XML DBアプリケーションの設計時に使用可能であり、考慮する必要があります。

- XSLT: XMLデータをHTMLやWMLなどの他の言語に変換する必要があるか、その場合は、アプリケーションによってXMLデータがどのように変換されるか。Oracle XML DBにXML文書を格納中に、文書の構造が特定のXML Schemaに準拠するかどうか(妥当かどうか)を確認できます(オプション)。第11章「XMLTypeデータの変換および検証」を参照してください。

- DOM再現性、ドキュメントの再現性。ドキュメントの再現性を維持するには非構造化記憶域を使用します。DOM再現性を維持するには、XML Schemaに基づくデータに対してバイナリXMLまたは構造化記憶域を使用します。第13章「PL/SQL APIs for XMLType」および「DOM再現性」を参照してください。

- XPath検索。SQL文に埋め込まれたまたはHTTP(S)リクエストの一部としてXPath構文を使用すると、データベース内のXMLコンテンツを問い合せることができます。第4章「XMLTypeの操作」、第12章「XMLデータの全文検索」、第21章「Oracle XML DBリポジトリのデータへのアクセス」および第25章「RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス」を参照してください。

- XMLの生成およびXMLTypeビュー。XMLデータを生成または再生成する必要があるか。「はい」の場合、第18章「データベースからのXMLデータの生成」を参照してください。

XML文書はどれほどの頻度でアクセス、更新および操作されるか。第4章「XMLTypeの操作」および第25章「RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス」を参照してください。

更新の対象は文書のフラグメントか、または文書全体か。XPath式を使用して、文書全体を再書込みせずに、更新中に文書の個々の要素および属性を指定できます。これは、特に大規模なXML文書の場合により効率的です。第7章「XML Schemaの格納と問合せ: 基本」を参照してください。

アプリケーションは、データ中心、ドキュメントおよびコンテンツ中心、または統合(データとドキュメント中心の両方)のいずれであるか。第3章「Oracle XML DBの使用」を参照してください。

メッセージ機能

ゲートウェイを介して、アプリケーション間でXMLデータを交換するか。Oracle Streamsアドバンスト・キューイング(AQ)またはSOAPに準拠させる必要があるか。第37章「Oracle Streams AQを使用したXMLデータの交換」を参照してください。

アドバンスト・キューイング(AQ)では、XMLおよびXMLTypeアプリケーションがサポートされています。XMLType属性を含むペイロードを持つキューを作成できます。これらのペイロードは、XML文書を含むメッセージの転送および格納に使用できます。XMLType属性を持つOracle Databaseオブジェクトを定義すると、次の操作を実行できます。

- 複数の型のXML文書を同じキュー内に格納します。この文書は、CLOB値として内部的に格納されます。

- XPathやXQuery式を使用して、XMLType属性を持つメッセージを選択的にデキューします。

- XPathやXQuery式を使用して、メッセージ内容を問い合せるルールベースのサブスクライバを定義します。

- 変換を定義して、Oracle DatabaseオブジェクトをXMLTypeに変換します。

関連項目:

- 第37章「Oracle Streams AQを使用したXMLデータの交換」

- 『Oracle Streamsアドバンスト・キューイング・ユーザーズ・ガイド』

記憶域

リレーショナル・データ、XMLデータ、XML Schemaなどをどの方法でどの場所に格納するか。

注意:
通常、データ構造、アクセス、言語および処理に対して選択する内容は相互に関連しています。ただし、記憶域モデルの選択は、他の選択とは関連がありません。

図2-1に、XMLType表およびビューに対するOracle XML DBの記憶域オプションを示します。

図2-1 XMLデータに対するOracle XML DBの記憶域オプション

既存のリレーショナル・データがある場合は、XMLTypeビューをそのデータに作成することで、そのデータにXMLデータとしてアクセスできます。次を使用して、XMLTypeビューを定義できます。

- SQL/XML関数。第18章「データベースからのXMLデータの生成」および第5章「Oracle XML DBでのXQueryの使用」を参照してください。

- オブジェクトタイプ: オブジェクト表、オブジェクト・コンストラクタおよびオブジェクト・ビュー

アプリケーション用に選択した記憶域オプションにかかわらず、Oracle XML DBでは同じ機能が提供されます。使用する記憶域モデルは、アプリケーションのパフォーマンスおよびXMLデータの再現性に影響する場合がありますが、次のオプションとは関係がありません。

- データの問合せまたは更新の方法および頻度。

- データのアクセス方法。これは、アプリケーション処理の要件のみによって決まります。

- アプリケーションで使用される言語。これは、アプリケーション処理の要件のみによって決まります。

関連項目:

- 「XMLType記憶域モデル」

- 「DOM再現性」

Oracle XML DBのパフォーマンス

XMLを使用してデータを表現する際の問題点の1つは、他の表現方法よりもオーバーヘッドが増加することです。この問題を解決するために、Oracle XML DBには、特にXML処理のパフォーマンスが大幅に向上するように設計された機能がいくつか組み込まれています。これらの機能については、次の各項で説明します。

- XML記憶域の要件

- XMLのメモリー管理

- XML解析の最適化

- ノード検索の最適化

- XML Schemaの最適化

- キャッシュ済のXML Schemaを使用したロード・バランシング

- ネイティブでないコードによるボトルネックの低減

- Javaでの型変換によるボトルネックの低減

XML記憶域の要件

XMLで表現されたデータをテキスト・ファイルにすると、同じデータをJavaオブジェクトまたはリレーショナル表に格納した場合よりサイズが平均で3倍になります。これには、主に次の2つの理由があります。

- タグ名(データを表すメタデータ)と空白(フォーマット文字)によって、文書内の領域量が大幅に増加します。特に、高度に構造化されたデータ中心のXMLの場合に増加します。

- XMLファイル内のすべてのデータが、判読可能な(文字列)形式で表現されているためです。

数値の文字列表現では、ネイティブな(バイナリ)表現の約2倍のバイト数が必要です。構造化またはバイナリXML記憶域を使用してXML文書をOracle XML DBに格納すると、格納処理によって文書内のすべてのタグと空白文字が破棄されます。

この最適化によって節約できる領域量は、データに対するタグ名の割合と文書内のコレクション数によって決まります。高度に構造化されたデータ中心のXMLデータの場合は、領域を大幅に節約できる可能性があります。文書の出力またはXPath評価などのノード・ベースの操作を行うと、Oracle XML DBは、関連するXML Schemaに含まれる情報を使用して必要なタグ情報を動的に再構成します。

XMLのメモリー管理

ドキュメント・オブジェクト・モデル(DOM)は、XML文書の代表的なプログラミング・モデルです。DOM APIは簡単に使用できますが、基礎となるDOMツリーの生成ではメモリーに関して高コストになります。一般的なDOM実装では、DOMツリー内のノードごとに約80から120バイトのシステム・オーバーヘッドが維持されます。高度に構造化されたデータの場合、DOMツリーには、基礎になる文書に比べて10から20倍のメモリー量が必要です。

従来のDOM実装では、操作を開始する前にXML文書のコンテンツ全体をDOMツリーにロードする必要があります。アプリケーションによる処理が文書内のわずかな割合のノードにのみ必要な場合は、メモリーや処理のオーバーヘッドに関して非常に非効率になります。かわりにSimple API for XML(SAX)を使用した場合、XML文書の処理に必要なメモリー量は削減できますが、そのデメリットは、XML文書内のノードに対して線形処理のみ可能であることです。

関連項目:

- DOMの詳細は、http://www.w3.org/DOM/を参照してください。

- SAXの詳細は、http://www.saxproject.org/を参照してください。

XOBを使用した、XML Schemaに基づく文書に関するメモリー・オーバーヘッドの削減

Oracle XML DBでは、XML Object (XOB)と呼ばれる動的メモリー内の内部構造を使用してXML Schemaに基づくXML文書を管理することで、DOMプログラミングに関連するメモリー・オーバーヘッドが削減されます。XOBはタブ名やノード型などの情報をコピーしないため、同等のDOMよりも大幅に小さく、関連するXML Schemaから容易に取得できます。Oracle XML DBでは、アプリケーションがスキーマに基づくXMLTypeのコンテンツを操作する際に、自動的にXOBを使用します。XOBの使用は、ユーザーには透過的です。XMLTypeデータ型、C、PL/SQLおよびJava APIの使用時にXOBが使用されていることはユーザーにはわかりません。

XOBによる遅延ロードされた仮想DOMの使用

XOBでは、遅延ロードされた仮想DOM機能を使用して、XML文書の操作に必要なメモリー量を削減することもできます。これにより、Oracle XML DBは、コードがそのオブジェクト内のノードで操作を開始するまで、サブ要素またはコレクションの一部であるノードの動的メモリー表現のロードを遅延できます。その結果、アプリケーションが文書内のいくつかのノードのみ操作する場合は、操作対象のノードとその直接の兄弟のみがメモリーにロードされます。XOBを使用できるのは、XML文書がXML Schemaに基づいている場合のみです。XML文書のコンテンツがXML Schemaに基づいていない場合、XOBのかわりに従来のDOMが使用されます。

XML解析の最適化

DOMツリーを移入するには、アプリケーションでXML文書を解析する必要があります。XMLからDOMツリーを作成する処理は、非常にCPU集中型の処理です。XML文書がテキストとして格納される典型的なDOMベースのアプリケーションでは、アプリケーションで文書の操作を開始する前に、すべての文書を解析してDOMツリーにロードする必要があります。また、DOMツリーのコンテンツが更新された場合は、ツリー全体をテキスト形式に再シリアライズしてディスクに書き込む必要があります。

Oracle XML DBを使用すると、文書を何度も解析する必要がなくなります。構造化またはバイナリXML記憶域として文書を格納した場合、XML文書をディスクからメモリーにロードする際の解析は不要です。Oracle XML DBでは、関連するXML Schemaから導出される情報を使用して、ディスク形式と動的メモリー形式間に直接マップします。XML Schemaに基づくデータが変更された場合、Oracle XML DBは、更新されたデータのみをディスクに書き込めます。XMLデータがXML Schemaに基づいていない場合は、かわりに従来のDOMが使用されます。

ノード検索の最適化

ほとんどのDOM実装では、DOMツリー内の特定のノードを検索するときに文字列比較を使用します。このため、DOMツリーの単純な検索でも、数百または数千もの命令サイクルが必要になる場合があります。XOBでのノード検索は、DOMでのノード検索と比較して非常に効率的です。XOBは、C/C++オブジェクトと同様に計算済のオフセット・モデルに基づいており、文字列比較ではなく動的なハッシュテーブルを使用してノード検索を実行します。

XML Schemaの最適化

従来のXMLアプリケーションでXML Schemaに関連する強力な機能を使用すると、多くの追加オーバーヘッドが発生する可能性があります。たとえば、XML Schemaに対してXML文書を検証するには、そのXML Schema自体を検索、解析および検証する必要があります。

Oracle XML DBでは、XML Schemaの使用に関連するオーバーヘッドを最小化します。データベースに登録されたXML Schemaは、テキスト、XOBおよびデータのディスク内表現との間のマップに必要なすべてのメタデータとともに、Oracle XML DBのスキーマ・キャッシュにロードされます。XML Schemaをデータベースに登録した後、そのXML Schemaを使用するために解析や検証を行う必要はありません。スキーマ・キャッシュは、データベースのすべてのユーザーが共有します。Oracle XML DBの操作でXML Schemaに含まれる情報が必要な場合は、必要な情報にキャッシュから直接アクセスできます。

キャッシュ済のXML Schemaを使用したロード・バランシング

スキーマの全体検証の実行やXML文書のテキスト形式へのシリアライズなど、一部の操作では多くのメモリーおよびCPUリソースが必要です。Oracle XML DBでは、これらの操作をクライアントまたは中間層のプロセッサに肩代わりさせることができます。Oracle Call Interface (OCI)インタフェースおよびJDBC用OCIドライバにより、XOBをクライアントで管理できます。XML Schemaのキャッシュされた表現はクライアントにもダウンロードできます。これにより、XML出力やXML Schemaの検証などの操作を、サーバー・リソースではなくクライアントまたは中間層のリソースを使用して実行できるようになります。

ネイティブでないコードによるボトルネックの低減

XMLベースのJavaアプリケーションでは、XMLファイルの解析時に別のボトルネックが発生します。ネイティブにコンパイルされたJavaまたはJITでコンパイルされたJavaでも、XML解析操作では、ネイティブなC言語を使用した場合に比較して2倍の実行時間がかかります。XMLアプリケーションを実装する際のパフォーマンス上の主要なボトルネックの1つは、XML文書内のデータをテキスト、Javaおよびネイティブ・サーバーの各表現に変換するコストです。この変換を実行するためのコストはXMLファイルのサイズと複雑さに比例するため、適度なサイズのファイルの場合でも重大なボトルネックになります。

Oracle XML DBではこの問題に対処するため、すべてのJavaインタフェースおよびPL/SQLインタフェースを、C言語でのネイティブ実装に対する軽量なファサードとして実装します。Java、C、PL/SQLおよびSQLすべてが同じ基礎となる実装を使用します。これによって、言語的に中立なXMLサポートが提供され、XML解析およびDOM処理のパフォーマンスが向上します。

Javaでの型変換によるボトルネックの低減

JavaおよびXMLの使用時の最大のボトルネックの1つは、型変換によるものです。Javaでは、内部的にUCS-2を使用して文字データを表現します。ほとんどのXMLファイルとデータベースには、UCS-2でエンコードされたデータは含まれていません。XMLファイルに含まれているすべてのデータは、Javaプログラムで操作する前に、8ビットまたはUTF-8エンコーディングからUCS-2エンコーディングに変換する必要があります。

Oracle XML DBではこの問題に対処するため、遅延型変換を使用します。遅延型変換を使用すると、アプリケーションがノードのコンテンツにアクセスするまで、そのノードのコンテンツはJavaで必要な形式に変換されません。データは、直前まで内部表現のままです。アプリケーションがXML文書内の数個のノードのみにアクセスする場合は、不要な型変換を回避することによってパフォーマンスが大幅に向上します。

Oracle Databaseから名前をロードし、生成されたHTMLにその名前を出力するJSPを考えてみます。一般的なJSP実装ではデータベース(ASCIIまたはISO8859キャラクタ・セットのデータが格納されている可能性があります)から名前を読み取り、そのデータをUCS-2に変換して、Javaに文字列として戻します。JSPでは、文字列コンテンツを参照せず、囲まれたHTMLの出力後にそのコンテンツを出力するのみで、クライアントのブラウザ用に元と同じASCIIまたはISO8859に再変換します。Oracle XML DBでは、XMLTypeに書込みインタフェースを提供します。このため、すべての要素は、それ自体をJavaキャラクタ・セットによる変換なしでストリーム(ServletOutputStreamなど)に直接書き込むことができます。図2-2にOracle XML DB Application Program Interface (API)スタックを示します。

図2-2 Oracle XML DBのApplication Program Interface(API)スタック

3 Oracle XML DBの使用

この章では、Oracle XML DBの使用方法について概説します。この章の例では、発注書のXMLコンテンツへのアクセスおよび管理の方法を示します。発注書は高度に構造化された文書ですが、ほとんど構造化されていないXML文書に対しても、ここに示す方法を使用することができます。

この章の内容は次のとおりです。

- XMLデータをXMLTypeとして格納

- XMLType表および列の作成

- 仮想列を使用したバイナリXMLデータのパーティション化または制約

- Oracle XML DBへのXMLコンテンツのロード

- XML文書のキャラクタ・セット

- W3CのXML Schema勧告の概要

- Oracle XML DBでのXML Schemaの使用

- XML Schemaインスタンス・ドキュメントの識別

- データベースを使用したXMLデータ整合性の規定

- Oracle XML DBを使用したXMLコンテンツに対するDML操作

- Oracle XML DBに格納されたXMLコンテンツの問合せ

- リレーショナル・ビューを使用したOracle XML DB内のXMLデータへのアクセス

- Oracle XML DBに格納されたXMLコンテンツの更新

- Oracle XML DBでの名前空間のサポート

- Oracle XML DBでのXMLTypeメソッドおよびSQL関数の処理

- リレーショナル・データからのXMLデータの生成

- XSL変換とOracle XML DB

- Oracle XML DBリポジトリの使用

- ブラウザを使用した、リレーショナル・データのXMLとしての表示

- DBUriサーブレットを使用したXSL変換

XMLデータをXMLTypeとして格納

Oracle XML DBが導入される前は、次の2つの方法でXMLコンテンツをOracle Databaseに格納していました。

- Oracle XML Developer's Kit(XDK)を使用してXML文書をOracle Database外部で解析し、抽出したXMLデータをデータベース内の1つ以上の表に行として格納します。

- キャラクタ・ラージ・オブジェクト(CLOB)、バイナリ・ラージ・オブジェクト(BLOB)、バイナリ・ファイル(BFILE)またはVARCHAR列を使用して、XML文書をOracle Databaseに格納します。

いずれの場合も、Oracle DatabaseはXMLコンテンツを管理していることを認識しません。

Oracle XML DBおよびXMLType抽象データ型により、Oracle DatabaseはXML対応になります。XMLデータをXMLType列または表として格納すると、Oracle Databaseはコンテンツに対してXML固有の操作を実行できます。たとえば、XMLの検証や最適化の操作などです。XMLType記憶域では、データベース内のXMLコンテンツを非常に効率的に処理できます。

XMLTypeの概要

XMLTypeは、データベースのXMLデータのネイティブな処理に対応した抽象データ型です。

- XMLTypeには、データベースのXMLデータの作成、抽出および索引付けを行う組込みメソッドが含まれています。

- XMLTypeは、XMLデータへのSQLアクセスを提供します。

- XMLTypeの機能は、PL/SQLおよびJavaで提供される一連のApplication Program Interface(API)を介して使用することもできます。XMLTypeは、PL/SQLストアド・プロシージャのパラメータ、戻り値および変数に使用できます。

XMLTypeを使用すると、SQL開発者は、XMLでの作業中にリレーショナル・データベースの機能を使用できます。XML開発者は、リレーショナル・データベースでの作業中にXML標準の機能を使用できます。

XMLTypeは、表の列およびビューのデータ型として使用できます。XMLType変数は、PL/SQLストアド・プロシージャのパラメータおよび戻り値として使用できます。また、XMLTypeは、SQL、PL/SQL、C、Java(JDBCを介して)およびOracle Data Provider for .NET(ODP.NET)でも使用できます。

XMLType APIによって、XMLコンテンツを操作する有効なメソッドがいくつか提供されています。たとえば、メソッドextract()は、XMLTypeインスタンスから1つ以上のノードを抽出します。

Oracle XML DBの機能は、関連するXML標準(XML Parser、XML DOM、XML Schema Validatorなど)のOracle XML Developer's KitのC実装に基づいています。

関連項目:

- 「XMLTypeデータ型」

- 使用可能なXMLType記憶域オプションおよびその相対的なメリットは、「XMLType記憶域モデル」を参照してください。

XMLTypeデータ型およびAPIのメリット

XMLTypeデータ型およびApplication Program Interface(API)は、XMLコンテンツに対するSQL操作およびSQLコンテンツに対するXML操作を可能にします。

- 汎用API: XMLTypeには、組込み関数、索引付けおよびナビゲーション・サポートが含まれるアプリケーション開発用の汎用APIが備わっています。

- XMLTypeおよびSQL: XMLTypeは、SQL文で他のデータ型と組み合せて使用できます。たとえば、XMLType列を問い合せ、抽出の結果をリレーショナル列と結合できます。Oracle Databaseでは、このような問合せを実行するための最適な方法を判断します。

- 索引付け: 複数の種類の索引を作成して、XMLデータに対する問合せのパフォーマンスを向上できます。

- XMLTypeデータの構造化記憶域の場合は、XMLType表および列の基礎となるBツリー索引およびファンクション索引をオブジェクト・リレーショナル表に作成できます。ファンクション索引は、スカラー・データ(単一の要素または属性を表す列)のみに作成します。

- XMLTypeデータの非構造化およびバイナリXML記憶域の場合は、XMLIndex索引を作成できます。これは、ドキュメントのXML構造を対象とした索引です。

- XMLデータのテキスト・コンテンツの索引は、Oracle TextのCONTEXT索引を使用して作成でき、全文検索で使用できます。これはすべてのXMLType記憶域モデルに適用されます。

XMLType表および列の作成

XMLTypeは抽象データ型なので、XMLType表または列を容易に作成することができます。記憶域オプションとXML Schemaを指定しない基本的なCREATE TABLE文では、XMLTypeデータはバイナリXMLとして格納されます。脚注 1

例3-1ではXMLType列を作成し、例3-2ではXMLType表を作成します。

例3-1 XMLType列を含む表の作成

CREATE TABLE mytable1 (key_column VARCHAR2(10) PRIMARY KEY, xml_column XMLType);

例3-2 XMLType表の作成

CREATE TABLE mytable2 OF XMLType;

関連項目:
「XML Schemaに基づくXMLType表および列の作成」

注意:
各自のデータベース・スキーマと異なるデータベース・スキーマにXMLType表を作成するには、権限CREATE ANY TABLEだけでなく、権限CREATE ANY INDEXも必要です。これは、表の作成時に列OBJECT_IDに一意索引が作成されるためです。列OBJECT_IDには、システム生成のオブジェクト識別子が格納されます。

仮想列を使用したバイナリXMLデータのパーティション化または制約

XMLデータには独自の構造がありますが、XMLTypeのオブジェクト・リレーショナル記憶域を除き、データベースのデータ構造には直接反映されません。つまり、個別のXML要素および属性がデータベースの個別の列や表にマップされることはありません。

したがって、個別の要素や属性の値に応じてXMLデータを制約またはパーティション化する場合、リレーショナル・データの標準的な手法は適用できません。このため、対象のXMLデータを表す仮想列を作成してから、その仮想列を使用して必要な制約またはパーティションを定義する必要があります。

この方法は、バイナリXMLとして格納されているXMLデータにのみ適用されます。非構造化記憶域を使用するXMLデータの場合、データベースはXML構造を認識せず、データはフラット・テキストとして扱われますが、バイナリXML記憶域の場合、構造が認識されます。この構造についての情報を使用して仮想列を作成すると、データベースではそれを制約またはパーティションに使用できます。

手順は次のとおりです。

1. 対象のXMLデータに対応する仮想列を定義します。

2. その列を使用して、XMLTypeデータを一括してパーティション化または制約します。

XMLTypeデータに対する仮想列の作成は、他の型のデータを使用した仮想列の作成と同様ですが、構文が多少異なります。特に、列定義に関連付けて制約を指定することができません。

XMLTypeは抽象データ型なので、仮想列をXMLType表に作成する場合、それらの列は非表示になります。これらはDESCRIBE文などに表示されません。表示されないことで、DESCRIBEなどの操作を使用するツールが、仮想列に惑わされずに正常に機能することができます。

注意:

- バイナリXML表のパーティショニングは11gリリース2 (11.2)以降でサポートされています。データベースの互換性(ファイルinit.ora内のパラメータcompatible)が11.2以上の場合にのみサポートされます。

- レンジ、ハッシュおよびリストのパーティション化がサポートされています。

- 仮想列を使用すると、XMLType表をパーティション化できます。XMLデータの仮想列を定義する列を使用して、XMLType 列を含むリレーショナル表をパーティション化することはできません。

XML要素または属性に基づく仮想列を作成するには、その要素や属性を含むSQL式によって仮想列を定義します。したがって、作成される列はファンクション・ベースです。これには、例3-3に示すように、SQL/XML関数XMLCastおよびXMLQueryを使用します。関数XMLQueryのXQuery式引数は、子および属性の軸のみを使用する簡単なXPath式にする必要があります。

例3-3 仮想列を使用したバイナリXML表のパーティション化

CREATE TABLE po_binaryxml OF XMLType
XMLTYPE STORE AS BINARY XML
VIRTUAL COLUMNS
(DATE_COL AS (XMLCast(XMLQuery('/PurchaseOrder/@orderDate'
PASSING OBJECT_VALUE RETURNING CONTENT)
AS DATE)))
PARTITION BY RANGE (DATE_COL)
(PARTITION orders2001 VALUES LESS THAN (to_date('01-JAN-2002')),
PARTITION orders2002 VALUES LESS THAN (MAXVALUE));

例3-3では、仮想列DATE_COLを使用してXMLType表をパーティション化します。この列は、発注書のorderDate要素をターゲットにしています。

パーティショニング用に仮想列を使用するには、そのデータ型が一定である必要があります。列または表内のXMLTypeデータが混在している場合、XML Schemaを使用してエンコードされる文書もあれば、スキーマを使用せずにエンコードされる文書もあります。このため、仮想列内のすべての行に常に同じデータ型が使用されるように、ファンクション式をキャストする必要があります。

注意:
パフォーマンスを最適にするため、パーティション化キーとして、XML文書の最初の32KB以内にターゲットがあるXPath式を選択してください。

バイナリXMLデータに対する制約も、同様の方法で定義します。例3-20を参照してください。

関連項目:

- 「XMLIndexのパーティション化および並列度」

- 「SQL制約を使用した参照整合性の規定」

- 仮想列を使用した表の作成の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

Oracle XML DBへのXMLコンテンツのロード

XMLコンテンツは、次の方法を使用してOracle XML DBにロードできます。

- 表ベースのロード:

- SQLまたはPL/SQLを使用したXMLコンテンツのロード

- Javaを使用したXMLコンテンツのロード

- Cを使用したXMLコンテンツのロード

- 小規模なXML文書を含む大規模なXMLファイルのロード

- SQL*Loaderを使用した大規模なXMLファイルのロード

- パスベースのリポジトリのロード方法:

- DBMS_XDBを使用したリポジトリへのXML文書のロード

- プロトコルを使用したリポジトリへの文書のロード

SQLまたはPL/SQLを使用したXMLコンテンツのロード

SQLまたはPL/SQLの簡単なINSERT操作を使用して、XML文書をデータベースにロードできます。文書は、XMLType列または表として格納する前に、XMLTypeコンストラクタの1つを使用してXMLTypeインスタンスに変換する必要があります。

関連項目:

- 第4章「XMLTypeの操作」

- 「XML用のAPI」

- XMLTypeコンストラクタの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

XMLTypeコンストラクタを使用すると、VARCHAR、CLOBおよびBFILE値を含む様々なソースからXMLTypeインスタンスを作成できます。このコンストラクタは、XMLTypeの作成に関連する処理量を減らす追加の引数を受け入れます。たとえば、ソースのXML文書が有効だとわかっている場合には、有効かどうかわからない場合に実行される型チェックを無効にする引数をコンストラクタに指定できます。

さらに、ソース・データがデータベース・キャラクタ・セットでエンコードされていない場合、XMLTypeインスタンスはBFILE値またはBLOB値を使用して構成できます。ソース・データのエンコーディングは、コンストラクタのキャラクタ・セットID(csid)引数で指定されます。

例3-5に、XMLコンテンツをXMLType表に挿入する方法を示します。この挿入を行う前に、処理するファイルが含まれたディレクトリを指すデータベース・ディレクトリ・オブジェクトを作成する必要があります。作成するためには、CREATE ANY DIRECTORY権限が必要です。

関連項目:
『Oracle Database SQL言語リファレンス』の第18章のGRANTに関する項

例3-4 データベース・ディレクトリの作成

CREATE DIRECTORY xmldir AS path_to_folder_containing_XML_file;

例3-5 XMLType表へのXMLコンテンツの挿入

INSERT INTO mytable2 VALUES (XMLType(bfilename('XMLDIR', 'purchaseOrder.xml'),
nls_charset_id('AL32UTF8')));

nls_charset_idに渡される値は、読み取られるファイルのエンコーディングがUTF-8であることを示します。

SQL INSERTを使用して、コレクションを含む大規模な文書を(XMLType列ではなく)XMLType表に挿入する場合、Oracle XML DBによってロード時間とメモリー使用量が最適化されます。

関連項目:
「コレクションでの大規模な文書のロードおよび取得」

Javaを使用したXMLコンテンツのロード

例3-6は、ドキュメント・オブジェクト・モデル(DOM)を指定して最初にJavaでXMLTypeインスタンスを作成することによって、XMLコンテンツをOracle XML DBにロードする方法を示しています。

例3-6 Javaを使用したXMLType表へのコンテンツの挿入

public void doInsert(Connection conn, Document doc)
throws Exception
{
String SQLTEXT = "INSERT INTO purchaseorder VALUES (?)";
XMLType xml = null;
xml = XMLType.createXML(conn,doc);
OraclePreparedStatement sqlStatement = null;
sqlStatement = (OraclePreparedStatement) conn.prepareStatement(SQLTEXT);
sqlStatement.setObject(1,xml);
sqlStatement.execute();
}

単純なバルク・ローダー・アプリケーションがOracle Technology Network (OTN)サイト(http://www.oracle.com/technetwork/database-features/xmldb/overview/index.html)で入手可能です。これにはJava Database Connectivity (JDBC)を使用してXMLファイルのディレクトリをOracle XML DBにロードする方法が示されています。JDBCは、Oracle Databaseに対する一連のJavaインタフェースです。

Cを使用したXMLコンテンツのロード

例3-7に、DOMを指定してXMLTypeインスタンスを作成することによって、CコードでXMLコンテンツをXMLType表に挿入する方法を示します。

例3-7 Cを使用したXMLType表へのコンテンツの挿入

#include "stdio.h"
#include <xml.h>
#include <stdlib.h>
#include <string.h>
#include <ocixmldb.h>
OCIEnv *envhp;
OCIError *errhp;
OCISvcCtx *svchp;
OCIStmt *stmthp;
OCIServer *srvhp;
OCIDuration dur;
OCISession *sesshp;
oratext *username = "QUINE";
oratext *password = "************";         /* Replace with the real password. */
oratext *filename = "AMCEWEN-20021009123336171PDT.xml";
oratext *schemaloc = "http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd";

/*--------------------------------------------------------*/
/* Execute a SQL statement that binds XML data            */
/*--------------------------------------------------------*/

sword exec_bind_xml(OCISvcCtx *svchp, OCIError *errhp, OCIStmt *stmthp,
void *xml,        OCIType *xmltdo, OraText *sqlstmt)
{
OCIBind *bndhp1 = (OCIBind *) 0;
sword  status = 0;
OCIInd ind = OCI_IND_NOTNULL;
OCIInd *indp = &ind;
if(status = OCIStmtPrepare(stmthp, errhp, (OraText *)sqlstmt,
(ub4)strlen((const char *)sqlstmt),
(ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT))
return OCI_ERROR;
if(status = OCIBindByPos(stmthp, &bndhp1, errhp, (ub4) 1, (dvoid *) 0,
(sb4) 0, SQLT_NTY, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, (ub4) 0, (ub4 *) 0, (ub4) OCI_DEFAULT))
return OCI_ERROR;
if(status = OCIBindObject(bndhp1, errhp, (CONST OCIType *) xmltdo,
(dvoid **) &xml, (ub4 *) 0,
(dvoid **) &indp, (ub4 *) 0))
return OCI_ERROR;
if(status = OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0,
(CONST OCISnapshot*) 0, (OCISnapshot*) 0,
(ub4) OCI_DEFAULT))
return OCI_ERROR;
return OCI_SUCCESS;
}

/*--------------------------------------------------------*/
/* Initialize OCI handles, and connect                    */
/*--------------------------------------------------------*/

sword init_oci_connect()
{
. . .
}

/*--------------------------------------------------------*/
/* Free OCI handles, and disconnect                       */
/*--------------------------------------------------------*/

void free_oci()
{
. . .
}

void main()
{
OCIType *xmltdo;
xmldocnode  *doc;
ocixmldbparam params[1];
xmlerr       err;
xmlctx  *xctx;
oratext *ins_stmt;
sword    status;
xmlnode *root;
oratext buf[10000];

/* Initialize envhp, svchp, errhp, dur, stmthp */
init_oci_connect();

/* Get an XML context */
params[0].name_ocixmldbparam = XCTXINIT_OCIDUR;
params[0].value_ocixmldbparam = &dur;
xctx = OCIXmlDbInitXmlCtx(envhp, svchp, errhp, params, 1);
if (!(doc = XmlLoadDom(xctx, &err, "file", filename,
"schema_location", schemaloc, NULL)))
{
printf("Parse failed.\n");
return;
}
else
printf("Parse succeeded.\n");
root = XmlDomGetDocElem(xctx, doc);
printf("The xml document is :\n");
XmlSaveDom(xctx, &err, (xmlnode *)doc, "buffer", buf, "buffer_length", 10000, NULL);
printf("%s\n", buf);

/* Insert the document into my_table */
ins_stmt = (oratext *)"insert into purchaseorder values (:1)";
status = OCITypeByName(envhp, errhp, svchp, (const text *) "SYS",
(ub4) strlen((const char *)"SYS"), (const text *) "XMLTYPE",
(ub4) strlen((const char *)"XMLTYPE"), (CONST text *) 0,
(ub4) 0, OCI_DURATION_SESSION, OCI_TYPEGET_HEADER,
(OCIType **) &xmltdo);
if (status == OCI_SUCCESS)
{
status = exec_bind_xml(svchp, errhp, stmthp, (void *)doc,
xmltdo, ins_stmt);
}
if (status == OCI_SUCCESS)
printf ("Insert successful\n");
else
printf ("Insert failed\n");

/* Free XML instances */
if (doc)
XmlFreeDocument((xmlctx *)xctx, (xmldocnode *)doc);
/* Free XML CTX */
OCIXmlDbFreeXmlCtx(xctx);
free_oci();
}

注意:
この機能を簡単に説明するために、この例では、デプロイされたシステムで通常使用されるパスワード管理手法を実行していません。本番環境では、Oracle Databaseパスワード管理のガイドラインに従い、サンプル・アカウントをすべて無効化してください。パスワード管理のガイドラインおよびセキュリティに関するその他の推奨事項は、『Oracle Databaseセキュリティ・ガイド』を参照してください。

関連項目:
この例の完全なリストは、付録A「Oracleが提供するXML Schemaおよび例」を参照してください。

小規模なXML文書を含む大規模なXMLファイルのロード

小規模なXML文書のコレクションで構成された大規模なXMLファイルをロードするときは、Simple API for XML(SAX)の解析機能を使用してファイルを一連の小規模な文書に分割してから文書を挿入すると、効率的にロードできます。SAXは、XML Parserがイベント・ベース・アプリケーション用に提供するXML標準インタフェースです。

SAXを使用して、ノードのコレクションから各文書を作成することによって、30MB以上の大規模なXMLファイルからデータベース表をロードできます。XMLファイルは、バルク・ロードすることもできます。

関連項目:

- SAXの詳細は、http://www.saxproject.org/を参照してください。

- SAXを使用して大きなファイルをロードするアプリケーション例については、http://www.oracle.com/technetwork/database-features/xmldb/overview/index.htmlを参照してください。

SQL*Loaderを使用した大規模なXMLファイルのロード

大量のXMLデータをOracle Databaseにロードするには、SQL*Loaderを使用します。SQL*Loaderは、従来型パスまたはダイレクト・パスのいずれかのモードでロードを実行します。表3-1に、2つのモードの比較を示します。

表3-1 SQL*Loaderの従来型パスおよびダイレクト・パスによるロード・モード

従来型パスによるロード・モード

ダイレクト・パスによるロード・モード

SQLを使用してデータをOracle Databaseにロードします。これはデフォルトのモードです。

SQLをバイパスして、データを直接Oracle Databaseにロードします。

メリット: SQLセマンティクスに従います。たとえば、トリガーが起動され、制約がチェックされます。

メリット: 従来のロード・モードより高速にデータをロードできます。

デメリット: ダイレクト・ロード・モードよりもデータのロードが遅くなります。

デメリット: SQLセマンティクスに従いません。たとえば、トリガーは起動されず、制約もチェックされません。

SQL*Loaderのダイレクト・パス・モードでLOBをロードすると、多くのメモリーを使用できます。メッセージSQL*Loader 700 (out of memory)が表示された場合は、オペレーティング・システムおよびプロセス・メモリーで処理できる行より多くの行が各ロード・コールに含まれている可能性があります。回避策: ROWSオプションを使用して、各データ保存で読み取られる行数を少なくします。

関連項目:
第35章「SQL*Loaderを使用したXMLデータのロード」

DBMS_XDBを使用したリポジトリへのXML文書のロード

XML文書をOracle XML DBリポジトリに格納して、表ベースではなくパスベースの方法でその文書にアクセスすることも可能です。指定のパスのリポジトリにXML文書をロードするには、PL/SQL関数DBMS_XDB.createResourceを使用します。例3-8に、これを示します。

例3-8 CREATERESOURCEを使用したリポジトリへのXMLコンテンツの挿入

DECLARE
res BOOLEAN;
BEGIN
res := DBMS_XDB.createResource('/home/QUINE/purchaseOrder.xml',
bfilename('XMLDIR', 'purchaseOrder.xml'),
nls_charset_id('AL32UTF8'));
END;/

Oracle XML DBを構成して使用するための多くの操作は、1つ以上のXML文書の処理に基づいています。たとえば、XML Schemaの登録や、XSL変換の実行などです。これらのXML文書をOracle Databaseで使用可能にする最も簡単な方法は、そのXML文書をOracle XML DBリポジトリにロードすることです。

プロトコルを使用したリポジトリへの文書のロード

Oracle XML DBリポジトリには、XML Schemaに基づくXML文書もXML Schemaに基づかないXML文書も格納できます。HTMLファイル、画像ファイルおよびMicrosoft Word文書などのXMLデータでないコンテンツも格納できます。

Windows ExplorerなどWebDAVをサポートするツールからWebDAVプロトコルなどのプロトコルを使用して、ローカル・ファイル・システムからOracle XML DBリポジトリにXML文書をロードできます。図3-1に、SCOTTフォルダのコンテンツをローカル・ハード・ドライブからOracle XML DBリポジトリ内のフォルダpoSourceにコピーする簡単なドラッグ・アンド・ドロップ操作を示します。

図3-1 Windows Explorerを使用したリポジトリへのコンテンツのロード

コピーされたフォルダには、XML Schema文書、HTMLページおよびいくつかのXSLTスタイルシートが含まれていることがあります。

XML文書のキャラクタ・セット

この項では、XML文書のキャラクタ・セットがどのように決定されるかを説明します。

注意:
AL32UTF8は、XMLTypeデータに適したOracle Databaseキャラクタ・セットです。これはIANAの登録済標準であるUTF-8エンコーディングと同等であり、すべての有効なXML文字をサポートします。
Oracle Databaseのデータベース・キャラクタ・セットUTF8(ハイフンなし)とデータベース・キャラクタ・セットAL32UTF8またはキャラクタ・エンコーディングUTF-8を混同しないでください。データベース・キャラクタ・セットUTF8はAL32UTF8で置き換えられています。XMLデータにはUTF8を使用しないでください。キャラクタ・セットUTF8でサポートされるのはUnicodeバージョン3.1以下のみです。すべての有効なXML文字がサポートされるわけではありません。AL32UTF8には、このような制限はありません。

XMLデータにデータベース・キャラクタ・セットUTF8を使用すると、システムが停止したりセキュリティに悪影響を及ぼす可能性があります。入力した文書要素の名前にデータベース・キャラクタ・セットでサポートされない文字が含まれている場合、その文字は置換文字(通常は「?」)で置き換えられます。このため、解析が終了して例外が発生します。リカバリ不能なエラーが発生する場合もあります。

XMLエンコーディング宣言

各XML文書は、エンティティと呼ばれる単位で構成されます。XML文書内の各エンティティでは、異なるエンコーディングの文字が使用される場合があります。UTF-8またはUTF-16以外のエンコーディングで格納されるエンティティは、使用する文字コードを示すエンコーディング仕様が含まれたXML宣言で始まる必要があります。次に例を示します。

<?xml version='1.0' encoding='EUC-JP' ?>

UTF-16でエンコードされたエンティティは、「XML 1.0 Reference」の付録Fで説明されているバイト・オーダー・マーク(BOM)で始まる必要があります。たとえば、大規模なendianのプラットフォームで、UTF-16データ・ストリームに必要なBOMは#xFEFFです。

エンコーディング宣言およびBOMの両方が存在しない場合、XMLエンティティはUTF-8でエンコードされていると想定されます。ASCIIはUTF-8のサブセットであるため、ASCIIエンティティではエンコーディング宣言は必要ありません。

多くの場合、使用する文字コードの情報は、XMLデータ以外に外部ソースからも取得できます。たとえば、データのエンコーディングは、次に示すように、HTTP(S)リクエストのContent-Typeフィールドのcharsetパラメータから取得できます。

Content-Type: text/xml; charset=ISO-8859-4

XML文書をデータベースにロードするときのキャラクタ・セットの決定

Oracle Database 10gリリース1以前のリリースでは、すべてのXML文書は、文書のエンコーディング宣言にかかわらずデータベース・キャラクタ・セットであるとみなされていました。Oracle Database 10gリリース1以降では、文書がデータベースにロードされるときに、その文書のエンコーディングがエンコーディング宣言から検出されます。

ただし、XMLデータがCLOBまたはVARCHAR値から取得される場合、これらの2つのデータ型は常にデータベース・キャラクタ・セットでエンコードされるので、エンコーディング宣言は無視されます。

さらに、プログラムAPIまたは転送プロトコルのいずれかを介してデータをOracle XML DBにロードするときは、外部エンコーディングを指定して文書のエンコーディング宣言をオーバーライドできます。XML Schemaに基づくXML文書に指定のエンコーディングに対して不適切な文字が含まれている場合、その文書をロードしようとするとエラーが発生します。

次の各例で、外部エンコーディングを指定するいくつかの方法を示します。

- PL/SQL関数DBMS_XDB.createResourceを使用してBFILEからファイル・リソースを作成する場合、CSID引数でファイルのエンコーディングを指定できます。CSIDにゼロを指定すると、ファイルのエンコーディングは文書のエンコーディング宣言から自動検出されます。

CREATE DIRECTORY xmldir AS '/private/xmldir';
CREATE OR REPLACE PROCEDURE loadXML(filename VARCHAR2, file_csid NUMBER) IS
xbfile  BFILE;
RET     BOOLEAN;
BEGIN
xbfile := bfilename('XMLDIR', filename);
ret := DBMS_XDB.createResource('/public/mypurchaseorder.xml',
xbfile,
file_csid);
END;/

- FTPプロトコルを使用して、文書をOracle XML DBにロードします。quote set_charset FTPコマンドを使用して、ロードするファイルのエンコーディングを指定します。

ftp> quote set_charset Shift_JIS
ftp> put mypurchaseorder.xml

- HTTP(S)プロトコルを使用して、文書をOracle XML DBにロードします。Oracle XML DBに転送するデータのエンコーディングは、リクエスト・ヘッダー内に指定します。

Content-Type: text/xml; charset= EUC-JP

データベースからXML文書を取り出すときのキャラクタ・セットの決定

Oracle XML DBに格納されたXML文書は、SQLクライアント、プログラムAPIまたは転送プロトコルを使用して取り出すことができます。取り出すデータのエンコーディングを指定できます(ただし、Oracle Database 10gより前のリリースでは、XMLデータはデータベース・キャラクタ・セットでのみ取り出されるため、エンコーディングを指定できません)。

XMLデータをCLOBまたはVARCHAR2値として格納すると、エンコーディング宣言がある場合、その宣言は、格納と同様に取出しでも常に無視されます。したがって、取り出す文書のエンコーディングは、その文書で明示的に宣言されているエンコーディングとは異なる場合があります。

データベースから取り出されるXML文書のキャラクタ・セットは、次の方法で決定されます。

- SQLクライアント: XMLの取出しに(SQL*Plusなどの)SQLクライアントが使用される場合、キャラクタ・セットはクライアント側の環境変数NLS_LANGによって決定されます。特に、XMLデータ自体にキャラクタ・セットが明示的に宣言されていても、この設定のほうが優先されます。
たとえば、クライアント側のNLS_LANG変数をAMERICAN_AMERICA.AL32UTF8に設定し、宣言<?xml version="1.0" encoding="EUC-JP"?>で指定されたエンコーディングEUC_JPのXML文書を取得する場合、取得される文書のキャラクタ・セットはEUC_JPではなく、AL32UTF8となります。

関連項目:
NLS_LANGの詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。

- PL/SQLおよびAPI: PL/SQLまたはプログラムAPIを使用すると、XMLデータをVARCHAR、CLOBまたはXMLTypeデータ型で取り出すことができます。SQLクライアントの場合、NLS_LANGを設定することにより、取り出すデータのエンコーディングを制御できます。
また、XMLTypeおよびURITypeメソッドを使用して、XMLデータをBLOB値で取り出すこともできます。これにより、BLOB値のキャラクタ・セットを指定できます。次に例を示します。

CREATE OR REPLACE FUNCTION getXML(pathname VARCHAR2, charset VARCHAR2)
RETURN BLOB IS
xblob BLOB;
BEGIN
SELECT XMLSERIALIZE(DOCUMENT e.RES AS BLOB ENCODING charset) INTO xblob
FROM RESOURCE_VIEW e WHERE equals_path(e.RES, pathname) = 1;
RETURN xblob;
END;
/

- FTP: FTP quote set_nls_localeコマンドを使用して、キャラクタ・セットを設定できます。

ftp> quote set_nls_locale EUC-JP
ftp> get mypurchaseorder.xml

関連項目:
FTP Quoteメソッド

- HTTP(S): HTTP(S)リクエストでAccept-Charsetパラメータを使用できます。

/httptest/mypurchaseorder.xml  1.1 HTTP/Host: localhost:2345
Accept: text/*
Accept-Charset:  iso-8859-1, utf-8

関連項目:
HTTP(S)のキャラクタ・セットの制御

W3CのXML Schema勧告の概要

W3CのXML Schema勧告では、一連のXML文書の構造、コンテンツおよび特定のセマンティクスを指定するための標準化された言語が定義されています。XML Schemaは、XML文書のクラスを示すメタデータとみなすことができます。XML Schemaの勧告については、http://www.w3.org/TR/xmlschema-0/を参照してください。

XMLインスタンス・ドキュメント

指定のXML Schemaに準拠する文書は、そのXML Schemaで定義されたクラスのメンバーまたはインスタンスとみなすことができます。したがって、インスタンス・ドキュメントという用語は、多くの場合、指定したXML Schemaに準拠するXML文書を示すために使用しています。XML Schemaの最も一般的な用途は、指定されたインスタンス・ドキュメントがXML Schemaで定義されたルールに準拠していることを確認することです。

XML Schema for Schemas

W3CのSchemaワーキング・グループは「Schema for Schemas」と呼ばれるXML Schemaを公開しています。このXML Schemaによって、XML Schema言語の定義またはボキャブラリが提供されます。有効なすべてのXML Schemaは、そのXML Schemaで定義されたクラスのメンバーとみなすことができます。したがって、XML Schemaは(http://www.w3.org/2001/XMLSchemaで公開されている)XML Schemaで定義されたクラスに準拠するXML文書です。

XML Schemaの編集

XML Schemaは、次のいずれかを使用して作成および編集できます。

- emacsやviなどの簡単なテキスト・エディタ

- Oracle JDeveloperに付属のXMLエディタなど、XML Schemaを認識するエディタ

- Altova社のXMLSpyなどの明示的なXML Schema作成ツール

XML Schemaの機能

XML Schema言語は、47のスカラー・データ型を定義します。これによって、要素と属性の厳密な型指定が可能になります。W3CのXML Schema勧告では、継承や拡張などのオブジェクト指向の技法もサポートしているため、XML Schema言語で定義された基本データ型から複合的なオブジェクトを持つXML Schemaを設計できます。ボキャブラリには、定義および順序付けの構造体、デフォルト値、必須コンテンツ、ネスト、セットの繰返しおよび再定義が含まれます。Oracle XML DBは、再定義を除くすべての構造体をサポートします。

発注書XML Schemaのテキスト表現

例3-9に、XMLファイルpurchaseOrder.xsdとしての発注書XML Schemaを示します。

例3-9 発注書XML Schema、purchaseOrder.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0">
<xs:element name="PurchaseOrder" type="PurchaseOrderType"/>
<xs:complexType name="PurchaseOrderType">
<xs:sequence>
<xs:element name="Reference" type="ReferenceType"/>
<xs:element name="Actions" type="ActionsType"/>
<xs:element name="Reject" type="RejectionType" minOccurs="0"/>
<xs:element name="Requestor" type="RequestorType"/>
<xs:element name="User" type="UserType"/>
<xs:element name="CostCenter" type="CostCenterType"/>
<xs:element name="ShippingInstructions" type="ShippingInstructionsType"/>
<xs:element name="SpecialInstructions" type="SpecialInstructionsType"/>
<xs:element name="LineItems" type="LineItemsType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemsType">
<xs:sequence>
<xs:element name="LineItem" type="LineItemType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemType">
<xs:sequence>
<xs:element name="Description" type="DescriptionType"/>
<xs:element name="Part" type="PartType"/>
</xs:sequence>
<xs:attribute name="ItemNumber" type="xs:integer"/>
</xs:complexType>
<xs:complexType name="PartType">
<xs:attribute name="Id">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="10"/>
<xs:maxLength value="14"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Quantity" type="moneyType"/>
<xs:attribute name="UnitPrice" type="quantityType"/>
</xs:complexType>
<xs:simpleType name="ReferenceType">
<xs:restriction base="xs:string">
<xs:minLength value="18"/>
<xs:maxLength value="30"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="ActionsType">
<xs:sequence>
<xs:element name="Action" maxOccurs="4">
<xs:complexType>
<xs:sequence>
<xs:element name="User" type="UserType"/>
<xs:element name="Date" type="DateType" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RejectionType">
<xs:all>
<xs:element name="User" type="UserType" minOccurs="0"/>
<xs:element name="Date" type="DateType" minOccurs="0"/>
<xs:element name="Comments" type="CommentsType" minOccurs="0"/>
</xs:all>
</xs:complexType>
<xs:complexType name="ShippingInstructionsType">
<xs:sequence>
<xs:element name="name" type="NameType" minOccurs="0"/>
<xs:element name="address" type="AddressType" minOccurs="0"/>
<xs:element name="telephone" type="TelephoneType" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="moneyType">
<xs:restriction base="xs:decimal">
<xs:fractionDigits value="2"/>
<xs:totalDigits value="12"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="quantityType">
<xs:restriction base="xs:decimal">
<xs:fractionDigits value="4"/>
<xs:totalDigits value="8"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="RequestorType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="128"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CostCenterType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="4"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="VendorType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PurchaseOrderNumberType">
<xs:restriction base="xs:integer"/>
</xs:simpleType>
<xs:simpleType name="SpecialInstructionsType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="2048"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NameType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AddressType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TelephoneType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="24"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="DateType">
<xs:restriction base="xs:date"/>
</xs:simpleType>
<xs:simpleType name="CommentsType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="2048"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="DescriptionType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

関連項目:
例3-10「注釈付きの発注書XML Schema、purchaseOrder.xsd」

発注書XML Schemaのグラフィカル表現

図3-2に、XMLSpyを使用して表示した発注書XML Schemaを示します。XMLSpyは、Altova社のグラフィカルでわかりやすいツールで、XML SchemaおよびXML文書を作成および編集するために使用します。詳細は、http://www.altova.comを参照してください。XMLSpyは、WebDAVおよびFTPプロトコルもサポートしているため、Oracle XML DBリポジトリに格納されているコンテンツに直接アクセスして編集できます。

図3-2 XML Schema PurchaseOrderのXMLSpyによるグラフィカル表現

この発注書XML Schemaは、次のような一般的なXML文書の主要な機能を示しています。

- グローバル要素PurchaseOrderは、complexType PurchaseOrderTypeのインスタンスです。

- PurchaseOrderTypeでは、PurchaseOrder要素を構成する一連のノードが定義されます。

- LineItem要素は、LineItems要素のコレクションで構成されます。

- 各LineItem要素は、2つの要素(DescriptionおよびPart)で構成されます。

- Part要素には、属性Id、QuantityおよびUnitPriceがあります。

Oracle XML DBでのXML Schemaの使用

この項では、Oracle XML DBでのXML Schemaの使用について説明します。

XML SchemaをOracle XML DBとともに使用する理由

次に、XML SchemaをOracle XML DBとともに使用する主な理由を説明します。

XML Schemaを使用したインスタンス・ドキュメントの検証

XML Schemaの最も一般的な用途は、インスタンス・ドキュメントが指定のXML Schemaに準拠していることを確認するメカニズムとして使用することです。XMLTypeメソッドisSchemaValid()およびschemaValidate()によって、XMLTypeとして格納されたインスタンス・ドキュメントのコンテンツを検証します。

ビジネス・ルールまたは書式準拠に対するインスタンス・ドキュメントの制約

XML Schemaは、XMLTypeの表または列の作成時に制約としても使用できます。たとえば、XMLTypeは、XML Schemaで定義されたいずれかのグローバル要素に準拠するXML文書の格納用に制限されます。

データベースへのXMLTypeコンテンツの格納方法の定義

Oracle XML DBでは、XML Schemaを、XMLTypeインスタンスのコンテンツをデータベース内に格納する方法を定義するメカニズムとしても使用します。バイナリXML、構造化、非構造化およびハイブリッド(構造化と非構造化の組合せ)のすべての記憶域モデルで、XML Schemaの使用をサポートしています。XMLTypeに使用可能な記憶域モデルの詳細は、「XMLType記憶域モデル」を参照してください。

XML文書の構造化記憶域

XML文書の構造化記憶域には、文書のコンテンツが一連のSQLオブジェクトに分解されて格納されます。これらのSQLオブジェクトは、SQL 1999タイプのフレームワークに基づいています。XML SchemaがOracle XML DBに登録されると、必要なSQL型定義がXML Schemaから自動的に生成されます。

SQL型定義は、XML Schemaで定義された各complexTypeから生成されます。complexTypeで定義された各要素または属性は、対応するSQL型のSQL属性になります。Oracle XML DBは、XML Schema勧告で定義された47のスカラー・データ型を、SQLでサポートされている19のスカラー・データ型に自動的にマップします。VARRAY型は要素ごとに生成され、複数回、生成される場合があります。

生成されたSQL型により、XML Schemaに準拠するXMLコンテンツは、分解され、情報を損失せずに一連のオブジェクトとしてデータベースに格納できます。文書が収集されると、XML Schemaにより定義された構造体は同等のSQL型に直接マップされます。これにより、Oracle XML DBでは、XMLを管理するときにOracle Databaseのすべての機能を使用でき、文書の格納に必要な容量を大幅に削減できます。また、XMLコンテンツの問合せおよび更新に必要なメモリーの量も削減できます。

ネーミング、マッピングおよび記憶域を制御するためのXML Schemaの注釈付け

W3CのXML Schema勧告では、ベンダー固有の情報をXML Schemaに追加できる注釈メカニズムが定義されています。Oracle XML DBでは、このメカニズムを使用して、XML Schemaとデータベース・オプションの間のマッピングを制御します。

XML Schema注釈を使用すると、次の操作を実行できます。

- XMLデータを格納するデータベース表の指定

- XML Schemaデータ型とSQLデータ型(構造化記憶域の場合)の間のデフォルト・マッピングの上書き

- XMLデータを格納するために作成されるデータベース・オブジェクトおよび属性の命名(構造化記憶域の場合)

オブジェクト・リレーショナルなXMLType記憶域の場合のコレクション格納方法の制御

オブジェクト・リレーショナルに格納されるデータのXML Schemaを登録し、登録パラメータGENTABLESをTRUEに設定する場合、関連付けられたXMLインスタンス・ドキュメントを格納するためにデフォルト表が自動的に作成されます。

格納されるときに、XMLコレクション要素の順序は維持されます。結果はOrdered Collectionです。脚注 2 データは次の方法でOrdered Collectionに格納できます。

- 表内のVARRAY。コレクション内の各要素は、SQLオブジェクトにマップされます。SQLオブジェクトのコレクションは、Ordered Collection Table(OCT)と呼ばれる表に、一連の行として格納されます。デフォルトでは、すべてのコレクションがOCTに格納されます。このデフォルト動作は、XML Schema注釈xdb:storeVarrayAsTable = "true"(デフォルト値)に対応しています。

- LOB内のVARRAY。コレクション内の各要素は、SQLオブジェクトにマップされます。SQLオブジェクトのコレクション全体が、VARRAYとしてシリアライズされてLOB列に格納されます。指定されたコレクションをLOB内のVARRAYとして格納右するには、XML Schema注釈xdb:storeVarrayAsTable = "false"を使用します。

Ordered Collectionでは表外への格納を使用することもできます。これはXML Schema注釈SQLInline = "false"に対応しており、コレクション表またはLOB内のREFのVARRAYが、表外に格納されたコレクションの内容に追随していることを意味します。

使用する前に、XML Schemaに注釈を付ける必要はありません。XML Schemaに注釈が付いていない場合、Oracle XML DBは一連のデフォルトの前提を使用してXML Schemaを処理します。

この項で取り上げた注釈のいずれも付けなかった場合、Oracle XML DBはコレクションをヒープに基づくOCTとして格納します。OCTを強制的に索引構成表(IOT)として格納するには、DBMS_XMLSCHEMA.registerSchemaのOPTIONSパラメータでREGISTER_NT_AS_IOTを渡します。

注意:
OracleからIOTの使用を明示的に指示された場合を除き、IOTでなく、ヒープに基づくOCTを使用してください。IOTの記憶域には、次のような大きな制限があります。

- コレクション表(IOT)のパーティショニングが無効化されます。

- 文書レベルのOracle Text索引しかサポートされません。要素に固有の索引や属性に固有の索引は無効になります。

XMLデータでのOracle Textの使用方法の詳細は、第12章「XMLデータの全文検索」を参照してください。

注意:
Oracle Database 11gリリース1より前のリリースの場合:

- OCTはデフォルトでIOTとして格納されていました。

- xdb:storeVarrayAsTableのデフォルト値はfalseでした。

関連項目:

- 構造化記憶域を使用してXMLType表および列を手動で作成する場合のコレクション記憶域の詳細は、「XML Schemaに基づくデータの構造化記憶域」を参照してください。

- 第7章「XML Schemaの格納と問合せ: 基本」

- 「表外に格納するための注釈属性SQLInLineのfalse設定」

- オブジェクト・リレーショナル形式で格納されたXMLTypeの表および列のパーティション化

Oracle XML DB名前空間の宣言

XML Schemaに注釈を付けるには、最初にOracle XML DB名前空間を宣言する必要があります。Oracle XML DB名前空間は、次のように宣言します。

http://xmlns.oracle.com/xdb

名前空間をXML Schemaで宣言するには、次のような名前空間宣言をXML Schemaのルート要素に追加します。

xmlns:xdb="http://xmlns.oracle.com/xdb"

名前空間接頭辞(xdb)が使用されていることに注意してください。名前空間接頭辞を使用すると、注釈を追加するときに名前空間をxdbに省略できます。

例3-10に、注釈付きのXML Schema PurchaseOrderの最初の部分を示します。完全なXML Schemaのコードは、例A-1を参照してください。

例3-10 注釈付きの発注書XML Schema、purchaseOrder.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
version="1.0"
xdb:storeVarrayAsTable="true">
<xs:element name="PurchaseOrder" type="PurchaseOrderType" xdb:defaultTable="PURCHASEORDER"/>
<xs:complexType name="PurchaseOrderType" xdb:SQLType="PURCHASEORDER_T">
<xs:sequence>
<xs:element name="Reference" type="ReferenceType" minOccurs="1" xdb:SQLName="REFERENCE"/>
<xs:element name="Actions" type="ActionsType" xdb:SQLName="ACTIONS"/>
<xs:element name="Reject" type="RejectionType" minOccurs="0" xdb:SQLName="REJECTION"/>
<xs:element name="Requestor" type="RequestorType" xdb:SQLName="REQUESTOR"/>
<xs:element name="User" type="UserType" minOccurs="1" xdb:SQLName="USERID"/>
<xs:element name="CostCenter" type="CostCenterType" xdb:SQLName="COST_CENTER"/>
<xs:element name="ShippingInstructions" type="ShippingInstructionsType"
xdb:SQLName="SHIPPING_INSTRUCTIONS"/>
<xs:element name="SpecialInstructions" type="SpecialInstructionsType"
xdb:SQLName="SPECIAL_INSTRUCTIONS"/>
<xs:element name="LineItems" type="LineItemsType" xdb:SQLName="LINEITEMS"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemsType" xdb:SQLType="LINEITEMS_T">
<xs:sequence>
<xs:element name="LineItem" type="LineItemType" maxOccurs="unbounded"
xdb:SQLName="LINEITEM" xdb:SQLCollType="LINEITEM_V"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemType" xdb:SQLType="LINEITEM_T">
<xs:sequence>
<xs:element name="Description" type="DescriptionType"
xdb:SQLName="DESCRIPTION"/>
<xs:element name="Part" type="PartType" xdb:SQLName="PART"/>
</xs:sequence>
<xs:attribute name="ItemNumber" type="xs:integer" xdb:SQLName="ITEMNUMBER"
xdb:SQLType="NUMBER"/>
</xs:complexType>
<xs:complexType name="PartType" xdb:SQLType="PART_T">
<xs:attribute name="Id" xdb:SQLName="PART_NUMBER" xdb:SQLType="VARCHAR2">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="10"/>
<xs:maxLength value="14"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Quantity" type="moneyType" xdb:SQLName="QUANTITY"/>
<xs:attribute name="UnitPrice" type="quantityType" xdb:SQLName="UNITPRICE"/>
</xs:complexType>
<xs:simpleType name="ReferenceType">
<xs:restriction base="xs:string">
<xs:minLength value="18"/>
<xs:maxLength value="30"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="ActionsType" xdb:SQLType="ACTIONS_T">
<xs:sequence>
<xs:element name="Action" maxOccurs="4" xdb:SQLName="ACTION" xdb:SQLCollType="ACTION_V">
<xs:complexType xdb:SQLType="ACTION_T">
<xs:sequence>
<xs:element name="User" type="UserType" xdb:SQLName="ACTIONED_BY"/>
<xs:element name="Date" type="DateType" minOccurs="0" xdb:SQLName="DATE_ACTIONED"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RejectionType" xdb:SQLType="REJECTION_T">
<xs:all>
<xs:element name="User" type="UserType" minOccurs="0" xdb:SQLName="REJECTED_BY"/>
<xs:element name="Date" type="DateType" minOccurs="0" xdb:SQLName="DATE_REJECTED"/>
<xs:element name="Comments" type="CommentsType" minOccurs="0" xdb:SQLName="REASON_REJECTED"/>
</xs:all>
</xs:complexType>
<xs:complexType name="ShippingInstructionsType" xdb:SQLType="SHIPPING_INSTRUCTIONS_T">
<xs:sequence>
<xs:element name="name" type="NameType" minOccurs="0" xdb:SQLName="SHIP_TO_NAME"/>
<xs:element name="address" type="AddressType" minOccurs="0" xdb:SQLName="SHIP_TO_ADDRESS"/>
<xs:element name="telephone" type="TelephoneType" minOccurs="0" xdb:SQLName="SHIP_TO_PHONE"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="moneyType">
<xs:restriction base="xs:decimal">
<xs:fractionDigits value="2"/>
<xs:totalDigits value="12"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="quantityType">
<xs:restriction base="xs:decimal">
<xs:fractionDigits value="4"/>
<xs:totalDigits value="8"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="RequestorType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="128"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CostCenterType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="4"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="VendorType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PurchaseOrderNumberType">
<xs:restriction base="xs:integer"/>
</xs:simpleType>
<xs:simpleType name="SpecialInstructionsType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="2048"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NameType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AddressType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TelephoneType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="24"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="DateType">
<xs:restriction base="xs:date"/>
</xs:simpleType>
<xs:simpleType name="CommentsType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="2048"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="DescriptionType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

PurchaseOrder XML Schemaには次の2つの名前空間が定義されています。

- http://www.w3c.org/2001/XMLSchema。これは、W3CによってSchema for Schemasのために予約されています。

- http://xmlns.oracle.com/xdb。これは、オラクル社によってOracle XML DBのスキーマ注釈用に予約されています。

PurchaseOrderスキーマは、次の注釈を含むいくつかの注釈を使用します。

- PurchaseOrder要素内のdefaultTable注釈。このXML Schemaに準拠するXML文書をpurchaseorderというデータベース表に格納することを指定します。

- SQLType注釈。
SQLTypeが最初に出現したとき、complexType要素PurchaseOrderTypeから生成されたSQL型の名前をpurchaseorder_tと指定します。

SQLTypeが2番目に出現したとき、complexType要素LineItemTypeから生成されたSQL型の名前をlineitem_tと指定し、LineItem要素のコレクションを管理するSQL型の名前をlineitem_vと指定します。

- SQLName注釈。purchaseorder_tの各SQL属性の明示的な名前を提供します。

図3-3に、XMLSpyのOracleタブを示します。このタブを使用すると、グラフィカル・エディタでの作業中にOracle XML DBのスキーマ注釈をXML Schemaに容易に追加できます。

図3-3 XMLSpyにおけるOracle XML DBスキーマ注釈のサポート

Oracle XML DBへのXML Schemaの登録

XML SchemaをOracle XML DBで使用するには、最初にそのXML SchemaをOracle XML DBに登録する必要があります。XML Schemaを登録した後は、XML文書を検証し、そのXML SchemaにバインドするXMLType表および列を作成できます。

XML SchemaをOracle XML DBに登録するには、次の2つの項目が必要です。

- XML Schema文書。

- Oracle Databaseに登録後、XML Schemaの一意の識別子として使用できる文字列。この一意の識別子は、XML Schemaで定義されたクラスのメンバーとしてインスタンス・ドキュメントを識別するために使用されます。通常、識別子はURLの形式を取り、多くの場合、スキーマの場所を示すヒントまたは文書の場所を示すヒントとして参照されます。

XML Schemaを登録するには、PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaを使用します。例3-11に、これを示します。デフォルトでは、XML Schemaが登録されると、Oracle XML DBは、インスタンス・ドキュメントの管理に必要なすべてのSQLオブジェクト型とXMLType表を自動的に生成します。XML Schemaは、グローバルまたはローカルとして登録できます。

関連項目:

- XML Schemaを登録する際の考慮事項は、「XML Schemaを登録する前の文書の削除とリロード」を参照してください。

- 「ローカルXML SchemaおよびグローバルXML Schema」

- DBMS_XMLSCHEMA.registerSchemaの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

例3-11 DBMS_XMLSCHEMA.REGISTERSCHEMAを使用したXML Schemaの登録

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd',
SCHEMADOC => XDBURIType('/source/schemas/poSource/xsd/purchaseOrder.xsd').getCLOB(),
LOCAL     => TRUE,
GENTYPES  => TRUE,
GENTABLES => TRUE);
END;
/

例3-11では、XML Schemaの一意の識別子は次のとおりです。

http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd

XML Schema文書は、すでにOracle XML DBリポジトリ(/source/schemas/poSource/xsd/purchaseOrder.xsd)にロードされています。

XML Schemaの登録時に、XDBURITypeは、リポジトリ内のXML Schema文書の場所に基づいてXML Schema文書のコンテンツにアクセスします。プロシージャregisterSchemaに渡されるオプションによって、例3-11のスキーマをローカルXML Schemaとして登録する必要があること、SQLオブジェクト、および登録プロセスで表を生成する必要があることが指定されます。

PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaは、次の操作を実行します。

- XML Schemaの解析および検証

- XML Schemaを記述するOracleデータ・ディクショナリ内の一連のエントリの作成

- XML Schemaで定義されたcomplexType要素に基づく一連のSQLオブジェクト定義の作成

- XML Schemaで定義された各グローバル要素のXMLType表の作成

関連項目:
「ローカルXML SchemaおよびグローバルXML Schema」

XML Schema登録時のSQL型および表の作成

例3-12では、XML SchemaをOracle XML DBに登録するときに、オブジェクト型を作成します。

例3-12 XML Schemaの登録時のオブジェクトの作成

DESCRIBE purchaseorder_t
purchaseorder_t is NOT FINAL
Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
SYS_XDBPD$                                         XDB.XDB$RAW_LIST_T
REFERENCE                                          VARCHAR2(30 CHAR)
ACTIONS                                            ACTIONS_T
REJECTION                                          REJECTION_T
REQUESTOR                                          VARCHAR2(128 CHAR)
USERID                                             VARCHAR2(10 CHAR)
COST_CENTER                                        VARCHAR2(4 CHAR)
SHIPPING_INSTRUCTIONS                              SHIPPING_INSTRUCTIONS_T
SPECIAL_INSTRUCTIONS                               VARCHAR2(2048 CHAR)
LINEITEMS                                          LINEITEMS_T

DESCRIBE lineitems_t
lineitems_t is NOT FINAL
Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
SYS_XDBPD$                                         XDB.XDB$RAW_LIST_T
LINEITEM                                           LINEITEM_V

DESCRIBE lineitem_v
lineitem_v VARRAY(2147483647) OF LINEITEM_T
LINEITEM_T is NOT FINAL
Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
SYS_XDBPD$                                         XDB.XDB$RAW_LIST_T
ITEMNUMBER                                         NUMBER(38)
DESCRIPTION                                        VARCHAR2(256 CHAR)
PART                                               PART_T

この例では、XML SchemaがOracle XML DBに登録されたときに、SQL型定義が作成されています。次のSQL型定義が含まれます。

- purchaseorder_t。この型を使用してPurchaseOrder要素から生成されたSQLオブジェクトを永続的に保持します。PurchaseOrder要素を含むXML文書がOracle XML DBに格納される場合、文書は分割され、文書のコンテンツはpurchaseorder_tのインスタンスとして格納されます。

- lineitems_t、lineitem_vおよびlineitem_t。これらの型はPurchaseOrder文書に存在する可能性のあるLineItem要素のコレクションを管理します。型lineitems_tは、型lineitem_vのインスタンスとして定義された単一の属性lineitemで構成されます。型lineitem_vはlinteitem_tオブジェクトのVARRAYとして定義されます。文書内の各LineItem要素に対し、lineitem_tオブジェクトのインスタンスが1つずつあります。

大規模なXML Schemaの操作

大規模で複雑なXML Schemaを操作する場合、いくつかの問題が発生することがあります。場合により、XML Schemaを登録する際、またはXML Schemaによって定義されたグローバル要素に基づく表を作成する際に、次のいずれかのエラーが発生することがあります。

- ORA-01792: 表またはビューに指定できる最大列数は1000です。

- ORA-04031: 共有メモリーのstringバイトを割当てできません("string","string","string","string")

これらのエラーは、グローバル要素に基づいてXMLType表または列を作成するとき、そのグローバル要素が多数の要素と属性の定義を含むcomplexTypeとして定義されている場合に発生します。これらのエラーはオブジェクト・リレーショナル記憶域を使用するXMLType表または列の作成時にのみ発生します。この場合、表または列はSQL型を使用して永続的に保持され、SQL型により定義された各オブジェクト属性は、基礎となる表の1つの列とみなされます。SQL型に別のSQL型に基づくオブジェクト属性が含まれる場合も、それらの型により定義された属性は基礎となる表の列とみなされます。

すべてのSQL型に含まれるオブジェクト属性の合計数がOracle Databaseの上限の1000列(1つの表で)を超えると、記憶域表は作成できません。complexTypeによって定義された要素と属性の総数が1000に達すると、その型のインスタンスがデータベースに格納される場合、生成されるSQLオブジェクトを管理できる単一の表を作成することはできません。

ヒント:
次の問合せを使用すると、オブジェクト・リレーショナル形式で格納されている特定のXMLType表の列数を特定できます。

SELECT count(*) FROM USER_TAB_COLS WHERE TABLE_NAME = '<the table>'

<the table>は、チェック対象の表です。

エラーORA-01792は、1000列の制限を超えたことを報告するものです。エラーORA-04031は、多数の要素および属性の定義の処理中に、メモリーが不足していることを報告するものです。要素と属性の定義が多すぎるというこの問題を解決するには、記憶域表の作成に使用するSQL型のオブジェクト属性の合計数を減らす必要があります。

削減を成功させるには、次の2つの方法があります。

- XML文書を管理する複数の XMLType表を使用する、トップダウン方法の使用。この方法は、指定した記憶域表について、SQL型階層内のSQL属性の数を減らします。いずれの表も管理するオブジェクト属性が1000を超えないかぎり、この問題は解決します。

- SQL型の階層のSQL属性の数を減らし、XML Schemaにより定義された一部の要素および属性を縮小して、単一CLOB値として格納されるようにする、ボトムアップ方法の使用。

いずれの方法とも、XML Schemaに注釈を付けて、特定のcomplexTypeをデータベースに格納する方法を定義します。

トップダウン方法の場合は、SQLInline = "false"およびdefaultTableという注釈によって、XML文書内の一部のサブ要素が別のXMLType表に行として強制的に格納されます。Oracle XML DBは、XMLTypeのREFを使用して2つの表の間の関係を保持します。この手法の適切な候補は、次のいずれかを実行するXML Schemaです。

- 含まれる各要素がcomplexTypeとして定義される選択を定義

- 多数の要素および属性の定義を含むcomplexTypeに基づいて要素を定義

ボトムアップ方法では、下位レベルの一部のcomplexType要素をオブジェクトとしてではなくCLOB値として格納することによって、SQLオブジェクト型の属性の数を減らします。これを行うには、complexTypeに注釈を付けるか、SQLType = "CLOB"を指定したcomplexTypeを使用します。

いずれの方法を使用するかは、アプリケーション、およびデータに対して実行される問合せと更新のタイプによって決まります。

グローバル要素の操作

デフォルトでは、XML Schemaがデータベースに登録するときに、Oracle XML DBは、XML Schemaにより定義される各グローバル要素に対してデフォルト表を生成します。

xdb:defaultTable属性を使用して、特定のグローバル要素に対するデフォルト表の名前を指定できます。指定するxdb:defaultTable属性値は、特定のデータベース・ユーザーにより登録されたすべてのスキーマ間で一意である必要があります。一部の要素に対して空でないデフォルト表名を指定しない場合、一意の名前が自動的に付けられます。

しかし実際には、ほとんどの場合、グローバル要素に対してデフォルト表を作成する必要はありません。XMLインスタンス・ドキュメントのルート要素として機能しない要素には、デフォルト表が使用されることはないため、デフォルト表は必要ありません。特に、XML Schemaに多数のグローバル要素定義が含まれている場合は、すべてのグローバル要素に対してデフォルト表を作成すると、プロセッサ時間に大量のオーバーヘッドが発生し、多くの領域が使用される可能性があります。

このため、一般に、どの文書内でもルート要素として使用されないことが確実なグローバル要素(または表外に格納されたローカル要素)に対しては、デフォルト表が作成されないようにすることができます。これを行うには、次のいずれかの方法を実行します。

- XMLインスタンス・ドキュメントのルート要素として表示されない各グローバル要素の定義に、注釈xdb:defaultTable = "" (空の文字列)を追加します。この方法を使用すると、通常はデフォルト表を自動的に作成し、必要な場合にxdb:defaultTable = ""を使用して明示的にデフォルト表の自動作成を禁止できます。

- XML Schemaの登録時にパラメータGENTABLESをFALSEに設定し、インスタンス・ドキュメントのルート要素として正当に表示できる各グローバル要素に対してデフォルト表を手動で作成します。この方法を使用すると、デフォルト表の自動作成は行われません。必要な表のみを手動で作成します。

XML Schemaに基づくXMLType列および表の作成

XML SchemaをOracle XML DBに登録した後は、XMLType列を含む表を定義する場合、またはXMLType表を作成する場合に、そのXML Schemaを参照できます。

XML Schemaに基づくデータを格納するXMLType表または列を作成する際に、記憶域モデルを指定しない場合、使用される記憶域モデルは、参照するXML Schemaの登録時に指定した記憶域モデルです。XML Schemaの登録時に記憶域モデルを指定しなかった場合は、オブジェクト・リレーショナル形式の記憶域が使用されます。

例3-13に、PurchaseOrder要素のデフォルト表である表purchaseorderを手動で作成する方法を示します。

例3-13 XML Schemaに準拠したXMLType表の作成

CREATE TABLE purchaseorder OF XMLType
XMLSCHEMA "http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd"
ELEMENT "PurchaseOrder"
VARRAY "XMLDATA"."ACTIONS"."ACTION"
STORE AS TABLE action_table
((PRIMARY KEY (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
VARRAY "XMLDATA"."LINEITEMS"."LINEITEM"
STORE AS TABLE lineitem_table
((PRIMARY KEY (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)));

Action要素のコレクションを管理するVARRAYの各メンバーは、Ordered Collection Table、action_tableに格納されます。LineItem要素のコレクションを管理するVARRAYの各メンバーは、Ordered Collection Table、lineitem_tableに行として格納されます。Ordered Collection Tableはヒープに基づいています。PRIMARY KEY指定のため、表には親の列に逆リンクするのに必要な疑似列NESTED_TABLE_IDおよび列SYS_NC_ARRAY_INDEX$が自動的に含まれます。

このCREATE TABLE文は、XML Schema登録の際、パラメータGENTABLESをTRUEに設定すると、Oracle XML DBにより自動生成されるCREATE TABLE文と同等です。デフォルトでは、XML Schema注釈storeVarrayAsTableの値はtrueで、XML Schema登録時に、コレクションに対してOrdered Collection Tables(OCT)を自動生成します。このOCTにはシステムが生成した、覚えにくい名前が付けられます。SQL文RENAME TABLEを使用して、わかりやすい名前を付けることができます。

例3-13のCREATE TABLE文は、単一レベルのネストが行われている発注書に対応しています。LineItem要素のコレクションを管理するVARRAYは、Ordered Collection Table、lineitem_tableです。

ここで、別のXML Schemaを想定し、Shipment要素のコレクションがShipments要素内にあり、この要素がLineItem要素内にあるとします。この場合は、例3-14に示すように、表を手動で作成できます。

例3-14 ネストしたコレクションのXMLType表の作成

CREATE TABLE purchaseorder OF XMLType
XMLSCHEMA "http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd"
ELEMENT "PurchaseOrder"
VARRAY "XMLDATA"."ACTIONS"."ACTION"
STORE AS TABLE action_table
((PRIMARY KEY (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
VARRAY "XMLDATA"."LINEITEMS"."LINEITEM"
STORE AS TABLE lineitem_table
((PRIMARY KEY (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$))
VARRAY "SHIPMENTS"."SHIPMENT"
STORE AS TABLE shipments_table
((PRIMARY KEY (NESTED_TABLE_ID,
SYS_NC_ARRAY_INDEX$))));

例3-15に示すように、SQL*PlusのDESCRIBE文を使用すると、XMLType表に関する情報を表示できます。

例3-15 XML Schemaに基づくXMLType表でのDESCRIBEの使用

DESCRIBE purchaseorder
Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
TABLE of SYS.XMLTYPE(XMLSchema
"http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd"
Element "PurchaseOrder") STORAGE Object-relational TYPE "PURCHASEORDER_T"

例3-15のDESCRIBE文の出力には、purchaseorder表に関する次の情報が表示されます。

- 表はXMLType表です。

- 表は、XML Schema PurchaseOrderで定義されたPurchaseOrder文書の格納用に制限されます。

- この表の行は、データベースに一連のオブジェクトとして格納されます。

- SQL型purchaseorder_tは、この表のベース・オブジェクトです。

デフォルト表

例3-13のXML Schemaでは、PurchaseOrder表がPurchaseOrder要素のデフォルト表であることが指定されています。XML Schemaに準拠するXML文書を、プロトコルまたはPL/SQLを使用してOracle XML DBリポジトリに挿入すると、そのXML文書のコンテンツはpurchaseorder表に行として格納されます。

XML Schemaをグローバル・スキーマとして登録した場合は、デフォルト表に対する適切なアクセス権をデータベースのすべてのユーザーに付与する必要があります。これによって、ユーザーは、グローバルに登録したXML Schemaに準拠するインスタンス・ドキュメントを操作できるようになります。

関連項目:
「ローカルXML SchemaおよびグローバルXML Schema」

XML Schemaインスタンス・ドキュメントの識別

XML文書をXML Schemaに基づくXMLType表または列に挿入する前に、関連付けられているXML Schemaを識別する必要があります。識別するには、次の2つの方法があります。

- XMLTypeの作成時に明示的にXML Schemaを識別します。これを行うには、XML Schemaの名前をXMLTypeコンストラクタに渡すか、またはXMLTypeのcreateSchemaBasedXML()メソッドを起動します。

- XMLSchema-instanceメカニズムを使用して、必要な情報をXML文書に明示的に提供します。このオプションはOracle XML DBを操作する場合に使用できます。

XMLSchema-instanceメカニズムのメリットは、Oracle XML DBリポジトリに挿入されたXML文書が登録済のXML SchemaのインスタンスであることをOracle XML DBプロトコル・サーバーが認識できることです。インスタンス・ドキュメントのコンテンツは、そのXML Schemaで指定されたデフォルト表に自動的に格納されます。

XMLSchema-instanceメカニズムは、W3CのXML Schemaワーキング・グループにより定義されています。この基本は、ターゲットのXMLスキーマを識別する属性をインスタンス・ドキュメントのルート要素に追加することです。これらの属性はXMLSchema-instance名前空間で定義されます。

インスタンス・ドキュメントを特定のXML Schemaで定義されたクラスのメンバーとして識別するには、名前空間宣言をインスタンス・ドキュメントのルート要素に追加して、XMLSchema-instance名前空間を宣言する必要があります。次に例を示します。

xmlns:xsi = http://www.w3.org/2001/XMLSchema-instance

XMLSchema-instance名前空間が宣言され、namespace接頭辞が指定されると、XML Schemaを識別する属性をインスタンス・ドキュメントのルート要素に追加できます。前述の例では、XMLSchema-instance名前空間の名前空間接頭辞がxsiと定義されています。この接頭辞は、XMLSchema-instanceの属性をインスタンス・ドキュメントのルート要素に追加する際に使用できます。

追加する属性は、いくつかの要因によって決定します。noNamespaceSchemaLocationおよびschemaLocationに、その可能性があります。インスタンス・ドキュメントが関連付けられているXML Schemaを識別するには、XML Schemaに応じて、1つまたは両方の属性が必要です。

属性noNamespaceSchemaLocationおよびschemaLocation

ターゲットのXML Schemaでターゲットの名前空間が宣言されていない場合は、noNamespaceSchemaLocation属性を使用してXML Schemaを識別します。この属性の値はスキーマの場所を示すヒントです。この値は、XML Schemaをデータベースに登録するときにPL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaに渡される一意の識別子です。

XML Schema purchaseOrder.xsdの場合、インスタンス・ドキュメントのルート要素の正しい定義は次のとおりです。

<PurchaseOrder
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:noNamespaceSchemaLocation=
"http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd">

ターゲットのXML Schemaでターゲットの名前空間が宣言されている場合は、schemaLocation属性を使用してXML Schemaを識別します。この属性の値は2つの値の組合せで、空白によって区切られています。

- XML Schemaで宣言されたターゲットの名前空間の値

- スキーマをデータベースに登録するときにプロシージャDBMS_XMLSCHEMA.registerSchemaに渡される一意の識別子である、スキーマの場所を示すヒント

たとえば、XML Schema PurchaseOrderにターゲットの名前空間宣言が含まれているとします。この場合、スキーマのルート要素は次のようになります。

<xs:schema targetNamespace="http://demo.oracle.com/xdb/purchaseOrder"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
version="1.0" xdb:storeVarrayAsTable="true">
<xs:element name="PurchaseOrder" type="PurchaseOrderType"
xdb:defaultTable="PURCHASEORDER"/>

この場合、インスタンス・ドキュメントのルート要素の正しい形式は次のとおりです。

<PurchaseOrder
xnlns="http://demo.oracle.com/xdb/purchaseOrder"
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation=
"http://demo.oracle.com/xdb/purchaseOrder
http://mdrake-lap:8080/source/schemas/poSource/xsd/purchaseOrder.xsd">

複数の名前空間の使用

XML Schemaに複数の名前空間で定義された要素が含まれている場合は、XML SchemaごとにschemaLocation属性のエントリが必要です。各エントリは、名前空間宣言およびスキーマの場所を示すヒントで構成されています。また、各エントリは1つ以上の空白文字で区切られています。主要なXML Schemaでターゲットの名前空間が宣言されていない場合でも、主要なXML Schemaのスキーマの場所を示すヒントを指定するnoNamespaceSchemaLocation属性をインスタンス・ドキュメントに含める必要があります。

データベースを使用したXMLデータ整合性の規定

Oracle XML DBを使用してXMLコンテンツを管理するメリットの1つは、SQLを使用してXML Schemaで提供される機能を補完できることです。SQLおよびXMLの機能と、ルールを規定するデータベースの機能を組み合せることによって、XMLコンテンツを管理する強力なフレームワークとしてデータベースを使用できます。

XMLType表または列に格納できるのは、整形式のXML文書のみです。整形式のXML文書とは、XML宣言で宣言されたXMLバージョンの構文に準拠しているXML文書です。これには、ルート要素が単一か、タグが適切にネストされているかなどが含まれます。さらに、XMLType表または列がXML Schemaに制限される場合、その表または列に格納できるのはXML Schemaに準拠する文書のみです。これ以外のXML文書をXML Schemaに基づくXMLTypeに格納または挿入しようとすると、エラーが発生します。例3-16に、これを示します。

例3-16 不適切なXML文書を挿入しようとした場合に発生するエラー

INSERT INTO purchaseorder
VALUES (XMLType(bfilename('XMLDIR', 'Invoice.xml'), nls_charset_id('AL32UTF8')))
VALUES (XMLType(bfilename('XMLDIR', 'Invoice.xml'), nls_charset_id('AL32UTF8')))
*
ERROR at line 2:
ORA-19007: Schema - does not match expected
http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd.

このようなエラーは、コンテンツが直接XMLType表に挿入されるときにのみ発生します。Oracle XML DBが、XML Schemaにより定義されたクラスのメンバーとして文書を認識していなかったことを示します。スキーマにより定義されたクラスのメンバーとして認識される文書は、次の条件を満たしている必要があります。

- XML文書のルート要素の名前が、XMLType表または列の定義で使用するグローバル要素の名前と一致する必要があります。

- XML文書にXMLSchema-instance名前空間の適切な属性が含まれているか、またはXMLTypeコンストラクタかXMLTypeのcreateSchemaBasedXML()メソッドを使用してXML文書がXML Schemaに明示的に関連付けられている必要があります。

制限されているXML SchemaでtargetNamespaceが宣言されている場合、インスタンス・ドキュメントには、XML Schemaで定義されたtargetNamespaceに文書のルート要素を配置するための適切な名前空間宣言が含まれている必要があります。

注意:
XMLによる制限は、個々のXML文書内で適用されます。データベース(SQL)による制限は、一連のXML文書にわたって適用されます。

XML Schemaの部分検証と全体検証の比較

この項では、XML文書をデータベースに挿入するときに使用する、XML Schemaの部分検証と全体検証の違いについて説明します。

部分検証

バイナリXML記憶域では、XML文書をXML Schemaに基づくXMLType表または列に挿入するたびに、Oracle XML DBはその文書の全体検証を実行します。他のすべてのXML記憶域モデルでは、Oracle XML DBは文書の部分検証のみを実行します。これは、バイナリXML記憶域を除き、XML Schemaの完全な検証はパフォーマンスの面で非常にコストが高くなるためです。

部分検証では、文書内に必須の要素および属性がすべて存在すること、および予期しない要素または属性のないことが確認されるのみです。つまり、XML文書の構造がXML Schemaから導出されたSQLデータ型定義に準拠していることのみが確認されます。部分検証では、インスタンス・ドキュメントがXML Schemaに完全に準拠しているかどうかは確認されません。

例3-17に、オブジェクト・リレーショナル形式で格納されている表PurchaseOrderにXML文書を挿入する間に部分検証が失敗した例を示します。

例3-17 不適切なXML文書の挿入時に発生するエラー(部分検証)

INSERT INTO purchaseorder
VALUES(XMLType(bfilename('XMLDIR', 'InvalidElement.xml'),
nls_charset_id('AL32UTF8')));
VALUES(XMLType(bfilename('XMLDIR', 'InvalidElement.xml'),
*
ERROR at line 2:
ORA-30937: No schema definition for 'UserName' (namespace '##local') in parent
'/PurchaseOrder'

全体検証

XMLデータをXML Schemaに基づくバイナリXML記憶域にロードすると、ターゲットXML Schemaに対する全体検証が行われます。これ以外の場合は、記憶域モデルと無関係に、次のいずれかの方法を使用して、XML Schemaに対するXMLインスタンス・ドキュメントの全体検証をいつでも強制的に実行できます。

- 表レベルのCHECK制約

- PL/SQLのBEFORE INSERTトリガー

どちらの方法でも、妥当なXML文書のみがXMLType表に格納されることが保証されます。

TABLE CHECK制約を使用する方法のメリットは、コーディングが簡単なことです。この方法のデメリットは、この方法がOracle SQL関数XMLisValidに基づいているため、XML文書が妥当であるかどうかしか示されないことです。XML文書が妥当でない場合、TABLE CHECK制約では、その理由についての情報を提供できません。

BEFORE INSERTトリガーの場合は、必要なコーディングが表レベルの制約よりわずかに多くなります。このトリガーでは、XMLTypeのschemaValidate()メソッドを起動してXML文書を検証します。schemaValidate()を使用するメリットは、例外が発生した場合にそのインスタンス・ドキュメントの問題点に関する追加情報が提供されることです。また、BEFORE INSERTトリガーを使用すると、無効な文書が存在する場合に適切な処置を行うことができます。

XML Schemaの全体検証による処理時間とメモリーの消費

バイナリXML記憶域を使用していない場合は、XML Schemaの全体検証を実行すると、多くの処理時間とメモリーが消費されます。このため、XML Schemaの全体検証は、必要なときにのみ実行してください。XML文書を検証するアプリケーションを使用する場合は、全体検証に関連するオーバーヘッドを回避することによって、バイナリ以外のXML記憶域での全体のスループットを向上させることができます。受信するXML文書の妥当性について確認できない場合は、スキーマに対して妥当なXML文書のみがXMLType表または列に含まれていることをデータベースで確認できます。

例3-18に、CHECK制約をXMLType表に追加してXML Schemaの全体検証を実行する方法を示します。例3-18のXML文書InvalidReferenceは、XML Schemaに従った妥当なXML文書ではありません。XML Schemaでは、Reference要素に関連付けられたテキスト・ノードの最小長を18文字とすることが定義されています。この例に示す文書では、ノードの値はSBELL-20021009で、14文字の長さしかありません。部分検証ではこのエラーは捕捉されません。制約またはトリガーがないかぎり、この文書をデータベースに挿入することが可能です。

例3-18 CHECK制約を使用したXML Schemaの全体検証の実施

ALTER TABLE purchaseorder
ADD CONSTRAINT validate_purchaseorder
CHECK (XMLIsValid(OBJECT_VALUE) = 1);

Table altered.

INSERT INTO purchaseorder
VALUES (XMLType(bfilename('XMLDIR', 'InvalidReference.xml'),
nls_charset_id('AL32UTF8')));

INSERT INTO purchaseorder
*

ERROR at line 1:
ORA-02290: check constraint (QUINE.VALIDATE_PURCHASEORDER) violated

疑似列OBJECT_VALUEを使用すると、トリガー内からXMLType表のコンテンツにアクセスできます。例3-19は、BEFORE INSERTトリガーを使用して、XMLType表に挿入されるデータが、指定されたXML Schemaに準拠していることを検証する方法を示しています。

例3-19 BEFORE INSERTトリガーを使用したXML Schemaの全体検証の実施

CREATE OR REPLACE TRIGGER validate_purchaseorder
BEFORE INSERT ON purchaseorder
FOR EACH ROW
BEGIN
IF (:new.OBJECT_VALUE IS NOT NULL) THEN :new.OBJECT_VALUE.schemavalidate();
END IF;
END;
/

INSERT INTO purchaseorder  VALUES (XMLType(bfilename('XMLDIR', 'InvalidReference.xml'),
nls_charset_id('AL32UTF8')));
VALUES (XMLType( bfilename('XMLDIR', 'InvalidReference.xml'),
*
ERROR at line 2:
ORA-31154: invalid XML document
ORA-19202: Error occurred in XML processing
LSX-00221: "SBELL-20021009" is too short (minimum length is 18)
ORA-06512: at "SYS.XMLTYPE", line 354
ORA-06512: at "QUINE.VALIDATE_PURCHASEORDER", line 3
ORA-04088: error during execution of trigger 'QUINE.VALIDATE_PURCHASEORDER'

SQL制約を使用した参照整合性の規定

W3CのXML Schema勧告では、XML文書のコンテンツを定義するための強力な言語が定義されています。ただし、現在はW3CのXML Schema勧告で扱われていない簡単なデータ管理の概念がいくつかあります。たとえば、要素または属性の値が次のいずれかのプロパティを持っているかを確認できることなどです。

- XML文書のセット間で一意であること(UNIQUE制約)

- 現在の文書以外の特定のデータ・ソース内に存在していること(FOREIGN KEY制約)

ただし、Oracle XML DBでは、そうした制約を強制的に適用できます。XMLデータで整合性を規定するために使用するメカニズムは、リレーショナル・データで整合性を規定するためのメカニズムと同じです。一意性と外部キーの関係などの簡単なルールは、制約を指定することによって規定できます。複雑なルールは、データベース・トリガーを指定して規定できます。

Oracle XML DBを使用すると、XML Schema構造体を使用して指定できるルールに加え、データベースを使用して、ビジネス・ルールもXMLコンテンツに実施することができます。データベースでは、XMLが表に直接挿入されているか、Oracle XML DBリポジトリでサポートされているプロトコルの1つを使用してアップロードされているかに関係なく、これらのビジネス・ルールを規定します。

例3-20、例3-21および例3-22に、SQL制約を使用して参照整合性を規定する方法を示します。例3-20では、バイナリXMLとして格納されているXMLType表の一意性制約を定義しています。発注書のReference要素を使用して、仮想列を定義します。一意性制約reference_is_uniqueは、ノード/PurchaseOrder/Reference/text()の値が表に格納されたすべての文書間で一意であることを保証しています。

関連項目:
「仮想列を使用したバイナリXMLデータのパーティション化または制約」

例3-20 仮想列を使用したバイナリXML表の制約

CREATE TABLE po_binaryxml OF XMLType
XMLTYPE STORE AS BINARY XML
VIRTUAL COLUMNS
(c_reference AS (XMLCast(XMLQuery('/PurchaseOrder/Reference'
PASSING OBJECT_VALUE RETURNING CONTENT)
AS VARCHAR2(32))));

INSERT INTO po_binaryxml SELECT OBJECT_VALUE FROM OE.purchaseorder;

132 rows created.

ALTER TABLE po_binaryxml ADD CONSTRAINT reference_is_unique UNIQUE (c_reference);

INSERT INTO po_binaryxml
VALUES (XMLType(bfilename('XMLDIR', 'DuplicateReference.xml'),
nls_charset_id('AL32UTF8')));
INSERT INTO po_binaryxml
*
ERROR at line 1:
ORA-00001: unique constraint (OE.REFERENCE_IS_UNIQUE) violated

例3-21では、例3-20と同様の一意性制約を定義していますが、標準のデータベース・スキーマOEのXMLType表purchaseorderにおける一意性制約も定義しています。さらに、各発注書のUser要素が、標準データベース表HR.employeesに存在する従業員の電子メール・アドレスであることを要求する外部キー制約を定義しています。OE.purchaseorder表の場合のように、オブジェクト・リレーショナル形式で格納されているXMLデータの場合、制約は、XMLコンテンツを管理するために使用されるSQLデータ型のオブジェクト属性によって指定される必要があります。

例3-21 オブジェクト・リレーショナル形式で格納されているXMLType表の整合性制約とトリガー

ALTER TABLE purchaseorder
ADD CONSTRAINT reference_is_unique
UNIQUE (XMLDATA."REFERENCE");

ALTER TABLE purchaseorder
ADD CONSTRAINT user_is_valid
FOREIGN KEY (XMLDATA."USERID") REFERENCES hr.employees(email);

INSERT INTO purchaseorder
VALUES (XMLType(bfilename('XMLDIR', 'purchaseOrder.xml'),
nls_charset_id('AL32UTF8')));

INSERT INTO purchaseorder
VALUES (XMLType(bfilename('XMLDIR', 'DuplicateReference.xml'),
nls_charset_id('AL32UTF8')));

INSERT INTO purchaseorder
*
ERROR at line 1:
ORA-00001: unique constraint (QUINE.REFERENCE_IS_UNIQUE) violated

INSERT INTO purchaseorder
VALUES (XMLType(bfilename('XMLDIR', 'InvalidUser.xml'),
nls_charset_id('AL32UTF8')));

INSERT INTO purchaseorder
*
ERROR at line 1:
ORA-02291: integrity constraint (QUINE.USER_IS_VALID) violated - parent key not
found

例3-20と同様に、例3-21の一意性制約reference_is_uniqueが発注書Reference要素の、表に格納されたすべてのドキュメントを通じての一意性を保証しています。外部キー制約user_is_validは、ここで要素Userの値がemployees表のemail列の値に対応することを保証しています。

XML文書DuplicateRefernce.xmlのReference要素に関連付けられたテキスト・ノードに、XML文書PurchaseOrder.xml内の対応するノードと同じ値が含まれています。したがって、両方の文書をOracle XML DBに格納しようとすると、制約reference_is_uniqueに違反します。

また、XML文書InvalidUser.xmlのUser要素に関連付けられたテキスト・ノードには、値HACKERが含まれています。employees表には、email列の値がHACKERのエントリはありません。この文書をOracle XML DBに格納しようとすると、制約user_is_validに違反します。

XML Schemaに基づくXMLコンテンツがOracle XML DBリポジトリにロードされると、制約およびトリガーを使用して定義された整合性ルールも規定されます。例3-22に、これを示します。FTPなどのプロトコルを使用してXML Schemaに基づくXMLコンテンツがOracle XML DBリポジトリにアップロードされると、データベース整合性も規定されます。

例3-22 FTPを使用してXMLをロードしたときのデータベース整合性の規定

$ ftp localhost 2100
Connected to localhost.
220 mdrake-sun FTP Server (Oracle XML DB/Oracle Database 10g Enterprise Edition
Release 10.1.0.0.0 - Beta) ready.
Name (localhost:oracle10): QUINE
331 Password required for QUINE
Password: password
230 QUINE logged in
ftp> cd /source/schemas
250 CWD Command successful
ftp> put InvalidReference.xml
200 PORT Command successful
150 ASCII Data Connection
550- Error Response
ORA-00604: error occurred at recursive SQL level 1
ORA-31154: invalid XML document
ORA-19202: Error occurred in XML processing
LSX-00221: "SBELL-20021009" is too short (minimum length is 18)
ORA-06512: at "SYS.XMLTYPE", line 333
ORA-06512: at "QUINE.VALIDATE_PURCHASEORDER", line 3
ORA-04088: error during execution of trigger 'QUINE.VALIDATE_PURCHASEORDER'
550 End Error Response
ftp> put InvalidElement.xml
200 PORT Command successful
150 ASCII Data Connection
550- Error Response
ORA-30937: No schema definition for 'UserName' (namespace '##local') in parent
'PurchaseOrder'
550 End Error Response
ftp> put DuplicateReference.xml
200 PORT Command successful
150 ASCII Data Connection
550- Error Response
ORA-00604: error occurred at recursive SQL level 1
ORA-00001: unique constraint (QUINE.REFERENCE_IS_UNIQUE) violated
550 End Error Response
ftp> put InvalidUser.xml
200 PORT Command successful
150 ASCII Data Connection
550- Error Response
ORA-00604: error occurred at recursive SQL level 1
ORA-02291: integrity constraint (QUINE.USER_IS_VALID) violated - parent key not
found
550 End Error Response

プロトコルを使用して文書をアップロードしているときにエラーが発生すると、Oracle XML DBはクライアントに対して完全なSQLエラー・トレースを提供します。エラーの解析とレポートの方法は、クライアント・アプリケーションに組み込まれたエラー処理によって決まります。たとえば、コマンドラインFTPツールなどのクライアントはOracle XML DBから戻されたエラーをレポートし、Microsoft Windows Explorerなどのクライアントは単に汎用エラー・メッセージをレポートします。

関連項目:

- 「XMLType表および列に対するリレーショナル制約の指定」

- 『Oracle Databaseエラー・メッセージ』

Oracle XML DBを使用したXMLコンテンツに対するDML操作

Oracle XML DBを使用してXMLコンテンツを管理するもう1つの主なメリットは、Oracle Databaseの機能を使用してXMLコンテンツの問合せと更新を行う強力で柔軟な機能が提供されることです。次の機能が含まれます。

- XML文書内のノードとフラグメントの取出し

- XML文書内のノードとフラグメントの更新

- XML文書内の特定ノード上での索引の作成

- XML文書のコンテンツ全体の索引付け

- XML文書に特定のノードが含まれるかどうかの判別

XPathおよびOracle XML

Oracle XML DBには、XMLTypeメソッドおよびXML固有のSQL関数が含まれています。それらのメソッドとSQL関数を使用すると、Oracle Databaseに格納されているXMLコンテンツを問合せおよび更新できます。これらのメソッドとSQL関数では、1つまたは複数の必須ノードを識別するために、W3CのXPath勧告が使用されています。XML文書の各ノードは、XPath式によって一意に識別できます。

XPath式は、スラッシュ記号で区切った要素名、属性名およびXPath関数のリストで構成されます。XPath式には、ターゲット・ノードの判別時に検索するツリーのブランチを決定する位置および条件を含めることができます。

XPathを使用したメソッドと関数がサポートされているため、XMLプログラマはOracle XML DBを使用し、標準に準拠した一般的な方法でXML文書を問合せおよび更新できます。

注意:
Oracle SQL関数およびXMLTypeメソッドは、W3C XPath勧告に準拠しています。このことは、XPath式がどのノードもターゲットにしていない場合にXMLデータに適用されると、空のシーケンスが戻される必要があることを示します。この場合にエラーが発生してはいけません。
XPath式をXMLデータに適用するOracle SQL関数またはXMLTypeメソッドによって、何が戻されるのかが決まります。たとえば、XPath式の引数のがどのノードもターゲットにしていない場合、SQL/XML関数XMLQueryはNULLを戻します。deleteXMLなどの更新のSQL関数は、入力XMLデータを変更せずに戻します。どのノードもターゲットになっていない場合にはエラーが発生することはありませんが、XPath式の引数が、属性ノードやテキスト・ノードなどの適切ではないノードをターゲットにしている場合は、更新のSQL関数でエラーが発生する可能性があります。

Oracle XML DBに格納されたXMLコンテンツの問合せ

この項では、Oracle XML DBの問合せ方法およびXMLコンテンツの取出し方法について説明します。この項の内容は次のとおりです。

- XML文書PurchaseOrder

- 疑似列OBJECT_VALUEを使用したXML文書のコンテンツの取出し

- XMLQUERYを使用したXML文書のフラグメントまたはノードへのアクセス

- XMLCASTおよびXMLQUERYを使用したテキスト・ノードおよび属性値へのアクセス

- XMLEXISTS、XMLCastおよびXMLQueryを使用したXML文書の検索

- XMLTABLEを使用したXMLTypeフラグメントでのSQL操作の実行

XML文書PurchaseOrder

この項では、例3-23のXML文書PurchaseOrderを使用した例を示します。

例3-23 XMLインスタンス・ドキュメントPurchaseOrder

<PurchaseOrder
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd">
<Reference>SBELL-2002100912333601PDT</Reference>
<Actions>
<Action>
<User>SVOLLMAN</User>
</Action>
</Actions>
<Reject/>
<Requestor>Sarah J. Bell</Requestor>
<User>SBELL</User>
<CostCenter>S30</CostCenter>
<ShippingInstructions>
<name>Sarah J. Bell</name>
<address>400 Oracle Parkway
Redwood Shores
CA
94065
USA</address>
<telephone>650 506 7400</telephone>
</ShippingInstructions>
<SpecialInstructions>Air Mail</SpecialInstructions>
<LineItems>
<LineItem ItemNumber="1">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="2">
<Description>The Unbearable Lightness Of Being</Description>
<Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="3">
<Description>Sisters</Description>
<Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
</LineItem>
</LineItems>
</PurchaseOrder>

疑似列OBJECT_VALUEを使用したXML文書のコンテンツの取出し

疑似列OBJECT_VALUEは、オブジェクト表の値の別名として使用できます。XMLTypeの単一列からなるXMLType表の場合、XML文書全体が取り出されます。(OBJECT_VALUEは、Oracle Database 10gリリース1より前のリリースで使用されていたvalue(x)およびSYS_NC_ROWINFO$別名に換わるものです。)

例3-24では、文書全体が改行なしで正しく出力されるように、SQL*Plus設定のPAGESIZEおよびLONGを使用しています。(読みやすいように、フォーマット出力で示しています。)

例3-24 OBJECT_VALUEを使用したXML文書全体の取出し

SET LONG 10000
SET PAGESIZE 100

SELECT OBJECT_VALUE FROM purchaseorder;

OBJECT_VALUE
-----------------------------------------------------------------------
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://localhost:8080/source/schemas
/poSource/xsd/purchaseOrder.xsd">
<Reference>SBELL-2002100912333601PDT</Reference>
<Actions>
<Action>
<User>SVOLLMAN</User>
</Action>
</Actions>
<Reject/>
<Requestor>Sarah J. Bell</Requestor>
<User>SBELL</User>
<CostCenter>S30</CostCenter>
<ShippingInstructions>
<name>Sarah J. Bell</name>
<address>400 Oracle Parkway
Redwood Shores
CA
94065
USA</address>
<telephone>650 506 7400</telephone>
</ShippingInstructions>
<SpecialInstructions>Air Mail</SpecialInstructions>
<LineItems>
<LineItem ItemNumber="1">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="2">
<Description>The Unbearable Lightness Of Being</Description>
<Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="3">
<Description>Sisters</Description>
<Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
</LineItem>
</LineItems>
</PurchaseOrder>

1 row selected.

XMLQUERYを使用したXML文書のフラグメントまたはノードへのアクセス

SQL/XML関数XMLQueryを使用すると、XPath式と一致するノードを抽出できます。結果は、XMLTypeのインスタンスとして戻されます。例3-25に、複数の問合せの例を示します。

例3-25 XMLQUERYを使用したXMLフラグメントへのアクセス

次の問合せは、XPath式と一致するReference要素を含むXMLTypeインスタンスを戻します。

SELECT XMLQuery('/PurchaseOrder/Reference' PASSING OBJECT_VALUE RETURNING CONTENT)
FROM purchaseorder;

XMLQUERY('/PURCHASEORDER/REFERENCE'PASSINGOBJECT_
-------------------------------------------------
<Reference>SBELL-2002100912333601PDT</Reference>

1 row selected.

次の問合せは、LineItemコレクション内の最初のLineItems要素を含むXMLTypeインスタンスを戻します。

SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem[1]'
PASSING OBJECT_VALUE RETURNING CONTENT)
FROM purchaseorder;

XMLQUERY('/PURCHASEORDER/LINEITEMS/LINEITEM[1]'PASSINGOBJECT_
-------------------------------------------------------------
<LineItem ItemNumber="1">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
</LineItem>

1 row selected.

次の問合せは、XPath式と一致する3つのDescription要素を含むXMLTypeインスタンスを戻します。これらの要素は、単一のXMLTypeインスタンス内のノードとして戻されます。XMLTypeインスタンスはXMLフラグメントなので、単一のルート・ノードを持ちません。

SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem/Description'
PASSING OBJECT_VALUE RETURNING CONTENT)
FROM purchaseorder;

XMLQUERY('/PURCHASEORDER/LINEITEMS/LINEITEM/DESCRIPTION'PASSINGOBJECT_
----------------------------------------------------------------------
<Description>A Night to Remember</Description>
<Description>The Unbearable Lightness Of Being</Description>
<Description>Sisters</Description>

1 row selected.

関連項目:
「XMLTABLEを使用したXMLTypeフラグメントでのSQL操作の実行」

XMLCASTおよびXMLQUERYを使用したテキスト・ノードおよび属性値へのアクセス

テキスト・ノードおよび属性値には、SQL/XML標準関数XMLQueryおよびXMLCastを使用してアクセスできます。このためには、XMLQueryに渡されるXPath式は、文書内の単一のテキスト・ノードまたは属性値(リーフ・ノード)を一意に識別する必要があります。例3-26に、複数の問合せを使用する例を示します。

例3-26 XMLCASTおよびXMLQueryを使用したテキスト・ノード値へのアクセス

次の問合せは、対象のXPath式と一致するReference要素に関連付けられたテキスト・ノードの値を戻します。値は、VARCHAR2値として戻されます。

SELECT  XMLCast(XMLQuery('$p/PurchaseOrder/Reference/text()'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30))
FROM purchaseorder;

XMLCAST(XMLQUERY('$P/PURCHASEO
------------------------------
SBELL-2002100912333601PDT

1 row selected.

次の問合せは、LineItem要素に含まれるDescription要素に関連付けられたテキスト・ノードの値を戻します。特定のLineItem要素は、そのId属性値によって指定されます。LineItem要素を識別する述語は、[Part/@Id="715515011020"]です。アットマーク(@)は、Idが要素でなく属性であることを指定します。値は、VARCHAR2値として戻されます。

SELECT XMLCast(
XMLQuery('$p/PurchaseOrder/LineItems/LineItem[Part/@Id="715515011020"]/Description/text()'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30))
FROM purchaseorder;

XMLCAST(XMLQUERY('$P/PURCHASEO
------------------------------
Sisters

1 row selected.

次の問合せは、最初のLineItem要素に含まれるDescription要素に関連付けられたテキスト・ノードの値を戻します。最初のLineItem要素は、位置述語[1]で示されます。

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/LineItems/LineItem[1]/Description'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(4000))
FROM purchaseorder;

XMLCAST(XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[1]/DESCRIPTION'PASSINGOBJECT_VALUEAS"P"
---------------------------------------------------------------------------------------------
A Night to Remember

1 row selected.

関連項目:

- SQL/XML関数XMLCastの詳細は、「SQL/XML関数XMLExistsおよびXMLCastを使用したXMLTypeデータの問合せ」を参照してください。

- SQL/XML関数XMLQueryの詳細は、第5章「Oracle XML DBでのXQueryの使用」を参照してください。

XMLEXISTS、XMLCastおよびXMLQueryを使用したXML文書の検索

SQL/XML標準関数XMLExistsは、指定された文書にW3CのXPath式と一致するノードが含まれているかどうかを評価します。関数XMLExistsは、関数に指定されたXPath式によって指定されたノードが文書に含まれている場合はブール値のtrueを、そうでない場合はfalseの値を戻します。XPath式には述語を含めることができるため、XMLExistsは、指定されたノードが文書内に存在するかどうか、および指定された値を持つノードが文書内に存在するかどうかを判断できます。

同様に、SQL WHERE句でSQL/XML関数XMLCastおよびXMLQueryを使用すると、一部のプロパティを満たす文書のみを問合せの結果として戻すことができます。例3-27に、XMLExists、XMLCastおよびXMLQueryを使用して文書を検索する方法を示します。

例3-27 XMLExists、XMLCastおよびXMLQueryを使用したXMLコンテンツの検索

次の問合せでは、XMLExistsを使用して、ルート要素PurchaseOrderの子であるReferenceという要素がXML文書に含まれているかどうかを確認します。

SELECT count(*) FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder/Reference' PASSING OBJECT_VALUE AS "p");

COUNT(*)
----------
132

1 row selected.

次の問合せでは、Reference要素に関連付けられたテキスト・ノードの値がSBELL-2002100912333601PDTであるかどうかを確認します。

SELECT count(*) FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

COUNT(*)
----------
1
1 row selected.

この問合せでは、Reference要素に関連付けられたテキスト・ノードの値がSBELL-XXXXXXXXXXXXXXXXXXであるかどうかを確認します。

SELECT count(*) FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-XXXXXXXXXXXXXXXXXX"]'
PASSING OBJECT_VALUE AS "p");

COUNT(*)
----------
0

1 row selected.

この問合せでは、XML文書にルート要素PurchaseOrderが含まれているかどうかを確認します。このルート要素に含まれるLineItems要素にはLineItem要素が含まれ、さらにこの要素にはId属性を持つPart要素が含まれている必要があります。

SELECT count(*) FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder/LineItems/LineItem/Part/@Id'
PASSING OBJECT_VALUE AS "p");

COUNT(*)
----------
132

1 row selected.

次の問合せでは、XML文書にルート要素PurchaseOrderが含まれているかどうかを確認します。このルート要素に含まれるLineItems要素にはLineItem要素が含まれ、さらにこの要素にはId属性値が715515009058のPart要素が含まれている必要があります。

SELECT count(*) FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder/LineItems/LineItem/Part[@Id="715515009058"]'
PASSING OBJECT_VALUE AS "p");

COUNT(*)
----------
21

次の問合せでは、XML文書にルート要素PurchaseOrderが含まれているかどうかを確認します。このルート要素にはLineItem要素が含まれ、さらにこの要素の3番目のLineItem要素にはId属性値が715515009058のPart要素が含まれます。

SELECT count(*) FROM purchaseorder
WHERE XMLExists(
'$p/PurchaseOrder/LineItems/LineItem[3]/Part[@Id="715515009058"]'
PASSING OBJECT_VALUE AS "p");

COUNT(*)
----------
1
1 row selected.

次の問合せは、User要素に関連付けられたテキスト・ノードが文字Sで始まる行のみをSELECT文の結果として戻します。XQueryでは、LIKEを使用した問合せをサポートしていません。

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Reference' PASSING OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(30))
FROM purchaseorder
WHERE XMLCast(XMLQuery('$p/PurchaseOrder/User' PASSING OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(30))
LIKE 'S%';

XMLCAST(XMLQUERY('$P/PURCHASEORDER
----------------------------------
SBELL-20021009123336231PDT
SBELL-20021009123336331PDT
SKING-20021009123336321PDT
...
36 rows selected.

次の問合せは、XML文書内のノードの値と別の表のデータに基づいて結合を実行します。

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Reference' PASSING OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(30))
FROM purchaseorder p, hr.employees e
WHERE XMLCast(XMLQuery('$p/PurchaseOrder/User' PASSING OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(30)) = e.email
AND e.employee_id = 100;

XMLCAST(XMLQUERY('$P/PURCHASEOREDER
-----------------------------------
SKING-20021009123336321PDT
SKING-20021009123337153PDT
SKING-20021009123335560PDT
SKING-20021009123336952PDT
SKING-20021009123336622PDT
SKING-20021009123336822PDT
SKING-20021009123336131PDT
SKING-20021009123336392PDT
SKING-20021009123337974PDT
SKING-20021009123338294PDT
SKING-20021009123337703PDT
SKING-20021009123337383PDT
SKING-20021009123337503PDT

13 rows selected.

次の問合せは、XMLExistsを使用して、User要素のテキスト・ノードに値SBELLが含まれる行のみをSELECT文の結果として戻します。

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Reference' PASSING OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(30)) "Reference"
FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder[User="SBELL"]' PASSING OBJECT_VALUE AS "p");

Reference
------------------------------
SBELL-20021009123336231PDT
SBELL-20021009123336331PDT
SBELL-20021009123337353PDT
SBELL-20021009123338304PDT
SBELL-20021009123338505PDT
SBELL-20021009123335771PDT
SBELL-20021009123335280PDT
SBELL-2002100912333763PDT
SBELL-2002100912333601PDT
SBELL-20021009123336362PDT
SBELL-20021009123336532PDT
SBELL-20021009123338204PDT
SBELL-20021009123337673PDT

13 rows selected.

例3-28では、SQL/XML関数XMLQueryおよびXMLExistsを使用して、最初のLineItem要素にId 715515009058の注文が含まれるPurchaseOrder要素についてReference要素を検索します。関数XMLExistsをWHERE句で使用して、選択する行を決定し、XMLQueryをSELECTリストで使用して、選択された文書のどの部分を結果に表示するかを制御します。

例3-28 XMLQueryとXMLExistsを使用したPurchaseOrderのReferenceの検索

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Reference' PASSING OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(30)) "Reference"
FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder/LineItems/LineItem[1]/Part[@Id="715515009058"]'
PASSING OBJECT_VALUE AS "p");

Reference
-------------------------
SBELL-2002100912333601PDT

1 row selected.

関連項目:

- SQL/XML関数XMLCastおよびXMLExistsの詳細は、「SQL/XML関数XMLExistsおよびXMLCastを使用したXMLTypeデータの問合せ」を参照してください。

- SQL/XML関数XMLQueryの詳細は、第5章「Oracle XML DBでのXQueryの使用」を参照してください。

XMLTABLEを使用したXMLTypeフラグメントでのSQL操作の実行

例3-25は、XPath式と一致する1つ以上のノードを含むXMLTypeインスタンスを戻す方法を示しています。指定されたXPath式と一致するノードが文書に複数含まれている場合、このような問合せでは、一致するすべてのノードが含まれるXMLフラグメントを戻します。XML文書と異なり、XMLフラグメントには、ルート要素である単一の要素はありません。

このような結果は、次の場合に一般的です。

- コレクションに含まれている一連の要素を取り出す場合。この場合、フラグメント内のすべてのノードは同じタイプです(例3-29を参照)。

- 対象のXPath式がワイルドカードで終わる場合。この場合、フラグメント内のノードは異なるタイプになることがあります(例3-31を参照)。

SQL/XML関数XMLTableを使用すると、XMLTypeインスタンスに含まれているXMLフラグメントを分割し、コレクション要素データを新しい仮想表に挿入することができ、その後、SQLを結合式などで使用して問い合せることができます。特に、XMLフラグメントを仮想表に変換することにより、複数のノードを戻すXMLQuery式の評価の結果を処理しやすくなります。

例3-29に、PurchaseOrder文書のDescription要素ごとにテキスト・ノードにアクセスする方法を示します。例3-25の単一のXMLフラグメント出力を複数のテキスト・ノードに分割します。

例3-29 XMLTABLEを使用したDescriptionノードへのアクセス

SELECT des.COLUMN_VALUE
FROM purchaseorder p,
XMLTable('/PurchaseOrder/LineItems/LineItem/Description'
PASSING p.OBJECT_VALUE) des
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

COLUMN_VALUE
------------
<Description>A Night to Remember</Description>
<Description>The Unbearable Lightness Of Being</Description>
<Description>Sisters</Description>

3 rows selected.

例3-29では、SQLを使用してテキスト・ノードのコンテンツを処理するために、SQL/XML関数XMLTableを使用してDescriptionノードのコレクションを仮想表に変換します。この仮想表には3つの行があり、単一のDescription要素を持つ単一のXMLTypeインスタンスが各行に含まれています。

XPath式は、Description要素をターゲットにしています。PASSING句では、XPath式を評価するためのコンテキストとしてXMLType表purchaseorderのコンテンツ(OBJECT_VALUE)を使用することを指定しています。

したがって、XMLTable式はpurchaseorder表に依存します。これは左側結合です。この相関結合によって、アクセスされるpurchaseorder行と、XMLTableによってその行から生成される行は、1対多(1:N)の関係であることが保証されます。この相関結合により、purchaseorder表は、FROMリストのXMLTable式よりも前に記述する必要があります。これは、PASSING句が表の列を参照する場合に一般的な要件です。

仮想表のXMLTypeインスタンスにはそれぞれ、Description要素が1つずつ含まれます。XMLTableのCOLUMNS句を使用して、XPath式'Description'のターゲットのデータを、SQLデータ型VARCHAR2(256)のdescriptionという列に分割できます。この列を定義する'Description'式は、コンテキストのXPath式'/PurchaseOrder/LineItems/LineItem'に相対的です。

SELECT des.description
FROM purchaseorder p,
XMLTable('/PurchaseOrder/LineItems/LineItem' PASSING p.OBJECT_VALUE
COLUMNS description VARCHAR2(256) PATH 'Description') des
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

DESCRIPTION
---------------------------------
A Night to Remember
The Unbearable Lightness Of Being
Sisters

3 rows selected.

COLUMNS句を使用すると、正確なSQLデータ型を指定できるため、静的型チェックがさらに便利になります。この例では、単一の列(description)のみを使用します。XMLType表に複数レベルで含まれているデータをリレーショナル・ビューの個別の行として公開するには、分割してリレーショナル列に格納する各文書レベルにXMLTableを適用します。この例は、例3-33を参照してください。

例3-30では、コレクション内の要素数をカウントします。また、ORDER BYやGROUP BYなどのSQLキーワードをSQL/XML関数XMLTableによって作成された仮想表データに適用する方法も示しています。

例3-30 XMLTABLEを使用したコレクション内の要素数のカウント

SELECT reference, count(*)
FROM purchaseorder,
XMLTable('/PurchaseOrder' PASSING OBJECT_VALUE
COLUMNS reference VARCHAR2(32) PATH 'Reference',
lineitem  XMLType      PATH 'LineItems/LineItem'),
XMLTable('LineItem' PASSING lineitem)
WHERE XMLExists('$p/PurchaseOrder[User="SBELL"]'
PASSING OBJECT_VALUE AS "p")
GROUP BY reference
ORDER BY reference;

REFERENCE                    COUNT(*)
--------------------------   --------
SBELL-20021009123335280PDT         20
SBELL-20021009123335771PDT         21
SBELL-2002100912333601PDT           3
SBELL-20021009123336231PDT         25
SBELL-20021009123336331PDT         10
SBELL-20021009123336362PDT         15
SBELL-20021009123336532PDT         14
SBELL-20021009123337353PDT         10
SBELL-2002100912333763PDT          21
SBELL-20021009123337673PDT         10
SBELL-20021009123338204PDT         14
SBELL-20021009123338304PDT         24
SBELL-20021009123338505PDT         20

13 rows selected.

例3-30の問合せでは、SQL/XML関数XMLExistsへのXPath式と一致する一連のXML文書が検索されます。これにより、次の2つの列を含む仮想表が生成されます。

- reference: この列には、選択された各文書のReferenceノードが含まれます。

- lineitem: この列には、選択された各文書の一連のLineItemノードが含まれます。

文書ごとにLineItemノードの数がカウントされます。相関結合によって、GROUP BYはLineItem要素が属するPurchaseOrder要素を正しく判別できます。

例3-31では、SQL/XML関数XMLTableを使用して、指定された要素の子要素の数をカウントする方法を示します。XMLTableに渡されるXPath式には、PurchaseOrder要素の直接の子孫である全要素と一致するワイルド・カード(*)が含まれます。XMLTableで作成された仮想表の各行には、XPath式と一致するノードが含まれます。仮想表内の行数をカウントすることによって、要素PurchaseOrderの子要素の数が判明します。

例3-31 XMLTABLEを使用した要素内の子要素数のカウント

SELECT count(*)
FROM purchaseorder p, XMLTable('/PurchaseOrder/*' PASSING p.OBJECT_VALUE)
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

COUNT(*)
----------
9

1 row selected.

リレーショナル・ビューを使用したOracle XML DB内のXMLデータへのアクセス

Oracle XML DBで提供されるXML特有の関数およびメソッドを使用すると、XMLコンテンツへのリレーショナル・アクセスを提供する、従来のリレーショナル・ビューを作成できます。これによって、Oracle Databaseには対処していてもXMLには対処していないプログラマ、ツールおよびアプリケーションでも、データベースに格納されたXMLコンテンツを操作できます。

リレーショナル・ビューでは、XPath式とXMLTableなどのSQL/XML問合せおよびアクセス関数を使用して、ビューの列とXML文書のノードとの間のマッピングを定義できます。XML文書が、CLOBインスタンスとしてではなく、構造化(オブジェクト・リレーショナル)XML記憶域またはバイナリXML記憶域を使用して格納されている場合のみ、パフォーマンス上の理由からこの方法をお薦めします。

関連項目:

- XMLTypeのデータ型および関数の詳細は、第4章「XMLTypeの操作」を参照してください。

- XPath 1.0の詳細は、http://www.w3.org/TR/xpathを参照してください。

- XPath 2.0の詳細は、http://www.w3.org/TR/xpath20/を参照してください。

- XMLでのUnicodeの使用については、http://www.w3.org/TR/2002/NOTE-unicode-xml-20020218/を参照してください。

単一レベルのXMLデータの分割

XMLType表内の各文書をリレーショナル・ビューの行として公開する必要がある場合は、次の方法を使用できます。

1. CREATE OR REPLACE VIEWを使用して、ビューを構成する一連の列を定義します。

2. XML文書内のノードを、ビューで定義されている列にマップします。このためには、SQL/XML関数XMLTableを適切なXPath式とともに使用して、ノードを抽出します。

この方法は、XMLType表内の文書とビュー内の行の間に、1対1 (1:1)の関係がある場合はいつでも使用できます。

例3-32では、XMLコンテンツを公開する簡単なリレーショナル・ビューpurchaseorder_master_viewの作成方法を示します。このビューには、XMLType表purchaseorderの行ごとに1つの行が含まれます。

例3-32 XMLコンテンツのリレーショナル・ビューの作成

CREATE OR REPLACE VIEW purchaseorder_master_view AS
SELECT po.*
FROM purchaseorder pur,
XMLTable(
'$p/PurchaseOrder' PASSING pur.OBJECT_VALUE as "p"
COLUMNS
reference       VARCHAR2(30)   PATH 'Reference',
requestor       VARCHAR2(128)  PATH 'Requestor',
userid          VARCHAR2(10)   PATH 'User',
costcenter      VARCHAR2(4)    PATH 'CostCenter',
ship_to_name    VARCHAR2(20)   PATH 'ShippingInstructions/name',
ship_to_address VARCHAR2(256)  PATH 'ShippingInstructions/address',
ship_to_phone   VARCHAR2(24)   PATH 'ShippingInstructions/telephone',
instructions    VARCHAR2(2048) PATH 'SpecialInstructions') po;

View created.

DESCRIBE purchaseorder_master_view

Name            Null?    Type
--------------------------------------------
REFERENCE                VARCHAR2(30)
REQUESTOR                VARCHAR2(128)
USERID                   VARCHAR2(10)
COSTCENTER               VARCHAR2(4)
SHIP_TO_NAME             VARCHAR2(20)
SHIP_TO_ADDRESS          VARCHAR2(256)
SHIP_TO_PHONE            VARCHAR2(24)
INSTRUCTIONS             VARCHAR2(2048)

複数レベルのXMLデータの分割

XMLType表に複数レベルで含まれているデータをリレーショナル・ビューの個別の行として公開する必要がある場合は、単一レベルの分割と同じ一般的な方法を使用し、1)ビューを構成する列の定義、および、2)列へのXMLノードのマップを行います。ただし、この場合は、分割してリレーショナル列に格納する各文書レベルにXMLTableを適用します。

この方法は、XMLType表内の文書とビュー内の行の間に、1対多 (1:N)関係がある場合はいつでも使用できます。

たとえば、各PurchaseOrder要素にLineItems要素が含まれていて、この要素に1つ以上のLineItem要素が含まれているとします。各LineItem要素には、DescriptionやItemNumber属性などの子要素があります。このような下位レベルのデータをリレーショナル値としてアクセス可能にするには、PurchaseOrder要素とLineItemコレクションの両方を分割する必要があります。この分割は、いずれもXMLTableを使用して行われます。要素PurchaseOrderを分割すると、LineItem要素は、XMLフラグメントが含まれている型XMLTypeのリレーショナル列にマップされます。この列は次に、XMLTypeへの2回目のコールに渡され、リレーショナル値の複数の行として複数の部分に分割されます。

例3-33に、これを示します。この例では、XMLType表purchaseorder内の文書とビューの行の間に1対多(1:N)の関係がある場合の、SQL/XML関数XMLTableの使用方法を示します。このビューはコレクションの個別のメンバーへのアクセスを提供し、コレクション・メンバーを行のセットとして公開します。

例3-33 ビューを使用したコレクションの各メンバーへのアクセス

CREATE OR REPLACE VIEW purchaseorder_detail_view AS
SELECT po.reference, li.*
FROM purchaseorder p,
XMLTable('/PurchaseOrder' PASSING p.OBJECT_VALUE
COLUMNS
reference VARCHAR2(30) PATH 'Reference',
lineitem  XMLType      PATH 'LineItems/LineItem') po,
XMLTable('/LineItem' PASSING po.lineitem
COLUMNS
itemno      NUMBER(38)    PATH '@ItemNumber',
description VARCHAR2(256) PATH 'Description',
partno      VARCHAR2(14)  PATH 'Part/@Id',
quantity    NUMBER(12, 2) PATH 'Part/@Quantity',
unitprice   NUMBER(8, 4)  PATH 'Part/@UnitPrice') li;

View created.

DESCRIBE purchaseorder_detail_view
Name           Null?    Type
----------------------------
REFERENCE               VARCHAR2(30)
ITEMNO                  NUMBER(38)
DESCRIPTION             VARCHAR2(256)
PARTNO                  VARCHAR2(14)
QUANTITY                NUMBER(12,2)
UNITPRICE               NUMBER(8,4)

例3-33では、ビューpurchaseorder_detail_viewの各行は、XMLType表purchaseorderに格納されているXML文書内の各LineItem要素に対応しています。

CREATE OR REPLACE VIEW文では、ビューを構成する一連の列を定義します。SELECT文は、コンテキストとしてpurchaseorder表を関数XMLTableに渡し、列referenceおよびlineitemを含む、仮想表pを作成します。これらの列には、発注書のReferenceおよびLineItem要素がそれぞれ含まれます。

列lineitemにはLineItem要素のコレクションがXMLTypeインスタンスとして含まれ、各行が各LineItem要素に対応します。これらの行は次に、2つ目のXMLTable式に渡され、そのコンテキストとして機能します。この2つ目のXMLTable式により、明細/項目行の仮想表が作成され、各列が要素LineItemの様々な子孫ノードに対応します。これらの子孫の大半は属性(ItemNumberやPart/@Idなど)です。子孫の1つはDescription子要素です。

Reference要素は列referenceとしてビューpurchaseorder_detail_viewに含まれます。ビューpurchaseorder_detail_viewの行をビューpurchaseorder_master_viewの対応する行に結合するのに使用できる外部キーを提供します。CREATE VIEW文の相関結合によって、ビューにアクセスするたびに、Reference要素と、関連するLineItem要素の間の1対多(1:N)の関係が保持されます。

リレーショナル・データとしてのXMLコンテンツの問合せ

この項の例では、XMLデータのリレーショナル問合せについて説明します。これらの例では、XMLType表および列に対してリレーショナル・ビューを作成するメリットをいくつか示します。

例3-34に、XMLデータのマスターおよび詳細なリレーショナル・ビューの問合せ方法を示します。

例3-34 ビューを使用したXMLデータの問合せ

マスター・ビューに対する次の単純な問合せでは、従来のSELECT文を使用して、userid列がSで始まる行を戻します。

SELECT reference, costcenter, ship_to_name
FROM purchaseorder_master_view
WHERE userid LIKE 'S%';

REFERENCE                      COST SHIP_TO_NAME
------------------------------ ---- --------------
SBELL-20021009123336231PDT     S30  Sarah J. Bell
SBELL-20021009123336331PDT     S30  Sarah J. Bell
SKING-20021009123336321PDT     A10  Steven A. King
...
36 rows selected.

次の問合せは、マスター・ビューと詳細ビューの結合に基づいています。従来のSELECT文により、itemno列の値が1で、対応するpurchaseorder_master_viewの行に値がSBELLのuserid列が含まれているpurchaseorder_detail_viewの行を検索します。

SELECT d.reference, d.itemno, d.partno, d.description
FROM purchaseorder_detail_view d, purchaseorder_master_view m
WHERE m.reference = d.reference
AND m.userid = 'SBELL'
AND d.itemno = 1;

REFERENCE                          ITEMNO PARTNO         DESCRIPTION
------------------------------ ------------------------------------------------
SBELL-20021009123336231PDT              1 37429165829    Juliet of the Spirits
SBELL-20021009123336331PDT              1 715515009225   Salo
SBELL-20021009123337353PDT              1 37429141625    The Third Man
SBELL-20021009123338304PDT              1 715515009829   Nanook of the North
SBELL-20021009123338505PDT              1 37429122228    The 400 Blows
SBELL-20021009123335771PDT              1 37429139028    And the Ship Sails on
SBELL-20021009123335280PDT              1 715515011426   All That Heaven Allows
SBELL-2002100912333763PDT               1 715515010320   Life of Brian - Python
SBELL-2002100912333601PDT               1 715515009058   A Night to Remember
SBELL-20021009123336362PDT              1 715515012928   In the Mood for Love
SBELL-20021009123336532PDT              1 37429162422    Wild Strawberries
SBELL-20021009123338204PDT              1 37429168820    Red Beard
SBELL-20021009123337673PDT              1 37429156322    Cries and Whispers

13 rows selected.

例3-34のビューの外観と動作は、標準のリレーショナル・ビューと同様です。このビューは、標準のリレーショナル構文を使用して問合せできます。問合せまたは生成される結果セットでは、XML固有の構文は必要ありません。

Oracle XML DBでは、ビジネス・インテリジェンスや分析機能などの高度なデータベース機能がXML対応でない場合でも、XMLコンテンツをリレーショナル・データとして公開することによって、これらの機能をXMLコンテンツに適用できます。

例3-35では、XMLコンテンツのリレーショナル・ビューを使用して、XML文書のビジネス・インテリジェンス問合せを実行する方法を示します。この例の問合せは、タイトルがUPCコード715515009058および715515009126で識別される発注を含むPurchaseOrder文書を選択します。

例3-35 ビューを使用したXMLデータのビジネス・インテリジェンス問合せ

SELECT partno, count(*) "No of Orders", quantity "No of Copies"
FROM purchaseorder_detail_view
WHERE partno IN (715515009126, 715515009058)
GROUP BY rollup(partno, quantity);

PARTNO         No of Orders No of Copies
-------------- ------------ ------------
715515009058              7            1
715515009058              9            2
715515009058              5            3
715515009058              2            4
715515009058             23
715515009126              4            1
715515009126              7            3
715515009126             11
34
9 rows selected.

例3-35の問合せは、PurchaseOrder文書ごとに、発注された各タイトルのコピー数を判別します。部品番号715515009126には、発注された品目のコピー数が1のPurchaseOrder文書は4つあり、発注された品目のコピー数が3のPurchaseOrder文書は7つあります。

Oracle XML DBに格納されたXMLコンテンツの更新

Oracle XML DBでは、XMLコンテンツに対する更新操作を実行できます。更新操作では、文書のコンテンツ全体または文書の一部を置き換えることができます。XML文書を部分的に更新する機能は非常に強力で、特に大きな文書に小さな変更を行う場合に、更新の実行に必要なネットワーク・トラフィックとディスクの入出力を大幅に削減できます。

SQL関数updateXMLを使用すると、XMLTypeインスタンスとして格納されたXML文書の部分的な更新が可能になります。これにより、文書に対する複数の変更を1回の操作で実行できます。各変更は、更新するノードを識別するXPath式と、ノードの新しい値で構成されます。

例3-36では、SQL関数updateXMLを使用して、要素Userに関連付けられたテキスト・ノードを更新します。

例3-36 UPDATEXMLを使用したXMLコンテンツの更新

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/User' PASSING OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(60))
FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

XMLCAST(XMLQUERY('$P/PURCHAS
----------------------------
SBELL

1 row selected.

UPDATE purchaseorder
SET OBJECT_VALUE =
updateXML(OBJECT_VALUE, '/PurchaseOrder/User/text()', 'SKING')
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

1 row updated.

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/User' PASSING OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(60))
FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

XMLCAST(XMLQUERY('$P/PURCHAS
----------------------------
SKING

1 row selected.

例3-37では、SQL関数updateXMLを使用して、XML文書内の要素全体を置換します。XPath式によって要素が参照され、置換値はXMLTypeオブジェクトとして渡されます。

例3-37 UPDATEXMLを使用した要素全体の置換

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[1]'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHAS
--------------------
<LineItem ItemNumber="1">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
</LineItem>

1 row selected.

UPDATE purchaseorder
SET OBJECT_VALUE =
updateXML(
OBJECT_VALUE,
'/PurchaseOrder/LineItems/LineItem[1]',
XMLType('<LineItem ItemNumber="1">
<Description>The Lady Vanishes</Description>
<Part Id="37429122129" UnitPrice="39.95" Quantity="1"/>
</LineItem>'))
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

1 row updated.

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[1]'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHAS
--------------------
<LineItem ItemNumber="1">
<Description>The Lady Vanishes</Description>
<Part Id="37429122129" UnitPrice="39.95" Quantity="1"/>
</LineItem>

1 row selected.

例3-38に、コレクション内で複数回出現するノードを、SQL関数updateXMLを使用して更新する際に発生する一般的なエラーを示します。UPDATE文で、Description要素のテキスト・ノードの値をThe Wizard of Ozに設定します。この現在のテキスト・ノードの値はSistersです。この文のWHERE句にはXMLExists式が含まれ、更新する一連のノードを識別します。

例3-38 コレクション内で複数回出現するノードの間違った更新

SELECT XMLCast(des.COLUMN_VALUE AS VARCHAR2(256))
FROM purchaseorder,
XMLTable('$p/PurchaseOrder/LineItems/LineItem/Description'
PASSING OBJECT_VALUE AS "p") des
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

XMLCAST(DES.COLUMN_VALUEASVARCHAR2(256))
----------------------------------------
The Lady Vanishes
The Unbearable Lightness Of Being
Sisters

3 rows selected.

UPDATE purchaseorder p
SET p.OBJECT_VALUE =
updateXML(p.OBJECT_VALUE,
'/PurchaseOrder/LineItems/LineItem/Description/text()',
'The Wizard of Oz')
WHERE XMLExists('$p/PurchaseOrder/LineItems/LineItem[Description="Sisters"]'
PASSING OBJECT_VALUE AS "p")
AND XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

1 row updated.

SELECT XMLCast(des.COLUMN_VALUE AS VARCHAR2(256))
FROM purchaseorder,
XMLTable('$p/PurchaseOrder/LineItems/LineItem/Description'
PASSING OBJECT_VALUE AS "p") des
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

XMLCAST(DES.COLUMN_VALUEASVARCHAR2(256))
----------------------------------------
The Wizard of Oz
The Wizard of Oz
The Wizard of Oz

3 rows selected.

例3-38では、SQL関数updateXMLは、目的のノードのみを更新するのではなく、Description要素に属するすべてのテキスト・ノードの値を更新します。これはupdateXMLの正しい動作ですが、意図していたものではありません。

WHERE句は、更新が必要な文書を識別するためにのみ使用でき、その文書内で更新が必要なノードの識別には使用できません。

文書が選択されると、updateXMLに渡されるXPath式により、文書内で更新が必要なノードが判別されます。この例では、XPath式によって3つすべてのDescriptionノードが識別されるため、関連する3つのテキスト・ノードすべてが更新されています。

SQL関数updateXMLを正しく使用してコレクション内で複数回出現するノードを更新するには、updateXMLに渡されるXPath式を使用して、XML文書内の更新対象のノードを識別します。XPath式に適切な述語を設定することによって、文書内の更新対象のノードを限定できます。例3-39では、コレクション内の1つのノードを更新する正しい方法を示します。

例3-39 コレクション内で複数回出現するノードの正しい更新

SELECT XMLCast(des.COLUMN_VALUE AS VARCHAR2(256))
FROM purchaseorder,
XMLTable('$p/PurchaseOrder/LineItems/LineItem/Description'
PASSING OBJECT_VALUE AS "p") des
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

XMLCAST(DES.COLUMN_VALUEASVARCHAR2(256))
----------------------------------------

A Night to Remember
The Unbearable Lightness Of Being
Sisters

3 rows selected.

UPDATE purchaseorder p
SET p.OBJECT_VALUE =
updateXML(
p.OBJECT_VALUE,
'/PurchaseOrder/LineItems/LineItem/Description[text()="Sisters"]/text()',
'The Wizard of Oz')
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

1 row updated.

SELECT XMLCast(des.COLUMN_VALUE AS VARCHAR2(256))
FROM purchaseorder,
XMLTable('$p/PurchaseOrder/LineItems/LineItem/Description'
PASSING OBJECT_VALUE AS "p") des
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

XMLCAST(DES.COLUMN_VALUEASVARCHAR2(256))
----------------------------------------
A Night to Remember
The Unbearable Lightness Of Being
The Wizard of Oz

3 rows selected.

SQL関数updateXMLを使用すると、文書に対する複数の変更を1つの文で実行できます。例3-40では、User要素およびSpecialInstructions要素に属するテキスト・ノードの値を1つの文で変更する方法を示します。

例3-40 UPDATEXMLを使用したテキスト・ノード値の変更

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/CostCenter'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(4)) "Cost Center",
XMLCast(XMLQuery('$p/PurchaseOrder/SpecialInstructions'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(2048)) "Instructions"
FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

Cost Center  Instructions
------------ ------------
S30          Air Mail

1 row selected.

次の単一のUPDATE SQL文により、User要素およびSpecialInstructions要素のテキスト・ノード値が変更されます。

UPDATE purchaseorder
SET OBJECT_VALUE =
updateXML(OBJECT_VALUE,
'/PurchaseOrder/CostCenter/text()',
'B40',
'/PurchaseOrder/SpecialInstructions/text()',
'Priority Overnight Service')
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

1 row updated.

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/CostCenter'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(4)) "Cost Center",
XMLCast(XMLQuery('$p/PurchaseOrder/SpecialInstructions'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(2048)) "Instructions"
FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

Cost Center  Instructions
------------ --------------------------
B40          Priority Overnight Service

1 row selected.

XML Schemaに基づくXML文書および基づかないXML文書の更新

updateXMLなどのSQL関数がXML文書を変更する方法は、XML文書の格納方法と、XML Schemaに基づいているかどうかにより異なります。

- CLOB値で格納されたXML文書: CLOBとして格納されたXML Schemaに基づくXML文書または基づかないXML文書をupdateXMLなどのSQL関数で更新すると、Oracle XML DBは、その文書からドキュメント・オブジェクト・モデル(DOM)を作成し、DOM APIメソッドを使用して適切なXMLデータを更新することで、更新を実行します。更新後、更新されたDOMは基礎となるCLOB値に戻されます。

- オブジェクト・リレーショナル形式で格納されたXML文書: オブジェクト・リレーショナル形式で格納されたXML Schemaに基づくXML文書をupdateXMLなどのSQL関数で更新すると、Oracle XML DBはXPathリライトを使用して、基礎となるオブジェクトのインプレース更新を実行できます。これは部分更新で、SQL関数へのXPath引数が同等のSQL操作に変換されます。すると、SQL操作によって基礎となるオブジェクトの属性が直接更新されます。このような部分更新は、DOMベースの更新よりもはるかに短時間で実行できます。このため、updateXMLなどのSQL関数を多数の文書に適用するSQLコードを実行すると、処理速度を大幅に改善できる場合があります。

- バイナリXML文書として格納されたXML文書: updateXMLなどのSQL関数をバイナリXML列で使用する場合、Oracle XML DBでは多くの場合、DOMを作成する必要はありません。文書中で更新が必要とされる正確な部分は、ストリーミングおよびXMLIndexなどの問合せ評価手法を使用して計算されます。更新されたデータは、最初の変更の発生箇所以降のみがディスクに書き込まれます。それ以前の変更はすべて変更されません。さらに、データの格納にSecureFile LOBが使用される(デフォルトの動作)場合、変更はスライド方式で適用され、残りのLOBのリライトは行われません。つまり、XMLデータのSecureFile LOB記憶域では、実際に変更されたデータのみが更新されます。これにより、非構造化記憶域と比べて、パフォーマンスが大幅に向上する可能性があります。これらの最適化は、XML Schemaに基づかないデータと基づくデータの両方に適用されます。

関連項目:
第8章「構造化記憶域のXPathリライト」

Oracle XML DBでの名前空間のサポート

名前空間のサポートは、W3CのXML勧告の主要な特徴です。Oracle XML DBでは、W3Cの名前空間勧告を完全にサポートしています。XMLTypeメソッドおよびXML固有のSQL関数はすべて、名前空間接頭辞を含むXPath式で使用できます。XPath式で使用する名前空間接頭辞を正しく解決するために、すべてのメソッドおよび関数は、名前空間宣言を指定するオプションのnamespace引数を受け入れます。指定されたXPath式に名前空間接頭辞が含まれている場合は、常にnamespaceパラメータが必要です。パラメータnamespaceが指定されている場合は、デフォルトの名前空間がnoNamespace名前空間でないかぎり、このパラメータでデフォルトの名前空間と接頭辞付き名前空間を明示的に宣言する必要があります。パラメータnamespaceが指定されていない場合、Oracle XML DBでは、XPath式について次のことを前提とします。

- XMLTypeインスタンスのコンテンツが登録済のXML Schemaに基づいていない場合、名前空間接頭辞を含むXPath式内の要素はすべてnoNamespace名前空間に存在すると想定されます。

- XMLTypeのコンテンツが登録済のXML Schemaに基づいている場合、名前空間接頭辞を含まないXPath式内の要素はすべて、XML Schemaで宣言されたtargetNamespaceがあれば、その名前空間に存在すると想定されます。XML Schemaでtargetnamespaceが宣言されていない場合は、名前noNamespaceが使用されます。

XPath式の解決に必要な名前空間を正しく定義しないと、XPathを使用した操作が予測どおりに機能しません。名前空間の宣言が正しくないか存在しない場合、操作の結果はエラーではなくNULLになります。混乱を避けるために、noNamespace以外の名前空間がXPath式またはターゲットXML文書のいずれかに存在する場合は必ず、デフォルト名前空間宣言を含む、一連の名前空間宣言をすべて渡します。

Oracle XML DBでのXMLTypeメソッドおよびSQL関数の処理

Oracle XML DBは、DOMベースまたはSQLベースの方法を使用して、XMLQueryメソッドやXMLTypeメソッドなどのSQL/XMLアクセスおよび問合せ関数を処理します。

- DOMベースのXMLTypeの処理: Oracle XML DBはXMLTypeオブジェクトのコンテンツからDOMを構成することで、必要な処理を実行します。DOM APIで提供されるメソッドを使用して、DOMで必要な処理を実行します。DOMツリーの更新が含まれる操作を実行する場合は、操作の完了時にXML文書全体をディスクに再書込みする必要があります。XMLTypeデータに対してDOMベースの操作を使用する処理は、機能上の評価と呼ばれます。
機能上の評価のメリットは、記憶域モデル(構造化、バイナリXMLまたは非構造化)に関係なく、XMLTypeインスタンスに使用できることです。機能上の評価のデメリットは、XPathリライトよりもコストがかかることと、多数のXML文書間でのスケーラビリティがないことです。

- SQLベースのXMLType処理: Oracle XML DBは、関数またはメソッドの完了に必要な処理を実行するSQL文を構成します。SQL文は、XML Schemaに基づくXMLTypeの基礎となるオブジェクト・リレーショナル・データ構造に対して直接機能します。このプロセスは、XPathリライトと呼ばれます。第8章「構造化記憶域のXPathリライト」を参照してください。
XPathリライトのメリットは、Oracle XML DBによって、XPathを使用したSQL関数およびメソッドをリレーショナルとほぼ同じ速度で評価できることです。これにより、操作では多数のXML文書間でスケーラビリティを持つことができます。XPathリライトのデメリットは、XML文書を格納するのに使用するオブジェクトに直接アクセスして更新するため、XML Schemaに基づくオブジェクト・リレーショナル記憶域テクニックを使用してXMLTypeインスタンスを格納した場合にしか使用できないことです。

- バイナリXMLデータのストリーム式の評価: バイナリXMLをXMLType記憶域モデルとして使用する場合、XMLQueryなどのSQL/XMLアクセスおよび問合せ関数で使用されるXPath式は、DOMの構築に依存せずにストリーム方式で評価されます。

リレーショナル・データからのXMLデータの生成

この項では、Oracle XML DBを使用してリレーショナル・データからXMLデータを生成する例を紹介します。

関連項目:

- 第5章「Oracle XML DBでのXQueryの使用」

- 第18章「データベースからのXMLデータの生成」

SQL/XML関数を使用した、リレーショナル・データからのXMLデータの生成

標準のSQL/XML関数を使用すると、XML文書を1つ以上生成できます。SQL/XML関数XMLQueryは、これを行うための最も一般的な方法です。この操作に使用できるSQL/XML関数には、他に次のものがあります。

- XMLElementは、要素を作成します。

- XMLAttributesは、属性を要素に追加します。

- XMLForestは、要素のフォレストを作成します。

- XMLAggは、要素のコレクションから単一の要素を作成します。

例3-41の問合せでは、これらの関数を使用して、表departments、locations、countries、employeesおよびjobsの情報を含むXML文書を生成します。

例3-41 SQL/XML関数を使用したXMLデータの生成

SELECT XMLElement(
"Department",
XMLAttributes(d.Department_id AS "DepartmentId"),
XMLForest(d.department_name AS "Name"),
XMLElement(
"Location",
XMLForest(street_address AS "Address",
city AS "City",
state_province AS "State",
postal_code AS "Zip",
country_name AS "Country")),
XMLElement(
"EmployeeList",
(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 "PHONE_NUMBER",
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)))
AS XML
FROM hr.departments d, hr.countries c, hr.locations l
WHERE department_name = 'Executive'
AND d.location_id = l.location_id
AND l.country_id  = c.country_id;

この問合せでは、次のXMLが戻されます。

XML
--------------------------------------------------------------------------------
<Department DepartmentId="90"><Name>Executive</Name><Location><Address>2004
Charade Rd</Address><City>Seattle</City><State>Washingto
n</State><Zip>98199</Zip><Country>United States of
America</Country></Location><EmployeeList><Employee
employeeNumber="101"><FirstNa
me>Neena</FirstName><LastName>Kochhar</LastName><EmailAddress>NKOCHHAR</EmailAdd
ess><PHONE_NUMBER>515.123.4568</PHONE_NUMBER><Start
Date>2005-09-21</StartDate><JobTitle>Administration Vice
President</JobTitle><Salary>17000</Salary><Manager>Steven King</Manager><Com
mission></Commission></Employee><Employee
employeeNumber="102"><FirstName>Lex</FirstName><LastName>De
Haan</LastName><EmailAddress>L
DEHAAN</EmailAddress><PHONE_NUMBER>515.123.4569</PHONE
NUMBER><StartDate>2001-01-13</StartDate><JobTitle>Administration Vice Presiden
t</JobTitle><Salary>17000</Salary><Manager>Steven
King</Manager><Commission></Commission></Employee></EmployeeList></Department>

この問合せは、departments表の行ごとに要素Departmentを生成します。

- 各Department要素には、属性DepartmentIDが含まれます。DepartmentIDの値はdepartment_ed列から生成されます。このDepartment要素には、サブ要素のName、LocationおよびEmployeeListも含まれます。

- Name要素に関連付けられたテキスト・ノードは、departments表のname列から生成されます。

- Location要素には、子要素Address、City、State、ZipおよびCountryが含まれます。これらの要素は、locations表およびcountries表の列からフォレスト、つまり名前付き要素を作成することで構成されます。列内の値は、名前付き要素に対するテキスト・ノードになります。

- EmployeeList要素には、Employee要素の集計が含まれます。EmployeeList要素のコンテンツは、現在の部門に対応するemployees表の一連の行を戻す副問合せによって作成されます。各Employee要素には、従業員に関する情報が含まれます。各Employee要素のコンテンツおよび属性は、表employeesおよびjobsから取得されます。

SQL/XML関数で生成される出力は、通常はフォーマット出力ではありません。ただし、関数XMLSerializeは例外で、XMLSerializeを使用してフォーマット出力します。このため、他のSQL/XML関数で必要な出力を生成するときに、(1)完全なDOMが作成されるのを回避し、(2)生成される文書のサイズを縮小できます。ほとんどのアプリケーションでは、このように大半のSQL/XML関数でフォーマット出力が生成されなくても問題ありません。ただし、生成された出力を手動で検証することは困難になります。

例3-42 従来のリレーショナル表のXMLTypeビューの作成

CREATE OR REPLACE VIEW department_xml OF XMLType
WITH OBJECT ID (substr(
XMLCast(
XMLQuery('$p/Department/Name'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30)),
1,
128))
AS
SELECT XMLElement(
"Department",
XMLAttributes(d.department_id AS "DepartmentId"),
XMLForest(d.department_name AS "Name"),
XMLElement("Location", XMLForest(street_address AS "Address",
city AS "City",
state_province AS "State",
postal_code AS "Zip",
country_name AS "Country")),
XMLElement(
"EmployeeList",
(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 "PHONE_NUMBER",
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))).extract('/*')
AS XML
FROM hr.departments d, hr.countries c, hr.locations l
WHERE d.location_id = l.location_id
AND l.country_id  = c.country_id;

View created.

XMLTypeビューによって、リレーショナル・データをXMLコンテンツとして永続的に保持できます。また、XMLTypeビューの行は、Oracle XML DBリポジトリに文書として永続的に保持できます。例3-43に示すように、XMLTypeビューのコンテンツは問合せが可能です。

例3-43は、XMLTypeビューに対する簡単な問合せを示しています。SQL/XML関数XMLExistsに渡されるXPath式によって、結果セットは、Executive部門の情報が含まれたノードに制限されます。結果は、わかりやすくするためフォーマット出力しています。

例3-43 XMLTypeビューの問合せ

SELECT OBJECT_VALUE FROM department_xml
WHERE XMLExists('$p/Department[Name="Executive"]' PASSING OBJECT_VALUE AS "p");

OBJECT_VALUE
------------------------------------------------
<Department DepartmentId="90">
<Name>Executive</Name>
<Location>
<Address>2004 Charade Rd</Address>
<City>Seattle</City>
<State>Washington</State>
<Zip>98199</Zip>
<Country>United States of America</Country>
</Location>
<EmployeeList>
<Employee employeeNumber="101">
<FirstName>Neena</FirstName>
<LastName>Kochhar</LastName>
<EmailAddress>NKOCHHAR</EmailAddress>
<PHONE_NUMBER>515.123.4568</PHONE_NUMBER>
<StartDate>2005-09-21</StartDate>
<JobTitle>Administration Vice President</JobTitle>
<Salary>17000</Salary>
<Manager>Steven King</Manager>
<Commission/>
</Employee>
<Employee employeeNumber="102">
<FirstName>Lex</FirstName>
<LastName>De Haan</LastName>
<EmailAddress>LDEHAAN</EmailAddress>
<PHONE_NUMBER>515.123.4569</PHONE_NUMBER>
<StartDate>2001-01-13</StartDate>
<JobTitle>Administration Vice President</JobTitle>
<Salary>17000</Salary>
<Manager>Steven King</Manager>
<Commission/>
</Employee>
</EmployeeList>
</Department>

1 row selected.

次の実行計画の出力に示すとおり、Oracle XML DBには、XMLExists式のXPath式の引数を、基礎となるリレーショナル表のSELECT文に正しくリライトする機能があります。

SELECT OBJECT_VALUE FROM department_xml
WHERE XMLExists('$p/Department[Name="Executive"]' PASSING OBJECT_VALUE AS "p");

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------
Plan hash value: 2414180351

----------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                   |     1 |    80 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE                |                   |     1 |   115 |            |          |
|*  2 |   HASH JOIN                    |                   |    10 |  1150 |     7  (15)| 00:00:01 |
|*  3 |    HASH JOIN                   |                   |    10 |   960 |     5  (20)| 00:00:01 |
|   4 |     TABLE ACCESS BY INDEX ROWID| EMPLOYEES         |    10 |   690 |     2   (0)| 00:00:01 |
|*  5 |      INDEX RANGE SCAN          | EMP_DEPARTMENT_IX |    10 |       |     1   (0)| 00:00:01 |
|   6 |     TABLE ACCESS FULL          | JOBS              |    19 |   513 |     2   (0)| 00:00:01 |
|   7 |    TABLE ACCESS FULL           | EMPLOYEES         |   107 |  2033 |     2   (0)| 00:00:01 |
|   8 |  NESTED LOOPS                  |                   |     1 |    80 |     3   (0)| 00:00:01 |
|   9 |   NESTED LOOPS                 |                   |     1 |    68 |     3   (0)| 00:00:01 |
|* 10 |    TABLE ACCESS FULL           | DEPARTMENTS       |     1 |    19 |     2   (0)| 00:00:01 |
|  11 |    TABLE ACCESS BY INDEX ROWID | LOCATIONS         |     1 |    49 |     1   (0)| 00:00:01 |
|* 12 |     INDEX UNIQUE SCAN          | LOC_ID_PK         |     1 |       |     0   (0)| 00:00:01 |
|* 13 |   INDEX UNIQUE SCAN            | COUNTRY_C_ID_PK   |     1 |    12 |     0   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("M"."EMPLOYEE_ID"="E"."MANAGER_ID")
3 - access("J"."JOB_ID"="E"."JOB_ID")
5 - access("E"."DEPARTMENT_ID"=:B1)
10 - filter("D"."DEPARTMENT_NAME"='Executive')
12 - access("D"."LOCATION_ID"="L"."LOCATION_ID")
13 - access("L"."COUNTRY_ID"="C"."COUNTRY_ID")

30 rows selected.

注意:
XMLTypeビューで操作するXML式でのXPathリライトは、XPath式で参照するノードが、SQL関数XMLAggを使用して作成された要素の子孫でない場合にのみサポートされます。

DBURITYPEを使用した、リレーショナル・データからのXMLデータの生成

SQL関数DBURITypeを使用して、リレーショナル・データからXMLを生成することもできます。関数DBURITypeは、指定された表またはビューの1つ以上の行を単一のXML文書として公開します。ルート要素の名前は、表またはビューの名前から導出されます。ルート要素には、一連のROW要素が含まれます。表またはビュー内の行ごとにROW要素が1つずつあります。各ROW要素の子は、表またはビューの列から導出されます。各子要素には、指定された行の列の値を持つテキスト・ノードが含まれます。

例3-44に、SQL関数DBURITypeを使用して、データベース・スキーマHRの表departmentsのコンテンツにアクセスする方法を示します。メソッドgetXML()を使用して結果の文書をXMLTypeインスタンスとして戻します。

例3-44 DBURITypeおよびgetXML()を使用したリレーショナル表からのXMLデータの生成

SELECT DBURIType('/HR/DEPARTMENTS').getXML() FROM DUAL;

DBURITYPE('/HR/DEPARTMENTS').GETXML()
------------------------------------------------------
<?xml version="1.0"?>
<DEPARTMENTS>
<ROW>
<DEPARTMENT_ID>10</DEPARTMENT_ID>
<DEPARTMENT_NAME>Administration</DEPARTMENT_NAME>
<MANAGER_ID>200</MANAGER_ID>
<LOCATION_ID>1700</LOCATION_ID>
</ROW>
...
<ROW>
<DEPARTMENT_ID>20</DEPARTMENT_ID>
<DEPARTMENT_NAME>Marketing</DEPARTMENT_NAME>
<MANAGER_ID>201</MANAGER_ID>
<LOCATION_ID>1800</LOCATION_ID>
</ROW>
</DEPARTMENTS>

例3-45では、XPath述語を使用して、DBURITypeによって生成されるXML文書に含める行を制限する方法を示します。この例のXPath式によって、値が10のDEPARTMENT_ID列のみにXML文書が制限されます。

例3-45 XPath述語を使用した行の制限

SELECT DBURIType('/HR/DEPARTMENTS/ROW[DEPARTMENT_ID="10"]').getXML()
FROM DUAL;

DBURITYPE('/HR/DEPARTMENTS/ROW[DEPARTMENT_ID="10"]').GETXML()
------------------------------------------------------------------
<?xml version="1.0"?>
<ROW>
<DEPARTMENT_ID>10</DEPARTMENT_ID>
<DEPARTMENT_NAME>Administration</DEPARTMENT_NAME>
<MANAGER_ID>200</MANAGER_ID>
<LOCATION_ID>1700</LOCATION_ID>
</ROW>

1 row selected.

SQL関数DBURITypeを使用すると、リレーショナル表の一部または全部の行を1つ以上のXML文書として簡単に公開できます。関数DBURITypeに渡されるURLを拡張してビューまたは表から単一列を戻すことができますが、その場合、URLには、ターゲットの表またはビューの単一行を識別する述語も含まれる必要があります。

例3-46に、これを示します。述語[DEPARTMENT_ID="10"]句は、department_id列に値10が含まれるdepartments行について、department_name列の値を問合せで戻します。

例3-46 XPath述語を使用した行と列の制限

SELECT DBURIType(
'/HR/DEPARTMENTS/ROW[DEPARTMENT_ID="10"]/DEPARTMENT_NAME').getXML()
FROM DUAL;

DBURITYPE('/HR/DEPARTMENTS/ROW[DEPARTMENT_ID="10"]/DEPARTMENT_NAME').GETXML()
-----------------------------------------------------------------------------
<?xml version="1.0"?>
<DEPARTMENT_NAME>Administration</DEPARTMENT_NAME>

1 row selected.

SQL関数DBURITypeは、次の点でSQL/XML関数よりも柔軟性が低くなっています。

- DBURITypeでは、生成された文書の形式を制御できません。

- データは、単一の表またはビューからのみ生成できます。

- 生成される文書は、1つ以上のROW要素で構成されます。各ROW要素には、ターゲット表の列ごとの子が含まれます。

- 子要素の名前は、列の名前から導出されます。

XML要素の名前を制御する場合、複数の表からの列を含める場合、または生成される文書に含める表の列を制御する場合は、必要な列を単一行として公開するリレーショナル・ビューを作成してから、関数DBURITypeを使用して、そのビューのコンテンツからXML文書を生成します。

XSL変換とOracle XML DB

W3CのXSLT勧告は、XML文書の形式を別の形式に変換する方法を指定するためのXML言語を定義します。変換には、1つのXML Schemaから別のXML Schemaへのマッピング、またはXMLからHTMLやWMLなどの他の形式へのマッピングが含まれる場合があります。

関連項目:
XSLT標準の詳細は、http://www.w3.org/XML/Schemaを参照してください。

XSL変換は、通常、必要なメモリー量および処理量の面からコストがかかります。文書の様々な部分へのランダムなアクセスが可能になるように、ソース・ドキュメントとスタイルシートの両方を解析してメモリー構造にロードする必要があります。ほとんどのXSLプロセッサは、DOMを使用して両方の文書の動的メモリー表現を提供します。次に、XSLプロセッサは、スタイルシートをソース・ドキュメントに適用して、3番目の文書を生成します。

Oracle XML DBには、XSL変換をデータベース内で実行できるXSLTプロセッサが含まれています。この方法では、Oracle XML DBで、変換の実行に必要なメモリーを大幅に削減する、XML特有のメモリー最適化を提供できます。さらに、文書の解析に関連するオーバーヘッドも削減できます。ただし、これらの最適化は、変換対象のソースがスキーマに基づくXML文書である場合にのみ使用できます。

Oracle XMLでは、次の3つの方法でXSLプロセッサを起動できます。

- SQL関数XMLtransform

- XMLTypeメソッドtransform()

- PL/SQLパッケージDBMS_XSLPROCESSOR

これらの各XML変換方法では、ソースXML文書およびXSLスタイルシートを、XMLTypeインスタンスの形式で入力として受け取ります。SQL関数XMLtransformおよびXMLTypeメソッドtransform()では、変換の結果としてXML文書または非XML文書(HTMLなど)が発生します。しかし、PL/SQLパッケージDBMS_XSLPROCESSORでは、変換の結果は有効なXML文書であることが求められます。パッケージDBMS_XSLPROCESSORを使用した変換によって生成されるHTMLは、XHTML(つまり、有効なXMLと有効なHTML)である必要があります。

例3-47は、XSLTスタイルシートPurchaseOrder.xslの一部を示しています。完全なスタイルシートは、「XSLスタイルシートの例: PurchaseOrder.xsl」に記載されています。

例3-47 XSLTスタイルシートの例: PurchaseOrder.xsl

<?xml version="1.0" encoding="WINDOWS-1252"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xdb="http://xmlns.oracle.com/xdb"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:template match="/">
<html>
<head/>
<body bgcolor="#003333" text="#FFFFCC" link="#FFCC00" vlink="#66CC99" alink="#669999">
<FONT FACE="Arial, Helvetica, sans-serif">
<xsl:for-each select="PurchaseOrder"/>
<xsl:for-each select="PurchaseOrder">
<center>
<span style="font-family:Arial; font-weight:bold">
<FONT COLOR="#FF0000">
<B>PurchaseOrder </B>
</FONT>
</span>
</center>
<br/>
<center>
<xsl:for-each select="Reference">
<span style="font-family:Arial; font-weight:bold">
<xsl:apply-templates/>
</span>
</xsl:for-each>
</center>
</xsl:for-each>
<P>
<xsl:for-each select="PurchaseOrder">
<br/>
</xsl:for-each>
<P/>
<P>
<xsl:for-each select="PurchaseOrder">
<br/>
</xsl:for-each>
</P>
</P>
<xsl:for-each select="PurchaseOrder"/>
<xsl:for-each select="PurchaseOrder">
<table border="0" width="100%" BGCOLOR="#000000">
<tbody>
<tr>
<td WIDTH="296">
<P>
<B>
<FONT SIZE="+1" COLOR="#FF0000" FACE="Arial, Helvetica, sans-serif">Internal</FONT>
</B>
</P>

...

</td>
<td width="93"/>
<td valign="top" WIDTH="340">
<B>
<FONT COLOR="#FF0000">
<FONT SIZE="+1">Ship To</FONT>
</FONT>
</B>
<xsl:for-each select="ShippingInstructions">
<xsl:if test="position()=1"/>
</xsl:for-each>
<xsl:for-each select="ShippingInstructions">
</xsl:for-each>

...

例3-47のスタイルシートに関して、Oracle XML DB固有のものはありません。スタイルシートは、XMLType表または列に格納でき、Oracle XML DBリポジトリ内にXML Schemaに基づかないXMLデータとしても格納できます。

変換をデータベース内部で実行することによって、Oracle XML DBでは、メモリー使用量、I/O操作およびネットワーク通信量などの機能を最適化できます。これらの最適化は、変換がソース文書内のノードの小さいサブセットで実行される場合に特に有効です。

従来のXSLプロセッサでは、XSL処理を開始する前に、ソース・ドキュメント全体を解析してメモリーにロードする必要があります。この処理には、多くのメモリーおよびプロセッサが必要です。この処理は、文書の小規模な部分を処理する場合にのみ非効率になります。

Oracle XML DBがスキーマに基づくXML文書でXSL変換を実行する場合、処理の開始前に文書を解析する必要はありません。遅延ロードされた仮想DOMの場合は、ノードへのアクセス時にコンテンツをディスクから直接ロードするため、文書の解析が不要になります。また、遅延ロードでは、文書の処理対象部分のみがメモリーにロードされるため、変換の実行に必要なメモリーの量も削減されます。

例3-48では、SQL関数XMLtransformを使用して、XMLType表に格納された文書にXSLスタイルシートを適用し、HTMLコードを生成する方法を示します。SQL関数XDBURITypeは、XSLスタイルシートをOracle XML DBリポジトリから読み取ります。

簡略にするため、例3-48では変換結果の一部のみを示しています。省略した部分は、省略記号(. . .)で示しています。図3-7に、変換された結果がWebブラウザでどのように表示されるかを示します。

例3-48 TRANSFORMを使用したスタイルシートの適用

SELECT
XMLtransform(
OBJECT_VALUE,
XDBURIType('/source/schemas/poSource/xsl/purchaseOrder.xsl').getXML())
FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

XMLTRANSFORM(OBJECT_VALUE, XDBURITYPE('/SOURCE/SCHEMAS/POSOURCE/XSL/PURCHASEORDER.XSL').GET
---------------------------------------------------------------------------------------------
<html xmlns:xdb="http://xmlns.oracle.com/xdb"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<head/>
<body bgcolor="#003333" text="#FFFFCC" link="#FFCC00" vlink="#66CC99" alink="#669999">
<FONT FACE="Arial, Helvetica, sans-serif">
<center>
<span style="font-family:Arial; font-weight:bold">
<FONT COLOR="#FF0000">
<B>PurchaseOrder </B>
</FONT>
</span>
</center>
<br/>
<center>
<span style="font-family:Arial; font-weight:bold">SBELL-2002100912333601PDT</span>
</center>
<P>
<br/>
<P/>
<P>
<br/>
</P>
</P>
<table border="0" width="100%" BGCOLOR="#000000">
<tbody>
<tr>
<td WIDTH="296">
<P>
<B>
<FONT SIZE="+1" COLOR="#FF0000" FACE="Arial, Helvetica,
sans-serif">Internal</FONT>
</B>
</P>
<table border="0" width="98%" BGCOLOR="#000099">
. . .
</table>
</td>
<td width="93">
</td>
<td valign="top" WIDTH="340">
<B>
<FONT COLOR="#FF0000">
<FONT SIZE="+1">Ship To</FONT>
</FONT>
</B>
<table border="0" BGCOLOR="#999900">
. . .
</table>
</td>
</tr>
</tbody>
</table>
<br/>
<B>
<FONT COLOR="#FF0000" SIZE="+1">Items:</FONT>
</B>
<br/>
<br/>
<table border="0">
. . .
</table>
</FONT>
</body>
</html>

1 row selected.

関連項目:
第11章「XMLTypeデータの変換および検証」

Oracle XML DBリポジトリの使用

Oracle XML DBリポジトリを使用すると、XMLコンテンツをファイル/フォルダ隠喩を使用して編成できます。これによって、URLを使用して、データベースに格納されたXML文書を一意に識別できます。これまでURLやXPath式などの構造体を使用してコンテンツを識別してきたXML開発者は、この方法の使用を検討できます。

Oracle XML DBリポジトリは、DAV標準に基づいてモデル化されています。DAV標準では、WebDAVサーバーで管理されるファイルやフォルダを示すためにリソースという用語が使用されます。リソースは、メタデータとコンテンツの組合せで構成されます。DAV仕様には、リソースごとにWebDAVサーバーが管理する一連の(システム定義の)メタデータ・プロパティ、およびDAVサーバーやDAV対応クライアントでメタデータを交換するために使用する一連のXML文書が定義されています。

Oracle XML DBリポジトリでは、あらゆる種類のコンテンツを管理できますが、コンテンツがXMLであるリソースを管理するための特別な機能と最適化機能が用意されています。

Oracle XML DBリポジトリのインストールおよび削除

Oracle XML DBリポジトリで管理されるすべてのメタデータおよびコンテンツは、一連の表を使用して、データベース・スキーマ(ユーザー・アカウント)XDBが所有するデータベース・スキーマに格納されます。ユーザーXDBはロックされたアカウントで、DBCAを使用するか、またはスクリプトcatqm.sqlを実行してインストールされます。スクリプトcatqm.sqlは、ディレクトリORACLE_HOME/rdbms/adminにあります。リポジトリは、DBCAを使用するか、またはスクリプトcatnoqm.sqlを実行して削除できます。catnoqm.sqlを実行すると、Oracle XML DBリポジトリに格納されたすべてのコンテンツが削除され、登録済のXML Schemaに関連するXMLType表または列が無効になるため、このスクリプトを実行するときは十分な注意が必要です。

関連項目:
データベース・スキーマXDBの詳細は、『Oracle Database 2日でセキュリティ・ガイド』を参照してください。

Oracle XML DBで提供される名前レベル・ロック

リレーショナル・データベースを使用して階層フォルダ構造を保持する場合、フォルダに対して項目を追加または削除するときに高度な同時実行性を保証することは重要な問題です。従来のファイル・システムでは、トランザクションの概念はありません。各操作(ファイルの追加、サブフォルダの作成、ファイル名の変更、ファイルの削除など)は、基本トランザクションとして処理されます。操作が完了すると、ファイル・システムのすべてのユーザーに対して変更がすぐに反映されます。

注意:
データベースによって適用されるトランザクション・セマンティクスの結果として、SQL文を使用して作成されたフォルダは、トランザクションがコミットされるまで他のデータベース・ユーザーから参照されません。Oracle XML DBリポジトリへの同時アクセスは、Oracle Databaseの同時実行性の制御に使用されるのと同じメカニズムを使用して制御されます。リポジトリのOracle Databaseとの統合により、XMLコンテンツに対する強力な管理オプションが提供されます。

Oracle XML DBリポジトリの主要なメリットの1つは、論理トランザクションでのリポジトリ操作でSQLを使用できることです。アプリケーションでは、1つ以上のフォルダを更新する操作が含まれた、長時間実行するトランザクションを作成できます。この場合、更新されたフォルダまたはディレクトリ・ツリーに排他ロックを設定する従来のロック方針では、同時実行性に関する重大な問題がすぐに発生します。

Oracle XML DBでは、フォルダ・レベル・ロックではなく名前レベル・ロックを提供して、これを解決します。サブフォルダまたはファイルの作成、名前の変更、移動、削除などのリポジトリ操作では、ターゲット・フォルダに対する排他書込みロックの付与は必要はありません。リポジトリは、フォルダ自体ではなくフォルダ内の名前をロックして、フォルダに対する同時操作を管理します。名前および変更タイプは、キューに入れられます。

トランザクションがコミットされた場合にのみ、フォルダがロックされてそのコンテンツが変更されます。したがって、Oracle XML DBでは、1つのフォルダのコンテンツに対して複数のアプリケーションが同時に更新を実行できます。また、キューを使用すると、2つのアプリケーションによる同じ名前のオブジェクトの作成を回避できるため、フォルダの同時実行性を管理できます。

同じトランザクションで1つのフォルダに対して複数の変更が行われる場合は、コミット時までフォルダの変更をキューに入れて、I/Oを最小限にすることもできます。

これは、短時間の間に複数のアプリケーションが同じディレクトリ内にファイルを生成する場合に役立ちます。たとえば、トレース・ファイルやログ・ファイルを生成する場合、印刷または電子メール配信用にスプール・ディレクトリを保持する場合などです。

プロトコルまたはSQLを使用した、リポジトリのコンテンツへのアクセスおよび処理

Oracle XML DBリポジトリに格納されたコンテンツは、次の方法で操作できます。

- HTTP(S)、WebDAV、FTPなどの業界標準のプロトコルを使用して、挿入、更新、削除など文書レベルの操作を実行します。

- SQLを使用して、表レベルまたは行レベルでOracle XML DBリポジトリに直接アクセスします。

- Oracle XML DB Content Connectorを使用します(第31章「Oracle XML DB Content Connectorの使用」を参照)。

標準プロトコルを使用したデータベース・コンテンツの格納と取出し

Oracle XML DBは、HTTP(S)、WebDAV、FTPなどの業界標準のインターネット・プロトコルをサポートしています。プロトコルのサポートとURLベースのアクセスを組み合せることによって、Windows Explorer、Microsoft Word、XMLSpyなどの標準的なデスクトップ・アプリケーションから、Oracle Databaseに格納されたコンテンツに対して挿入、取出し、更新および削除を行うことができます。

図3-4に、Windows Explorerを使用して、フォルダをローカル・ハード・ドライブからOracle Databaseに挿入する操作を示します。Windows Explorerは、WebDAVプロトコルをサポートしています。WebDAVはHTTP標準の拡張で、HTTPサーバーがファイル・サーバーとして機能できる動詞が追加されています。

Windows Explorerのコピー操作やFTPの入力コマンドを使用して、多数の文書をOracle XML DBリポジトリに転送する場合、それぞれのputまたはpostコマンドは、個別の基本操作として扱われます。これにより、ファイル転送のうちのいずれかが失敗してもクライアントに混乱が生じません。また、プロトコルを介して文書に加えられた変更は、リクエストが処理されるとすぐに、他のユーザーも参照できます。

図3-4 Oracle XML DBリポジトリへのファイルのコピー

FTPを使用したOracle XML DBへのコンテンツのアップロード

例3-49では、標準のコマンドラインFTPツールで文書をOracle XML DBリポジトリにロードするときに発行されるコマンドと、生成された出力を示します。

例3-49 FTPを使用したリポジトリへのコンテンツのアップロード

$ ftp mdrake-sun 2100
Connected to mdrake-sun.
220 mdrake-sun FTP Server (Oracle XML DB/Oracle Database 10g Enterprise Edition
Release 10.1.0.1.0 - Beta) ready.
Name (mdrake-sun:oracle10): QUINE
331 Password required for QUINE
Password: password
230 QUINE logged in
ftp> cd /source/schemas
250 CWD Command successful
ftp> mkdir PurchaseOrders
257 MKD Command successful
ftp> cd PurchaseOrders
250 CWD Command successful
ftp> mkdir 2002
257 MKD Command successful
ftp> cd 2002
250 CWD Command successful
ftp> mkdir "Apr"
257 MKD Command successful
ftp> put "Apr/AMCEWEN-20021009123336171PDT.xml"
"Apr/AMCEWEN-20021009123336171PDT.xml"
200 PORT Command successful
150 ASCII Data Connection
226 ASCII Transfer Complete
local: Apr/AMCEWEN-20021009123336171PDT.xml remote:
Apr/AMCEWEN-20021009123336171PDT.xml
4718 bytes sent in 0.0017 seconds (2683.41 Kbytes/s)
ftp> put "Apr/AMCEWEN-20021009123336271PDT.xml"
"Apr/AMCEWEN-20021009123336271PDT.xml"
200 PORT Command successful
150 ASCII Data Connection
226 ASCII Transfer Complete
local: Apr/AMCEWEN-20021009123336271PDT.xml remote:
Apr/AMCEWEN-20021009123336271PDT.xml
4800 bytes sent in 0.0014 seconds (3357.81 Kbytes/s)
.....
ftp> cd "Apr"
250 CWD Command successful
ftp> ls -l
200 PORT Command successful
150 ASCII Data Connection
-rw-r--r1 QUINE oracle 0 JUN 24 15:41 AMCEWEN-20021009123336171PDT.xml
-rw-r--r1 QUINE oracle 0 JUN 24 15:41 AMCEWEN-20021009123336271PDT.xml
-rw-r--r1 QUINE oracle 0 JUN 24 15:41 EABEL-20021009123336251PDT.xml
-rw-r--r1 QUINE oracle 0 JUN 24 15:41 PTUCKER-20021009123336191PDT.xml
-rw-r--r1 QUINE oracle 0 JUN 24 15:41 PTUCKER-20021009123336291PDT.xml
-rw-r--r1 QUINE oracle 0 JUN 24 15:41 SBELL-20021009123336231PDT.xml
-rw-r--r1 QUINE oracle 0 JUN 24 15:41 SBELL-20021009123336331PDT.xml
-rw-r--r1 QUINE oracle 0 JUN 24 15:41 SKING-20021009123336321PDT.xml
-rw-r--r1 QUINE oracle 0 JUN 24 15:41 SMCCAIN-20021009123336151PDT.xml
-rw-r--r1 QUINE oracle 0 JUN 24 15:41 SMCCAIN-20021009123336341PDT.xml
-rw-r--r1 QUINE oracle 0 JUN 24 15:41 VJONES-20021009123336301PDT.xml
226 ASCII Transfer Complete
remote: -l
959 bytes received in 0.0027 seconds (349.45 Kbytes/s)
ftp> cd ".."
250 CWD Command successful
....
ftp> quit
221 QUIT Goodbye.
$

図3-4および例3-49で示されている要点は、Windows ExplorerおよびFTPツールのいずれもがOracle XML DBの操作を認識していないことです。ツールおよびOracle XML DBの両方がオープン・インターネット・プロトコルをサポートしているため、最初から相互に使用できます。

WebDAVまたはFTPプロトコルを認識するツールを使用すると、Oracle XML DBリポジトリで管理されるコンテンツを作成できます。クライアントまたは中間層に追加のソフトウェアをインストールする必要はありません。

Windows ExplorerやFTPなどのツールを使用してフォルダのコンテンツを表示すると、そのフォルダに格納されたXML Schemaに基づくXML文書のサイズは0(ゼロ)バイトと表示されます。このように設計されているのは、次の2つの理由からです。

- 文書のどのサイズを表示する必要があるかが明確でありません。文書に関連するサイズには、文書を出力して生成されたCLOBインスタンスのサイズ、文書をデータベース内に永続的に保持するために使用するオブジェクトの格納に必要なバイト数などがあります。

- 選択された定義に関係なく、この情報を計算して保持するにはコストがかかります。

図3-5に、Internet ExplorerでURLおよびHTTPプロトコルを使用して、データベースに格納されたXML文書を表示する操作を示します。

図3-5 HTTPとURLを使用したパスベースのアクセス

プログラムを使用したOracle XML DBリポジトリへのアクセス

Oracle XML DBリポジトリは、SQLから直接アクセスして更新できます。そのため、SQLを使用してOracle Databaseと対話できるアプリケーションまたはプログラミング言語からも、リポジトリに格納されたコンテンツにアクセスして更新できます。Oracle XML DBには、プログラムによるリソースの作成、変更および削除を可能にするメソッドが備わったPL/SQLパッケージDBMS_XDBが含まれています。

例3-50に、PL/SQL関数DBMS_XDB.createResourceを使用して簡単なテキスト・ドキュメントのリソースを作成する方法を示します。

例3-50 CREATERESOURCEを使用したテキスト・ドキュメント・リソースの作成

DECLARE
res BOOLEAN;
BEGIN
res := DBMS_XDB.createResource('/home/QUINE/NurseryRhyme.txt',
bfilename('XMLDIR', 'tdadxdb-03-01.txt'),
nls_charset_id('AL32UTF8'));
END;
/

リポジトリ内のXMLコンテンツのアクセスおよび更新

この項では、Oracle XML DBリポジトリのコンテンツにアクセスして更新するための機能について説明します。

SQLを使用したXML文書へのアクセス

リポジトリに格納されたコンテンツには、SQLおよびPL/SQLからアクセスして更新できます。このリポジトリの構造は、複合したいくつかの方法で問い合せることができます。たとえば、/home/mystylesheetdir以外の場所にある、拡張子が.xslの文書の数を調べる問合せを発行できます。

また、パスベースのリポジトリ・アクセスとコンテンツ・ベースのアクセスを組み合せることもできます。たとえば、/home/purchaseOrders以外の場所にある、値がKINGのXPath /PurchaseOrder/User/text()で識別されるノードを持つ文書の数を問い合せることができます。

リポジトリを管理するためのすべてのメタデータは、データベース・スキーマ(ユーザー・アカウント)XDBが所有するデータベース・スキーマに格納されます。ユーザーXDBは、Oracle XML DBのインストール時に作成されます。このスキーマの主な表は、XDB$RESOURCEというXMLType表です。この表には、リポジトリ内のリソース(ファイルまたはフォルダ)ごとに1行ずつが含まれます。この表内の文書はリソース・ドキュメントと呼ばれます。Oracle XML DBのリソース・ドキュメントの構造を定義するXML Schemaは、URL http://xmlns.oracle.com/xdb/XDBResource.xsdに登録されています。

関連項目:
データベース・スキーマXDBの詳細は、『Oracle Database 2日でセキュリティ・ガイド』を参照してください。

RESOURCE_VIEWとPATH_VIEWを介して公開されるリポジトリのコンテンツ

表XDB$RESOURCEは、SQLプログラマに直接公開されていません。リポジトリのコンテンツは、2つのパブリック・ビュー(RESOURCE_VIEWおよびPATH_VIEW)を介して公開されます。リポジトリに格納された文書のメタデータおよびコンテンツはいずれも、これらのビューを介してアクセスして更新できます。いずれのビューにも仮想列RESが含まれます。パス表記法を使用したSQL文でドキュメントにアクセスして更新するには、RESを使用します。ビューに対する操作では、リポジトリ内の基礎となる表を使用します。

EXISTS_PATHとUNDER_PATHを使用した、WHERE句へのパスベースの述語の追加

Oracle XML DBには、リポジトリ固有のSQL関数としてexists_pathおよびunder_pathという2つの関数があります。これらの関数を使用して、パスベースの述語をSQL文のWHERE句に含めます。SQL操作では、リポジトリのフォルダ階層内におけるコンテンツの場所に基づいてリポジトリのコンテンツを選択できます。階層リポジトリ索引を使用すると、パスベースの問合せが効率的に実行されます。

XML Schemaに基づくXML文書をリポジトリに格納すると、文書のコンテンツはXML Schemaにより識別されるデフォルト表にオブジェクトとして格納されます。リポジトリには、文書に関するメタデータと、コンテンツを含むデフォルト表内の行を識別するポインタ(XMLTypeのREF)のみが含まれます。

リポジトリへの非XML文書の格納も可能

別の種類の文書をリポジトリに格納することも可能です。XMLでない、またはXML Schemaに基づかない文書をリポジトリに格納すると、文書のコンテンツは、文書のメタデータとともにLOBに格納されます。

フォルダと文書の作成、削除、名前変更、移動などを実行するためのPL/SQLパッケージ

Oracle XML DBリポジトリはSQLを使用してアクセスおよび更新できるため、PL/SQLプロシージャをコールできるアプリケーションはすべて、このリポジトリを使用できます。すべてのSQLおよびPL/SQLリポジトリ操作はトランザクション型です。リポジトリとそのコンテンツへのアクセスは、標準的なデータベース・セキュリティ制御とリポジトリのアクセス制御リスト(ACL)両方の対象となります。

提供されているPL/SQLパッケージDBMS_XDB、DBMS_XDBZおよびDBMS_XDB_VERSIONを使用すると、文書とフォルダの作成、削除および名前変更、フォルダ階層内でのファイルまたはフォルダの移動、ファイルまたはフォルダに対するアクセス権限の設定および変更、バージョニングの開始および管理を実行できます。

例3-51では、PL/SQLパッケージDBMS_XDBを使用して、フォルダ/publicの下位に一連のサブフォルダを作成します。

例3-51 PL/SQLパッケージDBMS_XDBを使用したフォルダの作成

DECLARE
RESULT BOOLEAN;
BEGIN
IF (NOT DBMS_XDB.existsResource('/public/mysource')) THEN
result := DBMS_XDB.createFolder('/public/mysource');
END IF;
IF (NOT DBMS_XDB.existsResource('/public/mysource/schemas')) THEN
result := DBMS_XDB.createFolder('/public/mysource/schemas');
END IF;
IF (NOT DBMS_XDB.existsResource('/public/mysource/schemas/poSource')) THEN
result := DBMS_XDB.createFolder('/public/mysource/schemas/poSource');
END IF;
IF (NOT DBMS_XDB.existsResource('/public/mysource/schemas/poSource/xsd')) THEN
result := DBMS_XDB.createFolder('/public/mysource/schemas/poSource/xsd');
END IF;
IF (NOT DBMS_XDB.existsResource('/public/mysource/schemas/poSource/xsl')) THEN
result := DBMS_XDB.createFolder('/public/mysource/schemas/poSource/xsl');
END IF;
END;
/

SQLを使用した文書のコンテンツへのアクセス

Oracle XML DBリポジトリに格納された文書のコンテンツには、いくつかの方法でアクセスできます。最も簡単な方法は、XDBURITypeを使用することです。XDBURITypeでは、URLを使用して、アクセスするリソースを指定します。XDBURITypeに渡されるURLは、リポジトリのルートから始まると想定されます。データ型XDBURITypeには、リソースに関連付けることのできる様々な種類のコンテンツにアクセスするためのメソッドgetBLOB()、getCLOB()およびgetXML()が用意されています。

例3-52では、XDBURITypeを使用してテキスト・ドキュメントのコンテンツにアクセスする方法を示します。

例3-52 XDBURITYPEを使用したリポジトリ内のテキスト・ドキュメントへのアクセス

SELECT XDBURIType('/home/QUINE/NurseryRhyme.txt').getCLOB() FROM DUAL;

XDBURITYPE('/HOME/QUINE/NURSERYRHYME.TXT').GETCLOB()
----------------------------------------------------
Mary had a little lamb
Its fleece was white as snow
and everywhere that Mary went
that lamb was sure to go

1 row selected.

文書のコンテンツには、リソース・ドキュメントを使用してもアクセスできます。例3-53では、テキスト・ドキュメントのコンテンツにアクセスする方法を示します。

例3-53 RESOURCE_VIEWを使用したリソース・コンテンツへのアクセス

SELECT CONTENT
FROM RESOURCE_VIEW,
XMLTable(XMLNAMESPACES (default 'http://xmlns.oracle.com/xdb/XDBResource.xsd'),
'/Resource/Contents' PASSING RES
COLUMNS content CLOB PATH 'text')
WHERE equals_path(RES, '/home/QUINE/NurseryRhyme.txt') = 1;

CONTENT
-------
Mary had a little lamb
Its fleece was white as snow
and everywhere that Mary went
that lamb was sure to go

1 row selected.

XML Schemaに基づくXML文書とXML Schemaに基づかないXML文書のコンテンツにも、リソースを使用してアクセスできます。例3-54では、リソース・ドキュメントのノードとXML文書のノードが含まれたXPath式、およびリソースを使用して、PurchaseOrder文書のコンテンツにアクセスする方法を示します。

例3-54 リソースと名前空間接頭辞を使用したXML文書へのアクセス

SELECT des.description
FROM RESOURCE_VIEW rv,
XMLTable(XMLNAMESPACES ('http://xmlns.oracle.com/xdb/XDBResource.xsd' AS "r"),
'/r:Resource/r:Contents/PurchaseOrder/LineItems/LineItem'
PASSING rv.RES
COLUMNS description VARCHAR2(256) PATH 'Description') des
WHERE
equals_path(rv.RES, '/home/QUINE/PurchaseOrders/2002/Mar/SBELL-2002100912333601PDT.xml') = 1;

DES.DESCRIPTION
---------------------------------
A Night to Remember
The Unbearable Lightness Of Being
The Wizard of Oz

3 rows selected.

例3-54では、名前空間接頭辞rを使用し、リソースの名前空間のメンバーであるノードをXPath式から識別しています。名前空間接頭辞rは、SQL/XML関数XMLTableのXMLNAMESPACES句を使用して定義されます。発注書XML Schemaで名前空間が定義されておらず、名前空間接頭辞をPurchaseOrder文書のノードに適用できないため、ここでは名前空間の宣言が必要になります。

関連項目:
XMLTableのXMLNAMESPACES句の詳細は、第5章「Oracle XML DBでのXQueryの使用」を参照してください。

XML Schemaに基づく文書のコンテンツへのアクセス

XML Schemaに基づくXML文書のコンテンツにアクセスするには、次の2つの方法があります。

- XML Schemaに基づかないXML文書の場合と同様に、リソース・ドキュメントを使用してアクセスします。この方法では、RESOURCE_VIEWを使用して、XML Schemaに基づく様々な種類のXML文書を1つのSQL文で問い合せることができます。

- XML SchemaをOracle XML DBに登録したときに定義したデフォルト表の行としてアクセスします。

結合でXMLRef要素を使用した、リソース・コンテンツへのアクセス

リソース・ドキュメントのXMLRef要素は、SQL文で単一の操作の一部としてメタデータおよびコンテンツにアクセスまたは更新するときに必要な結合キーを提供します。

次の問合せでは、要素XMLRefの値に基づく結合を使用して、リソース・コンテンツにアクセスします。

例3-55では、Oracle XML DBリポジトリのパスに基づいて、defaultTableの行を検索します。SQL関数refは、リソース・ドキュメントRES内のXMLRef要素の値に基づいて、デフォルト表内のターゲットの行を検索します。

例3-55 SQL関数REFおよび要素XMLRefを使用した、リポジトリのリソース・データの問合せ

SELECT des.description
FROM RESOURCE_VIEW rv,
purchaseorder p,
XMLTable('$p/PurchaseOrder/LineItems/LineItem' PASSING p.OBJECT_VALUE AS "p"
COLUMNS description VARCHAR2(256) PATH 'Description') des
WHERE equals_path(rv.RES, '/home/QUINE/PurchaseOrders/2002/Mar/SBELL-2002100912333601PDT.xml')
= 1
AND ref(p) = XMLCast(XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
fn:data(/Resource/XMLRef)' PASSING rv.RES RETURNING CONTENT)
AS REF XMLType);

DES.DESCRIPTION
---------------------------------
A Night to Remember
The Unbearable Lightness Of Being
The Wizard of Oz

3 rows selected.

例3-56では、メタデータ、パスおよびコンテンツに基づいて、XML文書からフラグメントを選択する方法を示します。この問合せは、/home/QUINE/PurchaseOrders/2002/Marの下にあり、部品番号715515009058の発注が含まれる文書に対して、要素Referenceの値を戻します。

例3-56 メタデータ、パスおよびコンテンツに基づくXML文書のフラグメントの選択

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Reference'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30))
FROM RESOURCE_VIEW rv, purchaseorder po
WHERE under_path(rv.RES, '/home/QUINE/PurchaseOrders/2002/Mar') = 1
AND ref(po) = XMLCast(
XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
fn:data(/Resource/XMLRef)'
PASSING rv.RES RETURNING CONTENT)
AS REF XMLType)
AND XMLExists('$p/PurchaseOrder/LineItems/LineItem/Part[@Id="715515009058"]'
PASSING po.OBJECT_VALUE AS "p");

XMLCAST(XMLQUERY('$P/PURCHASEO
------------------------------
CJOHNSON-20021009123335851PDT
LSMITH-2002100912333661PDT
SBELL-2002100912333601PDT

3 rows selected.

通常、XML Schemaに基づくXML文書のコンテンツにアクセスするときは、RESOURCE_VIEWまたはPATH_VIEWを単独で使用するよりも、RESOURCE_VIEWまたはPATH_VIEWをデフォルト表と結合して使用した方が効率的です。リソース・ドキュメントとデフォルト表を明示的に結合することによって、Oracle XML DBは、SQL文が1種類のXML文書に対してのみ機能することを認識します。したがって、XPathのリライトを使用すれば、デフォルト表およびリソースに対する操作を最適化できます。

リポジトリに格納された文書のコンテンツの更新

Oracle XML DBリポジトリに格納された文書のコンテンツは、プロトコルまたはSQLを使用して更新できます。

プロトコルを使用したリポジトリのコンテンツの更新

最も一般的なコンテンツ作成ツールは、HTTP、FTPおよびWebDAVプロトコルをサポートしています。このようなコンテンツ作成ツールでは、URLおよびHTTP動詞getを使用して文書のコンテンツにアクセスし、HTTP動詞putを使用してその文書のコンテンツを保存できます。したがって、適切なアクセス権限が付与されている場合、Oracle XML DBリポジトリに格納されたコンテンツにアクセスして編集するには、URLのみが必要です。

図3-6に、Microsoft WordのWebDAVサポートを使用して、Oracle XML DBリポジトリに格納された文書をMicrosoft Wordで更新および編集する方法を示します。

図3-6 Microsoft Wordを使用した、Oracle XML DBに格納されたコンテンツの更新および編集

Microsoft Wordなどの編集アプリケーションを使用してOracle XML DBに格納されたXML文書を更新すると、データベースは、文書の新しいコンテンツを含む入力ストリームを受け取ります。ただし、Wordなどのアプリケーションでは、Oracle XML DBは文書がどのように変更されたかを識別できません。そのため、部分的な変更は不可能です。文書全体を再度解析し、元の文書から導出されたすべてのオブジェクトを、新しいコンテンツから導出されたオブジェクトに置き換える必要があります。

SQLを使用したリポジトリのコンテンツの更新

updateXMLなどのSQL関数を使用すると、Oracle XML DBリポジトリに格納された文書のコンテンツを更新できます。文書のコンテンツを変更するには、リソース・ドキュメントまたは文書のコンテンツを保持するデフォルト表を更新します。

例3-57では、リソース・ドキュメントでSQL UPDATE文およびSQL関数updateXMLを使用して、簡単なテキスト・ドキュメントのコンテンツを更新する方法を示します。XPath式が更新操作のターゲットとしてupdateXMLに渡され、要素/Resource/Contents/textに属するテキスト・ノードが識別されます。

例3-57 リソースでUPDATEとUPDATEXMLを使用したドキュメントの更新

DECLARE
file         BFILE;
contents     CLOB;
dest_offset  NUMBER := 1;
src_offset   NUMBER := 1;
lang_context NUMBER := 0;
conv_warning NUMBER := 0;
BEGIN
file := bfilename('XMLDIR', 'tdadxdb-03-02.txt');
DBMS_LOB.createTemporary(contents, true, DBMS_LOB.SESSION);
DBMS_LOB.fileopen(file, DBMS_LOB.file_readonly);
DBMS_LOB.loadClobfromFile(contents,
file,
DBMS_LOB.getLength(file),
dest_offset,
src_offset,
nls_charset_id('AL32UTF8'),
lang_context,
conv_warning);
DBMS_LOB.fileclose(file);
UPDATE RESOURCE_VIEW
SET res = updateXML(res,
'/Resource/Contents/text/text()',
contents,
'xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd"')
WHERE equals_path(res, '/home/QUINE/NurseryRhyme.txt') = 1;
DBMS_LOB.freeTemporary(contents);
END;
/

関連するリソースの更新によって文書のコンテンツを更新する方法のメリットは、Oracle XML DBリポジトリに格納されたあらゆる種類の文書を更新できることです。

例3-58では、リソース・ドキュメントで更新処理を実行することによって、XML文書のノードを更新する方法を示します。ここでは、SQL関数updateXMLによって、User要素に関連付けられたテキスト・ノードの値を変更します。

例3-58 UPDATEとUPDATEXMLを使用したノードの更新

UPDATE RESOURCE_VIEW
SET res = updateXML(res,
'/r:Resource/r:Contents/PurchaseOrder/User/text()',
'SKING',
'xmlns:r="http://xmlns.oracle.com/xdb/XDBResource.xsd"')
WHERE equals_path(
res,
'/home/QUINE/PurchaseOrders/2002/Mar/SBELL-2002100912333601PDT.xml')
= 1;

1 row updated.

SELECT XMLCast(XMLQuery(
'declare namespace ns="http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource/ns:Contents/PurchaseOrder/User/text()'
PASSING RES AS "r" RETURNING CONTENT)
AS VARCHAR2(32))
FROM RESOURCE_VIEW
WHERE equals_path(RES,
'/home/QUINE/PurchaseOrders/2002/Mar/SBELL-2002100912333601PDT.xml')
= 1;

XMLCAST(XMLQUERY('DECLARENAMESPA
--------------------------------
SKING

1 row selected.

リポジトリ内のXML Schemaに基づく文書の更新

文書のコンテンツを管理するために使用するデフォルト表に対して更新操作を直接実行することによって、XML Schemaに基づくXML文書を更新できます。メタデータに基づくパスまたは条件が含まれたWHERE句を使用して文書を配置する必要がある場合、UPDATE文では、リソースとデフォルト表間の結合を使用する必要があります。

一般に、XML Schemaに基づくXML文書のコンテンツを更新する場合は、RESOURCE_VIEWまたはPATH_VIEWを単独で使用するよりも、RESOURCE_VIEWまたはPATH_VIEWをデフォルト表と結合して使用するほうが効率的です。リソース・ドキュメントとデフォルト表を明示的に結合することによって、Oracle XML DBは、SQL文が1種類のXML文書に対してのみ機能することを認識します。これによって、デフォルト表およびリソースで部分更新を使用できます。

例3-59では、SQL関数updateXMLは、パスによって識別されるターゲットの行を使用してデフォルト表を操作します。更新される行は、REFによって識別されます。REFは、SQL関数equals_pathを使用して、リポジトリ・パスによって識別されます。これにより、更新対象は、指定されたパスで識別されるリソースに対応する行のみに制限されます。

例3-59 リポジトリ内のXML Schemaに基づく文書の更新

UPDATE purchaseorder p
SET p.OBJECT_VALUE = updateXML(p.OBJECT_VALUE, '/PurchaseOrder/User/text()', 'SBELL')
WHERE ref(p) =
(SELECT XMLCast(XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
fn:data(/Resource/XMLRef)' PASSING rv.RES RETURNING CONTENT)
AS REF XMLType)
FROM RESOURCE_VIEW rv
WHERE equals_path(rv.RES,
'/home/QUINE/PurchaseOrders/2002/Mar/SBELL-2002100912333601PDT.xml')
= 1);

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/User/text()'
PASSING p.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(32))
FROM purchaseorder p, RESOURCE_VIEW rv
WHERE ref(p) = XMLCast(XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
fn:data(/Resource/XMLRef)' PASSING rv.RES RETURNING CONTENT)
AS REF XMLType)
AND equals_path(rv.RES, '/home/QUINE/PurchaseOrders/2002/Mar/SBELL-2002100912333601PDT.xml')
= 1;

XMLCAST(XMLQUERY('$P/PURCHASEO
------------------------------
SBELL

リポジトリ・データへのアクセスの制御

アクセス制御リスト(ACL)を使用すると、Oracle XML DBリポジトリ内のリソースへのアクセスを制御できます。ACLはアクセス制御エントリ(ACE)のリストで、各エントリは、特定のプリンシパルへの一連の権限を付与または拒否します。プリンシパルとは、データベース・ユーザー、データベース・ロール、LDAPユーザー、LDAPグループ、またはリソースの所有者である特別なプリンシパルDAV::ownerです。リポジトリ内の各リソースは、ACLによって保護されます。ACLによって、ユーザーがリソースに対して持つ権限(read-propertiesやupdateなど)が決まります。各リポジトリ操作には、現行ユーザーがその操作の実行を許可されているかどうかを判断するために、ACLの確認が含まれています。デフォルトでは、新規のリソースはその親フォルダのACLを継承します。ただし、PL/SQLプロシージャDBMS_XDB.setACLを使用してリソースのACLを設定することもできます。Oracle XML DBのリソースのセキュリティの詳細は、第27章「リポジトリのアクセス制御」を参照してください。

次の例で、現行ユーザーはQUINEです。問合せでは、フォルダ/publicのリソースの数が戻されます。このフォルダには、f1とf2の2つのリソースのみが存在すると想定します。また、f1のACLではread-properties権限がQUINEに付与されますが、f2のACLではQUINEに付与される権限はないと想定します。ユーザーがリソースを参照するには、そのリソースに対するread-properties権限が必要です。QUINEはf1のみ参照できるため、問合せの結果は1です。

SELECT count(*) FROM RESOURCE_VIEW r WHERE under_path(r.res, '/public') = 1;

COUNT(*)
--------
1

Oracle XML DBのトランザクション・セマンティクス

SQLを使用して作業をしている場合は、通常のトランザクション動作が適用されます。1つの論理作業単位内では、updateXMLなどのSQL関数のコールを複数回使用できます。updateXMLなどの関数を使用して実行された変更は、トランザクションがコミットされるまで他のデータベース・ユーザーから参照されません。任意の時点でROLLBACKを使用して、前回のコミット以降に行われた一連の変更をバック・アウトできます。

メタデータとフォルダ階層の問合せ

Oracle XML DBには、各リソースのシステム定義のメタデータがXML文書として保持されています。これらのリソース・ドキュメントの構造は、XML Schema XDBResource.xsdによって定義されます。このスキーマは、グローバルXML SchemaとしてURL http://xmlns.oracle.com/xdb/XDBResource.xsdに登録されています。

Oracle XML DBを使用すると、2つのパブリック・ビュー(RESOURCE_VIEWおよびPATH_VIEW)を使用して、メタデータおよびフォルダ階層に関する情報にアクセスできます。

RESOURCE_VIEWおよびPATH_VIEW

RESOURCE_VIEWには、Oracle XML DBリポジトリに格納されたファイルまたはフォルダごとに1つのエントリが含まれています。RESOURCE_VIEWの列RESにはリソース(リソースのコンテンツに関連付けられたメタデータ・プロパティを管理するXML文書)が含まれます。列ANY_PATHには、リソースのコンテンツにアクセスするために現行ユーザーがXDBURITypeに渡すことができる有効なURLが含まれます。このコンテンツがバイナリ・データでない場合、リソースそのものにもコンテンツが含まれます。

Oracle XML DBは、リンクの概念をサポートしています。リンクによって、指定した文書への複数のパスを定義できます。リンク・プロパティ文書と呼ばれる各XML文書では、(リソース固有ではなく)パス固有のメタデータ・プロパティが保持されます。リソースが作成されるたびに、最初のリンクも作成されます。

PATH_VIEWは、リンク・プロパティ文書を公開します。PATH_VIEWには、文書に対してアクセス可能なパスごとに1つのエントリがあります。PATH_VIEWの列RESには、このリンクの参照先のリソース・ドキュメントが含まれます。列PATHには、リンクがリソースへのアクセスに使用できるパスが含まれます。列LINKには、このPATHのリンク・プロパティ文書(メタデータ)が含まれます。

例3-60では、パブリック・ビューRESOURCE_VIEWおよびPATH_VIEWの内容を示します。

例3-60 RESOURCE_VIEWおよびPATH_VIEWの構造の表示

DESCRIBE RESOURCE_VIEW

Name      Null?    Type
-------------------------------------------------------------
RES                SYS.XMLTYPE(XMLSchema
"http://xmlns.oracle.com/xdb/XDBResource.xsd"
Element
"Resource")
ANY_PATH           VARCHAR2(4000)
RESID              RAW(16)

DESCRIBE PATH_VIEW

Name      Null?    Type
-------------------------------------------------------------
PATH               VARCHAR2(1024)
RES                SYS.XMLTYPE(XMLSchema
"http://xmlns.oracle.com/xdb/XDBResource.xsd"
Element
"Resource")
LINK               SYS.XMLTYPE
RESID              RAW(16)

関連項目:

- 第25章「RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス」

- ビューPATH_VIEWの詳細は、『Oracle Databaseリファレンス』を参照してください。

- ビューRESOURCE_VIEWの詳細は、『Oracle Databaseリファレンス』を参照してください。

RESOURCE_VIEWおよびPATH_VIEW内のリソースの問合せ

Oracle XML DBには、フォルダ限定の問合せを実行するために使用するSQL関数として、equals_pathおよびunder_pathの2つが用意されています。このような問合せは、RESOURCE_VIEWまたはPATH_VIEWを操作するSQL文を、Oracle XML DBのフォルダ階層内の特定の場所にある文書に制限します。関数equals_pathは、SQL文を、指定したパスで識別される単一の文書に制限します。関数under_pathは、SQL文を、階層内の特定の場所より下位に存在する文書に制限します。

次の各例に、RESOURCE_VIEWおよびPATH_VIEWに格納されたリソース・ドキュメントに対する簡単なフォルダ限定の問合せを示します。

例3-61の問合せは、SQL関数equals_pathおよびRESOURCE_VIEWを使用して、例3-60で作成したリソースにアクセスします。

例3-61 EQUALS_PATHおよびRESOURCE_VIEWを使用したリソースへのアクセス

SELECT XMLSerialize(DOCUMENT r.res AS CLOB)
FROM RESOURCE_VIEW r
WHERE equals_path(res, '/home/QUINE/NurseryRhyme.txt') = 1;

XMLSERIALIZE(DOCUMENTR.RESASCLOB)
--------------------------------------------------------------------------------
<Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd"
Hidden="false"
Invalid="false"
Container="false"
CustomRslv="false"
VersionHistory="false"
StickyRef="true">
<CreationDate>2005-06-13T13:19:20.566623</CreationDate>
<ModificationDate>2005-06-13T13:19:22.997831</ModificationDate>
<DisplayName>NurseryRhyme.txt</DisplayName>
<Language>en-US</Language>
<CharacterSet>UTF-8</CharacterSet>
<ContentType>text/plain</ContentType>
<RefCount>1</RefCount>
<ACL>
<acl description=
"Private:All privileges to OWNER only and not accessible to others"
xmlns="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:dav="DAV:"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd"
shared="true">
<ace>
<grant>true</grant>
<principal>dav:owner</principal>
<privilege>
<all/>
</privilege>
</ace>
</acl>
</ACL>
<Owner>QUINE</Owner>
<Creator>QUINE</Creator>
<LastModifier>QUINE</LastModifier>
<SchemaElement>http://xmlns.oracle.com/xdb/XDBSchema.xsd#text</SchemaElement>
<Contents>
<text>Hickory Dickory Dock
The Mouse ran up the clock
The clock struck one
The Mouse ran down
Hickory Dickory Dock
</text>
</Contents>
</Resource>

1 row selected.

例3-61に示すように、リソース・ドキュメントは、DAV標準で定義された一連のメタデータを取得するXML文書です。メタデータには、CreationDate、Creator、Owner、ModificationDate、DisplayNameなどの情報が含まれています。リソース・ドキュメントのコンテンツは、SQL/XMLアクセスおよび問合せ関数を使用して、他のXML文書と同様の方法で問合せおよび更新ができます。

例3-62の問合せにより、Oracle XML DBリポジトリに格納された各XSLスタイルシートへのパスを検索します。これは.xslで終わるDisplayNameの検索を実行します。

例3-62 リポジトリに格納されたXSLスタイルシートへのパスの判別

SELECT ANY_PATH FROM RESOURCE_VIEW
WHERE XMLCast(XMLQuery(
'declare namespace ns="http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource/ns:DisplayName'
PASSING RES AS "r" RETURNING CONTENT)
AS VARCHAR2(100))
LIKE '%.xsl';

ANY_PATH
-------------------------------------------
/source/schemas/poSource/xsl/empdept.xsl
/source/schemas/poSource/xsl/purchaseOrder.xsl

2 rows selected.

例3-63の問合せでは、パス/home/QUINE/PurchaseOrdersの下に存在するリソース(ファイルおよびフォルダ)の数をカウントします。PATH_VIEWではなくRESOURCE_VIEWを使用すると、複数リンクのターゲットであるリソースは1回のみカウントされます。SQL関数under_pathを使用すると、結果セットは、/home/QUINE/PurchaseOrdersで始まるパスを使用してアクセス可能な文書に制限されます。

例3-63 パスの下に存在するリソースのカウント

SELECT count(*)
FROM RESOURCE_VIEW
WHERE under_path(RES, '/home/QUINE/PurchaseOrders') = 1;

COUNT(*)
----------
145

1 row selected.

例3-64の問合せは、パス/home/QUINE/PurchaseOrders/2002/Aprで識別されるフォルダのコンテンツをリストします。この問合せによって、フォルダ内のディレクトリのリストを効率的に作成できます。

例3-64 パス内のフォルダのコンテンツのリスト

SELECT PATH
FROM PATH_VIEW
WHERE under_path(RES, '/home/QUINE/PurchaseOrders/2002/Apr') = 1;

PATH
----------------------------------------------------------------------
/home/QUINE/PurchaseOrders/2002/Apr/AMCEWEN-20021009123336171PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/AMCEWEN-20021009123336271PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/EABEL-20021009123336251PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/PTUCKER-20021009123336191PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/PTUCKER-20021009123336291PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/SBELL-20021009123336231PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/SBELL-20021009123336331PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/SKING-20021009123336321PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/SMCCAIN-20021009123336151PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/SMCCAIN-20021009123336341PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/VJONES-20021009123336301PDT.xml

11 rows selected.

例3-65の問合せは、パス/home/QUINE/PurchaseOrders/2002/Aprで識別されるフォルダに含まれる、関連するリソースのDisplayName要素がSで始まる一連のリンクをリストします。

例3-65 フォルダに含まれているリンクのリスト

SELECT PATH
FROM PATH_VIEW
WHERE XMLCast(XMLQuery(
'declare namespace ns="http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource/ns:DisplayName'
PASSING RES AS "r" RETURNING CONTENT)
AS VARCHAR2(100))
LIKE 'S%'
AND under_path(RES, '/home/QUINE/PurchaseOrders/2002/Apr') = 1;

PATH
----------------------------------------------------------------------
/home/QUINE/PurchaseOrders/2002/Apr/SBELL-20021009123336231PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/SBELL-20021009123336331PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/SKING-20021009123336321PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/SMCCAIN-20021009123336151PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/SMCCAIN-20021009123336341PDT.xml

5 rows selected.

例3-66の問合せにより、PurchaseOrder文書を含む、Oracle XML DBリポジトリの各リソースへのパスを検索します。文書はXML Schema URLおよびリポジトリに格納されたスキーマに基づくXMLデータのグローバル要素を識別する、メタデータ・プロパティSchemaElementに基づき識別されます。

例3-66 発注書のXML文書が含まれたリソースへのパスの検索

SELECT ANY_PATH
FROM RESOURCE_VIEW
WHERE XMLExists(
'declare namespace ns="http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource[ns:SchemaElement=
"http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd#PurchaseOrder"]'
PASSING RES AS "r");

この問合せは次のパスを戻します。それぞれのパスにPurchaseOrder文書が含まれています。

ANY_PATH
-----------------------------------------------------------------------
/home/QUINE/PurchaseOrders/2002/Apr/AMCEWEN-20021009123336171PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/AMCEWEN-20021009123336271PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/EABEL-20021009123336251PDT.xml
/home/QUINE/PurchaseOrders/2002/Apr/PTUCKER-20021009123336191PDT.xml

...

132 rows selected.

Oracle XML DBの階層リポジトリ索引

従来のリレーショナル・データベースでは、パスベースのアクセスおよびフォルダ限定の問合せはCONNECT BY操作を使用して実装します。このような問合せはコストがかかるため、パスベースのアクセスおよびフォルダ限定の問合せは、文書の数やフォルダ階層の深さが増すにつれて効率が下がります。

この問題に対処するために、Oracle XML DBでは階層リポジトリ索引という新しい索引タイプが導入されました。これを使用すると、CONNECT BY操作を使用しなくても、データベースでフォルダ限定の問合せを解決できます。したがって、Oracle XML DBでは、パスベースおよびフォルダ限定の問合せを効率的に実行できます。階層リポジトリ索引は、Oracleのドメイン索引として実装されます。これは、Oracle Text索引のサポートおよび他の多数の高度な索引タイプをデータベースに追加する場合の方法と同じです。

例3-67では、フォルダ限定の問合せで生成された実行計画の出力を示します。次に示すように、階層リポジトリ索引(XDBHI_IDX)を使用して問合せを解決します。

例3-67 フォルダ限定の問合せの実行計画の出力

SELECT PATH
FROM PATH_VIEW
WHERE XMLCast(
XMLQuery(
'declare namespace ns="http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource/ns:DisplayName'
PASSING RES AS "r" RETURNING CONTENT)
AS VARCHAR2(100))
LIKE 'S%'
AND under_path(RES, '/home/QUINE/PurchaseOrders/2002/Apr') = 1;

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------
Plan hash value: 2568289845

------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |               |    17 |  3111 |    34   (6)| 00:00:01 |
|   1 |  NESTED LOOPS                        |               |    17 |  3111 |    34   (6)| 00:00:01 |
|   2 |   NESTED LOOPS                       |               |    17 |  2822 |    34   (6)| 00:00:01 |
|   3 |    NESTED LOOPS                      |               |   466 | 63842 |    34   (6)| 00:00:01 |
|*  4 |     TABLE ACCESS BY INDEX ROWID      | XDB$RESOURCE  |     1 |   135 |     3   (0)| 00:00:01 |
|*  5 |      DOMAIN INDEX                    | XDBHI_IDX     |       |       |            |          |
|   6 |     COLLECTION ITERATOR PICKLER FETCH|               |       |       |            |          |
|*  7 |    INDEX UNIQUE SCAN                 | XDB_PK_H_LINK |     1 |    28 |     0   (0)| 00:00:01 |
|*  8 |   INDEX UNIQUE SCAN                  | SYS_C003900   |     1 |    17 |     0   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

4 - filter(CAST("P"."SYS_NC00011$" AS VARCHAR2(100)) LIKE 'S%')
5 - access("XDB"."UNDER_PATH"(SYS_MAKEXML('8758D485E6004793E034080020B242C6',734,"XMLEXTRA"
,"XMLDATA"),'/home/QUINE/PurchaseOrders/2002/Apr',9999)=1)
7 - access("H"."PARENT_OID"=SYS_OP_ATG(VALUE(KOKBF$),3,4,2) AND
"H"."NAME"=SYS_OP_ATG(VALUE(KOKBF$),2,3,2))
8 - access("R2"."SYS_NC_OID$"=SYS_OP_ATG(VALUE(KOKBF$),3,4,2))

25 rows selected.

文書をリポジトリに格納する方法

Oracle XML DBでは、XML文書を特別な方法で処理します。XML Schemaに基づくXML文書のコンテンツを格納するルールは、XML Schemaで定義されます。文書のコンテンツは、グローバル要素定義に関連付けられたデフォルト表に格納されます。

Oracle XML DBリポジトリには、JPEGイメージやWord文書など、XMLデータを含まないファイルも格納されます。各リソースのXML Schemaでは、使用可能な要素を定義し、ファイルのコンテンツをBLOBインスタンスとして格納するか、またはCLOBインスタンスとして格納するかを指定します。XML Schemaに基づかないXML文書のコンテンツは、CLOBインスタンスとしてリポジトリに格納されます。

リポジトリ内のファイルまたはフォルダごとに、1つのリソースおよび1つのリンク・プロパティ文書が存在します。指定した文書へのアクセス・パスが複数存在する場合は、リンクごとにリンク・プロパティ文書が存在します。リソース・ドキュメントおよびリンク・プロパティ文書は、両方ともXML文書として格納されます。これらの文書はすべてリポジトリ内の表に格納されます。

XMLファイルをリポジトリにロードすると、次の順序でイベントが発生します。

1. Oracle XML DBは、XML文書のルート要素を調べ、既知(登録済)のXML Schemaに関連付けられているかどうかを確認します。このとき、文書にXMLSchema-instance名前空間の名前空間宣言が含まれているかどうかが確認され、文書に関連付けられたXML Schemaを識別するschemaLocation属性またはnoNamespaceSchemaLocation属性が検索されます。

2. 文書が既知のXML Schemaに基づいている場合は、XML SchemaのメタデータがXML Schemaのキャッシュからロードされます。

3. XML文書は解析され、XML Schemaから導出された一連のSQLオブジェクトに分解されます。

4. XMLファイルから作成されたSQLオブジェクトは、XML Schemaがデータベースに登録されたときに定義されたデフォルト表に格納されます。

5. リソース・ドキュメントは、処理された文書ごとに作成されます。これによって、リポジトリを使用して、文書のコンテンツにアクセスできます。XML Schemaに基づくXMLTypeインスタンスのリソース・ドキュメントには、XMLRef要素が含まれています。この要素には、リソースに関連付けられたコンテンツが含まれるデフォルト表内の行を検索するときに使用できるXMLTypeのREFが含まれます。

ブラウザを使用した、リレーショナル・データのXMLとしての表示

Oracle XML DBに組み込まれたHTTPサーバーでは、ブラウザを使用して、Oracle XML DBリポジトリに格納された文書にアクセスできます。リソースにはXMLType表またはビューの行に対するREFを含めることができるため、パスを使用してこのようなコンテンツにアクセスできます。

DBUri SERVLETを使用した、ブラウザからの表またはビューへのアクセス

Oracle XML DBに含まれているDBUriサーブレットを使用すると、ブラウザからすべての表またはビューのコンテンツに直接アクセスできます。DBUriサーブレットは、DBURITypeの機能を使用し、表のコンテンツから簡単なXML文書を生成します。サーブレットはC言語ベースで、Oracle XML DB HTTPサーバーにインストールされます。デフォルトでは、サーブレットは仮想ディレクトリ/oradbにインストールされます。

DBUriサーブレットに渡されるURLは、DBURITypeに渡されるURLの拡張です。このURLは、Oracle XML DB HTTPサーバーのアドレスとポート番号、およびHTTP(S)リクエストをDBUriサーブレットに転送する仮想ルートを使用して拡張されています。このURLのデフォルト構成は/oradbです。

したがって、URL http://localhost:8080/oradb/HR/DEPARTMENTSは、HRデータベース・スキーマにあるDEPARTMENTS表のコンテンツが含まれるXML文書を戻します。この場合、Oracle XML DB HTTPサーバーはポート8080で実行され、DBUri servletの仮想ルートは/oradbで、リクエストを発行したユーザーにはHRデータベース・スキーマに対するアクセス権限があると想定されます。

DBUriサーブレットは、ROWタグの名前、およびクライアントに戻される文書のMIMEタイプを指定できるパラメータを受け取ります。

XMLType表またはビューのコンテンツにも、DBUri servletを介してアクセスできます。DBUri servletに渡されるURLでXMLType表またはXMLTypeビューを参照する場合は、表または行内のどの文書が戻されるかを判別できるXPath式を使用してURLを拡張できます。URLに追加するXPath式は、文書内のすべてのノードを参照できます。

DBUriサーブレットで生成されたXMLは、Oracle XML DBに組み込まれているXSLTプロセッサを使用して変換できます。これによって、DBUri servletで生成されたXMLを、HTMLなど読みやすい形式で表示できます。

関連項目:
「DBUriServlet」

スタイルシート処理を開始するには、DBUriサーブレットに渡されるURLの一部としてtransformパラメータを指定します。スタイルシートは、そのスタイルシートのデータベース内での場所を参照するURIを使用して指定します。URIは、表またはビュー内のXMLType列を識別するDBURIType値、またはOracle XML DBリポジトリに格納された文書へのパスのいずれかになります。スタイルシートは、生成されたXMLがクライアントに戻される前に、XMLに直接適用されます。DBUriサーブレットを使用してXSLT処理を実行するときは、contenttypeパラメータを使用して、生成された出力のMIMEタイプを明示的に指定することをお薦めします。

変換されるXML文書がXML Schemaに基づくXMLTypeインスタンスとして格納されると、Oracle XML DBは、遅延ロードされた仮想DOMの機能を使用できるため、XSL変換に関連するオーバーヘッドを削減できます。

URLのルートは/oradbであるため、このURLは、Oracle XML DBリポジトリのリソースとしてではなく、SCOTTデータベース・スキーマのpurchaseorder表にアクセスするDBUriサーブレットに渡されます。このURLには、結果セットを、述語で指定した値がノード/PurchaseOrder/Reference/text()に含まれる文書に制限するXPath式が含まれます。contenttypeパラメータは、生成される文書のMIMEタイプをtext/xmlに設定します。

DBUriサーブレットを使用したXSL変換

図3-7に、DBUriサーブレットで生成されたXMLコンテンツにXSL変換を適用する方法を示します。この例では、DBUriに渡すURLにtransformパラメータが含まれています。これによって、DBUriサーブレットは、メインのURLで識別されるPurchaseOrder文書がブラウザに戻される前に、Oracle SQL関数XMLTransformを使用して、スタイルシート/home/SCOTT/xsl/purchaseOrder.xslを文書に適用します。このスタイルシートによって、XML文書がわかりやすいHTMLページに変換されます。また、URLでは、contentTypeパラメータを使用して、最後の文書のMIMEタイプがtext/htmlになることを指定します。

図3-7 DBUriサーブレットを使用したPurchaseOrderのデータベースXSL変換

図3-8に、HTML文書として表示されたdepartments表を示します。コーディングは不要で、これを表示するためには、SQL/XML関数に基づくXMLTypeビュー、業界標準のXSLスタイルシートおよびDBUriサーブレットのみが必要です。

図3-8 DBUriサーブレットを使用したDepartments表のデータベースXSL変換

脚注の凡例

脚注1: XML Schemaに基づくデータのXMLType記憶域モデルは、参照するXML Schemaの登録時に指定したものです。登録時に記憶域モデルを指定しなかった場合は、バイナリXML記憶域が使用されます。
脚注2: XML Schema注釈maintainOrder = "false"を使用すると、Ordered Collectionでなく、Unordered Collectionが使用されます。XMLデータの場合、ドキュメント内の順序を保持するために、Ordered Collection(maintainOrder = "true")を使用することをお薦めします。デフォルトでは、属性maintainOrderはtrueです。

第II部

Oracle XML DBからのXMLデータの格納および取出し

第II部では、Oracle XML DBを使用してXMLデータを格納、取出し、検証および変換する方法を説明します。次の章で構成されます。

- 第4章「XMLTypeの操作」

- 第5章「Oracle XML DBでのXQueryの使用」

- 第6章「XMLTypeデータの索引付け」

- 第7章「XML Schemaの格納と問合せ: 基本」

- 第8章「構造化記憶域のXPathリライト」

- 第9章「XML Schemaの格納と問合せ: 高度」

- 第10章「XML Schemaの拡張」

- 第11章「XMLTypeデータの変換および検証」

- 第12章「XMLデータの全文検索」

4 XMLTypeの操作

この章では、XMLアプリケーションに対するXMLType操作(XML Schemaに基づく、および基づかない)について説明します。XMLType列および表の作成、操作、更新および問合せのガイドラインが含まれます。

この章の内容は次のとおりです。

- XMLデータの選択および問合せ

- XMLデータの更新

関連項目:

- XMLType記憶域の推奨事項は、第3章「Oracle XML DBの使用」を参照してください。

- XML Schemaに基づくXMLTypeの表および列の使用方法は、第7章「XML Schemaの格納と問合せ: 基本」を参照してください。

XMLデータの選択および問合せ

次の方法で、XMLType列からXMLデータを問い合せることができます。

- SQL、PL/SQLまたはJavaでXMLType列を選択する方法。

- XQuery言語を使用する方法。「XQueryのXMLTypeデータとの使用」を参照してください。

- XMLQueryなどのSQL/XML関数を使用してXMLType列を直接問い合せる方法。

- Oracle Text演算子を使用して全文検索を行う方法。第6章「XMLTypeデータの索引付け」および第12章「XMLデータの全文検索」を参照してください。

XPath式を使用したXML文書の検索

XPath言語はXML文書をナビゲートするためのW3C勧告です。XPath式もXQuery式だという意味で、XPath言語はXQuery言語のサブセットです。

XPathはXML文書をノードのツリーとしてモデル化します。このツリーを移動し、述語およびノード・テスト機能を適用するための豊富な操作が備わっています。XPath式をXML文書に適用すると、ノードのセットが戻されます。たとえば、式/PO/PONOは、文書のPOルート要素の下にあるすべてのPONO子要素を選択します。

注意:
Oracle SQL関数およびXMLTypeメソッドは、W3C XPath勧告に準拠しています。このことは、XPath式がどのノードもターゲットにしていない場合にXMLデータに適用されると、空のシーケンスが戻される必要があることを示します。この場合にエラーが発生してはいけません。
XPath式をXMLデータに適用するOracle SQL関数またはXMLTypeメソッドによって、何が戻されるのかが決まります。たとえば、XPath式の引数のがどのノードもターゲットにしていない場合、SQL/XML関数XMLQueryはNULLを戻します。deleteXMLなどの更新のSQL関数は、入力XMLデータを変更せずに戻します。どのノードもターゲットになっていない場合にはエラーが発生することはありませんが、XPath式の引数が、属性ノードやテキスト・ノードなどの適切ではないノードをターゲットにしている場合は、更新のSQL関数でエラーが発生する可能性があります。

表4-1に、XPathで使用する共通構造体を示します。

表4-1 XPathの共通構造体

XPath構造体

説明

/

XPath式のツリーのルートを示します。たとえば、/POは、名前がPOであるルート・ノードの子を示します。

/

任意のノードの子ノードを識別するための区切りとしても使用します。たとえば、/PurchaseOrder/Referenceは、ルート要素の子である発注書名要素Referenceを示します。

//

現行ノードのすべての子孫を識別するために使用します。たとえば、PurchaseOrder//ShippingInstructionsは、PurchaseOrder要素の下にあるすべてのShippingInstructions要素と一致します。

*

任意の子ノードと一致させるためのワイルド・カードとして使用します。たとえば、/PO/*/STREETは、PO要素の孫であるすべての「STREET」要素と一致します。

[ ]

述語式を示すために使用します。XPathはOR、AND、NOTなど、様々なバイナリ演算子をサポートしています。たとえば、/PO[PONO=20 AND PNAME="PO_2"]/SHIPADDRは、発注書番号が20で、発注書名がPO_2であるすべての発注書の出荷先要素を選択します。

大カッコは、位置(索引)を示す場合にも使用します。たとえば、/PO/PONO[2]は、POルート要素の下の2番目の発注書番号要素を示します。

関数

XPathおよびXQueryは、substring、round、notなどの一連の組込み関数をサポートしています。さらに、これらの言語では名前空間を使用することで拡張関数を利用できます。Oracle XQuery拡張関数では、名前空間http://xmlns.oracle.com/xdbに名前空間接頭辞oraを使用します。「Oracle XQuery拡張関数」を参照してください。

XPathは単一のノードまたは一連の要素、テキストまたは属性ノードを識別する必要があります。XPathの結果はブール式にはできません。

XMLTypeデータは、PL/SQL、CまたはJavaを使用して選択できます。XMLTypeメソッドgetNumberVal()を使用して、XMLデータをNUMBERとして取り出すこともできます。

SQL/XML関数XMLExistsおよびXMLCastを使用したXMLTypeデータの問合せ

SQL/XML標準関数XMLQuery、XMLTable、XMLExistsおよびXMLCastを使用すると、XMLTypeデータを問い合せて一部を抽出できます。

XMLQuery関数およびXMLTable関数の詳細は、第5章「Oracle XML DBでのXQueryの使用」を参照してください。関数XMLExistsおよびXMLCastについては、この項で説明します。

XMLEXISTS SQL/XML関数

図4-1に、SQL/XMLの標準関数XMLExistsの構文を示します。この関数は、所定のXQuery式が空でないXQueryシーケンスを戻すかどうかを確認します。その場合、関数はTRUEを戻します。そうでない場合はFALSEを戻します。

図4-1 XMLExistsの構文

XML_passing_clause::=

- XQuery_stringは完結したXQuery式で、プロローグをリテラル文字列として含む場合があります。XQueryのPASSING句(構文図のXML_passing_clause)を使用してバインドするXQuery変数を含めることができます。SQL/XML関数XMLQueryに対し認識されている、事前定義された名前空間の接頭辞は、XQuery_stringでも認識されています。「事前定義の名前空間と接頭辞」を参照してください。

- XML_passing_clauseはキーワードPASSINGに1つ以上のSQL式(expr)を続けたもので、それぞれXMLTypeインスタンスまたはSQLスカラー・データ型のインスタンスを戻します。1つを除いてすべての式では、その後にASおよびXQuery identifierが続いている必要があります。それぞれのexprの評価結果は、対応するidentifierにバインドされ、続いてXQuery_stringが評価されます。AS句に続いていないexprがあった場合、そのexprの評価結果は、XQuery_stringを評価する際のコンテキスト項目として使用されます。Oracle XML DBではBY VALUEを渡すことはできますが、BY REFERENCEは渡せないため、BY VALUE句は暗黙的で、省略可能です。

/PurchaseOrder/Referenceまたは/PurchaseOrder/Reference/text()などのXQuery式が、単一のノードをターゲットとする場合、XMLExistsはその式にtrueを戻します。どのノードも検索しないXQuery式を使用してXMLExistsをコールした場合、XMLExistsはfalseを戻します。

関数XMLExistsは、問合せ内で使用できます。また、問合せの評価を高速化するためのファンクション索引を作成する場合にも使用できます。

注意:
Oracle XML DBは、XMLExistsの使用をSQLのWHERE句またはCASE式に制限します。XMLExistsをSELECTリストの中で使用する必要がある場合は、次のようにそれをCASE式でラップします。

CASE WHEN XMLExists(...) THEN 'TRUE' ELSE 'FALSE' END

例4-1では、SQL/XML標準関数XMLExistsを使用して、SpecialInstructionsがExpediteに設定されている行を選択します。

例4-1 SQL/XML関数XMLExistsを使用したノードの検索

SELECT OBJECT_VALUE
FROM purchaseorder
WHERE XMLExists('/PurchaseOrder[SpecialInstructions="Expedite"]'
PASSING OBJECT_VALUE);

OBJECT_VALUE
--------------------------------------------------------------------
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

13 rows selected.

SQL/XML関数XMLExistsを使用してファンクション索引を作成すると、実行を高速化できます。また、XMLIndex索引を作成して、任意のXQuery検索を高速化することもできます。

注意:
Oracle Database 11gリリース2以前では、一部のユーザーは一部の処理の実行にOracle SQL関数existsNodeを使用していました。これらの処理は、SQL/XML関数XMLExistsを使用してより効率的に実行できるようになっています。関数existsNodeは、Oracle Database 11gリリース2で非推奨になりました。2つの関数は、次の重要な点が異なります。

- 関数existsNodeは、0または1を戻します。関数XMLExistsは、ブール値のTRUEまたはFALSEを戻します。

- existsNodeは、問合せSELECTリストで使用できます。SELECTリストではXMLExistsを直接使用できませんが、SELECTリストのCASE式内ではXMLExistsを使用できます。

関連項目:

- 「オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け」

- 「XMLIndex」

XMLCAST SQL/XML関数

図4-2に、SQL/XMLの標準関数XMLCastの構文を示します。

図4-2 XMLCastの構文

SQL/XML標準関数XMLCastは、その最初の引数を2番目の引数で指定されるSQLスカラー・データ型にキャストします。最初の引数は、評価されるSQL式です。次のSQLデータ型は第2引数として使用できます。

- NUMBER

- VARCHAR2

- CHAR

- CLOB

- BLOB

- REF XMLTYPE

- 任意のSQL日時データ型

注意:
標準SQL/XMLとは異なり、Oracle XML DBではXMLをSQLスカラー・データ型にキャストするためのXMLCastの使用を制限しています。Oracle XML DBは、XMLからXMLへのキャストやスカラーSQL型からXMLへのキャストをサポートしていません。

最初のXMLCast引数の評価結果は、XML値になります。この値は、XQueryアトミック処理を使用して、XQueryアトミック値をターゲット・データ型にキャストすることにより、ターゲットSQLデータ型に変換されます。この変換に失敗すると、エラーが発生します。変換が成功すると、戻される結果は、ターゲット・データ型のインスタンスになります。

例4-2の問合せは、Referenceノードのスカラー値を抽出します。

例4-2 XMLCASTを使用したXMLフラグメントのスカラー値の抽出

SELECT XMLCast(XMLQuery('/PurchaseOrder/Reference' PASSING OBJECT_VALUE
RETURNING CONTENT)
AS VARCHAR2(100)) "REFERENCE"
FROM purchaseorder
WHERE XMLExists('/PurchaseOrder[SpecialInstructions="Expedite"]'
PASSING OBJECT_VALUE);

REFERENCE
----------------------------
AMCEWEN-20021009123336271PDT
SKING-20021009123336321PDT
AWALSH-20021009123337303PDT
JCHEN-20021009123337123PDT
AWALSH-20021009123336642PDT
SKING-20021009123336622PDT
SKING-20021009123336822PDT
AWALSH-20021009123336101PDT
WSMITH-20021009123336412PDT
AWALSH-20021009123337954PDT
SKING-20021009123338294PDT
WSMITH-20021009123338154PDT
TFOX-20021009123337463PDT

13 rows selected.

注意:

- Oracle Database 11gリリース2以前では、一部のユーザーは一部の処理の実行にOracle SQL関数extractValueを使用していました。これらの処理は、SQL/XML関数XMLQueryおよびXMLCastを使用してより効率的に実行できるようになっています。関数extractValueは、Oracle Database 11gリリース2で非推奨になりました。

- 関数extractValueでは、XPath式の引数が複数のテキスト・ノードに一致するとエラーが発生します。XMLQueryの結果にXMLCastを適用すると、テキスト・ノードが連結されて戻され、エラーは発生しません。

関連項目:

- 「オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け」

- 「XMLIndex」

SQL/XML関数を使用したXMLデータの問合せの例

この項の各例では、SQLを使用してXMLデータを問い合せる方法を示します。例4-3では、purchaseorder表に2行を挿入してから、SQL/XML関数XMLCast、XMLQueryおよびXMLExistsを使用してそれらの行のデータを問い合せます。

例4-3 XMLTYPEデータの問合せ

INSERT INTO purchaseorder
VALUES (XMLType(bfilename('XMLDIR', 'SMCCAIN-2002091213000000PDT.xml'),
nls_charset_id('AL32UTF8')));

INSERT INTO purchaseorder
VALUES (XMLType(bfilename('XMLDIR', 'VJONES-20020916140000000PDT.xml'),
nls_charset_id('AL32UTF8')));

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Reference'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30)) reference,
XMLCast(XMLQuery('$p/PurchaseOrder/*//User'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30)) userid,
CASE
WHEN XMLExists('$p/PurchaseOrder/Reject/Date'
PASSING po.OBJECT_VALUE AS "p")
THEN 'Rejected'
ELSE 'Accepted'
END "STATUS",
XMLCast(XMLQuery('$p//Date'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(12)) status_date
FROM purchaseorder po
WHERE XMLExists('$p//Date' PASSING po.OBJECT_VALUE AS "p")
ORDER BY XMLCast(XMLQuery('$p//Date' PASSING po.OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(12));

REFERENCE                        USERID   STATUS   STATUS_DATE
-------------------------------- -------- -------- ------------
VJONES-20020916140000000PDT      SVOLLMAN Accepted 2002-10-11
SMCCAIN-2002091213000000PDT      SKING    Rejected 2002-10-12

2 rows selected.

例4-4では、PL/SQLカーソルを使用してXMLデータを問い合せます。ローカルのXMLTypeインスタンスを使用して、一時データが格納されます。

例4-4 PL/SQLカーソルを使用した一時XMLTYPEデータの問合せ

DECLARE
xNode      XMLType;
vText      VARCHAR2(256);
vReference VARCHAR2(32);
CURSOR getPurchaseOrder(reference IN VARCHAR2) IS
SELECT OBJECT_VALUE XML
FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder[Reference=$r]'
PASSING OBJECT_VALUE AS "p",
reference    AS "r");
BEGIN
vReference := 'EABEL-20021009123335791PDT';
FOR c IN getPurchaseOrder(vReference) LOOP
xNode := c.XML.extract('//Requestor');
SELECT XMLSerialize(CONTENT
XMLQuery('//text()' PASSING xNode RETURNING CONTENT))
INTO vText FROM DUAL;
DBMS_OUTPUT.put_line('The Requestor for Reference '
|| vReference || ' is '|| vText);
END LOOP;
vReference := 'PTUCKER-20021009123335430PDT';
FOR c IN getPurchaseOrder(vReference) LOOP
xNode := c.XML.extract('//LineItem[@ItemNumber="1"]/Description');
SELECT XMLSerialize(CONTENT
XMLQuery('//text()' PASSING xNode RETURNING CONTENT))
INTO vText FROM DUAL;
DBMS_OUTPUT.put_line('The Description of LineItem[1] for Reference '
|| vReference || ' is '|| vText);
END LOOP;
END;
/
The Requestor for Reference EABEL-20021009123335791PDT is Ellen S. Abel
The Description of LineItem[1] for Reference PTUCKER-20021009123335430PDT is
Picnic at
Hanging Rock

PL/SQL procedure successfully completed.

例4-5では、SQL/XML関数XMLTableを使用して、XML発注書からデータを抽出し、そのデータをリレーショナル表に挿入します。

例4-5 XMLTABLEを使用したXMLデータの抽出およびデータベース表への挿入

CREATE TABLE purchaseorder_table (reference           VARCHAR2(28) PRIMARY KEY,
requestor           VARCHAR2(48),
actions             XMLType,
userid              VARCHAR2(32),
costcenter          VARCHAR2(3),
shiptoname          VARCHAR2(48),
address             VARCHAR2(512),
phone               VARCHAR2(32),
rejectedby          VARCHAR2(32),
daterejected        DATE,
comments            VARCHAR2(2048),
specialinstructions VARCHAR2(2048));

CREATE TABLE purchaseorder_lineitem (reference,
FOREIGN KEY ("REFERENCE")
REFERENCES "PURCHASEORDER_TABLE" ("REFERENCE") ON DELETE CASCADE,
lineno      NUMBER(10), PRIMARY KEY ("REFERENCE", "LINENO"),
upc         VARCHAR2(14),
description VARCHAR2(128),
quantity    NUMBER(10),
unitprice   NUMBER(12,2));

INSERT INTO purchaseorder_table (reference, requestor, actions, userid, costcenter, shiptoname, address,
phone, rejectedby, daterejected, comments, specialinstructions)
SELECT t.reference, t.requestor, t.actions, t.userid, t.costcenter, t.shiptoname, t.address,
t.phone, t.rejectedby, t.daterejected, t.comments, t.specialinstructions
FROM purchaseorder p,
XMLTable('/PurchaseOrder' PASSING p.OBJECT_VALUE
COLUMNS reference           VARCHAR2(28)   PATH 'Reference',
requestor           VARCHAR2(48)   PATH 'Requestor',
actions             XMLType        PATH 'Actions',
userid              VARCHAR2(32)   PATH 'User',
costcenter          VARCHAR2(3)    PATH 'CostCenter',
shiptoname          VARCHAR2(48)   PATH 'ShippingInstructions/name',
address             VARCHAR2(512)  PATH 'ShippingInstructions/address',
phone               VARCHAR2(32)   PATH 'ShippingInstructions/telephone',
rejectedby          VARCHAR2(32)   PATH 'Reject/User',
daterejected        DATE           PATH 'Reject/Date',
comments            VARCHAR2(2048) PATH 'Reject/Comments',
specialinstructions VARCHAR2(2048) PATH 'SpecialInstructions') t
WHERE t.reference = 'EABEL-20021009123336251PDT';

INSERT INTO purchaseorder_lineitem (reference, lineno, upc, description, quantity, unitprice)
SELECT t.reference, li.lineno, li.upc, li.description, li.quantity, li.unitprice
FROM purchaseorder p,
XMLTable('/PurchaseOrder' PASSING p.OBJECT_VALUE
COLUMNS reference VARCHAR2(28) PATH 'Reference',
lineitem XMLType PATH 'LineItems/LineItem') t,
XMLTable('LineItem' PASSING t.lineitem
COLUMNS lineno      NUMBER(10)    PATH '@ItemNumber',
upc         VARCHAR2(14)  PATH 'Part/@Id',
description VARCHAR2(128) PATH 'Description',
quantity    NUMBER(10)    PATH 'Part/@Quantity',
unitprice   NUMBER(12,2)  PATH 'Part/@UnitPrice') li
WHERE t.reference = 'EABEL-20021009123336251PDT';

SELECT reference, userid, shiptoname, specialinstructions FROM purchaseorder_table;

REFERENCE                        USERID   SHIPTONAME                                       SPECIALINSTRUCTIONS
-------------------------------- -------- ------------------------------------------------ -------------------
EABEL-20021009123336251PDT       EABEL    Ellen S. Abel                                    Counter to Counter

SELECT reference, lineno, upc, description, quantity FROM purchaseorder_lineitem;

REFERENCE                            LINENO UPC            DESCRIPTION                          QUANTITY
-------------------------------- ---------- -------------- ---------------------------------- ----------
EABEL-20021009123336251PDT                1 37429125526    Samurai 2: Duel at Ichijoji Temple          3
EABEL-20021009123336251PDT                2 37429128220    The Red Shoes                               4
EABEL-20021009123336251PDT                3 715515009058   A Night to Remember                         1

例4-6では、PL/SQLプロシージャを定義および使用して、XML発注書からデータを抽出し、そのデータをリレーショナル表に挿入します。

例4-6 PL/SQLプロシージャを使用したXMLデータの抽出および表への挿入

CREATE OR REPLACE PROCEDURE insertPurchaseOrder(purchaseorder XMLType) AS reference VARCHAR2(28);
BEGIN
INSERT INTO purchaseorder_table (reference, requestor, actions, userid, costcenter, shiptoname, address,
phone, rejectedby, daterejected, comments, specialinstructions)
SELECT * FROM XMLTable('$p/PurchaseOrder' PASSING purchaseorder AS "p"
COLUMNS reference           VARCHAR2(28)   PATH 'Reference',
requestor           VARCHAR2(48)   PATH 'Requestor',
actions             XMLType        PATH 'Actions',
userid              VARCHAR2(32)   PATH 'User',
costcenter          VARCHAR2(3)    PATH 'CostCenter',
shiptoname          VARCHAR2(48)   PATH 'ShippingInstructions/name',
address             VARCHAR2(512)  PATH 'ShippingInstructions/address',
phone               VARCHAR2(32)   PATH 'ShippingInstructions/telephone',
rejectedby          VARCHAR2(32)   PATH 'Reject/User',
daterejected        DATE           PATH 'Reject/Date',
comments            VARCHAR2(2048) PATH 'Reject/Comments',
specialinstructions VARCHAR2(2048) PATH 'SpecialInstructions');

INSERT INTO purchaseorder_lineitem (reference, lineno, upc, description, quantity, unitprice)
SELECT t.reference, li.lineno, li.upc, li.description, li.quantity, li.unitprice
FROM XMLTable('$p/PurchaseOrder' PASSING purchaseorder AS "p"
COLUMNS reference VARCHAR2(28) PATH 'Reference',
lineitem XMLType PATH 'LineItems/LineItem') t,
XMLTable('LineItem' PASSING t.lineitem
COLUMNS lineno NUMBER(10)    PATH '@ItemNumber',
upc VARCHAR2(14)  PATH 'Part/@Id',
description VARCHAR2(128) PATH 'Description',
quantity NUMBER(10)    PATH 'Part/@Quantity',
unitprice NUMBER(12,2)  PATH 'Part/@UnitPrice') li;
END;
CALL insertPurchaseOrder(XMLType(bfilename('XMLDIR', 'purchaseOrder.xml'), nls_charset_id('AL32UTF8')));

SELECT reference, userid, shiptoname, specialinstructions FROM purchaseorder_table;

REFERENCE                        USERID   SHIPTONAME                                       SPECIALINSTRUCTIONS
-------------------------------- -------- ------------------------------------------------ -------------------
SBELL-2002100912333601PDT        SBELL    Sarah J. Bell                                    Air Mail

SELECT reference, lineno, upc, description, quantity FROM purchaseorder_lineitem;

REFERENCE                 LINENO UPC          DESCRIPTION                        QUANTITY
------------------------- ------ ------------ ---------------------------------- --------
SBELL-2002100912333601PDT      1 715515009058 A Night to Remember                       2
SBELL-2002100912333601PDT      2 37429140222  The Unbearable Lightness Of Being         2
SBELL-2002100912333601PDT      3 715515011020 Sisters                                   4

例4-7では、顧客名に"ll"(Lが2個)が付き、出荷指示に"Shores"という語が含まれている発注書のXML要素PurchaseOrderから発注書名を抽出します。この例では、Oracle XQuery拡張関数ora:containsを使用して全文検索を実行します。

例4-7 SQL/XML関数を使用したXMLデータの検索

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(128)) name,
count(*)
FROM purchaseorder po
WHERE
XMLExists(
'declare namespace ora="http://xmlns.oracle.com/xdb"; (: :)
$p/PurchaseOrder/ShippingInstructions[ora:contains(address/text(), "Shores") > 0]'
PASSING po.OBJECT_VALUE AS "p")
AND XMLCast(XMLQuery('$p/PurchaseOrder/Requestor/text()'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(128))
LIKE '%ll%'
GROUP BY XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(128));

NAME                   COUNT(*)
-------------------- ----------
Allan D. McEwen               9
Ellen S. Abel                 4
Sarah J. Bell                13
William M. Smith              7

例4-8は、SQL/XML関数XMLQueryを使用して、XPath式によって識別されるノードを抽出する方法を示しています。XMLQueryにより戻されるXMLTypeインスタンスは、ノードの集合、単一のノードまたはテキスト値のいずれかになります。例4-8では、XMLTypeメソッドisFragment()を使用して、結果がフラグメントかどうかを判別します。

例4-8 XMLQUERYを使用したXMLTYPEインスタンスからのフラグメントの抽出

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Reference' PASSING po.OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(30)) reference,
count(*)
FROM purchaseorder po, XMLTable('$p//LineItem[Part/@Id="37429148327"]' PASSING OBJECT_VALUE AS "p")
WHERE XMLQuery('$p/PurchaseOrder/LineItems/LineItem[Part/@Id="37429148327"]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT).isFragment() = 1
GROUP BY XMLCast(XMLQuery('$p/PurchaseOrder/Reference' PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30))
ORDER BY XMLCast(XMLQuery('$p/PurchaseOrder/Reference' PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30));

REFERENCE                          COUNT(*)
-------------------------------- ----------
TFOX-20021009123337784PDT                 3

注意:
フラグメントはXMLType列に挿入できません。SQL関数sys_XMLGenを使用すると、囲みタグを追加することによってフラグメントを整形式の文書に変換できます。「SYS_XMLGEN Oracle SQL関数」を参照してください。

XMLデータの更新

この項では、一時データおよび表に格納されたデータの両方のXMLデータの更新について説明します。次のSQL関数の使用についても説明します。

- updateXML

- insertChildXML

- insertChildXMLbefore

- insertChildXMLafter

- insertXMLbefore

- insertXMLafter

- appendChildXML

- deleteXML

XML文書全体の更新

未構造化記憶域(CLOB)では、更新を行うと文書全体が効果的に置換されます。XML文書全体を更新するには、SQLのUPDATE文を使用します。UPDATE文のSET句の右側にはXMLTypeインスタンスを指定する必要があります。これを作成するには、次のいずれかの方法を使用します。

- XMLインスタンスを戻すSQL関数またはXMLコンストラクタを使用する方法

- 既存のXMLインスタンスを変更およびバインドするPL/SQL DOM APIs for XMLTypeを使用する方法

- 既存のXMLインスタンスを変更およびバインドするJava PL/SQL DOM APIを使用する方法

CLOB値(未構造化記憶域)として格納されているXML Schemaに基づかないXML文書を更新する場合は、常にXML文書全体が更新されます。バイナリXMLとして格納されているXML Schemaに基づかないXML文書は、ピース単位で更新できます。「XML Schemaに基づくXML文書および基づかないXML文書の更新」を参照してください。

例4-9では、SQL UPDATE文を使用してXMLTypeインスタンスを更新します。

例4-9 SQL UPDATE文を使用したXMLTypeデータの更新

SELECT t.reference, li.lineno, li.description
FROM purchaseorder po,
XMLTable('$p/PurchaseOrder' PASSING po.OBJECT_VALUE AS "p"
COLUMNS reference VARCHAR2(28) PATH 'Reference',
lineitem  XMLType      PATH 'LineItems/LineItem') t,
XMLTable('$l/LineItem' PASSING t.lineitem AS "l"
COLUMNS lineno      NUMBER(10)    PATH '@ItemNumber',
description VARCHAR2(128) PATH 'Description') li
WHERE t.reference = 'DAUSTIN-20021009123335811PDT' AND ROWNUM < 6;

REFERENCE                         LINENO DESCRIPTION
-------------------------------- ------- -----------------
DAUSTIN-20021009123335811PDT           1 Nights of Cabiria
DAUSTIN-20021009123335811PDT           2 For All Mankind
DAUSTIN-20021009123335811PDT           3 Dead Ringers
DAUSTIN-20021009123335811PDT           4 Hearts and Minds
DAUSTIN-20021009123335811PDT           5 Rushmore

UPDATE purchaseorder po
SET po.OBJECT_VALUE = XMLType(bfilename('XMLDIR','NEW-DAUSTIN-20021009123335811PDT.xml'),
nls_charset_id('AL32UTF8'))
WHERE XMLExists('$p/PurchaseOrder[Reference="DAUSTIN-20021009123335811PDT"]'
PASSING po.OBJECT_VALUE AS "p");

SELECT t.reference, li.lineno, li.description
FROM purchaseorder po,
XMLTable('$p/PurchaseOrder' PASSING po.OBJECT_VALUE AS "p"
COLUMNS reference VARCHAR2(28) PATH 'Reference',
lineitem  XMLType      PATH 'LineItems/LineItem') t,
XMLTable('$l/LineItem' PASSING t.lineitem AS "l"
COLUMNS lineno      NUMBER(10)    PATH '@ItemNumber',
description VARCHAR2(128) PATH 'Description') li
WHERE t.reference = 'DAUSTIN-20021009123335811PDT';

REFERENCE                         LINENO DESCRIPTION
-------------------------------- ------- --------------------------------
DAUSTIN-20021009123335811PDT           1 Dead Ringers
DAUSTIN-20021009123335811PDT           2 Getrud
DAUSTIN-20021009123335811PDT           3 Branded to Kill

XMLデータを更新するためのSQL関数

XMLデータを付加的に更新する(周囲のXML文書全部を置き換えずにXMLデータを置換、挿入または削除する)ために使用できるOracle SQL関数がいくつかあります。これは、部分更新とも呼ばれます。これらのOracle SQL関数については、次の各項で説明します。

- updateXML - 任意の種類のXMLノードを置換します。「UPDATEXML SQL関数」を参照してください。

- insertChildXML - XMLの要素ノードまたは属性ノードを、指定された要素ノードの子として挿入します。「INSERTCHILDXML SQL関数」を参照してください。

- insertChildXMLbefore - 新しいコレクション要素を、同じ型の指定されたコレクション要素の直前に挿入します。「INSERTCHILDXMLBEFORE SQL関数」を参照してください。

- insertChildXMLafter - 新しいコレクション要素を、同じ型の指定されたコレクション要素の直後に挿入します。「INSERTCHILDXMLAFTER SQL関数」を参照してください。

- insertXMLbefore - 任意の種類のXMLノードを、指定されたノード(属性ノード以外)の直前に挿入します。「INSERTXMLBEFORE SQL関数」を参照してください。

- insertXMLafter - 任意の種類のXMLノードを、指定されたノード(属性ノード以外)の直後に挿入します。「INSERTXMLAFTER SQL関数」を参照してください。

- appendChildXML - 任意の種類のXMLノードを、指定された要素ノードの最後の子ノードとして挿入します。「APPENDCHILDXML SQL関数」を参照してください。

- deleteXML - 任意の種類のXMLノードを削除します。「DELETEXML SQL関数」を参照してください。

関数insertChildXML、insertChildXMLbefore、insertChildXMLafter、insertXMLbefore、insertXMLafter、appendChildXMLを使用して、XMLデータを挿入します。関数deleteXMLを使用して、XMLデータを削除します。XMLデータを置換するには、関数updateXMLを使用します。

特に、親ノード全体を置き換えることによってXMLデータを挿入または削除する場合は、関数updateXMLを使用しないでください。使用しても機能しますが、これ以外のいずれかの関数を使用するほうがローカルな更新を実行できるため、効率的です。

これらのOracle SQL関数はそれ自体ではデータベース・データを変更しません。これらはすべて副次的な影響のない純粋な関数です。各関数は、入力されたXMLデータにXPath式の引数を適用し、入力されたXMLデータの変更済コピーを戻します。その後、その結果を使用してSQL DML演算子UPDATEを実行し、データベース・データを変更できます。これは、SQL関数upperを使用してデータベース・データを大文字に変換する方法と変わりません。UPDATEなどのSQL DML演算子を使用して、格納されたデータを変更する必要があります。

これらの関数はそれぞれ、XML Schemaに基づくXML文書および基づかないXML文書のどちらにも使用できます。XML Schemaに基づくデータの場合、これらのOracle SQL関数はその結果に対して部分検証を実行します。該当する場合は、引数の値のXML Schemaとの互換性もチェックされます。

注意:
Oracle SQL関数およびXMLTypeメソッドは、W3C XPath勧告に準拠しています。このことは、XPath式がどのノードもターゲットにしていない場合にXMLデータに適用されると、空のシーケンスが戻される必要があることを示します。この場合にエラーが発生してはいけません。
XPath式をXMLデータに適用するOracle SQL関数またはXMLTypeメソッドによって、何が戻されるのかが決まります。たとえば、XPath式の引数がどのノードもターゲットにしていない場合、SQL/XML関数XMLQueryはNULLを戻します。deleteXMLなどの更新のOracle SQL関数は、入力されたXMLデータを変更せずに戻します。どのノードもターゲットになっていない場合にはエラーが発生することはありませんが、XPath式の引数が、属性ノードやテキスト・ノードなどの適切ではないノードをターゲットにしている場合は、更新のSQL関数でエラーが発生する可能性があります。

関連項目:
XML Schemaに対する部分検証の詳細は、「部分検証」を参照してください。

SQL関数を使用したXML要素の挿入

XMLノードを既存のXMLデータ(のコピー)に挿入するためのOracle SQL関数がいくつかあります。いずれも、XPath式により参照されるノードを複数の場所に挿入できます。各関数は、新しいノードの挿入位置と、ターゲットXMLデータの参照方法が異なります。

- 関数appendChildXMLは、ターゲット要素にノードを追加します。つまり、ターゲット要素ごとに、任意の種類の1つ以上のノードを要素の最後の子として挿入します。

- 関数insertChildXMLは、ターゲット要素の下に新しい子(同じ型の1つ以上の要素、または単一の属性)を挿入します。親の下の新しい子要素の位置は指定されません。ターゲット・データがXML Schemaに基づいている場合、そのスキーマを使用して挿入位置を指定できる場合もあります。できない場合、挿入位置は任意です。

- 関数insertXMLbeforeは、任意の種類の1つ以上のノードを、ターゲット・ノード(属性ノード以外)の直前に挿入します。
関数insertXMLafterも同様にノードを挿入しますが、ターゲットの直前ではなく直後に挿入します。

- 関数insertChildXMLbeforeはinsertChildXMLと似ていますが、挿入されるノードが(属性でなく)要素である必要があることと、兄弟関係における新しい要素の位置をユーザーが指定する点が異なります。これはinsertXMLbeforeと似ていますが、任意の要素ではなく、コレクション要素のみ挿入する点が異なります。挿入位置により、後続のコレクション・メンバーが指定されます。挿入する実際の要素は、コレクションの要素型に対応している必要があります。
関数insertChildXMLafterも同様にノードを挿入しますが、ターゲットの直前ではなく直後に挿入します。

insertChildXMLbefore(insertChildXMLafter)とinsertXMLbefore(insertXMLbeforeafter)は結果は似ていますが、ターゲットの場所の表現方法が異なります。前者の関数では、ターゲットは新しい子の親です。後者の関数では、ターゲットは後ろの(または前の)兄弟です。この違いは、関数名(Child)に表れています。

たとえば、新しいLineItem要素を、要素/PurchaseOrder/LineItemsの3つ下にあるLineItem要素の前に挿入する場合、insertChildXMLbeforeを使用し、ターゲットの親を/PurchaseOrder/LineItemsとして指定し、後続の兄弟をLineItem[3]として指定します。または、insertXMLbeforeを使用し、ターゲットの後続の兄弟を/PurchaseOrder/LineItems/LineItem[3]として指定することもできます。insertChildXMLを使用して挿入する場合は、コレクション内の新しい要素の位置を指定できません。どの位置になるかは不確定です。

さらにこれらの関数は、insertXMLbefore、insertXMLafterおよびappendChildXMLを除くすべてが、オブジェクト・リレーショナル形式またはバイナリXMLとして格納されている、XMLType表および列に対するSQL UPDATE操作のために最適化されている点が異なります。

関連項目:
「XMLデータを更新するOracle SQL関数の最適化」

UPDATEXML SQL関数

Oracle SQL関数updateXMLは、任意の種類のXMLノードを置換します。更新のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数updateXMLには、次のパラメータがあります(この順序どおり)。

- target-data(XMLType) - 置換するターゲット・ノードを含むXMLデータ。

- 1つ以上の、 xpathパラメータとreplacementパラメータの組。

- xpath(VARCHAR2)– target-data内で置換するノードを検索するXPath 1.0式。それぞれのターゲットとなるノードは、replacementにより置換されます。これらは、どのような種類のノードでもかまいません。xpathがノードの空シーケンスと一致する場合、置換は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。

- replacement(XMLTypeまたはVARCHAR2): xpathでターゲットとなっているデータを置換するXMLデータ。replacementのデータ型は、置換されるデータと一致している必要があります。xpathが要素ノードを置換の対象とする場合、データ型はXMLTypeでなければなりません。xpathが属性ノードやテキスト・ノードをターゲットにする場合は、VARCHAR2である必要があります。属性ノードの場合、replacementは、名前を含む完全な属性ノード(たとえばmy_attribute="23")ではなく、属性の置換値のみ(たとえば23)です。

- namespace (VARCHAR2、オプション) : パラメータxpathのXML名前空間。

Oracle SQL関数updateXMLを使用すると、既存の要素、属性およびノードを新しい値で置換できます。新しいノードを挿入したり、既存のノードを削除することは、効率的な方法ではありません。updateXMLを使用して、挿入または削除するノードの親ノード全体を置換するだけで、挿入および削除を実行できます。

関数updateXMLは、メモリー内の一時XMLインスタンスのみを更新します。表に格納されたデータを更新するには、SQLのUPDATE文を使用します。

図4-3に構文を示します。

図4-3 UPDATEXMLの構文

例4-10では、新しいXML文書を作成するのではなく、UPDATE文の右側にupdateXMLを使用して表内のXML文書を更新します。選択された部分のみではなく、文書全体が更新されます。

例4-10 UPDATEおよびUPDATEXMLを使用したXMLTYPEの更新

SELECT XMLQuery('$p/PurchaseOrder/Actions/Action[1]' PASSING po.OBJECT_VALUE AS "p"
RETURNING CONTENT) action
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

ACTION
--------------------------------
<Action>
<User>SVOLLMAN</User>
</Action>

UPDATE purchaseorder po
SET po.OBJECT_VALUE = updateXML(po.OBJECT_VALUE,
'/PurchaseOrder/Actions/Action[1]/User/text()',
'SKING')
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

SELECT XMLQuery('$p/PurchaseOrder/Actions/Action[1]' PASSING po.OBJECT_VALUE AS "p"
RETURNING CONTENT) action
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

ACTION
---------------------------------
<Action>
<User>SKING</User>
</Action>

例4-11では、Oracle SQL関数updateXMLを使用して複数のノードを更新します。

例4-11 UPDATEXMLを使用した、複数のテキスト・ノードと属性値の更新

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30)) name,
XMLQuery('$p/PurchaseOrder/LineItems'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) lineitems
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

NAME             LINEITEMS
---------------- ------------------------------------------------------------------------
Sarah J. Bell    <LineItems>
<LineItem ItemNumber="1">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="2">
<Description>The Unbearable Lightness Of Being</Description>
<Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="3">
<Description>Sisters</Description>
<Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
</LineItem>
</LineItems>

UPDATE purchaseorder
SET OBJECT_VALUE = updateXML(OBJECT_VALUE,
'/PurchaseOrder/Requestor/text()','Stephen G. King',
'/PurchaseOrder/LineItems/LineItem[1]/Part/@Id','786936150421',
'/PurchaseOrder/LineItems/LineItem[1]/Description/text()','The Rock',
'/PurchaseOrder/LineItems/LineItem[3]',
XMLType('<LineItem ItemNumber="99">
<Description>Dead Ringers</Description>
<Part Id="715515009249" UnitPrice="39.95" Quantity="2"/>
</LineItem>'))
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30)) name,
XMLQuery('$p/PurchaseOrder/LineItems'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) lineitems
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

NAME             LINEITEMS
---------------- ------------------------------------------------------------------
Stephen G. King  <LineItems>
<LineItem ItemNumber="1">
<Description>The Rock</Description>
<Part Id="786936150421" UnitPrice="39.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="2">
<Description>The Unbearable Lightness Of Being</Description>
<Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="99">
<Description>Dead Ringers</Description>
<Part Id="715515009249" UnitPrice="39.95" Quantity="2"/>
</LineItem>
</LineItems>

例4-12では、SQL関数updateXMLを使用して、コレクション内で選択されたノードを更新します。

例4-12 UPDATEXMLを使用した、コレクション内で選択されたノードの更新

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30)) name,
XMLQuery('$p/PurchaseOrder/LineItems'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) lineitems
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

NAME             LINEITEMS
---------------- ----------------------------------------------------------------
Sarah J. Bell    <LineItems>
<LineItem ItemNumber="1">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="2">
<Description>The Unbearable Lightness Of Being</Description>
<Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="3">
<Description>Sisters</Description>
<Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
</LineItem>
</LineItems>

UPDATE purchaseorder
SET OBJECT_VALUE =
updateXML(OBJECT_VALUE,
'/PurchaseOrder/Requestor/text()','Stephen G. King',
'/PurchaseOrder/LineItems/LineItem/Part[@Id="715515009058"]/@Quantity',
25,
'/PurchaseOrder/LineItems/LineItem[Description/text() =
"The Unbearable Lightness Of Being"]',
XMLType('<LineItem ItemNumber="99">
<Part Id="786936150421" Quantity="5" UnitPrice="29.95"/>
<Description>The Rock</Description>
</LineItem>'))
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30)) name,
XMLQuery('$p/PurchaseOrder/LineItems'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) lineitems
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

NAME             LINEITEMS
---------------- -------------------------------------------------------------
Stephen G. King  <LineItems>
<LineItem ItemNumber="1">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="25"/>
</LineItem>
<LineItem ItemNumber="99">
<Part Id="786936150421" Quantity="5" UnitPrice="29.95"/>
<Description>The Rock</Description>
</LineItem>
<LineItem ItemNumber="3">
<Description>Sisters</Description>
<Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
</LineItem>
</LineItems>

UPDATEXMLおよびNULL値

- XML要素をNULLに更新すると、要素の属性および子が削除され、要素は空になります。要素のタイプおよび名前空間プロパティは保持されます。例4-13を参照してください。

- 属性値をNULLに更新した場合、値は空の文字列として表示されます。例4-13を参照してください。

- 要素のテキスト・ノードをNULLに更新すると、その要素のコンテンツ(テキスト)は削除されます。要素自体は残りますが、空になります。 例4-14を参照してください。

例4-13では、次のものすべてをNULLに更新します。

- Description要素と、Part要素の属性Id値が715515009058のLineItem要素のQuantity属性

- Description要素のコンテンツ(テキスト)が「The Unbearable Lightness Of Being」であるLineItem要素

例4-13 UPDATEXMLを使用したNULL更新 - 要素および属性

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30)) name,
XMLQuery('$p/PurchaseOrder/LineItems'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) lineitems
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

NAME             LINEITEMS
---------------- -------------------------------------------------------------------
Sarah J. Bell    <LineItems>
<LineItem ItemNumber="1">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="2">
<Description>The Unbearable Lightness Of Being</Description>
<Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="3">
<Description>Sisters</Description>
<Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
</LineItem>
</LineItems>

UPDATE purchaseorder
SET OBJECT_VALUE =
updateXML(
OBJECT_VALUE,
'/PurchaseOrder/LineItems/LineItem[Part/@Id="715515009058"]/Description', NULL,
'/PurchaseOrder/LineItems/LineItem/Part[@Id="715515009058"]/@Quantity', NULL,
'/PurchaseOrder/LineItems/LineItem[Description/text()=
"The Unbearable Lightness Of Being"]', NULL)
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30)) name,
XMLQuery('$p/PurchaseOrder/LineItems'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) lineitems
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

NAME             LINEITEMS
---------------- ----------------------------------------------------------------
Sarah J. Bell    <LineItems>
<LineItem ItemNumber="1">
<Description/>
<Part Id="715515009058" UnitPrice="39.95" Quantity=""/>
</LineItem>
<LineItem/>
<LineItem ItemNumber="3">
<Description>Sisters</Description>
<Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
</LineItem>
</LineItems>

例4-14では、Description属性の値が「A Night to Remember」であるPart要素のテキスト・ノードをNULLに更新します。この例のXMLデータは、修正された別の発注書XML Schemaに対応しています(「コピーに基づく拡張の使用例」を参照)。そのXML Schemaでは、DescriptionはPart要素の属性であり、兄弟要素ではありません。

例4-14 UPDATEXMLを使用したNULL更新 - テキスト・ノード

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/LineItems/LineItem/Part[@Description="A Night to Remember"]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(128)) part
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[@Reference="SBELL-2003030912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

PART
----
<Part Description="A Night to Remember" UnitCost="39.95">715515009058</Part>

UPDATE purchaseorder
SET OBJECT_VALUE =
updateXML(OBJECT_VALUE,
'/PurchaseOrder/LineItems/LineItem/Part[@Description="A Night to Remember"]/text()', NULL)
WHERE XMLExists('$p/PurchaseOrder[@Reference="SBELL-2003030912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/LineItems/LineItem/Part[@Description="A Night to Remember"]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(128)) part
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[@Reference="SBELL-2003030912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

PART
----
<Part Description="A Night to Remember" UnitCost="39.95"/>

関連項目:
例3-36「UPDATEXMLを使用したXMLコンテンツの更新」

同じXMLノードの複数回の更新

同じXMLノードをupdateXML式で複数回更新できます。たとえば、/EMP[EMPNO=217]および/EMP[EMPNAME="Jane"]/EMPNOの両方を更新できます。ここで最初のXPathはそれを含むEMPNOノードも識別します。更新の順番は、左から右へ、XPath式の順番によって決定されます。連続するXPathはそれぞれ、前のXPathの更新結果に基づいて機能します。

UPDATEXML使用時のDOM 再現性の保持

ここでは、Oracle SQL関数updateXMLを使用する際にDOM再現性を保持するためのガイドラインを示します。

DOM再現性が保持される場合

要素をNULLに更新する場合は、<myElem/>のように、その親で目的の要素が空に表示されるようにします。要素内のテキスト・ノードをNULLに更新する場合は、その要素からテキスト・ノードを削除します。属性ノードをNULLに更新する場合は、myAttr=""のように、属性の値が空の文字列になるようにします。

DOM再現性が保持されない場合

complexType要素をNULLに更新する場合は、<myElem/>のように、その親で目的の要素が空に表示されるようにします。SQLインラインsimpleType要素をNULLに更新する場合は、その親から要素が見えないようにします。テキスト・ノードをNULLに更新する場合は、親simpleType要素をNULLに設定する場合と同じ手順を実行します。複合コンテンツを格納する位置指定ディスクリプタがないため、DOM再現性が保持されない場合、テキスト・ノードはsimpleType要素内でのみ出現できます。属性ノードをNULLに更新する場合は、要素からその属性を削除します。

DOM再現性が保持されるかどうかの判別

XML Schema内のXMLTypeの特定部分についてDOM再現性が保持されるかどうかを判別するには、属性maintainDOMのスキーマ・メタデータを問い合せます。

関連項目:

- XML Schemaを問い合せてDOM再現性の値を取り出す例は、「登録されたXML Schemaの問合せによる注釈の取得」を参照してください。

- 「DOM再現性」

XMLデータを更新するOracle SQL関数の最適化

ほとんどの場合、XMLデータを更新するOracle SQL関数は、入力されたXML文書全体のコピーをメモリー内に生成してから、そのコピーを更新します。ただし、関数updateXML、insertChildXML、insertChildXMLbefore、insertChildXMLafterおよびdeleteXML 、つまり、insertXMLbefore、insertXMLafterおよびappendChildXMLを除くすべてが、オブジェクト・リレーショナル形式またはバイナリXMLとして格納されている、XMLType表および列に対するSQL UPDATE操作のために最適化されます。

構造化記憶域の場合、特定の条件が満たされると、関数呼び出しは、オブジェクト・リレーショナル列を新しい値で直接更新するようにリライトできます。バイナリXML記憶域の場合、ターゲットの更新の前のデータは変更されず、SecureFile LOBが使用されている場合(デフォルトの動作)は、スライド挿入を使用して、変更が必要なデータ部分のみが更新されます。

関連項目:

- ピース単位の更新の詳細は、「XML Schemaに基づくXML文書および基づかないXML文書の更新」を参照してください。

- XPathリライトの条件の詳細は、第3章「Oracle XML DBの使用」および第8章「構造化記憶域のXPathリライト」を参照してください。

- 「XQuery用のパフォーマンス・チューニング」

オブジェクト・リレーショナル記憶域の例では、例4-15に記載されているupdateXMLへのXPath引数は、Oracle XML DBで処理され、例4-16に記載されている同等のオブジェクト・リレーショナルSQLコードにリライトされます。

例4-15 UPDATEXML式内のXPath式

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/User'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30))
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

XMLCAST(XMLQUERY('$P/PURCHASEO
------------------------------
SBELL

UPDATE purchaseorder
SET OBJECT_VALUE = updateXML(OBJECT_VALUE, '/PurchaseOrder/User/text()', 'SVOLLMAN')
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE AS "p");

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/User'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30))
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

XMLCAST(XMLQUERY('$P/PURCHASEO
------------------------------
SVOLLMAN

例4-16 UPDATEXML式と同等のオブジェクト・リレーショナル形式の文

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/User'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30))
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

XMLCAST(XMLQUERY('$P/PURCHASEO
------------------------------
SBELL

UPDATE purchaseorder p
SET p."XMLDATA"."USERID" = 'SVOLLMAN'
WHERE p."XMLDATA"."REFERENCE" = 'SBELL-2002100912333601PDT';

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/User'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(30))
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

XMLCAST(XMLQUERY('$P/PURCHASEO
------------------------------
SVOLLMAN

注意:
ここで説明するDML用のXMLDATAの使用方法は、Oracle XML DBの内部動作の説明に限定されます。DML操作には、XMLDATA自身を使用しないでください。XMLDATAを直接使用できるのは、DDL操作に対してのみで、DML操作には使用できません。
一般的に、コード内ではXML Schemaオブジェクト・モデルとSQLオブジェクト・モデル間の現在のマッピングに依存しないでください。Oracle XML DB実装のマッピングは将来変更される可能性があります。

XMLデータを変更するOracle SQL関数を使用した、XMLビューの作成

XMLデータを変更するOracle SQL関数(updateXML、insertChildXML、insertChildXMLbefore、insertChildXMLafter、insertXMLbefore、insertXMLafter、appendChildXMLおよびdeleteXML)を使用して、XMLデータの新しいビューを作成できます。

例4-17では、Oracle SQL関数updateXMLを使用してpurchaseorder表のビューを作成します。

例4-17 UPDATEXMLを使用したビューの作成

CREATE OR REPLACE VIEW purchaseorder_summary OF XMLType AS
SELECT updateXML(OBJECT_VALUE,
'/PurchaseOrder/Actions', NULL,
'/PurchaseOrder/ShippingInstructions', NULL,
'/PurchaseOrder/LineItems', NULL) AS XML
FROM purchaseorder p;

SELECT OBJECT_VALUE FROM purchaseorder_summary
WHERE XMLExists('$p/PurchaseOrder[Reference="DAUSTIN-20021009123335811PDT"]'                  PASSING OBJECT_VALUE AS "p");

OBJECT_VALUE
---------------------------------------------------------------------------
<PurchaseOrder
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd">
<Reference>DAUSTIN-20021009123335811PDT</Reference>
<Actions/>
<Reject/>
<Requestor>David L. Austin</Requestor>
<User>DAUSTIN</User>
<CostCenter>S30</CostCenter>
<ShippingInstructions/>
<SpecialInstructions>Courier</SpecialInstructions>
<LineItems/>
</PurchaseOrder>

INSERTCHILDXML SQL関数

Oracle SQL関数insertChildXMLは、親のXML要素の下に新しい子(同じ型の1つ以上の要素、または単一の属性)を挿入します。挿入のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数insertChildXMLには、次のパラメータがあります(この順序どおり)。

- target-data(XMLType) - ターゲットの親要素を含むXMLデータ。

- parent-xpath(VARCHAR2)– target-data内で親要素を検索するXPath 1.0式。child-dataは、それぞれの親要素の下に挿入されます。
parent-xpathが要素ノードの空シーケンスと一致する場合、挿入は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。parent-xpathが要素ノードのシーケンスと一致しない場合(特に、parent-xpathが1つ以上の属性ノードまたはテキスト・ノードと一致する場合)、エラーが発生します。

- child-name (VARCHAR2): 挿入する子要素または属性の名前。属性名は、child-nameの一部として先頭にアットマーク(@)が付くことで、要素名と区別されます。たとえば、@my_attributeとmy_elementです。(アットマークは属性名の一部ではありませんが、引数内でchild-nameが属性であることを示す働きをします。)

- child-data(XMLTypeまたはVARCHAR2) - 挿入する子XMLデータ。

- 1つ以上の要素を挿入する場合、このデータ型はXMLTypeで、要素ノードを含みます。child-data内の最上位の要素ノードはそれぞれ、child-nameと同じ名前(タグ)を持つ必要があります(そうでない場合、エラーが発生します)。

- 属性を挿入する場合、このデータ型はVARCHAR2で、(スカラー)属性値を表します。挿入位置に同じ名前の属性がすでに存在する場合、エラーが発生します。

- namespace(オプション、VARCHAR2): パラメータparent-xpathおよびchild-dataのXML名前空間。

XMLデータchild-dataは、1つ以上の子要素として、または単一の子属性として、parent-xpathで見つかった各親要素の下に挿入されます。

NULL引数に対する関数insertChildXMLの動作は、次のとおりです(優先順位の高い順に示します)。

- child-nameがNULLの場合、エラーが発生します。

- target-dataまたはparent-xpathがNULLの場合、NULLが戻されます。

- child-dataがNULLの場合、次のようになります。

- child-name名が要素名の場合、挿入は行われず、target-dataがそのままの状態で戻されます。

- child-name名が属性名の場合、空の属性値が挿入されます。たとえば、my_attribute = ""になります。

図4-4に構文を示します。

図4-4 INSERTCHILDXMLの構文

target-dataがXML Schemaに基づいている場合、そのスキーマを参照して挿入位置が決定されます。たとえば、スキーマがchild-nameという子要素をparent-xpathの最初の子要素に制限している場合、挿入はこれに基づいて行われます。同様に、child-nameまたはchild-data引数が、関連付けられたスキーマに対して不適切である場合は、エラーが発生します。

親要素がchild-nameという名前と種類に対応する子を持っていない場合(かつ、関連付けられたXML Schemaが存在し、そのスキーマによってそのような子が許可されている場合)、child-dataが、child-nameという名前で、新しい子要素または新しい属性値として挿入されます。

親要素がすでにchild-nameという名前(アットマークなし)の子属性を持つ場合は、エラーが発生します。親要素がすでにchild-nameという名前の子要素を持つ場合(かつ、関連付けられたXML Schemaが存在し、そのスキーマによって複数の子要素が許可されている場合)、child-dataは、その要素がchild-nameという名前の子要素になるように挿入されます。ただし、子シーケンス内の位置は予想外の結果になります。

既存の空でない子要素のコレクションに要素を挿入する必要があり、順序が重要な場合は、SQL/XML関数appendChildXMLまたはinsertXMLbeforeを使用してください。

例4-18に、SQL UPDATE文とOracle SQL関数insertChildXMLを使用して、新しいLineItem要素をLineItems要素の子として挿入する方法を示します。

例4-18 LineItems要素へのLineItem要素の挿入

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[@ItemNumber=222]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[@ITEMNUMBER=222]'
---------------------------------------------------------------

1 row selected.

UPDATE purchaseorder
SET OBJECT_VALUE =
insertChildXML(OBJECT_VALUE,
'/PurchaseOrder/LineItems',
'LineItem',
XMLType('<LineItem ItemNumber="222">
<Description>The Harder They Come</Description>
<Part Id="953562951413"
UnitPrice="22.95"
Quantity="1"/>
</LineItem>'))
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING OBJECT_VALUE AS "p");

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[@ItemNumber=222]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[@ITEMNUMBER=222]'
---------------------------------------------------------------
<LineItem ItemNumber="222">
<Description>The Harder They Come</Description>
<Part Id="953562951413" UnitPrice="22.95" Quantity="1"/>
</LineItem>

1 row selected.

更新するXMLデータがXMLスキーマに基づいていて、ネームスペースを参照する場合、挿入するデータも同じネームスペースを参照する必要があります。参照しない場合は、挿入されるデータがXMLスキーマに準拠しないため、エラーが発生します。

例4-19は例4-18と似ていますが、挿入されるLineItem要素が名前空間を参照しています。これは、関連するXML Schemaでこの要素に対する名前空間が必要であることを前提としています。

例4-19 名前空間を使用する要素の挿入

UPDATE purchaseorder
SET OBJECT_VALUE =
insertChildXML(OBJECT_VALUE,
'/PurchaseOrder/LineItems',
'LineItem',
XMLType('<LineItem xmlns="films.xsd" ItemNumber="222">
<Description>The Harder They Come</Description>
<Part Id="953562951413"
UnitPrice="22.95"
Quantity="1"/>
</LineItem>'))
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING OBJECT_VALUE AS "p");

このような名前空間の使用方法は、関数insertChildXMLに対する名前空間引数の使用方法とは異なるため、注意してください。そのオプションの引数に指定される名前空間は、挿入されるコンテンツではなく、XPath引数のみに適用されます。

INSERTCHILDXMLBEFORE SQL関数

Oracle SQL関数insertChildXMLbeforeは、1つ以上のコレクション要素をターゲットの親要素の子として挿入します。各ターゲットは、指定された既存のコレクション要素の直前に挿入されます。挿入のターゲットである既存のXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数insertChildXMLbeforeには、次のパラメータがあります(この順序どおり)。

- target-data(XMLType) - 挿入のターゲットであるXMLデータ。

- parent-xpath(VARCHAR2)– target-data内で親要素を検索するXPath 1.0式。child-dataは、それぞれの親要素の下に挿入されます。
parent-xpathが要素ノードの空シーケンスと一致する場合、挿入は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。parent-xpathが要素ノードのシーケンスと一致しない場合(特に、parent-xpathが1つ以上の属性ノードまたはテキスト・ノードと一致する場合)、エラーが発生します。

- child-xpath (VARCHAR2): 挿入されるchild-dataの直後の位置の既存の子を検索する相対XPath 1.0式。この式は、parent-xpathに示された要素の子要素に名前を指定している必要があります。また、述語を含めることもできます。

- child-data(XMLType) - 挿入する子要素XMLデータ。このデータ型は常にXMLTypeであり、要素ノードを含んでいます。child-data内の最上位の要素ノードはそれぞれ、child-xpathに示された要素と同じデータ型を持つ必要があります(そうでない場合、エラーが発生します)。

- namespace(オプション、VARCHAR2) - パラメータparent-xpath、child-xpathおよびchild-dataのネームスペース。

XMLデータchild-dataは、1つ以上の子要素として、parent-xpathで見つかった各親要素の下に挿入されます。

NULL引数に対する関数insertChildXMLbeforeの動作は、次のとおりです(優先順位の高い順に示します)。

- child-nameがNULLの場合、エラーが発生します。

- target-dataまたはparent-xpathがNULLの場合、NULLが戻されます。

- child-dataがNULLの場合、挿入は行われず、target-dataがそのままの状態で戻されます。

図4-5に構文を示します。

図4-5 INSERTCHILDXMLBEFOREの構文

INSERTCHILDXMLAFTER SQL関数

Oracle SQL関数insertChildXMLafterは、1つ以上のコレクション要素をターゲットの親要素の子として挿入します。各ターゲットは、指定された既存のコレクション要素の直後に挿入されます。挿入のターゲットである既存のXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数insertChildXMLafterには、次のパラメータがあります(この順序どおり)。

- target-data(XMLType) - 挿入のターゲットであるXMLデータ。

- parent-xpath(VARCHAR2)– target-data内で親要素を検索するXPath 1.0式。child-dataは、それぞれの親要素の下に挿入されます。
parent-xpathが要素ノードの空シーケンスと一致する場合、挿入は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。parent-xpathが要素ノードのシーケンスと一致しない場合(特に、parent-xpathが1つ以上の属性ノードまたはテキスト・ノードと一致する場合)、エラーが発生します。

- child-xpath (VARCHAR2): 挿入されるchild-dataの直前の位置の既存の子を検索する相対XPath 1.0式。この式は、parent-xpathに示された要素の子要素に名前を指定している必要があります。また、述語を含めることもできます。

- child-data(XMLType) - 挿入する子要素XMLデータ。このデータ型は常にXMLTypeであり、要素ノードを含んでいます。child-data内の最上位の要素ノードはそれぞれ、child-xpathに示された要素と同じデータ型を持つ必要があります(そうでない場合、エラーが発生します)。

- namespace(オプション、VARCHAR2) - パラメータparent-xpath、child-xpathおよびchild-dataのネームスペース。

XMLデータchild-dataは、1つ以上の子要素として、parent-xpathで見つかった各親要素の下に挿入されます。

NULL引数に対する関数insertChildXMLafterの動作は、次のとおりです(優先順位の高い順に示します)。

- child-nameがNULLの場合、エラーが発生します。

- target-dataまたはparent-xpathがNULLの場合、NULLが戻されます。

- child-dataがNULLの場合、挿入は行われず、target-dataがそのままの状態で戻されます。

図4-6に構文を示します。

図4-6 INSERTCHILDXMLAFTERの構文

INSERTXMLBEFORE SQL関数

Oracle SQL関数insertXMLbeforeは、任意の種類の1つ以上のノードを、属性ノード以外のターゲット・ノードの直前に挿入します。挿入のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数insertXMLbeforeには、次のパラメータがあります(この順序どおり)。

- target-data(XMLType) - 挿入のターゲットであるXMLデータ。

- successor-xpath(VARCHAR2) - 属性ノード以外の種類のtarget-data内で0個以上のノードを検索するXPath 1.0式。XML-dataが、これらの各ノードの直前に挿入されます。こうすれば、XML-dataのノードは、successor-xpathノードの前にある各兄弟になります。
successor-xpathがノードの空のシーケンスと一致する場合、挿入は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。successor-xpathが、属性ノード以外のノードのシーケンスと一致する場合、エラーが発生します。

- XML-data (XMLType) - 挿入されるXMLデータ。任意の種類の1つ以上のノード。ノードの順序は、挿入後も保持されます。

- namespace(オプション、VARCHAR2) – パラメータsuccessor-xpathのネームスペース。

XML-dataノードは、successor-xpathで見つかった属性以外のノードそれぞれの直前に挿入されます。

関数insertXMLbeforeのNULL引数に対する動作は、次のとおりです。

- target-dataまたはparent-xpathがNULLの場合、NULLが戻されます。

- それ以外の場合、child-dataがNULLであれば、挿入は行われず、target-dataがそのままの状態で戻されます。

図4-7に構文を示します。

図4-7 INSERTXMLBEFOREの構文

例4-20 最初のLineItem要素の直前にLineItem要素を挿入

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[1]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[1]'PASSINGPO.OBJECT_
------------------------------------------------------------------
<LineItem ItemNumber="1">
<Description>Salesman</Description>
<Part Id="37429158920" UnitPrice="39.95" Quantity="2"/>
</LineItem>

UPDATE purchaseorder
SET OBJECT_VALUE =
insertXMLbefore(OBJECT_VALUE,
'/PurchaseOrder/LineItems/LineItem[1]',
XMLType('<LineItem ItemNumber="314">
<Description>Brazil</Description>
<Part Id="314159265359"
UnitPrice="69.95"
Quantity="2"/>
</LineItem>'))
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING OBJECT_VALUE AS "p");

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[position() <= 2]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[POSITION()<=2]'PASSINGPO.OBJECT_
------------------------------------------------------------------------------
<LineItem ItemNumber="314">
<Description>Brazil</Description>
<Part Id="314159265359" UnitPrice="69.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="1">
<Description>Salesman</Description>
<Part Id="37429158920" UnitPrice="39.95" Quantity="2"/>
</LineItem>

注意:
Oracle SQL関数insertXMLbeforeを使用する問合せは、最適化されません。このため、関数insertChildXML、insertChildXMLbeforeまたはinsertChildXMLafterをかわりに使用することをお薦めします。「XQuery用のパフォーマンス・チューニング」を参照してください。

INSERTXMLAFTER SQL関数

Oracle SQL関数insertXMLafterは、任意の種類の1つ以上のノードを、属性ノード以外のターゲット・ノードの直後に挿入します。挿入のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。したがって、これはinsertXMLbeforeと似ていますが、ターゲット・ノードの前ではなく後に挿入します。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数insertXMLafterには、次のパラメータがあります(この順序どおり)。

- target-data(XMLType) - 挿入のターゲットであるXMLデータ。

- successor-xpath(VARCHAR2) - 属性ノード以外の種類のtarget-data内で0個以上のノードを検索するXPath 1.0式。XML-dataが、これらの各ノードの直後に挿入されます。こうすれば、XML-dataのノードは、successor-xpathノードの後ろにある各兄弟になります。
successor-xpathがノードの空のシーケンスと一致する場合、挿入は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。successor-xpathが、属性ノード以外のノードのシーケンスと一致する場合、エラーが発生します。

- XML-data (XMLType) - 挿入されるXMLデータ。任意の種類の1つ以上のノード。ノードの順序は、挿入後も保持されます。

- namespace(オプション、VARCHAR2) – パラメータsuccessor-xpathのネームスペース。

XML-dataノードは、successor-xpathで見つかった属性以外のノードそれぞれの直後に挿入されます。

関数insertXMLafterのNULL引数に対する動作は、次のとおりです。

- target-dataまたはparent-xpathがNULLの場合、NULLが戻されます。

- それ以外の場合、child-dataがNULLであれば、挿入は行われず、target-dataがそのままの状態で戻されます。

図4-8に構文を示します。

図4-8 INSERTXMLAFTERの構文

注意:
Oracle SQL関数insertXMLafterを使用する問合せは、最適化されません。このため、関数insertChildXML、insertChildXMLbeforeまたはinsertChildXMLafterをかわりに使用することをお薦めします。「XQuery用のパフォーマンス・チューニング」を参照してください。

APPENDCHILDXML SQL関数

Oracle SQL関数appendChildXMLは、任意の種類の1つ以上のノードを、指定された要素ノードの最後の子として挿入します。挿入のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数appendChildXMLには、次のパラメータがあります(この順序どおり)。

- target-data(XMLType): ターゲットの親要素を含むXMLデータ。

- parent-xpath(VARCHAR2) - 挿入操作のターゲットであるtarget-dataにあるゼロまたは複数の要素ノードを検索するXPath 1.0式。child-dataは、こうした各親要素の最後の子として挿入されます。
parent-xpathが要素ノードの空シーケンスと一致する場合、挿入は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。parent-xpathが要素ノードのシーケンスと一致しない場合(特に、parent-xpathが1つ以上の属性ノードまたはテキスト・ノードと一致する場合)、エラーが発生します。

- child-data (XMLType) : 挿入される子データ。任意の種類の1つ以上のノード。ノードの順序は、挿入後も保持されます。

- namespace(オプション、VARCHAR2) : パラメータparent-xpathの名前空間。

XMLデータchild-dataは、parent-xpathにより指定された各要素ノードの最後の子として挿入されます。

関数appendChildXMLのNULL引数に対する動作は、次のとおりです。

- target-dataまたはparent-xpathがNULLの場合、NULLが戻されます。

- それ以外の場合、child-dataがNULLであれば、挿入は行われず、target-dataがそのままの状態で戻されます。

図4-9に構文を示します。

図4-9 APPENDCHILDXMLの構文

例4-21 Action要素の最後の子としてDate要素を挿入

SELECT XMLQuery('$p/PurchaseOrder/Actions/Action[1]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/ACTIONS/ACTION[1]'PASSINGPO.OBJECT_VALUE
-------------------------------------------------------------------
<Action>
<User>KPARTNER</User>
</Action>

UPDATE purchaseorder
SET OBJECT_VALUE =
appendChildXML(OBJECT_VALUE,
'PurchaseOrder/Actions/Action[1]',
XMLType('<Date>2002-11-04</Date>'))
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING OBJECT_VALUE AS "p");

SELECT XMLQuery('$p/PurchaseOrder/Actions/Action[1]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/ACTIONS/ACTION[1]'PASSINGPO.OBJECT_VALUE
-------------------------------------------------------------------
<Action>
<User>KPARTNER</User>
<Date>2002-11-04</Date>
</Action>

注意:
Oracle SQL関数appendChildXMLを使用する問合せは、最適化されません。このため、関数insertChildXML、insertChildXMLbeforeまたはinsertChildXMLafterをかわりに使用することをお薦めします。「XQuery用のパフォーマンス・チューニング」を参照してください。

DELETEXML SQL関数

Oracle SQL関数deleteXMLは、任意の種類のXMLノードを削除します。削除のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数deleteXMLには、次のパラメータがあります(この順序どおり)。

- target-data(XMLType) - (削除される)ターゲット・ノードを含むXMLデータ。

- xpath(VARCHAR2) - 削除操作のターゲットであるtarget-dataにあるゼロまたは複数のノードを検索するXPath 1.0式。こうした各ノードは削除されます。
xpathがノードの空シーケンスと一致する場合、削除は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。xpathが最上位の要素ノードと一致する場合、エラーが発生します。

- namespace(オプション、VARCHAR2) : パラメータxpathの名前空間。

xpathで見つかったXMLノードがtarget-dataから削除されます。target-dataまたはxpathがNULLの場合、関数deleteXMLはNULLを戻します。

図4-10に構文を示します。

図4-10 DELETEXMLの構文

例4-22 LineItem要素(番号222)の削除

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[@ItemNumber=222]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[@ITEMNUMBER=222]'PASSINGPO
------------------------------------------------------------------------
<LineItem ItemNumber="222">
<Description>The Harder They Come</Description>
<Part Id="953562951413" UnitPrice="22.95" Quantity="1"/>
</LineItem>

UPDATE purchaseorder
SET OBJECT_VALUE =
deleteXML(OBJECT_VALUE,
'/PurchaseOrder/LineItems/LineItem[@ItemNumber="222"]')
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING OBJECT_VALUE AS "p");

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[@ItemNumber=222]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[@ITEMNUMBER=222]'PASSINGPO
------------------------------------------------------------------------

1 row selected.

5 Oracle XML DBでのXQueryの使用

この章では、Oracle XML DBでのXQuery言語の使用方法を説明します。XQuery言語でのOracle XML DBサポート、たとえばSQL/XML関数XMLQueryおよびXMLTable、それにSQL*Plus XQUERYコマンドについて説明します。

この章の内容は次のとおりです。

- Oracle XML DBにおけるXQueryの概要

- XQuery言語の概要

- SQL/XML関数XMLQUERYおよびXMLTABLE

- XQueryの用途

- 事前定義の名前空間と接頭辞

- URIスキームoradb: XQueryを使用した表またはビュー・データの問合せ

- Oracle XQuery拡張関数

- XMLQUERYおよびXMLTABLEの例

- XQuery用のパフォーマンス・チューニング

- Oracle XML DBにおけるXQuery静的型チェック

- SQL*Plus XQUERYコマンド

- XQueryの、PL/SQL、JDBC、およびODP.NETとの使用

- Oracle XML DBでのXQueryサポート

Oracle XML DBにおけるXQueryの概要

Oracle XML DBのXQuery言語サポートは、SQL/XML関数XMLQueryおよびXMLTableのネイティブ実装により提供されています。便宜性の観点から、SQL*PlusのコマンドXQUERYも用意されており、XQuery式を直接入力することができます。実質的に、このコマンドにより、SQL*PlusはXQueryコマンドライン・インタプリタになります。

Oracle XML DBは、SQL/XML関数XMLQuery、XMLTable、XMLExistsおよびXMLCastに引数として渡されるXQuery式をコンパイルします。このコンパイルにより、SQL問合せブロックと、SQL/XML関数とXPath関数を使用する演算子ツリーが作成されます。XMLQuery、XMLTable、XMLExistsまたはXMLCastを含むSQL文は一括してコンパイルおよび最適化され、リレーショナル・データベースとXQuery特有の最適化テクノロジの両方を活用します。使用するXML記憶域と索引付けメソッドにより、XPath関数をさらに最適化することができます。結果として生じる最適化された演算子ツリーは、ストリーム方式で実行されます。

関連項目:

- 「SQL/XML関数XMLQUERYおよびXMLTABLE」および「SQL*Plus XQUERYコマンド」

- XQuery言語を拡張するOracle固有のXQuery関数については「Oracle XQuery拡張関数」

- Oracle XML DBでのXQueryサポートの詳細は、「Oracle XML DBでのXQueryサポート」

XQuery言語の概要

Oracle XML DBはXQuery言語の最新バージョンの仕様、W3C XQuery 1.0勧告をサポートしています。このセクションでは、XQuery言語の簡単な概要を示します。詳細は、XQuery言語に関する最新の書籍や、http://www.w3c.orgから入手できる、XQueryを定義している標準に関する文書を参照してください。

シーケンスに基づく関数言語

XQuery 1.0はXMLデータの問合せのために設計されたW3C言語です。多くの点でSQLに類似していますが、SQLが単に構造化されたリレーショナル・データを問い合せるために設計されているのに対し、XQueryは、様々なデータ・ソースの半構造化されたXMLデータを問い合せるために特に設計されています。XQueryは、XMLデータがあれば、Webサービスからアクセスできるデータベース表に格納されているか、他の方法でその場で作成されるかに関係なく、XMLデータを問い合せるためにいつでも使用できます。XMLデータの問合せの他に、XQueryはXMLデータの構成にも使用できます。この点で、XQueryはXSLTやその他のSQL/XMLパブリッシング関数(XMLElementなど)の代用として使用できます。

XQueryは、XML Information Set (Infoset)データ・モデルとXML Schema型体系を統合した、Post-Schema-Validation Infoset (PSVI)データ・モデルに基づいています。XQueryではシーケンスに基づく新しいデータ・モデルが定義されています。各XQuery式の結果がシーケンスです。XQueryは常にシーケンスの操作に関わります。このためXQueryは集合操作言語に類似しています。ただしシーケンスは順序付けされていて、重複項目を含むことができる点が異なります。XQueryシーケンスが他の言語のシーケンスと異なる点は、ネストされたXQueryシーケンスは実際の効果において常にフラット化されるという点です。

多くの場合、シーケンスを順序のないものとして処理することにより最適化を促進できます。ただしそれは可能な場合に限られ、ユーザーの責任となります。この順序なしモードは、ネストされた反復(for)の処理で順序を結合する場合や、XPath式を処理する場合に適用できます(たとえば/a/bでは、一致するb要素は文書順序に関係なく処理できます)。

XQueryシーケンスはゼロ個以上の項目から構成されています。項目は、アトム型(スカラー)の値またはXMLノードです。項目は、XML Schemaの型に基づくリッチ型体系を使用して型指定されます。この型体系は、ブール、数値、および文字列といった単純なスカラー型に制限されていたXPath 1.0から大きく変更された部分です。

XQueryは関数言語です。このため、評価され、値(XQueryではシーケンス)を戻す、可能な式の集合からなります。XQueryは関数言語なので、通常は参照が透過的です。同じコンテキストで評価された同じ式は同じ値を戻します。

こうした数学的長所の例外には、次のものがあります。

- 外部環境との相互作用から値を導出するXQuery式。たとえば、fn:current-time(...)またはfn:doc(...)といった式は常に同じ値を戻すとはかぎりません。これは、それらの式が、変化する外部の条件に依存しているためです(時刻の変化、ターゲット文書のコンテンツの変化)。
fn:docのような場合には、XQueryは単一の問合せの実行の内部で参照が透過的なものと定義されます。単一の問合せの内部では、同じ引数を伴うfn:docの呼出しは、同じ文書を結果とします。

- 個別のXQuery言語の実装に依存するものとして定義されているXQuery式。そうした式の評価結果は、実装に応じて異なる場合があります。関数fn:docは、本質的に実装により定義される関数の例です。

参照の透過性は、XQuery変数にも適用されます。同じコンテキストでの同じ変数は同じ値を持ちます。関数言語はこの点で、数学で言う形式主義に似ており、手続き型、または命令型のプログラミング言語とは異なっています。手続き型言語の変数は、実際にはメモリー位置の名前で、現在の値や状態を持っており、任意の時点におけるその内容により表現されます。XQueryなど宣言型言語における変数は、実際には静的な値の名前です。

XQuery式

XQuery式では大/小文字が区別されます。式には次のものが含まれます。

- 1次式: リテラル、変数、または関数アプリケーション。変数名は、たとえば$fooのように、ドル記号($)で始まります。リテラルには、数値、数値、文字、または実体参照。

- XPath式: 任意のXPath式。XPath 2.0標準はXQueryのサブセットになります。

- FLWOR式: 最も重要なXQuery式で、次の要素を順番に並べたもので構成されています。FLWORという名もそれに由来しています。for、let、where、order by、return。

- XQueryシーケンス: カンマ(,)コンストラクタはシーケンスを作成します。unionやintersectといったシーケンス操作関数も使用できます。XQueryシーケンスはすべて、事実上フラットです。ネストされたシーケンスは、フラット化された同等のものとして処理されます。このため、たとえば(1, 2, (3, 4, (5), 6), 7)は(1, 2, 3, 4, 5, 6, 7)として処理されます。(42)などの単一シーケンスは、大部分のXQueryコンテキストで、単一項目42と同じ動作をします。前述のように、任意のXQuery式の結果はシーケンスです。

- 直接(リテラル)構成: XML要素と属性の構文により、要素と属性が自動的に構成されます。構文に表記したとおりに使用されることになります。たとえば、XQuery式<a>33</a>により、XML要素<a>33</a>が構成されます。

- 計算による(動的)構成: 計算された値を使用して、実行時にXMLデータを構成できます。たとえば、次のXQuery式によりこのXMLデータ<foo toto="5"><bar>tata titi</bar> why? </foo>が構成されます。

<foo>attribute toto {2+3},
element bar {"tata", "titi"},
text {" why? "}</foo>

この例では、要素fooが直接構成で、他の部分の構成は計算されたものです。実践では、計算されるコンストラクタの引数はリテラル(toto、"tata"など)ではなく式(2+3など)で、評価されます。要素や属性コンストラクタの名前と値引数は、どちらも計算できます。中カッコ({, })は、XQuery式を評価対象外にするのに使用します。

- 条件式: 通常どおりですが、式の各部分が任意の式になることに注意してください。たとえば、この条件式では、任意のXQuery式が各部分式(something、somethingElse、expression1、およびexpression2)に入ります。

if (something < somethingElse) then expression1 else expression2

- 数式、リレーショナル式 – 通常どおりですが、各リレーショナル式が(ブール脚注1)値を戻すことに注意してください。次に例を示します。

2 + 3
42 < $a + 5
(1, 4) = (1, 2)
5 > 3 eq true()

- 量化式: 全称(every)および存在(some)関数を使用してFLWOR式を簡単に使用できる場合があります。次に例を示します。

every $foo in doc("bar.xml")//Whatever satisfies $foo/@bar > 42
some $toto in (42, 5), $titi in (123, 29, 5) satisfies $toto = $titi

- 正規表現: XQueryの正規表現はXML Schema1.0およびPerlに基づいています。(「XQueryの関数と演算子のサポート」を参照)

- 型表現: XQuery型を表現するXQuery式。たとえば、item()、node()、attribute()、element()、document-node()、namespace()、text()、xs:integer、xs:string。脚注 2
型表現は、次のような出現インジケータを持てます。?(オプション。0回または1回)、*(0回以上)、+(1回以上)。たとえば、document-node(element())*、item()+、attribute()?。

XQueryには、型と組み合せて使用する演算子もあります。cast as、castable as、treat as、instance の、typeswitch、およびvalidateなどです。たとえば、"42" cast as xs:integerは、値が整数の2である式です。(厳密には、値が型を表現していないので、これは型表現ではありません)。

FLWOR式

XQuery一般について考えた場合、FLWOR式には多くの学習事項があります。この項の説明は簡単な概要にすぎません。

FLWORはXQueryで最も一般的な式構文です。FLWOR(「フラワー」と読みます)は、for、let、where、order by、およびreturnを表しています。FLWOR式には1つ以上のforまたはlet句と、1つのreturn句を持ちます。1つのwhereおよびorder by句がオプションです。

- for: 1つ以上の変数を任意の値に順にバインドします。つまり、各変数に対し反復を行いますが、変数を各回の反復で別の値にバインドします。
各回の反復で、変数は出現する順にバインドされ、forリストで$laterの前にリストされた変数$earlierの値が、変数$laterのバインドで使用されます。たとえば、次の式は、2回目の反復で$iを4にバインドし、$jを6(2+4)にバインドします。

for $i in (3, 4), $j in ($i, 2+$i)

- let: 1つ以上の変数をバインドします。
forと同様、letでも、letのバインディング・リストで先にリストされている別の変数を使用して(またはforやletで囲むことにより)、変数を計算した値にバインドできます。たとえば、次の式は$jを5(3+2)にバインドします。

let $i := 3, $j := $i + 2

- where: forおよびletの変数バインディングを特定の条件に応じてフィルタします。SQLのWHERE句に類似しています。

- order by: whereフィルタリングの結果をソートします。

- return: 順序付けとフィルタリングがされた値を構成します。これがFLWOR式の最終的な結果です。フラット化されたシーケンスになります。

式forとletは、SQLのFROM句に対して同じように機能します。式whereは、SQLのWHERE句と同じように機能し、式order byはSQLのORDER BYと似ています。式returnは、SQLのSELECTに似ています。両方の言語で名前が共通している2つのキーワード(where、order by)を除いて、FLWOR句の順序はSQL句の順序と反対ですが、対応する句の意味は非常に類似しています。

FLWOR式(order byを含む)の使用は、文書の順序と異なる順序でXQueryシーケンスを構成する唯一の方法です。

SQL/XML関数XMLQUERYおよびXMLTABLE

SQL/XML関数XMLQuery、XMLTable、XMLExists、XMLCastは、SQL/XML標準により、SQL言語とXQuery言語の一般インタフェースとして定義されています。他のSQL/XML関数と同様、これらの関数を使用すると、SQLとXML、両方の強力な機能と柔軟性を活用できます。これらの関数を使用すると、リレーショナル・データを使用したXMLデータの構成、XML同様のリレーショナル・データに対する問合せ、およびXMLデータからのリレーショナル・データの構成が可能です。

SQL関数XMLExistsおよびXMLCastについては、このマニュアルの別の項で説明します。この項では、関数XMLQueryとXMLTableについて説明しますが、本章の例の大半はXMLExistsおよびXMLCastも使用します。一般的な使用方法は次のとおりです。

- XMLQueryとXMLCastは通常、SELECTリストで使用します。

- XMLTableは一般的にSQLのFROM句で使用します。

- XMLExistsは通常、SQLのWHERE句で使用します。

XMLQueryとXMLTableの両方がXQuery式を評価します。XQuery言語では、式は常に項目のシーケンスを戻します。関数XMLQueryはこのシーケンスの項目を集計し、単一のXML文書または断片を戻します。関数XMLTableは、XQueryシーケンスからの1つの項目を各行に含むSQL表を戻します。

関連項目:

- OracleによるSQL/XML標準のサポートの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- SQL/XML関数の詳細は、http://www.sqlx.org

- XQuery言語の詳細は、http://www.w3.orgを参照してください。

- Oracle XML DBSで他のSQL/XML関数を使用する方法の詳細は、「SQL関数を使用したXMLの生成」を参照してください。

- 「SQL/XML関数XMLExistsおよびXMLCastを使用したXMLTypeデータの問合せ」

Oracle XML DBのXMLQUERY SQL/XML関数

SQL/XML関数XMLQueryを使用して、XMLデータの構成や問合せができます。この関数は引数としてXQuery式、文字列としてリテラル、そしてオプションで、XQueryコンテキスト項目をSQL式として取ります。コンテキスト項目は、XQuery式を評価する際のXPathコンテキストを確立します。この他に、XMLQueryは、XQuery式の評価の際にXQuery変数にバインドされた値を持つ任意の数のSQL式を引数として受け取ります。関数はXQuery式の評価結果をXMLTypeインスタンスとして戻します。

図5-1 XMLQUERYの構文

XML_passing_clause::=

- XQuery_stringは完結したXQuery式で、プロローグをリテラル文字列として含む場合があります。

- XML_passing_clauseはキーワードPASSINGに1つ以上のSQL式(expr)を続けたもので、それぞれXMLTypeインスタンスまたはSQLスカラー・データ型の(つまり、オブジェクト・データ型でもコレクション・データ型でもない)インスタンスを戻します。それぞれの式(expr)は、適切にキャストされた表またはビューの列の値、PL/SQL変数、バインド変数のいずれかになります。1つを除いてすべての式では、その後にASおよびXQuery identifierが続いている必要があります。それぞれのexprの評価結果は、対応するidentifierにバインドされ、続いてXQuery_stringが評価されます。AS句に続いていないexprがあった場合、そのexprの評価結果は、XQuery_stringを評価する際のコンテキスト項目として使用されます。Oracle XML DBではBY VALUEを渡すことはできますが、BY REFERENCEは渡せないため、BY VALUE句は暗黙的で、省略可能です。

- RETURNING CONTENTは、XMLQueryのアプリケーションが戻す値が、パラメータ化されたXML型XML(CONTENT)のインスタンスであり、パラメータ化された型XML(SEQUENCE)のインスタンスではないことを示します。これは拡張Infosetデータ・モデルに準拠した文書フラグメントです。このため、任意の数の子を持つ単一の文書ノードとなります。子はそれぞれ任意のXMLノード型を取ることができ、特に、テキスト・ノードになることが可能です。
SQL/XML関数XMLQueryでOracle XML DBがサポートするのはRETURNING CONTENT句のみです。RETURNING SEQUENCE句はサポートしていません。

XMLTypeの列、表、またはビューは、関数XMLQueryのコンテキスト項目引数として渡すことができます。例として、例5-8を参照してください。

リレーショナル表やビューに対して、XMLデータのときのように最初にSQL/XMLビューを作成する必要なく問合せを実行するには、XQuery関数fn:collectionをXQuery式内で使用し、URIスキーム名oradbを使用するURIを、データのデータベースの場所とともに引数として引き渡します。「URIスキームoradb: XQueryを使用した表またはビュー・データの問合せ」を参照してください。

注意:
Oracle Database 11gリリース2より前のリリースでは、一部のユーザーは一部の処理の実行にOracle SQL関数extractおよびextractValueを使用していました。これらの処理は、SQL/XML関数XMLQueryおよびXMLCastを使用するとより効率的に実行できます。SQL関数extractおよびextractValueは、Oracle Database 11gリリース2で非推奨になりました。

関連項目:

- SQL/XML関数XMLQueryの定義の詳細は、http://www.sqlx.orgを参照してください。

- Oracle DatabaseにおけるSQL/XML関数XMLQueryの参考情報は、『Oracle Database SQL言語リファレンス』を参照してください。

Oracle XML DBのXMLTABLE SQL/XML関数

SQL/XML関数XMLTableは、XQuery式の評価結果を新規の仮想表に対するリレーショナル行と列に分解します。その仮想表は、既存のデータベース表に挿入したり、SQLを使用して(join式など)問い合せたりできます(例5-9を参照)。SQLのFROM句でXMLTableを使用します。

図5-2 XMLTABLEの構文

XML_namespaces_clause::=

XMLTABLE_options::=

XML_passing_clause::=

XML_table_column::=

- XQuery_stringは完結したXQuery式で、プロローグをリテラル文字列として含む場合があります。式の値は XMLTable関数への入力となります。つまり、このXQueryの結果が分解されリレーショナル・データとして格納されます。

- オプションのXMLNAMESPACES句にはXML名前空間宣言が含まれており、XML_table_columnのPATH句で、XQuery_stringおよびXPath式により参照されます。

- XML_passing_clauseはキーワードPASSINGに1つ以上のSQL式(expr)を続けたもので、それぞれXMLTypeインスタンスまたはSQLスカラー・データ型の(つまり、オブジェクト・データ型でもコレクション・データ型でもない)インスタンスを戻します。それぞれの式(expr)は、適切にキャストされた表またはビューの列の値、PL/SQL変数、バインド変数のいずれかになります。1つを除いてすべての式では、その後にASおよびXQuery identifierが続いている必要があります。それぞれのexprの評価結果は、対応するidentifierにバインドされ、続いてXQuery_stringが評価されます。AS句に続いていないexprがあった場合、そのexprの評価結果は、XQuery_stringを評価する際のコンテキスト項目として使用されます。Oracle XML DBではBY VALUEを渡すことはできますが、BY REFERENCEは渡せないため、BY VALUE句は暗黙的で、省略可能です。

- オプションのCOLUMNS句は、XMLTableにより作成される仮想表の列を定義します。

- COLUMNS句を省略した場合、XMLTableは、COLUMN_VALUEという名前で単独のXMLType疑似列を戻します。

- FOR ORDINALITYは、columnが生成される行数の列になることを示します(SQLデータ型NUMBER)。最大で1個のFOR ORDINALITY句がある必要があります。

- FOR ORDINALITY列を除き、生成された各列に列のデータ型を指定する必要があります。XMLTypeまたは任意のSQLデータ型(構文の説明でdatatypeと呼ばれる)を指定できます。

- オプションのPATH句は、XQuery式stringにより扱われたXQueryの結果の一部がcolumnコンテンツの一部として使用されることを示しています。複数のPATH句を使用してXQueryの結果を異なる仮想表の列に分割できます。
PATHを省略した場合は、XQuery式がcolumnであるものと仮定されます。たとえば、次の2つの式は等価です。

XMLTable(... COLUMNS foo)
XMLTable(... COLUMNS foo PATH 'FOO')

XQuery式stringはXQuery_stringに対して相対的であるため、相対パスの表記にする必要があります。

- オプションのDEFAULT句は、PATH式の結果が空のシーケンス(またはNULL)になる場合に使用する値を指定します。そのexprは、評価されてデフォルト値を生成するXQuery式です。

関連項目:

- SQL/XML関数XMLTableの定義の詳細は、http://www.sqlx.orgを参照してください。

- Oracle DatabaseにおけるSQL/XML関数XMLTableの参考情報は、『Oracle Database SQL言語リファレンス』を参照してください。

注意:
Oracle Database 11gリリース2より前のリリースでは、一部のユーザーは一部の処理の実行に、SQL TABLEコレクション式でOracle SQL関数XMLSequence(TABLE(XMLSequence(...)))を使用していました。これらの処理は、SQL/XML関数XMLTableを使用するとより効率的に実行できます。関数XMLSequenceは、Oracle Database 11gリリース2で非推奨になりました。
SQL TABLEコレクション式の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

XQueryの用途

SQL/XML生成関数またはXSLTを使用して実行される処理には、XQueryを使用して実行できるものが多く、両者の用途は多くの点で一致しています。あるタスクを実行する際にどのツールを使用するかは、様々な考慮事項に基づいて決定されるものであり、その考慮事項の多くはOracle Database以外に関連するものです。このような一般的な問題については、外部のドキュメントを参照してください。

一般的には、XMLデータに主眼を置いている場合はXQueryが使用され、リレーショナル・データに主眼を置いている場合はSQL/XML生成関数(XMLElement、XMLAggなど)が使用されます。

他の条件が同じであれば、既存のXML文書から抽出されたフラグメントに基づいて問合せによってXML文書を構成する場合は通常、リレーショナル・データからスカラー値を抽出し、SQL/XML生成関数を使用して目的のXMLデータを構成するよりも、通常はXQueryのFLOWR式が単純になります(そのためコードのメンテナンスも簡単になります)。一方、既存のリレーショナル・データに基づいて問合せによってXML文書を構成する場合は、通常、SQL/XML生成関数を使用する方が適しています。

Oracle XML DBに関しては、SQL/XML生成関数を使用しても、XMLQueryおよびXMLTableを使用しても、期待できるパフォーマンスは、同じ一般的なレベルです。これは、いずれも最適化のリライト対象になります。

事前定義のネームスペースと接頭辞

次の名前空間と接頭辞は、Oracle XML DBでXQueryとともに使用するように事前定義されています。

表5-1 事前定義の名前空間と接頭辞

接頭辞

名前空間

説明

ora

http://xmlns.oracle.com/xdb

Oracle XML DB名前空間

local

http://www.w3.org/2003/11/xpath-local-functions

XPathのローカル関数宣言名前空間

fn

http://www.w3.org/2003/11/xpath-functions

XPath関数名前空間

xml

http://www.w3.org/XML/1998/namespace

XML名前空間

xs

http://www.w3.org/2001/XMLSchema

XML Schema名前空間

xsi

http://www.w3.org/2001/XMLSchema-instance

XML Schemaインスタンス名前空間

これらの接頭辞は、あらかじめXQuery式プロローグで宣言しなくてもXQuery式で使用できます。また、xml以外は、すべてプロローグ内で再定義できます。ora以外の接頭辞はすべて、XQuery標準で事前定義されています。

URIスキームoradb: XQueryを使用した表またはビュー・データの問合せ

XQuery関数fn:docとfn:collectionを使用して、Oracle XML DBリポジトリのリソースに対して問い合せることができます — 「XQueryを使用したOracle XML DBリポジトリ内でのXMLデータの問合せ」を参照してください。この項では、XQuery関数fn:collectionを使用した、データベースの表およびビュー内のデータの問合せについて説明します。

これを行うには、問い合せる表またはビューを指定する、関数fn:collectionのURI引数を渡します。Oracle URIスキーマoradbによりこの使用が識別されます。これがないと、引数はリポジトリの場所として扱われます。

問い合せる表またはビューは、リレーショナルまたはXMLType型のどちらでもかまいません。リレーショナルの場合は、データはその場で変換され、XMLとして扱われます。fn:collectionによって戻される結果は、常にXQueryシーケンスです。

- XMLTypeの表については、fn:collectionによって戻される各XML文書のルート要素は、表のXML文書のルート要素と同じです。

- リレーショナルの表の場合、fn:collectionによって戻される各XML文書のルート要素はROWです。ROW要素の子は、表の列と同じ名前(大文字)を持つ要素です。子要素の内容は、列のデータに一致します。列の型がXMLTypeの場合は内容はXML要素で、それ以外の場合(列はスカラー型)は内容はxs:string型です。

fn:collectionに引き渡されるURI要素の形式は、次のとおりです。

- データベース・スキーマDB-SCHEMA内のXMLTypeまたはリレーショナルの表あるいはビューTABLEの場合

oradb:/DB-SCHEMA/TABLE/

TABLEがバブリック・シノニムか、TABLEが現在ログイン中のデータベース・ユーザーがアクセス可能な表またはビューの場合、DB-SCHEMAにPUBLICを使用できます。

- リレーショナルの表またはビュー内のXMLType列の場合

oradb:/DB-SCHEMA/REL-TABLE/ROWPRED/X-COL

REL-TABLEはリレーショナル表またはビューで、PREDはXMLType列と関係しないXPath述語です。X-COLはREL-TABLEのXMLType列です。PREDはオプションで、DB-SCHEMA、REL-TABLEおよびX-COLは必須です。

オプションのXPath述語PREDは、次の条件を満たす必要があります。

- XMLType列が一切関係しない。

- 一般的な同等の結合(and)と分離(or)および不等の比較(=、!=、>、<、>=、<=)のみが関係している。

- それぞれの比較演算について、REL-TABLEの両側の名前(XML以外)列、またはある列と他方のような一方の名前が、表5-2で指定された正しい型の値である。他の型を使用すると、エラーが発生します。

表5-2 oradb式: 比較用の列の型

リレーショナルの列の型

XQuery値の型

VARCHAR2、CHAR

xs:stringまたは文字列リテラル

NUMBER、FLOAT、BINARY_FLOAT、BINARY_DOUBLE

xs:decimal、xs:float、xs:double、または数値リテラル

DATE、TIMESTAMP、TIMESTAMP WITH TIMEZONE、TIMESTAMP WITH LOCAL TIMEZONE

xs:date、xs:time、xs:dateTime

INTERVALYEARTOMONTH

xs:yearMonthDuration

INTERVALDAYTOSECOND

xs:dayTimeDuration

RAW

xs:hexBinary

ROWID

xs:stringまたは文字列リテラル

たとえば、このXQuery式は、表oe.warehousesのXMLType列warehouse_specにあって、列warehouse_idの値が6より小さい行のすべてのXML文書を表します。

fn:collection('oradb:/OE/WAREHOUSES/ROW[WAREHOUSE_ID < 6]/WAREHOUSE_SPEC')

関連項目:
「XQueryを使用した表またはビュー・データの問合せ」

Oracle XQuery拡張関数

Oracle XML DBには、W3C標準に用意されているものの他に、いくつかのXQuery関数が追加されています。それらの追加関数はOracle XML DB名前空間、http://xmlns.oracle.com/xdbにあります。この名前空間は事前定義の接頭辞oraを使用します。この項ではこれらのOracle拡張関数を説明します。

ora:contains XQuery関数

ora:contains構文

ora:contains (input_text, text_query [, policy_name] [, policy_owner])

XQueryおよびXPath関数ora:containsは、SQL/XML関数XMLQuery、XMLTableまたはXMLExistsへのコールのXQuery式内で使用できます。これは、全文述語を伴う構成検索を制限する場合に使用されます。関数ora:containsはinput_textがtext_queryと一致した場合は正の整数を戻し(数字が大きいほど、一致の関連性は高くなります)、一致しない場合はゼロを戻します。XQuery式内部で使用される場合(XPath式のみでなく)、XQueryの戻り型はxs:integer()です。XQuery式外部のXPath式で使用される場合、XPathの戻り型はnumberです。

引数input_textは単一のテキスト・ノードまたは属性に対して評価される必要があります。ora:containsにおけるtext_queryの構文と意味論は、いくつかの制限を伴う他はcontainsにおけるtext_queryと同一です。

関連項目:
「ora:contains XQuery関数」

ora:matches XQuery関数

ora:matches構文

ora:matches (target_string, match_pattern [, match_parameter])

XQuery関数ora:matchesを使用すると、正規表現を使用して文字列内のテキストを検索できます。target_string引数が正規表現match_pattern引数に一致していればtrue()を、それ以外の場合はfalse()を戻します。target_stringが空のシーケンスの場合はfalse()を戻します。オプションの引数match_parameterは、検索文字列を修飾するコードで、大文字/小文字の区別などを指定できます。

XQuery関数ora:matchesの動作はSQL条件REGEXP_LIKEと同じですが、引数の型はSQLデータ型ではなくXQuery型です。引数の型は次のとおりです。

- target_string – xs:string?脚注3

- match_pattern - xs:string

- match_parameter - xs:string

関連項目:
SQL条件REGEXP_LIKEの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

ora:replace XQuery関数

ora:replace構文

ora:replace (target_string, match_pattern, replace_string [, match_parameter])

XQuery関数ora:replaceを使用すると、正規表現を使用して文字列内のテキストを置換することができます。target_string内にある正規表現match_patternが出現するたびに、replace_stringに置換されます。置換の結果得られる新しい文字列を戻します。target_stringが空のシーケンスの場合は、空の文字列("")を戻します。オプションの引数match_parameterは、検索文字列を修飾するコードで、大文字/小文字の区別などを指定できます。

XQuery関数ora:replaceの動作はSQL関数regexp_replaceと同じですが、引数の型はSQLデータ型ではなくXQuery型です。引数の型は次のとおりです。

- target_string – xs:string?脚注4

- match_pattern - xs:string

- replace_string - xs:string

- match_parameter - xs:string

さらにora:replaceは引数replace_stringを必要とし(regexp_replaceではオプション)、位置や出現回数を表す引数は使用しません。検索は最初の文字から開始され、すべての出現箇所が置換されます。

関連項目:
SQL関数regexp_replaceの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

ora:sqrt XQuery関数

ora:sqrt構文

ora:sqrt (number)

XQuery関数ora:sqrtは、数値引数の平方根を戻します。引数はXQuery型xs:decimal、xs:float、またはxs:doubleのいずれかです。戻り値のXQuery型は引数と同じです。

ora:tokenize XQuery関数

ora:tokenize構文

ora:tokenize (target_string, match_pattern [, match_parameter])

XQuery関数ora:tokenizeでは、正規表現を使用して入力文字列target_stringを文字列のシーケンスに分割できます。正規表現match_patternと一致する部分文字列はそれぞれ、分割位置を示すセパレータとして扱われます。

トークンのシーケンスは、型xs:string*のXQuery値(xs:string値のシーケンス)として戻されます。target_stringが空のシーケンスの場合は、それが戻されます。オプションの引数match_parameterは、検索文字列を修飾するコードで、大文字/小文字の区別などを指定できます。

引数の型は次のとおりです。

- target_string – xs:string?脚注5

- match_pattern - xs:string

- match_parameter - xs:string

Oracle XQuery拡張式プラグマ

W3CのXQuery仕様では、実装により定義された拡張式を実装で提供できます。XQuery拡張式は、カッコ({、 })で囲まれたXQuery式で、実装で定義されたプラグマが接頭辞になります。

Oracle実装では、この項で説明するプラグマが提供されます。ここに記載したプラグマ以外のプラグマは認識されません。その他のプラグマ、すなわち不正なプラグマ・コンテンツを持つプラグマ(例: (#ora:view_on_null something_else #))を使用すると、エラーが発生します。

ora:view_on_nullの例では、null_test表にVARCHAR2(10)型の列aとbがあり、列b(aではない)が空であるとします。

- (#ora:defaultTable #) – リポジトリ・データの格納に使用されるデフォルトの表を指定します。これを使用して、Query関数fn:docまたはfn:collectionを使用するリポジトリ問合せのパフォーマンスを向上させます。「Oracle XQueryプラグマora:defaultTableの使用」を参照してください。

- (#ora:invalid_path empty #) – 無効なXPath式のターゲットとなるノードがある場合、それが存在しないかのように処理します。次に例を示します。

SELECT XMLQuery('(#ora:invalid_path empty #)
{exists($p/PurchaseOrder//NotInTheSchema)}'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
FROM oe.purchaseorder p;

表oe.purchaseorderのXML Schemaでは、NotInTheSchemaのようなノードは、PurchaseOrderノードの子孫とし使用できません。プラグマがない場合、このような無効なXPath式を使用するとエラーが発生します。しかし、プラグマを使用すると、コール元のコンテキストは、XPath式にターゲット・ノードがないかのように動作します。この例では、コール元のコンテキストはXQuery関数existsで、空のノード・シーケンスが渡されると、XQueryのブール値falseを戻します。(この例ではXQuery関数existsは動作を説明するためのみに使用されています。プラグマは関数existsに特に関連付けられていません)。

- (#ora:view_on_null empty #) – XQuery関数fn:collectionは、それぞれのNULL列に対して空のXML要素を戻します。たとえば、次の問合せでは、<ROW><A>x</A><B></B></ROW>が戻されます。

SELECT XMLQuery('(#ora:view_on_null empty #)
{for $i in fn:collection("oradb:/PUBLIC/NULL_TEST")/ROW
return $i}'
RETURNING CONTENT)
FROM DUAL;

- (#ora:view_on_null null #) – XQuery関数fn:collectionは、NULL列には要素を戻しません。たとえば、次の問合せでは、<ROW><A>x</A></ROW>が戻されます。

SELECT XMLQuery('(#ora:view_on_null null #)
{for $i in fn:collection("oradb:/PUBLIC/NULL_TEST")/ROW
return $i}'
RETURNING CONTENT)
FROM DUAL;

- (#ora:xq_proc #) – プラグマに続くXQuery式内のXQueryプロシージャのコールを最適化しないでください。かわりに機能上の評価を使用します。
これは、SQLヒント/*+ NO_XML_QUERY_REWRITE */と同じ効果がありますが、プラグマの範囲は後に続くXQuery式のみです(SQL文全体ではありません)。

関連項目:
オプティマイザ・ヒントNO_XML_QUERY_REWRITEの詳細は、「XMLIndexの使用の無効化」を参照してください。

- (#ora:xq_qry #) – プラグマに続くXQuery式を最適化してみてください。つまり、もし可能な場合は、機能面で評価しないでください。
ora:xq_procとora:xq_qryの両方の使用例として、次の問合せでは、XMLQueryに対するXQuery式の引数は、一般的に機能面で評価されますが、プラグマora:xq_qryの後に続くfn:collection部分式は可能なかぎり最適化されます。

SELECT XMLQuery('(#ora:xq_proc#)   (: Do not optimize the XQuery expression :)
{for $i in (#ora:xq_qry#)   (: Optimize this subexpression :)
{fn:collection("oradb:/HR/REGIONS")},
$j in (#ora:xq_qry#)   (: Optimize this subexpression :)
{fn:collection("oradb:/HR/COUNTRIES")}
where $i/ROW/REGION_ID = $j/ROW/REGION_ID
and $i/ROW/REGION_NAME = $regionname
return $j}'
PASSING CAST('&REGION' AS VARCHAR2(40)) AS "regionname"
RETURNING CONTENT)
AS asian_countries FROM DUAL;

XMLQUERYおよびXMLTABLEの例

XQueryは非常に汎用性と表現力に富む言語で、SQL/XML関数XMLQuery、XMLTableおよびXMLExistsにより、それらの表現力と計算力がSQLの同様の長所と組み合されます。この項では、これら2つのSQL/XML関数でできることについて説明します。XMLExistsの詳細は、「XMLEXISTS SQL/XML関数」を参照してください。

Oracle XML DBでは、通常は次のようにXQueryを使用します。ここでの例は、それらの使用方法の違いを示すように構成されています。

- Oracle XML DBリポジトリ内でXMLデータを問い合せる。
「XQueryを使用したOracle XML DBリポジトリ内でのXMLデータの問合せ」を参照してください。

- リレーショナル表またはビューを、XMLデータと同様に問い合せる。これを実行するには、Oracle XQuery関数fn:collectionを使用して、URIスキーム名oradbを使用するURIを、引数としてデータのデータベースの場所とともに引き渡します。
「XQueryを使用した表またはビュー・データの問合せ」を参照してください。

- XMLTypeリレーショナル・データを問い合せ、場合により関数XMLTableを使用して結果のXMLをリレーショナル・データに分解します。
「XQueryのXMLTypeデータとの使用」を参照してください。

例5-1は、この章の他の例の一部で使用するOracle XML DBリポジトリ・リソースを作成します。

例5-1 例で使用するリソースの作成

DECLARE
res BOOLEAN;
empsxmlstring VARCHAR2(300):=
'<?xml version="1.0"?>
<emps>
<emp empno="1" deptno="10" ename="John" salary="21000"/>
<emp empno="2" deptno="10" ename="Jack" salary="310000"/>
<emp empno="3" deptno="20" ename="Jill" salary="100001"/>
</emps>';
empsxmlnsstring VARCHAR2(300):=
'<?xml version="1.0"?>
<emps xmlns="http://example.com">
<emp empno="1" deptno="10" ename="John" salary="21000"/>
<emp empno="2" deptno="10" ename="Jack" salary="310000"/>
<emp empno="3" deptno="20" ename="Jill" salary="100001"/>
</emps>';
deptsxmlstring VARCHAR2(300):=
'<?xml version="1.0"?>
<depts>
<dept deptno="10" dname="Administration"/>
<dept deptno="20" dname="Marketing"/>
<dept deptno="30" dname="Purchasing"/>
</depts>';
BEGIN
res := DBMS_XDB.createResource('/public/emps.xml',   empsxmlstring);
res := DBMS_XDB.createResource('/public/empsns.xml', empsxmlnsstring);
res := DBMS_XDB.createResource('/public/depts.xml',  deptsxmlstring);
END;
/

XQueryとシーケンス

重要なことは、XQueryが汎用のシーケンス操作言語であるということです。式や結果は、XMLデータでなくてもかまいません。XQueryシーケンスは数値、文字列、ブール値、日付など任意のXQuery型の項目と、様々な型のXMLノード(document-node()、element()、attribute()、text()、namespace()など)を含むことができます。例5-2に例を示します。

例5-2 様々な型の項目シーケンスに適用されるXMLQuery

SELECT XMLQuery('(1, 2 + 3, "a", 100 to 102, <A>33</A>)'
RETURNING CONTENT) AS output
FROM DUAL;

OUTPUT
--------------------------
1 5 a 100 101 102<A>33</A>

1 row selected.

例5-2では、SQL/XML関数XMLQueryを、異なる様々な種類の項目を含むXQueryシーケンスに適用します。

- 整数リテラル: 1

- 算術式: 2 + 3

- 文字列リテラル: "a"

- 整数のシーケンス: 100 to 102

- 構成されたXML要素ノード: <A>33</A>

例5-2は、カンマ演算子(,)とカッコ((、))を使用してグループ化したシーケンスの構成も示しています。

シーケンス式100 to 102の評価結果はシーケンス(100, 101, 102)なので、XMLQueryの引数は、ネストされたシーケンスを含むシーケンスです。シーケンス引数は、XQueryシーケンスと同様、自動的にフラット化されます。実際の引数は、(1, 5, "a", 100, 101, 102, <A>33</A>)となります。

XQueryを使用したOracle XML DBリポジトリ内でのXMLデータの問合せ

この項では、XQueryとXMLデータをOracle XML DBリポジトリとともに使用する例を紹介します。XQuery関数fn:docとfn:collectionは、それぞれリポジトリ内のファイルおよびフォルダのリソースを問い合せるときに使用します。この項の例では、XQuery関数fn:docを使用してXMLデータを含むリポジトリ・ファイルを取得し、FLWOR式の句forおよびletを使用してXQuery変数をそのデータの部分にバインドしています。

関連項目:
XQuery関数fn:doc、fn:collectionおよびfn:doc-available

例5-3は、Oracle XML DBリポジトリ内の2つのXML文書リソース、/public/emps.xmlおよび/public/depts.xmlを問い合せます。fn:docの使用法および可能なFLWOR式のそれぞれの句を説明しています。

例5-3 for、let、order by、where、およびreturnを使用するFLOWR式

SELECT XMLQuery('for $e in doc("/public/emps.xml")/emps/emp
let $d :=
doc("/public/depts.xml")//dept[@deptno = $e/@deptno]/@dname
where $e/@salary > 100000
order by $e/@empno
return <emp ename="{$e/@ename}" dept="{$d}"/>'
RETURNING CONTENT) FROM DUAL;

XMLQUERY('FOR$EINDOC("/PUBLIC/EMPS.XML")/EMPS/EMPLET$D:=DOC("/PUBLIC/DEPTS.XML")
--------------------------------------------------------------------------------
<emp ename="Jack" dept="Administration"></emp><emp ename="Jill" dept="Marketing"
></emp>

1 row selected.

例5-3では、各種のFLWOR句が次の操作を行っています。

- forは/public/emps.xml内のemp要素について反復を実行し、変数$eを各要素の値に順にバインドします。つまり、従業員全体のリストについて反復を実行し、$eを各従業員にバインドします。

- letは変数$dを、/public/emps.xml内の、deptno属性が要素$eのdeptno属性と同じであるdept要素が持つdname属性のすべての値で構成されているシーケンスにバインドします(結合操作)。つまり、これは$dを、従業員$eの部門と同じ部門番号を持つすべての部門の名前にバインドします。(depts.xml内の各deptno値に対してdname値が一意であることもあり得ます)。forと異なりletは値に対して反復を行わないことに注意してください。この例で、$dは1度のみバインドされています。

- forとletを同時に使用すると、タプル($e, $d)のストリームを生成できます。ここで$eはある従業員、$dはその従業員が所属するすべての部門の名前(この場合は従業員の一意の部門の一意の名前)を表します。

- whereはそのタプル・ストリームをフィルタリングし、給与が100,000を超える従業員のみを残します。

- order byは、フィルタリングされたタプル・ストリームを従業員番号empnoでソートします(デフォルトでは昇順)。

- returnは、各タプルについて1つのemp要素を構成します。それらの要素の属性enameおよびdeptが、それぞれ入力の属性enameおよび$dを使用して構成されます。出力内の要素名と属性名empおよびenameと入力文書emps.xml内の同じ名前の間に必然的な関係はないことに注意してください。

例5-4でもFLWOR式の句をそれぞれ使用しています。この例は、組込みXQuery関数 http://www.w3.org/2003/11/xpath-functionsの名前空間にあるXQuery関数doc、count、avg、およびintegerの使用方法を示しています。この名前空間は接頭辞fnにバインドされます。

例5-4 組込み関数を使用したFLOWR式

SELECT XMLQuery('for $d in fn:doc("/public/depts.xml")/depts/dept/@deptno
let $e := fn:doc("/public/emps.xml")/emps/emp[@deptno = $d]
where fn:count($e) > 1
order by fn:avg($e/@salary) descending
return
<big-dept>{$d,
<headcount>{fn:count($e)}</headcount>,
<avgsal>{xs:integer(fn:avg($e/@salary))}</avgsal>}
</big-dept>'
RETURNING CONTENT) FROM DUAL;

XMLQUERY('FOR$DINFN:DOC("/PUBLIC/DEPTS.XML")/DEPTS/DEPT/@DEPTNOLET$E:=FN:DOC("/P
--------------------------------------------------------------------------------
<big-dept deptno="10"><headcount>2</headcount><avgsal>165500</avgsal></big-dept>

1 row selected.

例5-4では、各種のFLWOR句が次の操作を行っています。

- forは、入力文書/public/depts.xml内のdeptno属性について反復を実行し、変数$dを各属性の値に順にバインドします。

- letは変数$eを、入力文書/public/emps.xmlの、deptno属性が$dという値を持つすべてのemp要素で構成されるシーケンスにバインドします(join操作)。

- Together, forとletを同時に使用すると、タプル($d, $e)のストリームを生成できます。ここで$dは部門番号、$eはその部門の従業員の集合を表します。

- whereはそのタプル・ストリームをフィルタリングし、1人以上の従業員を持つタプルのみを残します。

- order byは、フィルタリングされたタプル・ストリームを平均給与の降順でソートします。平均は、名前空間fnのXQuery関数avgを、属性salaryの値に適用して計算します。この値は$eのemp要素に連結されています。

- returnは、order byで生成された各タプルについて1つのbig-dept要素を構成します。big-deptのtext()ノードには、$dにバインドされた部門番号が含まれます。XQuery関数countで指定されたとおり、headcount子要素には、従業員数が$eにバインドされて含まれます。avgsal子要素には、計算された平均給与が含まれます。

XQueryを使用した表またはビュー・データの問合せ

この項では、XQueryを使用してリレーショナル・データをXMLデータであるかのように問い合せる例について説明します。

例5-5では、Oracle XQuery関数fn:collectionをFLWOR式で使用して、2つのリレーショナル表regionsおよびcountriesを問い合せています。どちらの表も、サンプル・データベース・スキーマHRに属しています。この例ではさらに、SQLスカラー値AsiaがXQuery変数$regionnameに渡されています。どのSQL式でも、評価することによってPASSINGを使用してXQueryに渡す値を生成できます。その場合、値はSQL*Plus変数REGIONにより与えられます。またこの値は、適切なスカラーSQLデータ型(この場合はVARCHAR2(40))にキャストする必要があります。

例5-5 リレーショナル表をXMLとして問い合せる

DEFINE REGION = 'Asia'
SELECT XMLQuery('for $i in fn:collection("oradb:/HR/REGIONS"),
$j in fn:collection("oradb:/HR/COUNTRIES")
where $i/ROW/REGION_ID = $j/ROW/REGION_ID
and $i/ROW/REGION_NAME = $regionname
return $j'
PASSING CAST('&REGION' AS VARCHAR2(40)) AS "regionname"
RETURNING CONTENT) AS asian_countries
FROM DUAL;

これによって、次の結果が戻されます。(ここではわかりやすいように、この結果をフォーマット出力しています。)

ASIAN_COUNTRIES
-----------------------------------------
<ROW>
<COUNTRY_ID>AU</COUNTRY_ID>
<COUNTRY_NAME>Australia</COUNTRY_NAME>
<REGION_ID>3</REGION_ID>
</ROW>
<ROW>
<COUNTRY_ID>CN</COUNTRY_ID>
<COUNTRY_NAME>China</COUNTRY_NAME>
<REGION_ID>3</REGION_ID>
</ROW>
<ROW>
<COUNTRY_ID>HK</COUNTRY_ID>
<COUNTRY_NAME>HongKong</COUNTRY_NAME>
<REGION_ID>3</REGION_ID>
</ROW>
<ROW>
<COUNTRY_ID>IN</COUNTRY_ID>
<COUNTRY_NAME>India</COUNTRY_NAME>
<REGION_ID>3</REGION_ID>
</ROW>
<ROW>
<COUNTRY_ID>JP</COUNTRY_ID>
<COUNTRY_NAME>Japan</COUNTRY_NAME>
<REGION_ID>3</REGION_ID>
</ROW>
<ROW>
<COUNTRY_ID>SG</COUNTRY_ID>
<COUNTRY_NAME>Singapore</COUNTRY_NAME>
<REGION_ID>3</REGION_ID>
</ROW>

1 row selected.

例5-5では、各種のFLWOR句が次の操作を行っています。

- forは、fn:collectionのコールにより戻されるXML要素のシーケンスについて反復を実行します。最初のコールでは、各要素はリレーショナル表hr.regionsの行に対応し、変数$iにバインドされます。同様に、fn:collectionの2回目のコールでは、$jは、表hr.countriesの後続する行にバインドされます。regionsおよびcountriesはXMLType表ではないため、各表の行に対応する最上位要素はROWです(ラッパー要素)。行要素についての反復は順序付けられていません。

- whereは両方の表から行をフィルタリングし、各表でregion_idが同一であり(region_idに結合を実行)、region_nameがAsiaである行のペアのみを残します。

- returnは、hr.countries表からの行を、ROWを最上位要素とする、XMLフラグメントを含むXML文書として戻します。

例5-6では、ネストされたFLWOR式でfn:collection を使用して、リレーショナル・データを問い合せています。

例5-6 ネストされたFLWOR問合せでのリレーショナル・データの使用

CONNECT hr
Enter password: password

Connected.

GRANT SELECT ON LOCATIONS TO OE
/
CONNECT oe
Enter password: password

Connected.

SELECT XMLQuery(
'for $i in fn:collection("oradb:/OE/WAREHOUSES")/ROW
return <Warehouse id="{$i/WAREHOUSE_ID}">
<Location>
{for $j in fn:collection("oradb:/HR/LOCATIONS")/ROW
where $j/LOCATION_ID eq $i/LOCATION_ID
return ($j/STREET_ADDRESS, $j/CITY, $j/STATE_PROVINCE)}
</Location>
</Warehouse>'
RETURNING CONTENT) FROM DUAL;

この問合せは、ネストされたFLWOR式の使用例です。アクセスするリレーショナル表は、サンプル・データベース・スキーマoeにあるwarehousesと、サンプル・データベース・スキーマHRにあるlocationsです。この例をユーザーoeとして実行するには、最初にユーザーhrとして接続し、ユーザーoeに対して、表locationsでSELECT操作を実行する権限を付与する必要があります。

これによって、次の結果が戻されます。(ここではわかりやすいように、この結果をフォーマット出力しています。)

XMLQUERY('FOR$IINFN:COLLECTION("ORADB:/OE/WAREHOUSES")/ROWRETURN<WAREHOUSEID="{$
--------------------------------------------------------------------------------
<Warehouse id="1">
<Location>
<STREET_ADDRESS>2014 Jabberwocky Rd</STREET_ADDRESS>
<CITY>Southlake</CITY>
<STATE_PROVINCE>Texas</STATE_PROVINCE>
</Location>
</Warehouse>
<Warehouse id="2">
<Location>
<STREET_ADDRESS>2011 Interiors Blvd</STREET_ADDRESS>
<CITY>South San Francisco</CITY>
<STATE_PROVINCE>California</STATE_PROVINCE>
</Location>
</Warehouse>
<Warehouse id="3">
<Location>
<STREET_ADDRESS>2007 Zagora St</STREET_ADDRESS>
<CITY>South Brunswick</CITY>
<STATE_PROVINCE>New Jersey</STATE_PROVINCE>
</Location>
</Warehouse>
<Warehouse id="4">
<Location>
<STREET_ADDRESS>2004 Charade Rd</STREET_ADDRESS>
<CITY>Seattle</CITY>
<STATE_PROVINCE>Washington</STATE_PROVINCE>
</Location>
</Warehouse>
<Warehouse id="5">
<Location>
<STREET_ADDRESS>147 Spadina Ave</STREET_ADDRESS>
<CITY>Toronto</CITY>
<STATE_PROVINCE>Ontario</STATE_PROVINCE>
</Location>
</Warehouse>
<Warehouse id="6">
<Location>
<STREET_ADDRESS>12-98 Victoria Street</STREET_ADDRESS>
<CITY>Sydney</CITY>
<STATE_PROVINCE>New South Wales</STATE_PROVINCE>
</Location>
</Warehouse>
<Warehouse id="7">
<Location>
<STREET_ADDRESS>Mariano Escobedo 9991</STREET_ADDRESS>
<CITY>Mexico City</CITY>
<STATE_PROVINCE>Distrito Federal,</STATE_PROVINCE>
</Location>
</Warehouse>
<Warehouse id="8">
<Location>
<STREET_ADDRESS>40-5-12 Laogianggen</STREET_ADDRESS>
<CITY>Beijing</CITY>
</Location>
</Warehouse>
<Warehouse id="9">
<Location>
<STREET_ADDRESS>1298 Vileparle (E)</STREET_ADDRESS>
<CITY>Bombay</CITY>
<STATE_PROVINCE>Maharashtra</STATE_PROVINCE>
</Location>
</Warehouse>

1 row selected.

例5-6では、各種のFLWOR句が次の操作を行っています。

- 外側のforはfn:collectionにより戻されたXML要素のシーケンスについて反復を実行します。各要素はリレーショナル表oe.warehousesの行に対応していて、変数$iにバインドされています。warehousesはXMLType表ではないので、行に対応する最上位の要素はROWとなります。行要素についての反復は順序付けられていません。

- 内側のforも同様にfn:collectionにより戻されたXML要素のシーケンスについて反復を実行します。各要素はリレーショナル表hr.locationsの行に対応していて、変数$jにバインドされています。

- whereはタプル($i, $j)をフィルタリングし、location_id の子が、$iおよび$jに対して同じであるタプルのみを残します(location_idに基づいてjoinを実行します)。

- 内側のreturnは、要素 STREET_ADDRESS、CITY、およびSTATE_PROVINCEのXQueryシーケンスを、すべてlocations表のROW要素 $jの子、つまり、locations表の同名の列の値として構成します。

- 外側のreturnは内側のreturnの結果をLocation要素で囲み、それをさらにWarehouse要素で囲みます。Warehouse要素に対して、値を表warehousesのwarehouse_id列から取得したid属性を提供します。

関連項目:
例5-6の実行計画は、例5-15を参照してください。

例5-7では、SQL/XML関数XMLTableは、XQuery問合せの結果を仮想リレーショナル・データに分解するために使用されています。この例で使用されているXQuery式は 例5-6で使用されているものと同一です。XQuery式の評価結果はWarehouse要素のシーケンスです。関数XMLTableは、行がWarehouse要素である仮想リレーショナル表を生成します。正確には、仮想表の各行に対応する疑似列COLUMN_VALUEはXMLフラグメント(XMLType型)で、単一のWarehouse要素を持ちます。

例5-7 XMLTableでリレーショナル表をXMLとして問い合せる

SELECT *
FROM XMLTable(
'for $i in fn:collection("oradb:/OE/WAREHOUSES")/ROW
return <Warehouse id="{$i/WAREHOUSE_ID}">
<Location>
{for $j in fn:collection("oradb:/HR/LOCATIONS")/ROW
where $j/LOCATION_ID eq $i/LOCATION_ID
return ($j/STREET_ADDRESS, $j/CITY, $j/STATE_PROVINCE)}
</Location>
</Warehouse>');

これにより例5-6と同じ結果が生成されます。ただし、すべてのWarehouse要素が統合され単一の行に出力されるのでなく、各Warehouse要素が別々の行として出力される点が異なります。

COLUMN_VALUE
--------------------------------------------------------
<Warehouse id="1">
<Location>
<STREET_ADDRESS>2014 Jabberwocky Rd</STREET_ADDRESS>
<CITY>Southlake</CITY>
<STATE_PROVINCE>Texas</STATE_PROVINCE>
</Location>
</Warehouse>
<Warehouse id="2">
<Location>
<STREET_ADDRESS>2011 Interiors Blvd</STREET_ADDRESS>
<CITY>South San Francisco</CITY>
<STATE_PROVINCE>California</STATE_PROVINCE>
</Location>
</Warehouse>
. . .

9 rows selected.

関連項目:
例5-7の実行計画は、例5-16を参照してください。

XQueryのXMLTypeデータとの使用

この項では、XQueryをXMLTypeリレーショナル・データとともに使用する例を紹介します。

例5-8の問合せでは関数XMLQueryでPASSING句を使用して、XMLType列warehouse_specをコンテキスト項目としてXQueryに渡します。これにより、領域が80,000を超えるウェアハウス(/Warehouse/ Area > 80000)のそれぞれについてDetails要素が作成されます。

例5-8 XMLQueryでPASSING句を使用してXMLType列を問い合せる

SELECT warehouse_name,
XMLQuery(
'for $i in /Warehouse
where  $i/Area > 80000
return <Details>
<Docks num="{$i/Docks}"/>
<Rail>{if ($i/RailAccess = "Y") then "true" else "false"}
</Rail>
</Details>'
PASSING warehouse_spec RETURNING CONTENT) big_warehouses
FROM oe.warehouses;

これによって、次の出力が生成されます。

WAREHOUSE_NAME
--------------
BIG_WAREHOUSES
--------------
Southlake, Texas

San Francisco

New Jersey
<Details><Docks num=""></Docks><Rail>false</Rail></Details>

Seattle, Washington
<Details><Docks num="3"></Docks><Rail>true</Rail></Details>

Toronto

Sydney

Mexico City

Beijing

Bombay

9 rows selected.

例5-8では、関数XMLQueryは表warehousesの各行のwarehouse_spec列に適用されます。各FLWOR句は次の操作を実行します。

- forは列warehouse_spec(渡されたコンテキスト項目)の各行のWarehouse要素について反復を実行します。各要素はそれぞれ$iにバインドされます。反復は順序付けられていません。

- whereはWarehouse要素をフィルタリングして、Area子の値が80,000を超えるもののみを残します。

- returnはDetailsの要素のXQueryシーケンスを構成します。各要素は子要素DocksおよびRailを含みます。構成されたDocks要素のnum属性はWarehouseの子Docksのtext()値に設定されます。Railのtext()コンテンツは、要素WarehouseのRailAccess属性の値に応じて、trueまたはfalseに設定されます。

例5-8のSELECT文は、表warehousesの各行に適用されます。XMLQuery式は、XQuery式に一致しない行については空のシーケンスを戻します。New JerseyとSeattleの倉庫のみがXQuery問合せに適合するので、それらの倉庫についてのみ<Details>...</Details>が戻されます。

例5-9はSQL/XML関数XMLTableを使用して、XML Schemaに基づくデータを含むXMLType表oe.purchaseorderを問い合せます。PASSING句を使用して、XMLTableのXQuery式の引数のコンテキスト項目としてpurchaseorder表を提供します。結果として得られる仮想表の疑似列COLUMN_VALUEは、CostCenter要素が値A10を持ち、User要素が値SMCCAINを持つReference情報を含む、構成された要素A10poを保持します。この問合せは、仮想表とデータベース表purchaseorderの間の結合を実行します。

例5-9 XMLTABLEでXML Schemaに基づくデータを使用する

SELECT xtab.COLUMN_VALUE
FROM purchaseorder, XMLTable('for $i in /PurchaseOrder
where $i/CostCenter eq "A10"
and $i/User eq "SMCCAIN"
return <A10po pono="{$i/Reference}"/>'
PASSING OBJECT_VALUE) xtab;

COLUMN_VALUE
---------------------------------------------------
<A10po pono="SMCCAIN-20021009123336151PDT"></A10po>
<A10po pono="SMCCAIN-20021009123336341PDT"></A10po>
<A10po pono="SMCCAIN-20021009123337173PDT"></A10po>
<A10po pono="SMCCAIN-20021009123335681PDT"></A10po>
<A10po pono="SMCCAIN-20021009123335470PDT"></A10po>
<A10po pono="SMCCAIN-20021009123336972PDT"></A10po>
<A10po pono="SMCCAIN-20021009123336842PDT"></A10po>
<A10po pono="SMCCAIN-20021009123336512PDT"></A10po>
<A10po pono="SMCCAIN-2002100912333894PDT"></A10po>
<A10po pono="SMCCAIN-20021009123337403PDT"></A10po>

10 rows selected.

関数XMLTableのPASSING句により、XMLTypeのOBJECT_VALUEがpurchaseorder表に渡され、XPathコンテキストとして使用されます。したがって、XMLTable式はpurchaseorder表に依存します。このため、表purchaseorderは、FROMリストのXMLTable式よりも前に記述する必要があります。これは、データの依存関係が存在する状況では一般的な要件です。

注意:
PASSING 句が、問合せにおいてXMLType表の列の1つを参照している場合、その表は必ず問合せのFROMリストのXMLTable式よりも前に記述する必要があります。これは、XMLTable式がXMLType表に依存しているためです。XMLType表のアクセス行と、XMLTableによってそこから生成された行との間に1対多(1:N)の関係を保証するためには、左側(相関)結合が必要です。

例5-10で得られる結果は例5-9に類似しています。XMLTableのかわりにXMLQueryを使用してoe.purchaseorderを問い合せます。次の2つの例では、XQuery式により戻される空のシーケンスの処理が異なります。例5-9では、これらの空のシーケンスはpurchaseorder表を使用して結合されないため、SQL問合せの結果セットは全体で10行のみとなります。例5-10では、これらの空のシーケンスは、132行が含まれ、それぞれが表purchaseorderの各行に対応するSQL問合せの結果セットの一部となります。10行を除いて行はすべて空で、出力でも空行となります。紙数を節約するために、ここでは空行は省略してあります。

例5-10 XMLQUERYでXML Schemaに基づくデータを使用する

SELECT XMLQuery('for $i in /PurchaseOrder
where $i/CostCenter eq "A10"
and $i/User eq "SMCCAIN"
return <A10po pono="{$i/Reference}"/>'
PASSING OBJECT_VALUE
RETURNING CONTENT)
FROM purchaseorder;

XMLQUERY('FOR$IIN/PURCHASEORDERWHERE$I/COSTCENTEREQ"A10"AND$I/USEREQ"SMCCAIN"RET
--------------------------------------------------------------------------------
<A10po pono="SMCCAIN-20021009123336151PDT"></A10po>
<A10po pono="SMCCAIN-20021009123336341PDT"></A10po>
<A10po pono="SMCCAIN-20021009123337173PDT"></A10po>
<A10po pono="SMCCAIN-20021009123335681PDT"></A10po>
<A10po pono="SMCCAIN-20021009123335470PDT"></A10po>
<A10po pono="SMCCAIN-20021009123336972PDT"></A10po>
<A10po pono="SMCCAIN-20021009123336842PDT"></A10po>
<A10po pono="SMCCAIN-20021009123336512PDT"></A10po>
<A10po pono="SMCCAIN-2002100912333894PDT"></A10po>
<A10po pono="SMCCAIN-20021009123337403PDT"></A10po>

132 rows selected.

関連項目:
例5-10の実行計画は、例5-17を参照してください。

例5-11では、XMLTable句PASSINGおよびCOLUMNSを使用します。XQuery式は最上位のPurchaseOrder要素について反復を実行し、コスト・センターA10を含む発注書に対応するPO要素を構成します。結果のPO要素は続いてXMLTableに渡されて処理されます。

例5-11 XMLTABLEでのPASSINGおよびCOLUMNS句の使用

SELECT xtab.poref, xtab.priority, xtab.contact
FROM purchaseorder,
XMLTable('for $i in /PurchaseOrder
let $spl := $i/SpecialInstructions
where $i/CostCenter eq "A10"
return <PO>
<Ref>{$i/Reference}</Ref>
{if ($spl eq "Next Day Air" or $spl eq "Expedite") then
<Type>Fastest</Type>
else if ($spl eq "Air Mail") then
<Type>Fast</Type>
else ()}
<Name>{$i/Requestor}</Name>
</PO>'
PASSING OBJECT_VALUE
COLUMNS poref    VARCHAR2(20) PATH 'Ref',
priority VARCHAR2(8)  PATH 'Type' DEFAULT 'Regular',
contact  VARCHAR2(20) PATH 'Name') xtab;

POREF                PRIORITY CONTACT
-------------------- -------- --------------------
SKING-20021009123336 Fastest  Steven A. King
SMCCAIN-200210091233 Regular  Samuel B. McCain
SMCCAIN-200210091233 Fastest  Samuel B. McCain
JCHEN-20021009123337 Fastest  John Z. Chen
JCHEN-20021009123337 Regular  John Z. Chen
SKING-20021009123337 Regular  Steven A. King
SMCCAIN-200210091233 Regular  Samuel B. McCain
JCHEN-20021009123338 Regular  John Z. Chen
SMCCAIN-200210091233 Regular  Samuel B. McCain
SKING-20021009123335 Regular  Steven X. King
SMCCAIN-200210091233 Regular  Samuel B. McCain
SKING-20021009123336 Regular  Steven A. King
SMCCAIN-200210091233 Fast     Samuel B. McCain
SKING-20021009123336 Fastest  Steven A. King
SKING-20021009123336 Fastest  Steven A. King
SMCCAIN-200210091233 Regular  Samuel B. McCain
JCHEN-20021009123335 Regular  John Z. Chen
SKING-20021009123336 Regular  Steven A. King
JCHEN-20021009123336 Regular  John Z. Chen
SKING-20021009123336 Regular  Steven A. King
SMCCAIN-200210091233 Regular  Samuel B. McCain
SKING-20021009123337 Regular  Steven A. King
SKING-20021009123338 Fastest  Steven A. King
SMCCAIN-200210091233 Regular  Samuel B. McCain
JCHEN-20021009123337 Regular  John Z. Chen
JCHEN-20021009123337 Regular  John Z. Chen
JCHEN-20021009123337 Regular  John Z. Chen
SKING-20021009123337 Regular  Steven A. King
JCHEN-20021009123337 Regular  John Z. Chen
SKING-20021009123337 Regular  Steven A. King
SKING-20021009123337 Regular  Steven A. King
SMCCAIN-200210091233 Fast     Samuel B. McCain

32 rows selected.

例5-11では、PurchaseOrderの子から取得したデータは、POの子、Ref、TypeおよびNameを構成するのに使用されます。Typeのコンテンツは/PurchaseOrder/SpecialInstructionsのコンテンツから取得されますが、SpecialInstructionsのクラスはTypeに対応して異なる方法で分割されます。

関数XMLTableはXQuery評価の結果を、poref、priority、およびcontactの仮想表の3つのVARCHAR2列に分割します。DEFAULT句は、Regularのデフォルトのpriorityを指定するのに使用されます。

例5-12では、SQL/XML関数XMLTableは、XMLTypeコレクション要素LineItemのXMLデータを、仮想表の個別の列に分割するために使用されています。

例5-12 XMLTABLEを使用してXMLコレクション要素をリレーショナル・データに分解する

SELECT lines.lineitem, lines.description, lines.partid,
lines.unitprice, lines.quantity
FROM purchaseorder,
XMLTable('for $i in /PurchaseOrder/LineItems/LineItem
where $i/@ItemNumber >= 8
and $i/Part/@UnitPrice > 50
and $i/Part/@Quantity > 2
return $i'
PASSING OBJECT_VALUE
COLUMNS lineitem    NUMBER       PATH '@ItemNumber',
description VARCHAR2(30) PATH 'Description',
partid      NUMBER       PATH 'Part/@Id',
unitprice   NUMBER       PATH 'Part/@UnitPrice',
quantity    NUMBER       PATH 'Part/@Quantity') lines;

LINEITEM DESCRIPTION                           PARTID UNITPRICE QUANTITY
-------- ------------------------------ ------------- --------- --------
11 Orphic Trilogy                   37429148327        80        3
22 Dreyer Box Set                   37429158425        80        4
11 Dreyer Box Set                   37429158425        80        3
16 Dreyer Box Set                   37429158425        80        3
8 Dreyer Box Set                   37429158425        80        3
12 Brazil                           37429138526        60        3
18 Eisenstein: The Sound Years      37429149126        80        4
24 Dreyer Box Set                   37429158425        80        3
14 Dreyer Box Set                   37429158425        80        4
10 Brazil                           37429138526        60        3
17 Eisenstein: The Sound Years      37429149126        80        3
16 Orphic Trilogy                   37429148327        80        4
13 Orphic Trilogy                   37429148327        80        4
10 Brazil                           37429138526        60        4
12 Eisenstein: The Sound Years      37429149126        80        3
12 Dreyer Box Set                   37429158425        80        4
13 Dreyer Box Set                   37429158425        80        4

17 rows selected.

関連項目:

- 例5-12の実行計画は、例5-18を参照してください。

- XMLTableを複数の文書レベルに適用する具体例(マルチレベル連鎖)は、「複数レベルのXMLデータの分割」を参照してください。

XQueryでのネームスペースの使用

XQuery declare namespace宣言をXQuery式のプロローグで使用して、名前空間の接頭辞を定義することができます。declare default namespaceを使用して、式のデフォルトの名前空間として名前空間を確立できます。

名前空間宣言を記述した行の末尾にセミコロン(;)を置いた場合、SQL*Plusでは、そのセミコロンがSQLの終端文字として解釈されます。SQL*Plusを使用する場合は、この点に注意が必要です。これを避けるには、次のいずれかを実行します。

- 同じ行のセミコロンの後にテキストを挿入する。

- 同じ行のセミコロンの後に、(: :)のようなコメントを挿入する。

- SQL*PlusコマンドSET SQLTERMINATORを使用して、SQLの終端文字の認識を無効にする。

例5-13は、XQuery式の名前空間宣言の使用方法を示しています。

例5-13 XMLQUERYでの名前空間宣言の使用

SELECT XMLQuery('declare namespace e = "http://example.com";
ERROR:
ORA-01756: quoted string not properly terminated

for $i in doc("/public/empsns.xml")/e:emps/e:emp
SP2-0734: unknown command beginning "for $i in ..." - rest of line ignored.
...

-- This works - do not end the line with ";".
SELECT XMLQuery('declare namespace e = "http://example.com"; for
$i in doc("/public/empsns.xml")/e:emps/e:emp
let $d :=
doc("/public/depts.xml")//dept[deptno=$i/@deptno]/@dname
where $i/@salary > 100000
order by $i/@empno
return <emp ename="{$i/@ename}" dept="{$d}"/>'
RETURNING CONTENT) FROM DUAL;

XMLQUERY('DECLARENAMESPACEE="HTTP://EXAMPLE.COM";FOR$IINDOC("/PUBLIC/EMPSNS.XML"
--------------------------------------------------------------------------------
<emp ename="Jack" dept=""></emp><emp ename="Jill" dept=""></emp>

-- This works too - add a comment after the ";".
SELECT XMLQuery('declare namespace e = "http://example.com";  (: :)
for $i in doc("/public/empsns.xml")/e:emps/e:emp
let $d := doc("/public/depts.xml")//dept[deptno=$i/@deptno]/@dname
where $i/@salary > 100000
order by $i/@empno
return <emp ename="{$i/@ename}" dept="{$d}"/>'
RETURNING CONTENT) FROM DUAL;

XMLQUERY('DECLARENAMESPACEE="HTTP://EXAMPLE.COM";(::)FOR$IINDOC("/PUBLIC/EMPSNS.
--------------------------------------------------------------------------------
<emp ename="Jack" dept=""></emp><emp ename="Jill" dept=""></emp>

1 row selected.

-- This works too - tell SQL*Plus to ignore the ";".
SET SQLTERMINATOR OFF

SELECT XMLQuery('declare namespace e = "http://example.com";
for $i in doc("/public/empsns.xml")/e:emps/e:emp
let $d :=
doc("/public/depts.xml")//dept[deptno=$i/@deptno]/@dname
where $i/@salary > 100000
order by $i/@empno
return <emp ename="{$i/@ename}" dept="{$d}"/>'
RETURNING CONTENT) FROM DUAL
/

XMLQUERY('DECLARENAMESPACEE="HTTP://EXAMPLE.COM";FOR$IINDOC("/PUBLIC/EMPSNS.XML"
--------------------------------------------------------------------------------
<emp ename="Jack" dept=""></emp><emp ename="Jill" dept=""></emp>

XQuery名前空間宣言は、XQuery式の外部では無効です。XMLTable式で使用する名前空間接頭辞をXQuery式の外部で宣言するにはXMLNAMESPACES句を使用します。この句はXMLTableのXQuery式の引数でも使用できるため、XQueryプロローグを別個に宣言する必要はありません。

例5-14では、XMLNAMESPACESは名前空間http://example.comに対応する接頭辞eを定義するために使用されます。このネームスペースはCOLUMNS句とXMLTable式のXQuery式で使用されます。

例5-14 XMLTABLEでのXMLNAMESPACES句の使用

SELECT * FROM XMLTable(XMLNAMESPACES ('http://example.com' AS "e"),
'for $i in doc("/public/empsns.xml")
return $i/e:emps/e:emp'
COLUMNS name VARCHAR2(6) PATH '@ename',
id   NUMBER      PATH '@empno');

これによって、次の結果が戻されます。

NAME           ID
------ ----------
John            1
Jack            2
Jill            3

3 rows selected.

修飾名e:enameおよびe:empnoがCOLUMNS句に存在することにより、XMLNAMESPACES句を使用する必要が生じています。そうでなければ、XQuery式のみのためにはプロローグ名前空間宣言(declare namespace e = "http://example.com")で十分です。

XMLTable式で同一の名前空間が使用されているので、デフォルトの名前空間XMLNAMESPACES (DEFAULT 'http://example.com')を使用できます。このため、修飾名$i/e:emps/e:empを、明示的接頭辞を使用せずに$i/emps/empと書いてかまいません。

XQuery用のパフォーマンス・チューニング

XQuery式を使用するSQL問合せは、多くの場合、1つ以上の方法でリライト(最適化)できます。このような最適化は、XML問合せのリライトまたは最適化と呼ばれます。XPath式は、XQuery式の適切なサブセットです。

XPathリライトは、XML問合せリライトのサブセットであり、XPath式を使用する問合せがリライトされます。XPathリライトでは、XMLIndexの最適化と、バイナリXMLのストリーミング評価が行われます。また、構造化記憶域やリレーショナル・データのXMLTypeビューの場合は、基礎となるオブジェクト・リレーショナル形式またはリレーショナル形式の構造へのリライトも行われます。

問合せのチューニングは、SQLのパフォーマンスと同様に、XQueryのパフォーマンスも改善することができます。XQueryのパフォーマンスをチューニングするには、該当するXML記憶域モデルと索引を選択します。

一般のデータベースの問合せと同様に、チューニングが必要かどうかは、問合せの実行計画をチェックして決定します。計画が最適でない場合は、次のマニュアルで個別のチューニング情報を参照してください。

- 構造化記憶域: 第8章「構造化記憶域のXPathリライト」

- 非構造化記憶域およびバイナリXML記憶域: 第6章「XMLTypeデータの索引付け」

また、次の式は処理コストがかかることがあり、そのため、大量のデータを処理する場合にパフォーマンスにオーバーヘッドが発生する可能性があることに注意してください。

- 次のOracle SQL関数を使用するSQL式(XPath式引数を受け入れる):

- appendChildXML(かわりにinsertChildXMLAfterを使用)

- insertXMLAfter(かわりにinsertChildXMLAfterを使用)

- insertXMLBefore(かわりにinsertChildXMLBeforeを使用)

- 次の軸を使用するXQuery式(かわりにforwardおよびdescendentの軸を使用):

- ancestor

- ancestor-or-self

- descendant-or-self

- following

- following-sibling

- namespace

- parent

- preceding

- preceding-sibling

- ノード・アイデンティティを伴うXQuery式(順序比較演算子<<および>>の使用など)

関連項目:
「Oracle XML DBでのXQueryのサポート」

次の各項では、この章でここまでに示した例の一部に対する実行計画を示し、それがどのように実行されるかを説明します。

- 「リレーショナル・データに関するXQueryの最適化」: fn:collectionおよびURIスキームoradbを使用して、その場で作成されたXMLデータをターゲットとするXQuery式の例。

- XML Schemaに基づくXMLTypeデータに対するXQueryの最適化: オブジェクト・リレーショナル形式でXML Schemaに基づくXMLType表をターゲットとするXQuery式の例を示します。

関連項目:

- 第8章「構造化記憶域のXPathリライト」

- XMLIndexの使用方法の詳細は、第6章「XMLTypeデータの索引付け」を参照してください。

- バイナリXMLデータのストリーミング評価の詳細は、「Oracle XML DBでのXMLTypeメソッドおよびSQL関数の処理」を参照してください。

ルールベースおよびコストベースのXQueryの最適化

XQuery式を使用する問合せに対しては、使用されているXMLType記憶域モデルや索引付けなどの様々な要因によって、競合する最適化候補が複数あります。

デフォルトでは、Oracle XML DBは、優先順位付きのルール・セットに従って、特定の問合せおよびコンテキストに対して使用する最適化候補を決定します。この動作は、ルールベースのXML問合せのリライトと呼ばれます。

また、Oracle XML DBはコストベースのXML問合せのリライトを使用することもできます。このモードでは、Oracle XML DBは、特定の問合せに対する様々なXML最適化候補のパフォーマンスを評価し、最もパフォーマンスが高いと予測される組合せを選択します。

オプティマイザ・ヒント/*+ COST_XML_QUERY_REWRITE */を使用すると、特定のSQL文に対してコストベースの最適化を強制できます。

リレーショナル・データに関するXQueryの最適化

例5-15は、XMLとしてアクセスされるリレーショナル・データに対するXMLQueryの最適化を示します。例5-16に、同じコンテキストにおけるXMLTableの最適化を示します。

例5-15 リレーショナル・データに関するXMLQueryの最適化

例5-6の問合せと、その実行計画をもう一度見てみます。この例は、問合せが最適化されていることを示しています。

SELECT XMLQuery(
'for $i in fn:collection("oradb:/OE/WAREHOUSES")/ROW
return <Warehouse id="{$i/WAREHOUSE_ID}">
<Location>
{for $j in fn:collection("oradb:/HR/LOCATIONS")/ROW
where $j/LOCATION_ID eq $i/LOCATION_ID
return ($j/STREET_ADDRESS, $j/CITY, $j/STATE_PROVINCE)}
</Location>
</Warehouse>'
RETURNING CONTENT) FROM DUAL;

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------
Plan hash value: 3341889589

-------------------------------------------------------------------------------------------
| Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |            |     1 |       |     2   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE              |            |     1 |    41 |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| LOCATIONS  |     1 |    41 |     1   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN         | LOC_ID_PK  |     1 |       |     0   (0)| 00:00:01 |
|   4 |  SORT AGGREGATE              |            |     1 |     6 |            |          |
|   5 |   TABLE ACCESS FULL          | WAREHOUSES |     9 |    54 |     2   (0)| 00:00:01 |
|   6 |  FAST DUAL                   |            |     1 |       |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - access("LOCATION_ID"=:B1)

18 rows selected.

例5-16 リレーショナル・データに関するXMLTableの最適化

例5-7の問合せと、その実行計画をもう一度見てみます。この例は、問合せが最適化されていることを示しています。

SELECT *
FROM XMLTable(
'for $i in fn:collection("oradb:/OE/WAREHOUSES")/ROW
return <Warehouse id="{$i/WAREHOUSE_ID}">
<Location>
{for $j in fn:collection("oradb:/HR/LOCATIONS")/ROW
where $j/LOCATION_ID eq $i/LOCATION_ID
return ($j/STREET_ADDRESS, $j/CITY, $j/STATE_PROVINCE)}
</Location>
</Warehouse>');

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------
Plan hash value: 1021775546

-------------------------------------------------------------------------------------------
| Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |            |     9 |    54 |     2   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE              |            |     1 |    41 |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| LOCATIONS  |     1 |    41 |     1   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN         | LOC_ID_PK  |     1 |       |     0   (0)| 00:00:01 |
|   4 |  TABLE ACCESS FULL           | WAREHOUSES |     9 |    54 |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - access("LOCATION_ID"=:B1)

16 rows selected.

XML SchemaベースのXMLTypeデータに関するXQueryの最適化

例5-17に、XML Schemaに基づくXMLType表に関するXMLQueryの最適化を示します。例5-18に、同じコンテキストにおけるXMLTableの最適化を示します。

例5-17 XML Schemaに基づくXMLTypeデータを含むXMLQueryの最適化

例5-10の問合せと、その実行計画をもう一度見てみます。この例は、問合せが最適化されていることを示しています。

SELECT XMLQuery('for $i in /PurchaseOrder
where $i/CostCenter eq "A10"
and $i/User eq "SMCCAIN"
return <A10po pono="{$i/Reference}"/>'
PASSING OBJECT_VALUE
RETURNING CONTENT)
FROM purchaseorder;

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------
Plan hash value: 3611789148

-------------------------------------------------------------------------------------
| Id  | Operation           | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |               |     1 |   530 |     5   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE     |               |     1 |       |            |          |
|*  2 |   FILTER            |               |       |       |            |          |
|   3 |    FAST DUAL        |               |     1 |       |     2   (0)| 00:00:01 |
|*  4 |    TABLE ACCESS FULL| PURCHASEORDER |     1 |   530 |     5   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - filter(:B1='SMCCAIN' AND :B2='A10')
4 - filter(SYS_CHECKACL("ACLOID","OWNERID",xmltype('<privilege
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd DAV:http://xmlns.oracle.com/xdb/dav.xsd">
<read-properties/><read-contents/></privilege>'))=1)

22 rows selected.

例5-18 XML Schemaに基づくXMLTypeデータを含むXMLTableの最適化

例5-12の問合せと、その実行計画をもう一度見てみます。この例は、問合せが最適化されていることを示しています。XQueryの結果は生成されません。結果セット全体を生成するにはXMLのコレクション要素LineItemの基礎となる記憶域の列が使用されます。

SELECT lines.lineitem, lines.description, lines.partid,
lines.unitprice, lines.quantity
FROM purchaseorder,
XMLTable('for $i in /PurchaseOrder/LineItems/LineItem
where $i/@ItemNumber >= 8
and $i/Part/@UnitPrice > 50
and $i/Part/@Quantity > 2
return $i'
PASSING OBJECT_VALUE
COLUMNS lineitem    NUMBER       PATH '@ItemNumber',
description VARCHAR2(30) PATH 'Description',
partid      NUMBER       PATH 'Part/@Id',
unitprice   NUMBER       PATH 'Part/@UnitPrice',
quantity    NUMBER       PATH 'Part/@Quantity') lines;

-----------------------------------------------------------------------------------------------
| Id  | Operation                    | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                |     4 |   384 |     7   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                |                |       |       |            |          |
|   2 |   NESTED LOOPS               |                |     4 |   384 |     7   (0)| 00:00:01 |
|*  3 |    TABLE ACCESS FULL         | PURCHASEORDER  |     1 |    37 |     5   (0)| 00:00:01 |
|*  4 |    INDEX RANGE SCAN          | SYS_C005478    |    17 |       |     1   (0)| 00:00:01 |
|*  5 |   TABLE ACCESS BY INDEX ROWID| LINEITEM_TABLE |     3 |   177 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - filter(SYS_CHECKACL("ACLOID","OWNERID",xmltype('<privilege
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd DAV:http://xmlns.oracle.com/xdb/dav.xsd"><read-prop
erties/><read-contents/></privilege>'))=1)
4 - access("NESTED_TABLE_ID"="PURCHASEORDER"."SYS_NC0003400035$")
5 - filter("SYS_NC00013$">50 AND "SYS_NC00012$">2 AND "ITEMNUMBER">=8 AND
"SYS_NC_TYPEID$" IS NOT NULL)

25 rows selected.

この例は、表oe.purchaseorderを完全に検索します。それぞれの発注文書について、XMLTable式が評価されます。purchaseorder表でなくXMLTable式にSQL問合せの実行をまかせる方が効率的です。

XQuery式はリレーショナル式にリライトされていますが、基礎となるリレーショナル・データに基づいて索引を作成することによって最適化を改善できます。この問合せは、純粋なSQL問合せを最適化する場合と同じ方法で最適化できます。これは、Oracle XML DBのXQueryには常にあてはまります。SQLで使用する最適化テクニックをそのまま使用できます。

コレクション要素LineItemのUnitPrice属性は、適切な索引ターゲットです。適用されるXMLスキーマが、Ordered Collection Table(OCT)を使用してLineItem要素を格納することを指定しています。

ただし、このOCTの名前は、XML発注書がXML Schemaに基づくデータとして分解されたときに、Oracle XML DBにより生成されます。サンプル・データベース・スキーマHRの表purchaseorderを使用するかわりに、プロパティとデータが同じで、OCTにわかりやすい名前が付いた新しいpurchaseorder表を(異なるデータベース・スキーマに)手動で作成します。その手順は、例3-13を参照してください。

例3-13と同様にpurchaseorder表が作成されたと仮定すると、次の文により適切な索引が作成されます。

CREATE INDEX unitprice_index ON lineitem_table("PART"."UNITPRICE");

この索引が定義されている場合、例5-12の問合せにより、XMLTable式が全体の評価を実行することを示す実行結果が結果として得られます。

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Plan hash value: 1578014525

----------------------------------------------------------------------------------------
| Id  | Operation          | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                   |     3 |   624 |     8   (0)| 00:00:01 |
|   1 |  NESTED LOOPS      |                   |     3 |   624 |     8   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN| SYS_IOT_TOP_49323 |     3 |   564 |     5   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN| UNITPRICE_INDEX   |    20 |       |     2   (0)| 00:00:01 |
|*  4 |   INDEX UNIQUE SCAN| SYS_C004411       |     1 |       |     0   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("SYS_NC00013$">50)
filter("ITEMNUMBER">=8 AND "SYS_NC00012$">2)
3 - access("SYS_NC00013$">50)
4 - access("NESTED_TABLE_ID"="PURCHASEORDER"."SYS_NC0003400035$")

Note
-----
- dynamic sampling used for this statement

23 rows selected.

XQueryの最適化の診断: XMLOptimizationCheck

SQLコードの実行計画を調べて、XQueryの最適化が行われるか、計画が部分的に最適化されるかを判断できます。後者の場合は、計画の直後に次のような注記が表示されます。

Unoptimized XML construct detected (enable XMLOptimizationCheck
for more information)

また、実行計画の出力をオプティマイザ・ヒントNO_XML_QUERY_REWRITEの後に表示される計画の出力と比較することもできます。これによってXQueryの最適化がオフになります。

さらに、SQL*PlusのSETコマンドでシステム変数XMLOptimizationCheckを使用して、SQLのXML診断能力モードをオンにすることができます。

SET XMLOptimizationCheck ON

このモードがオンの場合、XQuery最適化の実行計画が自動的にチェックされ、計画が部分的な最適化の場合は、エラーが発生して診断情報がトレース・ファイルに書き込まれ、どの演算子が書きなおされていないのかが示されます。

XMLOptimizationCheckの主な利点は、潜在的な問題がただちに明らかになることです。このため、常にこのモードをオンにしておくのが望ましいと言えます。そして、何らかの理由でアプリケーションやデータベースに変更が生じたため、SQL操作で書き直しができない場合、原因に気がつかないうちにパフォーマンスが低下するかわりに実行が停止します。

注意:

- レベル8192(0x2000)のイベント19027を使用すると、特定の式がリライトされない理由を示すトレースをダンプできます。

- XMLOptimizationCheckは、Oracle Database 11gリリース2(11.2.0.2)以前は利用できませんでした。旧リリースのユーザーは、イベント19201を直接操作して、XQueryの最適化情報を取得していました。

関連項目:
オプティマイザ・ヒントNO_XML_QUERY_REWRITEの詳細は、「XMLIndexの使用の無効化」を参照してください。

リポジトリのデータに対するfn:docおよびfn:collectionのパフォーマンスの向上

Oracle XML DBでは、XQuery関数fn:docおよびfn:collectionを使用して、Oracle XML DBリポジトリ内の文書やコレクションを参照できます。リポジトリのXMLTypeデータがオブジェクト・リレーショナル形式またはバイナリXML形式で格納されている場合、fn:docおよびfn:collectionを使用する問合せは関数として評価されます。つまり、これらは基礎となる記憶域表に直接アクセスできるように最適化されていません。

こうした問合せのパフォーマンスを向上するには、問い合せるリポジトリ・データを保持する実際のデータベースの表にそれらをリンクする必要があります。これを行うには、次のいずれかの方法を実行します。

- RESOURCE_VIEWビューを、データを保持するXMLType表と結合し、XQuery関数fn:docおよびfn:collectionのかわりに、Oracle SQL関数equals_pathおよびunder_pathをそれぞれ使用します。これらのSQL関数は、パフォーマンスに優れた方法でリポジトリ・リソースを参照します。

- Oracle XQuery拡張式プラグマora:defaultTableを使用します。

どちらの方法を使用しても結果は同じです。XQueryの標準関数fn:docとfn:collectionを引き続き使用できるほか、コードが簡略化されるため、ora:defaultTableプラグマの使用をお薦めします。

この項の例で、これらの2つの方法について説明しています。

fn:docとfn:collectionにかわるequals_pathおよびunder_pathの使用

SQL関数equals_pathおよびunder_pathは、それぞれ指定したリポジトリ・パスにあるリソースを参照します。例5-19および例5-20に、関数fn:docおよびequals_pathでのこの処理を示します。関数fn:collectionおよびunder_pathが同じように処理されます。

例5-19 fn:docを使用した、最適化されていないリポジトリの問合せ

SELECT XMLQuery('let $val :=
fn:doc("/home/OE/PurchaseOrders/2002/Sep/VJONES-20021009123337583PDT.xml")
/PurchaseOrder/LineItems/LineItem[@ItemNumber =19]
return $val' RETURNING CONTENT)
FROM DUAL;

例5-20 EQUALS_PATHを使用した、最適化されたリポジトリの問合せ

SELECT XMLQuery('let $val := $DOC/PurchaseOrder/LineItems/LineItem[@ItemNumber = 19]
return $val' PASSING OBJECT_VALUE AS "DOC" RETURNING CONTENT)
FROM RESOURCE_VIEW rv, purchaseorder p
WHERE ref(p) = XMLCast(XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
fn:dataFoot 6 (/Resource/XMLRef)' PASSING rv.RES RETURNING CONTENT)
AS REF XMLType)
AND equals_path(rv.RES, '/home/OE/PurchaseOrders/2002/Sep/VJONES-20021009123337583PDT.xml')
= 1;

Oracle XQueryプラグマora:defaultTableの使用

Oracle XQuery拡張式プラグマora:defaultTableを使用すると、問い合せるリポジトリ・データを格納するデフォルトの表を指定できます。問合せは、デフォルトのテーブルをRESOURCE_VIEWビューに自動的に結合し、XQuery関数fn:docとfn:collectionのかわりに、Oracle SQL関数equals_pathおよびunder_pathを使用するようにリライトされます。このため結果は、手動で問合せのコードを記述して、明示的な結合およびequals_pathやunder_pathを使用する場合と同じです。例5-21に、この詳細を説明します。問合せが自動的にリライトされ、例5-20のようになります。

例5-21 Oracle XQueryプラグマora:defaultTableを使用したリポジトリの問合せ

SELECT XMLQuery('for $doc in (#ora:defaultTable PURCHASEORDER #)
{fn:doc("/home/OE/PurchaseOrders/2002/Sep/VJONES-20021009123337583PDT.xml")}
let $val := $doc/PurchaseOrder/LineItems/LineItem[@ItemNumber = 19]
return $val}'
RETURNING CONTENT)
FROM DUAL;

範囲を明確にするため、プラグマora:defaultTableを、大きい式ではなく適切な文書やコレクションの式、fn:docまたはfn:collectionに直接適用することをお薦めします。

Oracle XML DBにおけるXQuery静的型チェック

Oracle XML DBはすべてのXQuery式を型チェックします。しかし、実行時の型チェックはコストがかかることがあります。最適化技法として、指定された問合せに対してコンパイル時に十分な静的型情報を利用できる場合は常に、Oracle XML DBはその問合せの静的な(コンパイル時)型チェックを行います。指定された問合せに対してコンパイル時に十分な静的型情報を利用できない場合は、Oracle XML DBはその問合せの動的(実行時)型チェックを使用します。

静的型チェックでは、コンパイル時にエラーが発生するので、実行時間を節約できることがあります。静的型チェック・エラーには、データ型エラーと、XML Schemaの観点から無効であるXPath式の使用の両方を含みます。

コンパイル時に十分な静的型情報を提供する一般的な方法には、次の方法があります。

- リレーショナル・データに関してXQueryとfn:docまたはfn:collectionを使用。

- XQueryを使用して、問合せコンパイル時にXML Schema情報を利用できるXMLType表、列またはビューを問い合せます。

この項では、静的型チェックの有効性と、型情報を通信するこれら2つの手段の使用方法を示す例を紹介します。

fn:collectionおよびURIスキームoradbによってその場で生成されるXMLデータは、ROWを最上位の要素に持ちますが、例5-22の問合せには、ROWのラッパー要素が欠けています。この脱落により、問合せのコンパイル時エラーが発生します。このようにfn:collectionとoradbによりリレーショナル・データをラップし忘れる誤りはよくあることですが、静的型チェックがないと、診断が困難な場合があります。例5-5に正しいコードを示します。

例5-22 XQuery式の静的型チェック: oradb URIスキーム

-- This produces a static-type-check error, because "ROW" is missing.
SELECT XMLQuery('for $i in fn:collection("oradb:/HR/REGIONS"),
$j in fn:collection("oradb:/HR/COUNTRIES")
where $i/REGION_ID = $j/REGION_ID and $i/REGION_NAME = "Asia"
return $j'
RETURNING CONTENT) AS asian_countries
FROM DUAL;
SELECT XMLQuery('for $i in fn:collection("oradb:/HR/REGIONS"),
*
ERROR at line 1:
ORA-19276: XPST0005 - XPath step specifies an invalid element/attribute name:
(REGION_ID)

例5-23では、XQueryの静的型チェックにより、XPath式とそのターゲットXML Schemaに基づくデータの不一致を検出します。要素CostCenterが、ここではcostcenterと誤ったスペルになっています(XQueryおよびXPathは大文字/小文字を区別します)。例5-11に正しいコードを示します。

例5-23 XQuery式の静的型チェック: スキーマベースのXML

-- This results in a static-type-check error: CostCenter is not the right case.
SELECT xtab.poref, xtab.usr, xtab.requestor
FROM purchaseorder,
XMLTable('for $i in /PurchaseOrder where $i/costcenter eq "A10" return $i'
PASSING OBJECT_VALUE
COLUMNS poref     VARCHAR2(20) PATH 'Reference',
usr       VARCHAR2(20) PATH 'User' DEFAULT 'Unknown',
requestor VARCHAR2(20) PATH 'Requestor') xtab;
FROM purchaseorder,
*
ERROR at line 2:
ORA-19276: XPST0005 - XPath step specifies an invalid element/attribute name:
(costcenter)

SQL*Plus XQUERYコマンド

例5-24は、XQuery式の前にSQL*PlusコマンドXQUERYを付け、式の後にスラッシュ(/)を単独で付けることにより、SQL*PlusコマンドラインでXQuery式を直接入力する方法を示します。Oracle Databaseでは、このコマンドで送信されたXQuery式を、SQL/XML関数XMLQueryおよびXMLTable内のXQuery式と同様に処理します。実行は同一で、同じ最適化を使用します。

例5-24 SQL*Plus XQUERYコマンドの使用

SQL> XQUERY for $i in fn:collection("oradb:/HR/DEPARTMENTS")
2  where $i/ROW/DEPARTMENT_ID < 50
3  return $i
4  /

Result Sequence
--------------------------------------------------------------------------------
<ROW><DEPARTMENT_ID>10</DEPARTMENT_ID><DEPARTMENT_NAME>Administration</DEPARTMEN
T_NAME><MANAGER_ID>200</MANAGER_ID><LOCATION_ID>1700</LOCATION_ID></ROW>

<ROW><DEPARTMENT_ID>20</DEPARTMENT_ID><DEPARTMENT_NAME>Marketing</DEPARTMENT_NAM
E><MANAGER_ID>201</MANAGER_ID><LOCATION_ID>1800</LOCATION_ID></ROW>

<ROW><DEPARTMENT_ID>30</DEPARTMENT_ID><DEPARTMENT_NAME>Purchasing</DEPARTMENT_NA
ME><MANAGER_ID>114</MANAGER_ID><LOCATION_ID>1700</LOCATION_ID></ROW>

<ROW><DEPARTMENT_ID>40</DEPARTMENT_ID><DEPARTMENT_NAME>Human Resources</DEPARTME
NT_NAME><MANAGER_ID>203</MANAGER_ID><LOCATION_ID>2400</LOCATION_ID></ROW>

XQueryに固有の設定で使用できるSQL*Plus SETコマンドもいくつかあります。現在の設定を参照するにはSHOW XQUERYを使用します。

- SET XQUERY BASEURI: XQUERYのベースURIを設定します。XQuery式内のURIは、このURIに相対的です。

- SET XQUERY CONTEXT: 以降のXQUERY評価で使用するコンテキスト項目を指定します。

関連項目:
『SQL*Plusユーザーズ・ガイドおよびリファレンス』

XQueryの、PL/SQL、JDBC、およびODP.NETとの使用

この章の前項で、SQLからXQueryを呼び出す方法を示しました。この項では、XQueryを、PL/SQL、JDBC、およびOracle Data Provider for .NET(ODP.NET)用のOracle APIとともに使用する例を示します。

例5-25は、XQueryをPL/SQLとともに使用する方法、特に、XMLQueryのPASSING句を使用して動的変数をXQuery式にバインドする方法を示します。バインド変数:1および:2は、PL/SQLバインド変数nbitemsおよびpartidに、それぞれバインドされます。その後、それぞれXQuery変数itemnoおよびidとしてXQueryに渡されます。

例5-25 XQueryをPL/SQLとともに使用する

DECLARE
sql_stmt VARCHAR2(2000); -- Dynamic SQL statement to execute
nbitems  NUMBER := 3; -- Number of items
partid   VARCHAR2(20):= '715515009058'; -- Part ID
result   XMLType;
doc      DBMS_XMLDOM.DOMDocument;
ndoc     DBMS_XMLDOM.DOMNode;
buf      VARCHAR2(20000);
BEGIN
sql_stmt :=
'SELECT XMLQuery(
''for $i in fn:collection("oradb:/OE/PURCHASEORDER") ' ||
'where count($i/PurchaseOrder/LineItems/LineItem) = $itemno ' ||
'and $i/PurchaseOrder/LineItems/LineItem/Part/@Id = $id ' ||
'return $i/PurchaseOrder/LineItems'' ' ||
'PASSING :1 AS "itemno", :2 AS "id" ' ||
'RETURNING CONTENT) FROM DUAL';

EXECUTE IMMEDIATE sql_stmt INTO result USING nbitems, partid;
doc  := DBMS_XMLDOM.newDOMDocument(result);
ndoc := DBMS_XMLDOM.makeNode(doc);
DBMS_XMLDOM.writeToBuffer(ndoc, buf);
DBMS_OUTPUT.put_line(buf);
END;
/

これによって、次の出力が生成されます。

<LineItems>
<LineItem ItemNumber="1">
<Description>Samurai 2: Duel at Ichijoji Temple</Description>
<Part Id="37429125526" UnitPrice="29.95" Quantity="3"/>
</LineItem>
<LineItem ItemNumber="2">
<Description>The Red Shoes</Description>
<Part Id="37429128220" UnitPrice="39.95" Quantity="4"/>
</LineItem>
<LineItem ItemNumber="3">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="1"/>
</LineItem>
</LineItems>
<LineItems>
<LineItem ItemNumber="1">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="2">
<Description>The Unbearable Lightness Of Being</Description>
<Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="3">
<Description>Sisters</Description>
<Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
</LineItem>
</LineItems>

PL/SQL procedure successfully completed.

例5-26は、XQueryをJDBCとともに使用して、変数をその位置によってSQL/XML関数XMLTableのPASSING句にバインドします。

例5-26 XQueryをJDBCとともに使用する

import java.sql.*;
import oracle.sql.*;
import oracle.jdbc.*;
import oracle.xdb.XMLType;
import java.util.*;

public class QueryBindByPos
{
public static void main(String[] args) throws Exception, SQLException
{
System.out.println("*** JDBC Access of XQuery using Bind Variables ***");
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
OracleConnection conn
= (OracleConnection)
DriverManager.getConnection("jdbc:oracle:oci8:@localhost:1521:ora11gR1", "oe", "oe");
String xqString
= "SELECT COLUMN_VALUE" +
"FROM XMLTable('for $i in fn:collection(\"oradb:/OE/PURCHASEORDER\") " +
"where $i/PurchaseOrder/Reference= $ref " +
"return $i/PurchaseOrder/LineItems' " +
"PASSING ? AS \"ref\")";
OraclePreparedStatement stmt = (OraclePreparedStatement)conn.prepareStatement(xqString);
String refString = "EABEL-20021009123336251PDT"; // Set the filter value
stmt.setString(1, refString); // Bind the string
ResultSet rs = stmt.executeQuery();
while (rs.next())
{
XMLType desc = (XMLType) rs.getObject(1);
System.out.println("LineItem Description: " + desc.getStringVal());
desc.close();
}
rs.close();
stmt.close();
}
}

これによって、次の出力が生成されます。

*** JDBC Access of Database XQuery with Bind Variables ***
LineItem Description: Samurai 2: Duel at Ichijoji Temple
LineItem Description: The Red Shoes
LineItem Description: A Night to Remember

例5-27は、XQueryをODP.NETおよびC#言語とともに使用する方法を示します。C#の入力パラメータ:nbitemsおよび:partidは、それぞれXQuery変数itemnoおよびidとしてXQueryに渡されます。

例5-27 XQueryをODP.NETおよびC#とともに使用する

using System;
using System.Data;
using System.Text;
using System.IO;
using System.Xml;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;

namespace XQuery
{
/// <summary>
/// Demonstrates how to bind variables for XQuery calls
/// </summary>
class XQuery
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
int rows = 0;
StreamReader sr = null;

// Create the connection.
string constr = "User Id=oe;Password=***********;Data Source=ora11gr2"; // Replace with real password.
OracleConnection con = new OracleConnection(constr);
con.Open();

// Create the command.
OracleCommand cmd = new OracleCommand("", con);

// Set the XML command type to query.
cmd.CommandType   = CommandType.Text;

// Create the SQL query with the XQuery expression.
StringBuilder blr = new StringBuilder();
blr.Append("SELECT COLUMN_VALUE FROM XMLTable");
blr.Append("(\'for $i in fn:collection(\"oradb:/OE/PURCHASEORDER\") ");
blr.Append("   where count($i/PurchaseOrder/LineItems/LineItem) = $itemno ");
blr.Append("      and $i/PurchaseOrder/LineItems/LineItem/Part/@Id = $id ");
blr.Append("   return $i/PurchaseOrder/LineItems\' ");
blr.Append("  PASSING :nbitems AS \"itemno\", :partid AS \"id\")");

cmd.CommandText = blr.ToString();
cmd.Parameters.Add(":nbitems", OracleDbType.Int16, 3, ParameterDirection.Input);
cmd.Parameters.Add(":partid", OracleDbType.Varchar2, "715515009058", ParameterDirection.Input);

// Get the XML document as an XmlReader.
OracleDataReader dr = cmd.ExecuteReader();
dr.Read();

// Get the XMLType column as an OracleXmlType
OracleXmlType xml = dr.GetOracleXmlType(0);

// Print the XML data in the OracleXmlType object
Console.WriteLine(xml.Value);
xml.Dispose();

// Clean up.
cmd.Dispose();
con.Close();
con.Dispose();
}
}
}

これによって、次の出力が生成されます。

<LineItems>
<LineItem ItemNumber="1">
<Description>Samurai 2: Duel at Ichijoji Temple</Description>
<Part Id="37429125526" UnitPrice="29.95" Quantity="3"/>
</LineItem>
<LineItem ItemNumber="2">
<Description>The Red Shoes</Description>
<Part Id="37429128220" UnitPrice="39.95" Quantity="4"/>
</LineItem>
<LineItem ItemNumber="3">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="1"/>
</LineItem>
</LineItems>

関連項目:

- 第13章「PL/SQL APIs for XMLType」

- 第15章「Java DOM API for XMLType」

- 第17章「Oracle XML DBでのOracle Data Provider for .NETの使用」

Oracle XML DBでのXQueryサポート

この項では、XQuery言語のためのOracle XML DBについて説明します。

XQueryとSQLのサポート

Oracle XML DBのXQuery言語サポートは、リレーショナル記憶域の使用範囲とXMLデータの問合せの使用範囲のベスト・フィットの実現を目指しています。つまり、Oracle XML DBは一般的なXQuery実装ですが、それと同時に、リレーショナル問合せとXML問合せの連携動作に特に注意して設計されています。

この項では、Oracle XML DBのXQuery実装の個別のプロパティについて説明します。XQuery標準は、言語処理の一部の特性について、実装により定義されるのか、実装に依存するのかを明示的にコール・アウトしています。また、XQuery標準で規定されているが、Oracle XML DBでサポートされていない機能もいくつかあります。

XQuery標準で指定された実装の選択肢

XQuery仕様では、言語処理の次の点に関しては実装により定義するように指定されています。

- 暗黙的タイムゾーン・サポート: Oracle XML DBでは、暗黙的タイムゾーンを常にZと仮定しています。タイムゾーンのないxs:date、xs:timeおよびxs:datetimeのインスタンスは、自動的にUTCに変換されます。

Oracle XML DBでサポートされていないXQuery機能

XQuery標準で規定されている次の機能は、Oracle XML DBではサポートされていません。

- copy-namespacesモード: Oracle XML DBでcopy-namespaces宣言についてサポートされるのは、preserveとinheritのみです。既存の要素ノードが要素コンストラクタまたは文書コンストラクタによりコピーされた場合、元の要素の範囲にあるすべてのネームスペースはコピー内に保持されます。そうでない場合は、コピーされたノードは構築されたノードの範囲内にあるすべてのネームスペースを継承します。no-preserveまたはno-inheritを指定するとエラーが発生します。

- バージョン・エンコーディング: Oracle XML DBでは、バージョン宣言の中のオプションのエンコーディング宣言はサポートされません。つまり、(encoding an-encoding)を宣言xquery version a-version;の中に含むことはできません。特に、問合せで使用するエンコーディングは指定できません。エンコーディング宣言が含まれるとエラーが発生します。

- xml:id: Oracle XML DBでは、xml:idの使用はサポートされません。xml:idを使用するとエラーが発生します。

- XQueryプロローグのデフォルト照合宣言

- XQueryプロローグの境界空間宣言

- XQueryデータ型xs:duration。かわりにxs:yearMonthDurationまたはxs:DayTimeDurationを使用します。

XQueryのオプション機能

XQuery標準で規定されている次のオプション機能は、Oracle XML DBではサポートされていません。

- スキーマ検証機能

- モジュール機能

XQueryの関数と演算子のサポート

Oracle XML DBでは、XQuery 1.0およびXPath 2.0の関数および演算子の最新の仕様に含まれるXQueryの関数と演算子がすべてサポートされていますが、次の例外があります。次のものはサポートされていません。

- XQueryの正規表現関数(fn:matches、fn:replaceおよびfn:tokenize)。これらのかわりに、Oracle XQuery関数ora:matches、ora:replaceおよびora:tokenizeをそれぞれ使用してください。

- 関数fn:idおよびfn:idref。

- 引数のない関数fn:collection。

- XQuery関数のオプションの照合パラメータ。

XQuery関数fn:doc、fn:collectionおよびfn:doc-available

Oracle XML DBでは、Oracle XML DBリポジトリにあるすべてのリソースについて、XQuery関数fn:doc、fn:collectionおよびfn:doc-availableがサポートされています。

関数fn:docはURI引数によりターゲットとされているリポジトリのファイル・リソースを戻します。このリソースは整形式のXMLデータのファイルにしてください。関数fn:collectionも同様ですが、リポジトリのフォルダ・リソースに対して機能します(フォルダ内の各ファイルには整形式のXMLデータが含まれている必要があります)。

Oracle URIスキームoradbとともに使用すると、fn:collectionは既存のリレーショナル・データからその場で派生した、リポジトリにないXMLデータを戻すことができます。

XQuery関数fn:collectionは、URIスキームoradbとともに使用した場合、ターゲットの表やビュー、列が存在しないと、エラーが発生します。関数fn:docとfn:collectionでは、引数として引き渡されたリポジトリのリソースが見つからない場合、エラーは発生しません。かわりに、空のシーケンスが戻されます。

任意の文書が存在するかどうかは、XQuery関数fn:doc-availableを使用して判断できます。文書の引数が存在する場合はtrue、存在しなければfalseがそれぞれ戻されます。

関連項目:
XQueryの関数と演算子の定義についてはhttp://www.w3.org

脚注の凡例

脚注1: 戻り値は、通常と同様、シーケンスです。ただしXQueryでは、項目が1つのシーケンスはその項目自身と等価です。この場合、その単独の項目はブール値です。
脚注2: 名前空間の接頭辞xsは、XML Schemaの名前空間http://www.w3.org/2001/XMLSchemaであらかじめ定義されています。
脚注3: ここでは、疑問符(?)は0回または1回出現することを示すインジケータで、引数が空のシーケンスである場合もあります。「XQuery式」を参照してください。
脚注4: ここでは、疑問符(?)は0回または1回出現することを示すインジケータで、引数が空のシーケンスである場合もあります。「XQuery式」を参照してください。
脚注5: ここでは、疑問符(?)は0回または1回出現することを示すインジケータで、引数が空のシーケンスである場合もあります。「XQuery式」を参照してください。
脚注6: XQuery関数fn:dataは、その引数の分解に使用されます。この場合は、XMLRefノード型指定されたアトミック値を戻します。

6 XMLTypeデータの索引付け

頻繁に問い合せるXMLデータの特定部分に着目できるよう当該XMLデータに対して索引を作成し、パフォーマンスを向上できます。この章では、これを実現するためのガイドラインを示します。スキーマに基づくか否かにかかわらず、また、使用されるXMLType記憶域モデル(バイナリXML、非構造化、ハイブリッド、または構造化)に関係なく、XMLTypeデータに索引付けするための様々な方法について説明します。

この章の内容は次のとおりです。

- 索引に関連するOracle XML DBのタスク

- XMLTypeデータの索引付けの概要

- オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け

- XMLIndex

- XMLデータに対するOracle Text索引

注意:
ここで示す実行計画は、説明のためのみに使用しています。ここで示す例を実際の環境で実行しても、実行計画が同一になるわけではありません。

関連項目:

- 索引付けの概要は、『Oracle Database概要』を参照してください。

- アプリケーション開発における索引付けの詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

索引に関連するOracle XML DBのタスク

表6-1は、XMLデータの索引付けに関連するいくつかの基本的なユーザー・タスクの参照先を示します。

表6-1 基本的なXML索引付けタスク

操作の詳細

参照先

オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け

「オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け」、「ガイドライン: Ordered Collection表に対する索引の作成」

XMLIndex索引の作成、削除または名前の変更

例6-6、例6-8

特定の表または列に対するXMLIndex索引名の取得

例6-7

指定されたXMLIndex索引を問合せの評価に使用するかどうかの判断

「XMLIndexが使用されるかどうかを判別する方法」

XMLIndex索引の使用の無効化

「XMLIndexの使用の無効化」

表6-2は、構造化コンポーネントを含むXMLIndex索引付けに関連するいくつかのユーザー・タスクの参照先を示します。

表6-2 構造化コンポーネントを含むXMLIndex索引に関連するタスク

操作の詳細

参照先

構造化コンポーネントが含まれるXMLIndex索引の作成

例6-20、例6-24

XMLIndex索引の構造化コンポーネントの削除(すべての構造グループの削除)

例6-21

構造化コンポーネントが含まれるXMLIndex索引と問合せの間のデータ型の対応の確認

「XMLIndex構造化コンポーネントのデータ型に関する考慮事項」

XMLIndex構造化コンポーネントのコンテンツ表に対するBツリー索引の作成

例6-22

XMLIndex構造化コンポーネントのコンテンツ表に対するOracle Text CONTEXT索引の作成

例6-23

表6-3は、非構造化コンポーネントを含むXMLIndex索引付けに関連するいくつかのユーザー・タスクの参照先を示します。

表6-3 非構造化コンポーネントを含むXMLIndex索引に関連するタスク

操作の詳細

参照先

非構造化コンポーネントが含まれるXMLIndex索引の作成

例6-9、例6-11、例6-31、例6-33、例6-34、例6-35、例6-36

XMLIndex索引の非構造化コンポーネントの削除(パス表の削除)

例6-12

XMLIndex索引作成時の、パス表への名前付け

例6-9

XMLIndex索引作成時の、記憶域オプションの指定

例6-11

XMLIndexパス表にある既存の2次索引すべての表示

例6-13、例6-19

XMLIndex索引に対するパス表名の取得

例6-10

パス表の指定による、非構造化コンポーネントが含まれるXMLIndex索引名の取得

例6-26

XMLIndexパス表に対する2次索引の作成

「非構造化コンポーネントを含むXMLIndexの使用」

XMLIndexパス表にあるすべての2次索引に関する情報の取得

例6-19

パス表のVALUE列に対するファンクション索引の作成

例6-14

パス表のVALUE列に対する数値索引の作成

例6-16

パス表のVALUE列に対する日付索引の作成

例6-17

パス表のVALUE列に対するOracle TextのCONTEXT索引の作成

例6-18

XMLIndex索引の使用における、特定のXPath式の除外または包含

「XMLIndexパスのサブセット化: 索引付けするパスの指定」

XMLIndexで使用されるXPath式のネームスペース接頭辞の指定

「XMLIndexパスのサブセット化: 索引付けするパスの指定」

XMLIndex索引の使用における、特定のXPath式の除外または包含

「XMLIndexパスのサブセット化: 索引付けするパスの指定」

XMLIndexで使用されるXPath式のネームスペース接頭辞の指定

「XMLIndexパスのサブセット化: 索引付けするパスの指定」

表6-4は、XMLIndex索引付けに関連するその他のユーザー・タスクの参照先を示します。

表6-4 XMLIndex索引に関連するその他のタスク

操作の詳細

参照先

XMLIndex索引の作成およびメンテナンスで並列処理を使用することの指定

「XMLIndexのパーティション化および並列度」

XMLIndexパス表の並列度の変更による、索引パフォーマンスのチューニング

「XMLIndexのパーティション化および並列度」

XMLIndex索引のメンテナンスのスケジュール

「XMLIndex索引の非同期(遅延)メンテナンス」

XMLIndex索引および実表の手動による同期化

「XMLIndex索引の非同期(遅延)メンテナンス」

コストベース・オプティマイザに対する表または索引に関する統計の収集

例6-38

Oracle TextのCONTEXT索引の作成

例6-39

XMLIndex構造化コンポーネントのコンテンツ表に対するOracle Text CONTEXT索引の作成

例6-23

XMLデータの全文検索におけるOracle TextのCONTEXT索引の使用

例6-40

Oracle TextのCONTEXT索引を問合せに使用するかどうかの表示

例6-40

XMLTypeデータの索引付けの概要

データベース索引では、表データに対するアクセスを高速化することにより、パフォーマンスが向上します。索引の使用は、更新が少ないオンライン・トランザクション処理(OLTP)環境に特に適しています。

XMLデータを索引付けする基本的な方法は、XMLIndexを使用することです。Oracle Text CONTEXT索引を使用して、XMLIndexの使用を補完することもできます。

XMLIndexによるXMLデータのファイングレイン構造の対処

表の1列または複数の列、またはファンクション式に対して索引を作成できます。XMLデータには独自のファイングレイン構造がありますが、その構造は、XMLデータが格納されるデータベース表の構造に必ずしも反映されるとはかぎりません。このような理由から、XMLデータに効果的に索引付けする方法は、他の大部分のデータベース・データに対する索引付けとは多少異なります。

構造化XML記憶域では、要素や属性などのXMLオブジェクトは、オブジェクト・リレーショナル列および表に対応しているため、これらの列および表に対してBツリー索引を作成する方法は、対応するXMLオブジェクトに効果的に索引付けする場合に最適です。この場合、記憶域モデルはXMLデータのファイングレイン構造を直接反映するため、構造化XMLデータの索引付けにおいて特別な問題は生じません。「オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け」を参照してください。

非構造化、ハイブリッドおよびバイナリXML記憶域では、標準的な索引(Bツリー、ビットマップ)を使用してデータベース列に索引付けすると、多くの場合、XML文書の特定部分にアクセスする際に問題が生じます。XML文書を含むXMLType列がCLOBインスタンスとして格納されると、その文書内の細部が列の索引にアクセスできなくなります。つまり、列の索引に関しては、文書全体が単独のユニットとして機能することになります。ハイブリッド記憶域では、XML文書の一部が分割され、オブジェクト・リレーショナル形式(構造化記憶域)で格納されますが、1つ以上のXMLフラグメントがCLOBインスタンス(非構造化記憶域)として格納されます。このような場合は、通常、XML SchemaのcomplexTypeまたは複合要素をCLOB記憶域にマッピングします。これは、通常はフラグメント全体が1つの単位としてアクセスされるためです。標準的な索引の場合、索引付けの単位としても機能します。

XMLIndexは通常のXML固有の索引により、XMLデータの内部構造に索引付けします。その主な目的の1つとして、非構造化、ハイブリッドおよびバイナリXML記憶域によって課される索引付けの制限を克服することがあげられます。

- 非構造化コンポーネントを含むXMLIndex索引では、文書のXMLタグに索引付けし、それをターゲットとするXPath式に基づいて文書のフラグメントを識別します。また、スカラー・ノードの値に対して索引付けすることで、単独の値または値の範囲に基づく高速参照も可能にします。さらに、索引付けする各ノードに対し、文書の階層情報(親と子、祖先と子孫、および兄弟の関係)を記録します。この索引コンポーネントは、構造が少ない文書または可変構造を持つ文書からXMLフラグメントを抽出する問合せで特に便利です。

- 構造化コンポーネント含むXMLIndex索引では、ほとんどの部分が構造化されていないXMLデータでも、高度に構造化された予測可能な部分に索引付けします。この索引コンポーネントは、構造化コンテンツのアイランドを投影および使用する問合せで特に便利です。

関連項目:
「XMLIndex」

Oracle Text索引

要素や属性などのXMLノードにアクセスする以外にも、XMLテキスト・ノード内の特定の節に対して高速アクセスを提供する必要があることがあります。Oracle Text索引は全文文字列に対して索引付けすることで、この目的を達成します。Oracle TextのCONTEXT索引では、XMLの全文検索を実行するためのOracle SQL関数containsを使用できます。構造化記憶域では、XPathリライトにより、ora:contains XPath関数を使用する問合せが、contains SQL関数を使用する問合せにリライトされることが多いため、このようなケースでもOracle Text索引が使用されます。

全文索引は、特に、XML要素とテキストノード・コンテンツが混在する、文書中心のアプリケーションにおいて有用です。全文検索は、構造化XML検索と組み合せる(XPath式によって識別されるXML文書の一定部分に対して検索を限定する)ことによってさらに強力に、焦点を絞って行えるようになります。

関連項目:
「XMLデータに対するOracle Text索引」

最適化による、使用する適切な索引の選択

1つのケースで複数の索引が該当する場合は、どの索引が使用されるでしょうか。パフォーマンスを最大化する索引(複数可)は、コストベースの最適化によって決定されます。Oracle Text索引はテキストにのみ適用されるため、XMLデータではテキスト・ノードを意味します。テキスト・ノードがターゲットとされ、対応するOracle Text索引が定義されている場合は、Oracle Text索引が使用されます。特定のコンテキストにおいて他の索引も適している場合は、これらも使用されます。ただし、索引が定義されており、特定の状況下において適しているように見えても、その索引が必ずしも使用されるとはかぎりません。コストベース・オプティマイザが費用効率を発揮できないと判断した索引は使用されません。

XMLデータの非推奨の索引

Oracle Database 11gリリース1(11.1)以前のリリースでは、XMLTypeデータにおいてCTXXPath索引の使用が適していることもありました。Oracle Database 11gリリース2(11.2)以前のリリースでは、XMLTypeデータにおいてファンクション索引の使用が適していることもありました。これらの索引付け方式は、XMLTypeデータで使用しないことをお薦めします。

ファンクション索引

Oracle Database 11gリリース2(11.2)以前のリリースでは、XPath式が単一ノードをターゲットにしている場合、XMLTypeデータにおいてファンクション索引の使用が適していることもありました。かわりに、XMLIndexの構造化コンポーネントを使用することをお薦めします。これにより、ファンクション索引のメンテナンス操作に関連するオーバーヘッドを軽減し、オプティマイザで索引を適切に選択できる状況が増えます。その結果、既存のDML文の変更が不要になります。

さらに、構造化記憶域では、Oracle SQL関数extractValue(非推奨)で索引を定義すると、XPathリライトにより、(extractValueに対してファンクション索引ではなく)基礎のオブジェクトに対してBツリー索引が自動的に作成されることがあります。XPathのターゲットは単一の要素または属性である必要があります。XMLQueryに適用されるXMLCastに対しても、同様のショートカットが存在します。

関連項目:

- 「オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け」

- 「XMLIndex構造化コンポーネント」

CTXXPath索引

XMLデータの索引付けに使用されていたもう1つの索引CTXXPathは、Oracle Database 11gリリース1 (11.1)で非推奨になりました。CTXXPath索引はXMLIndexに置き換えられ、旧データベース・リリースでのみ使用されることになります。XMLフラグメントの抽出には使用されず、等価述語の事前フィルタとしてのみ機能します。事前フィルタリングを実行後、XPath式は関数として評価されます(つまり、XPathリライトの利点は活用されません)。

注意:
CTXSYS.CTXXPath索引は、Oracle Database 11gリリース1 (11.1)で非推奨になりました。CTXXPathによって提供されていた機能は、XMLIndexで提供されるようになります。
CTXXPath索引をXMLIndex索引に置換することをお薦めします。今後リリースされるデータベースでは、CTXXPathはサポートされなくなります。

オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け

XMLノードに対応する基礎となるデータベース列に対してBツリー索引を作成することで、オブジェクト・リレーショナル形式(構造化記憶域)で格納されたXMLデータを効果的に索引付けできます。

索引付けされるデータが単一の場合、つまりXMLインスタンス文書で一度のみ発生する可能性がある場合、表面的上ファンクション索引を作成するショートカットを使用できます。この場合、索引を定義する式はファンクション・アプリケーションで、単一データをターゲットとするXPath式の引数を使用します。ショートカットはXMLQueryに適用されるXMLCastに対して定義され、もう1つのショートカットはOracle SQL関数extractValueに対して定義されます(非推奨)。

多くの場合、Oracle XML DBでは、基礎となるオブジェクト・リレーショナル表または列に対して適切な索引が自動的に作成されますが、CREATE INDEX文が示すように、ターゲットとなるXMLTypeデータに対して、ファンクション索引は作成されません。

extractValueショートカットの場合、作成される索引はBツリー索引です。XMLQueryに適用されるXMLCastの場合、作成される索引は、ファンクション式から得られるスカラー値に対するファンクション索引です。これについては、「繰り返し使用しないtext()ノードまたは属性値の索引付け」で説明します。

索引付けされるデータがコレクションの場合、このようなショートカットを使用できません。手動でBツリー索引を作成する必要があります。これについては、「繰り返し使用する(コレクション)要素の索引付け」で説明します。

繰り返し使用しないtext()ノードまたは属性値の索引付け

サンプル・データベース・スキーマOEの表purchaseorderはオブジェクト・リレーショナルに格納されます。各発注書には単一のReference要素が含まれます。つまりこの要素は単一です。したがって、ショートカットを使用して、基礎となるオブジェクト・リレーショナル・データに索引を作成できます。

例6-1に、Reference要素のテキスト・コンテンツをターゲットとし、XMLQueryに適用されるXMLCastを使用して、表面上ファンクション索引を作成しようとするCREATE INDEX文を示します(この要素のコンテンツはテキストのみのため、要素をターゲットにすることは、ノード・テストtext()を使用してテキスト・ノードをターゲットにすることと同じです)。

例6-2は、同じデータをターゲットにし、Oracle SQL関数extractValue(非推奨)を使用して表面上ファンクション索引を作成します。

例6-1 単一の要素でXMLCASTおよびXMLQUERYを使用したCREATE INDEX

CREATE INDEX po_reference_ix ON purchaseorder
(XMLCast(XMLQuery ('$p/PurchaseOrder/Reference' PASSING po.OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(128)));

例6-2 単一の要素でEXTRACTVALUEを使用したCREATE INDEX

CREATE INDEX po_reference_ix ON purchaseorder
(extractValue(OBJECT_VALUE, '/PurchaseOrder/Reference'));

実際、例6-1と例6-2では、ターゲットとなるXMLTypeデータに対してファンクション索引は作成されません。かわりに、Oracle XML DBによってCREATE INDEX文がリライトされ、基礎となるスカラー・データに対して索引が作成されます。

関連項目:
このようなCREATE INDEX文に適用されるXPathリライトの詳細は、例8-4および例8-5を参照してください。

これらのショートカットのいずれかを使用するとき、CREATE INDEX文は前述のように基礎となるスカラー・データ上に索引を作成できない場合があります。そのかわり、実際には参照されるXMLTypeデータにファンクション索引を作成します。(これは索引の値がスカラーである場合でも当てはまります)。

このような場合は、索引を削除し、同じXPathをターゲットとする構造化コンポーネントを含むXMLIndex索引をかわりに作成します。一般的に、XMLTypeデータに対してはファンクション索引を使用しないことをお薦めします。

これは使用される格納方法にかかわらず、XMLTypeデータの一般的なルールです。ファンクション索引のかわりに構造化コンポーネントでXMLIndexを使用します。このルールはOracle Database 11gリリース 2 (11.2)から適用されます。このルールを守ることにより、ファンクション索引のメンテナンス操作に関連するオーバーヘッドを軽減し、オプティマイザで索引を適切に選択できる状況が増えます。

関連項目:
「ファンクション索引」

繰り返し使用する(コレクション)要素の索引付け

構造化記憶域では、コレクションはXMLTypeインスタンスのOrdered Collection Table(OCT)として格納されるため、メンバーに直接アクセスできます。構造化記憶域モデルは、XMLデータのファイングレイン構造を直接反映するため、各コレクション・メンバーをターゲットとする索引を作成できます。

このような索引は、手動で作成する必要があります。Oracle SQL関数extractValue(非推奨)に対して表面上ファンクション索引を作成する場合に、Bツリー索引を自動的に作成する専用の機能は、コレクションに適用されません(extractValueに渡されるXPath式は、単一要素をターゲットにする必要があります)。

コレクションに対してBツリー索引を作成するには、コレクションの管理に使用するSQLオブジェクトの構造を理解する必要があります。その情報に基づき、従来のオブジェクト・リレーショナルSQLコードを使用して、適切なSQLオブジェクト属性に対して索引を直接作成できます。この方法の例は、「ガイドライン: Ordered Collection表に対する索引の作成」を参照してください。

XMLIndex

この項の内容は次のとおりです。

- XMLIndexの利点

- 構造化XMLIndexコンポーネントと非構造化XMLIndexコンポーネント

- XMLIndex構造化コンポーネント

- XMLIndex非構造化コンポーネント

- XMLIndex索引の作成、削除、変更、および検証

- 非構造化コンポーネントを含むXMLIndexの使用

- 構造化コンポーネントを含むXMLIndexの使用

- XMLIndexが使用されるかどうかを判別する方法

- XMLIndexの使用の無効化

- XMLIndexパスのサブセット化: 索引付けするパスの指定

- 非構造化コンポーネントを含むXMLIndexを使用するためのガイドライン

- 構造化コンポーネントを含むXMLIndexの使用のガイドライン

- XMLIndexのパーティション化および並列度

- XMLIndex索引の非同期(遅延)メンテナンス

- コストベース・オプティマイザに対するXMLIndexオブジェクトの統計の収集

- XMLIndexに関連するデータ・ディクショナリの静的なパブリック・ビュー

- CREATE INDEXおよびALTER INDEXのPARAMETERS句

構造化(オブジェクト・リレーショナル)記憶域では、Bツリー索引を効果的に使用できます。基礎となるオブジェクトを直接ターゲット化することで、焦点がより明確に絞られます。ただし、バイナリXMLまたはCLOB記憶域を使用して格納されているXML文書、またはオブジェクト・リレーショナル記憶域に埋め込まれたCLOBインスタンスに格納されたXMLフラグメントの詳細な構造(要素および属性)を指定する場合、通常は効果を発揮しません。これは、XMLIndex(非構造化およびハイブリッド記憶域)の特殊ドメインです。

XMLIndexは一般的に、文書の一部に対してアクセスする場合に使用されるため、これらの部分を1つ以上のCLOBインスタンスにパックします。それでも、文書内のこれらの部分に対して問い合せる必要が生じることもあります。このような場合に、XMLIndexが役立ちます。

また、関連する文書構造とデータ型に対する特定の知識がなく、XML Schemaにxsd:any要素が含まれている場合にも使用されます。これらの要素に対応するデータはCLOBインスタンスに格納され、XMLIndexを使用して、アクセス速度を高められます。

XMLIndexの利点

XMLIndexはドメイン索引で、XMLデータのドメイン用に特化して設計されています。これは論理的索引です。XMLIndex索引は、SQL/XML関数XMLQuery、XMLTable、XMLExistsおよびXMLCastに対して使用できます。

XMLIndexには、他の索引付け方式に比べ、次のような利点があります。

- XMLIndex索引は、問合せのどの部分においても効果があります。つまり、WHERE句での使用に限定されません。これは、XMLデータで使用される他の種類の索引では考えられません。

- 非構造化コンポーネントを含むXMLIndex索引では、SELECTリスト・データとFROMリスト・データの両方に対するアクセスを高速化でき、特にXMLフラグメント抽出において有用です。ファンクション索引とCTXXPath索引は両方とも非推奨になったため、文書のフラグメントの抽出には使用できません。

- XMLIndex索引は、XML Schemaに基づくデータ、またはスキーマに基づかないデータに対して使用できます。非構造化記憶域、ハイブリッド記憶域またはバイナリXML記憶域で使用できます。Bツリー索引は、オブジェクト・リレーショナル形式(構造化記憶域)で格納されるXML Schemaに基づくデータに対してのみ使用でき、CLOBインスタンスに格納されるXML Schemaに基づくデータに対しては効果的ではありません。

- XMLIndex索引は、コレクション(文書内に複数回出現するノード)をターゲットとするXPath式による検索において使用できます。ファンクション索引の場合とは異なります。

- 問合せに使用されるXPath式に関する事前の知識は不要です。XMLIndex索引の非構造化コンポーネントは、汎用性に富んでいます。ファンクション索引の場合とは異なります。

- 問合せに使用されるXPath式が事前にわかっている場合は、頻繁に問合せされる構造化された固定のデータ・アイランドをターゲットとする構造化XMLIndexコンポーネントを使用することで、パフォーマンスを向上できます。

- XMLIndex索引(索引の作成とメンテナンス)は、複数のデータベース処理により、並列的に実行できます。これは、非推奨になったファンクション索引およびCTXXPATH索引の場合とは異なります。

構造化XMLIndexコンポーネントと非構造化XMLIndexコンポーネント

XMLIndexを使用して半構造化脚注 1 のXMLデータ(一般的にほとんどまたはまったく固定構造を持たないデータ)を索引付けします。バイナリXMLまたはCLOBベース記憶域を使用して格納されたデータに適用されます。これには、オブジェクト・リレーショナル記憶域(ハイブリッド記憶域)に埋め込まれたCLOBインスタンスに格納されたXMLデータも含まれます。

それでも、半構造化XMLデータには、予測可能な構造化データ・アイランドが含まれることがあります。そのため、XMLIndex索引は、そのようなアイランドの索引付け用の構造化コンポーネントと、ほとんど構造を持たないまたは可変構造のデータの索引付け用の非構造化コンポーネントの2つのコンポーネントを持つことができます。

構造化コンポーネントは、構造化コンテンツのアイランドを投影および使用する問合せで使用すると役立ちます。非構造化コンポーネントは、XMLフラグメントを抽出する問合せで使用すると役立ちます。1つのXMLIndex索引に、必ずしも両方のコンポーネントが含まれている必要はありません。

構造化コンポーネントとは異なり、非構造化コンポーネントは汎用的で、比較的ターゲットを限定しません。特定のXPathサブセットにのみ適用されるように非構造化コンポーネントを制限することもできますが、そのパス表索引ノードの内容のスカラー型が異なる場合は、異なるデータ型を処理するようにVALUE列に対して複数の2次索引を作成する必要があることがあります(「VALUE列に対する2次索引」を参照)。また、非構造化コンポーネントのみを使用した場合、構造化アイランドを投影する問合せに対してプローブやそのパス表の自己結合が何度も行われるために、効率が悪くなることがあります。

一方、構造化コンポーネントは、ほとんど構造を持たない問合せや、XMLフラグメントを抽出する問合せには適していません。構造化データ・アイランドの索引付けには構造化コンポーネントを使用し、ほとんど構造を持たないデータの索引付けには非構造化コンポーネントを使用してください。

図6-1は第1章の図1-5と同じです。最後の行はXMLIndexがXMLデータの様々なユースケースに適用できるかどうかを示します。XMLIndexが半構造化XMLデータ(格納されているかどうかに関係なくに)適していることを示します(最後の3列)。構造化コンポーネントでのXMLIndex索引は、構造化アイランドを含むドキュメント中心データに有用です(4列目)。

図6-1 XMLのユースケースとXML索引付け

関連項目:

- 「XMLIndex構造化コンポーネント」

- 「XMLIndex非構造化コンポーネント」

- 各XMLIndexコンポーネント・タイプで提供される利点をまとめたものについては、「XMLIndexの利点」参照してください。

XMLIndex構造化コンポーネント

XMLコンテンツの固定の構造化アイランドを投影する問合せに対しては、周囲のデータが比較的構造化されていない場合でも、XMLIndex索引の構造化コンポーネントを作成して使用します。

構造化XMLIndexコンポーネントは、このようなアイランドをリレーショナル形式で編成します。この場合、これはSQL/XML関数XMLTableと類似しており、構造化コンポーネントの定義に使用する構文も類似しています。索引付けデータの格納に使用するリレーショナル表はデータ型を認識し、各列は異なるスカラー・データ型を持つことができます。

したがって、XMLIndex索引の構造化コンポーネントを作成することは、XMLデータの構造化部分をリレーショナル形式へ分解することと考えることができます。これは、次のような点でXMLTypeのオブジェクト・リレーショナル形式の記憶域モデルとは異なります。

- 構造化索引コンポーネントは、指定されたデータの特定の部分(頻繁に問い合せる部分)を明示的に分解します。オブジェクト・リレーショナル形式のXMLType記憶域の場合は、XMLType表または列全体が自動的に分解されます。

- XMLIndex索引の構造化コンポーネントは、XML Schemaに基づくデータにもXML Schemaに基づかないデータにも適用できます。オブジェクト・リレーショナル形式のXMLType記憶域は、XML Schemaに基づくデータにのみ適用できます。

- 構造化XMLIndexコンポーネントに対して分解されたデータは、XMLTypeデータ自体の記憶域モデルとしてではなく索引として、XMLTypeデータとともに格納されます。

- 構造化XMLIndexコンポーネントに対しては、同じデータを、データ型が異なる列として何度も投影できます。

XMLIndex索引の構造化コンポーネントに使用する索引コンテンツ表は索引の一部ですが、通常のリレーショナル表なので、標準的なリレーショナル索引(主キーおよび外部キー制約を満たす索引を含む)を使用すれば、これらの表にも索引を作成できます。また、Oracle Text CONTEXT索引などのドメイン索引を使用して索引を作成することもできます。

また、XMLIndex索引の構造化コンポーネントは、汎化ファンクション索引として考えることもできます。ファンクション索引は、リレーショナル列を1つのみ持つ構造化XMLIndexコンポーネントのようなものです。

特定のアプリケーションに対して複数のファンクション索引を作成することを予定している場合、かわりに構造化XMLIndex索引を使用することを考慮してください。また、構造化索引コンポーネントの列にBツリー索引も作成します。

注意:

- SQL/XML関数XMLTableを使用する問合せは通常、XMLIndex構造化コンポーネントのリレーショナル索引付け表を使用するようにリライトすることができます。これらの表には、システム定義の内部列も含まれます。これらの内部列は将来的に変更される可能性があるため、その存在や内容を前提とするようなコードは記述しないでください。

- SQL TABLEコレクション式内のOracle SQL関数XMLSequence (TABLE(XMLSequence(...)))を使用する問合せは、XMLIndex構造化コンポーネントの索引付け表を使用するようにリライトされません。Oracle SQL関数XMLSequenceは、Oracle Database 11gリリース2で非推奨になりました。かわりに、標準のSQL/XML関数XMLTableを使用してください。
SQL TABLEコレクション式の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

透過的な索引コンテンツ表の無視

XMLIndex構造化コンポーネントの索引コンテンツ表は通常のリレーショナル表ですが、読取り専用の表でもあるため、表の列を追加または削除したり、表の行を変更(挿入、更新または削除)したりすることはできません。

したがって、通常はリレーショナル索引コンテンツ表は無視してかまいません。DESCRIBEしたり、(2次)索引を作成する以外、それらにアクセスできません。それらに関する統計を明示的に収集する必要はありません。XMLIndex索引自体、またはXMLIndex索引が定義されている実表に関する統計のみ収集する必要があります。索引コンテンツ表に関する統計は透過的に収集され保持されます。

関連項目:
「コストベース・オプティマイザに対するXMLIndexオブジェクトの統計の収集」

XMLIndex構造化コンポーネントのデータ型に関する考慮事項

XMLIndex構造化コンポーネントに使用されるリレーショナル表では、SQLデータ型が使用されます。問合せ内で使用されるXQuery式では、XMLデータ型(XML Schemaデータ型およびXQueryデータ型)が使用されます。

一貫性や型チェックを保証するために、XQueryの入力規則の部分式のデータ型が自動的に変わることがあります。たとえば、XPath式/PurchaseOrder/LineItem[@ItemNumber = 25]を使用して問合せされる文書がXML Schemaに基づいていない場合、部分式@ItemNumberは型なしとなり、XQueryの比較演算子=によって自動的にxs:doubleにキャストされます。XMLIndex構造化コンポーネントを使用してこのデータに索引を作成するには、SQLデータ型としてBINARY_DOUBLEを使用する必要があります。

これは通例です。構造化コンポーネントを含むXMLIndex索引を問合せに適用するには、データ型が対応している必要があります。表6-5に、対応するデータ型を示します。

表6-5 XMLIndexでのXMLデータ型とSQLデータ型の対応

XMLデータ型

SQLデータ型

xs:decimal

INTEGERまたはNUMBER

xs:double

BINARY_DOUBLE

xs:float

BINARY_FLOAT

xs:date

DATE、TIMESTAMP WITH TIMEZONE

xs:dateTime

TIMESTAMP、TIMESTAMP WITH TIMEZONE

xs:dayTimeDuration

INTERVALDAYTOSECOND

xs:yearMonthDuration

INTERVALYEARTOMONTH

注意:
XMLデータ型がxs:dateまたはxs:dateTimeの場合、索引を作成する問合せ対象のデータにタイムゾーン・コンポーネントが含まれていないことがわかっていれば、SQLデータ型DATEまたはTIMESTAMPを使用するとパフォーマンスを高めることができます。データにタイムゾーン・コンポーネントが含まれている可能性がある場合は、SQLデータ型TIMESTAMP WITH TIMEZONEを使用する必要があります。

対象となるXMLデータ型とSQLデータ型に1対1の組込みの対応関係がない場合は、問合せに対して索引が取得されるように、(表6-5に従って)両者を対応させる必要があります。これには、次の2つの方法があります。

- 索引を問合せに対応させる: 構造化索引コンポーネント内の列を、XMLデータ型と対応するように定義(または再定義)します。たとえば、索引付けの対象となる問合せにXMLデータ型xs:doubleを使用するには、対応するSQLデータ型BINARY_DOUBLEを使用するように索引を定義します。

- 問合せを索引に対応させる: 問合せ内で、XQuery式の関連部分を、索引コンテンツ表に使用するSQLデータ型と対応するデータ型に明示的にキャストします。

例6-3および例6-4に、問合せ内でXQuery式をキャストして、索引コンテンツ表に使用するSQLデータ型に一致させる方法を示します。

例6-3 問合せデータと索引データを対応させる: SQLのキャスト

SELECT count(*) FROM purchaseorder
WHERE XMLCast(XMLQuery('$p/PurchaseOrder/LineItem/@ItemNumber'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
AS INTEGER)
= 25;

例6-4 問合せデータと索引データを対応させる: XQueryのキャスト

SELECT count(*) FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder/LineItem[xs:decimal(@ItemNumber) = 25]'
PASSING OBJECT_VALUE AS "p");

この2つの例では、数字25はどちらも受注品目番号ですが、それぞれ異なる役割を果しています。例6-3では25はデータ型INTEGERのSQL数値であり、例6-4では25はデータ型xs:decimalのXQuery数値です。

例6-3では、XMLQueryの結果がSQLのINTEGER型にキャストされ、SQLの値25と比較されます。例6-4では、属性ItemNumberの値がXMLデータ型xs:decimalに(XQuery内で)キャストされます。これはXQueryの値25と比較され、索引に使用されるSQLデータ型(INTEGER)に対応します。このように、この例では2つの異なる種類のデータ型の変換が行われますが、どちらも型が索引コンテンツ表と一致するように問合せデータが変換されます。

関連項目:
XML Schemaデータ型とSQLデータ型の組込みの対応関係の詳細は、「XML Schemaデータ型のSQLデータ型へのマッピング」を参照してください。

XMLIndex非構造化コンポーネント

Bツリー索引は、個々のXML要素または属性を表す特定のデータベース列や、構造化ドキュメントの特定部分に適用されるXMLIndex構造化コンポーネントに対して定義します。これに対し、XMLIndex索引の非構造化コンポーネントは、デフォルトで非常に汎用性に富んでいます。索引付けに使用する特定のXPath式や使用しない特定のXPath式を限定することにより焦点を絞り込んだ場合を除き、非構造化XMLIndexコンポーネントはXMLデータのすべての使用可能なXPath式に適用されます。

XMLIndex索引の非構造化コンポーネントは、次の3つの論理部分で構成されます。

- パス索引: 文書のXMLタグを索引付けし、様々な文書のフラグメントを識別します。

- 順序索引: XML文書におけるノードの階層的な位置を索引付けします。親と子、祖先と子孫、および兄弟の関係を追跡します。

- 値索引: XML文書の値を索引付けします。値の等価性または値の範囲による参照が可能です。値索引は、問合せ述語(WHERE句)の値に使用されます。

XMLIndex索引の非構造化コンポーネントは、パス表と、そのパス表の一連の(ローカルの)2次索引を使用します。これらは前述の論理部分を実装します。2つの2次索引が自動的に作成されます。

- pikey索引: パスおよび順序の両方の論理索引を実装します。

- 値索引: 論理値の索引を実装します。

これらの2つの索引を変更したり、追加の2次索引を作成できます。パス表とその2次索引はすべて、XMLIndex索引が作成される実表の所有者によって所有されます。

pikey索引は、パスと順序の関係を処理し、ほとんどの場合で最適なパフォーマンスが得られます。値索引を取得すべきときに取り出されない場合は、パスおよび順序の関係で個別の索引をpikey索引のかわりに使用できます。このような(オプション)の索引は、それぞれパスID索引および順序キー索引と呼ばれます。特定の場合の要件でpikey索引が不十分の場合は、最適な結果を得るためにOracleサポートに問い合せてください。

パス表では、XML文書で索引付けされる1つのノードに対して1行が使用されます。索引付けされたノードごとに、パス表には次のものが格納されます。

- 文書を格納する表に対応するROWID。

- 対応する文書のフラグメントへの高速アクセスを提供するロケータ。XML Schemaに基づくデータのバイナリXML記憶域については、データ型情報も格納します。

- 文書におけるノードの階層的な位置を記録するための順序キー。これは、図書目録やインターネット・プロトコルSNMPで使用されるような、デューイ10進分類キーのようなものです。このようなシステムでは、3.21.5というキーは、文書のルート・ノードの3番目の子の21番目の子の5番目の子というノード位置を表します。

- ノードに対するXPathパスを表す識別子。

- ノードの有効なテキスト値。

表6-6に、パス表に含まれる主な情報脚注2を示します。

表6-6 XMLIndexのパス表

列

データ型

説明

PATHID

RAW(8)

ノードのXPathパスに対する一意の識別子です。

RID

ROWID

XMLデータを格納するために使用される表のROWIDです。

ORDER_KEY

RAW(1000)

ノードの階層的な位置を識別するための、10進数の順序キーです。(ドキュメントの順序は保持されます。)

LOCATOR

RAW(2000)

フラグメント位置情報です。フラグメント抽出に使用されます。XML Schemaに基づくデータのバイナリXML記憶域では、データ型情報もここに格納されます。

VALUE

VARCHAR2(4000)

ノードの有効テキスト値。

pikey索引では、パス表の列PATHID、RIDおよびORDER_KEYを使用して、パスと順序の索引を表します。オプションのパスID索引では、列PATHIDおよびRIDを使用して、パス索引を表します。値索引は、VALUE列に対する索引です。

例6-5では、2つの発注書のパス表の内容を見ていきます。

例6-5 2つの発注書のパス表の内容

<PurchaseOrder>
<Reference>SBELL-2002100912333601PDT</Reference>
<Actions>
<Action>
<User>SVOLLMAN</User>
</Action>
</Actions>
. . .
</PurchaseOrder>

<PurchaseOrder>
<Reference>ABEL-20021127121040897PST</Reference>
<Actions>
<Action>
<User>ZLOTKEY</User>
</Action>
<Action>
<User>KING</User>
</Action>
</Actions>
. . .
</PurchaseOrder>

これらの発注書を格納するXMLType表または列のXMLIndex索引には、XML文書で索引付けされたノードに対し、1行ずつ使用するパス表が含まれます。仮に、XPath式に従ってノードに索引付けする際、システムによって次のPATHIDが割り当てられるとします。

PATHID

索引付けされたXPath

1

/PurchaseOrder

2

/PurchaseOrder/Reference

3

/PurchaseOrder/Actions

4

/PurchaseOrder/Actions/Action

5

/PurchaseOrder/Actions/Action/User

結果として作成されるパス表は、次のようになります(LOCATOR列は示されません)。

PATHID

RID

ORDER_KEY

VALUE

1

R1

1

SBELL-2002100912333601PDTSVOLLMAN

2

R1

1.1

SBELL-2002100912333601PDT

3

R1

1.2

SVOLLMAN

4

R1

1.2.1

SVOLLMAN

5

R1

1.2.1.1

SVOLLMAN

1

R2

1

ABEL-20021127121040897PSTZLOTKEYKING

2

R2

1.1

ABEL-20021127121040897PST

3

R2

1.2

ZLOTKEYKING

4

R2

1.2.1

ZLOTKEY

5

R2

1.2.1.1

ZLOTKEY

4

R2

1.2.2

KING

5

R2

1.2.2.1

KING

表パスは透過的であり、無視

パス表の列に2次索引を作成した場合でも、パス表そのものは通常は無視できます。パス表には、それをDESCRIBEしたり、(2次)索引を作成したりする以外はアクセスできません。パス表に関する統計を明示的に収集する必要はありません。統計は、XMLIndex索引、またはXMLIndex索引が定義されている実表についてのみ収集する必要があります。統計は収集され、パス表と2次索引に透過的に保持されます。

関連項目:
「コストベース・オプティマイザに対するXMLIndexオブジェクトの統計の収集」

XMLIndexパス表のVALUE列

VALUE列の2次索引は、一致する文字列に関する述語を有するWHERE句のXPath式で使用されます。次に例を示します。

/PurchaseOrder[Reference/text() = "SBELL-2002100912333601PDT"]

列VALUEには、要素または属性ノードの有効テキスト値が格納されます。索引付けの際、コメントおよび処理命令は無視されます。

- 属性では、有効テキスト値は属性値です。

- 単純な要素(子のない要素)では、有効テキスト値は、要素のすべてのテキスト・ノードを連結したものになります。

- 複雑な要素(子のある要素)では、有効テキスト値は、(1)要素そのもののテキスト・ノードを連結したもの、(2)単純要素のすべての子孫の有効テキスト値になります。(これは再帰的定義です。)

ただし、有効テキスト値は4000バイト(単純な要素または属性の場合)および80バイト(複雑な要素の場合)に制限(切捨て)されます。

VALUE列のサイズは、VARCHAR2(4000)に固定されています。索引の作成または更新時における超過分(4000バイトを超える分)は切り捨てられますが、当該行のLOCATOR値はフラグ付けされるため、必要に応じて完全な値を実表から取得することは可能です。

VALUE列に対する4000バイトの上限に加え、当該列に対して作成される2次索引のキーのサイズにも制限があります。これは、Bツリー索引とファンクション索引にも該当します。XMLIndexの制限ではありません。索引キーのサイズの限界は、データベースのブロック・サイズの関数です。VALUEに対してどの程度の索引付けがなされるかは、この制限値によって決定します。

つまり、有効テキスト値の最初の4000バイトのみがVALUE列に格納され、VALUE列の最初のNバイトに対してのみ索引が作成されるということです。ここでNとは、索引キーのサイズの制限を表します(N < 4000)。索引キーのサイズの制限が課されることにより、VALUE列の索引は、有効テキスト値の事前フィルタとしてのみ機能します。

たとえば、データベースのブロック・サイズにより、VALUE列の索引を800バイト以内に抑え、有効テキスト値のうち最初の800バイト分のみを索引付けするとします。有効テキスト値の最初の800バイト分に対してXMLIndexを使用してテストを実行し、そのテキスト接頭辞が問合せ値に一致した場合のみ、残りの有効テキスト値がテストされます。

VALUE列の2次索引は、substr SQL関数(サブストリング等価性)です。この関数を使用して、テキスト接頭辞をテストするためです。このファンクション索引は、VALUE列に対するXMLIndexの実装の一環として自動的に作成されます。

たとえば、問合せのWHERE句のXPath式/PurchaseOrder[Reference/text() = :1]は、実質的に、次のようなテストにリライトされることがあります。

substr(VALUE, 1 800) = substr(:1, 1, 800) AND VALUE = :1;

この結合は2つの部分から構成され、左から右に向かって処理されます。1つ目のテストでは、substr関数の索引を事前フィルタとして使用し、冒頭800バイトがバインド変数:1の冒頭800バイトに一致しないテキストを削除します。

索引は、1つ目のテストでのみ使用されます。VALUE列の完全な値は索引付けされません。1つ目のテストで事前フィルタリングを実行した後、2つ目のテストで有効テキスト値全体をチェックします。つまり、VALUE列の完全な値と、:1の値の等価性を確認します。このチェックでは索引は使用されません。

テキストの冒頭800バイトのみが索引付けされる場合でも、問合せパフォーマンスでは、最大4000バイトをVALUE列に格納することが重要になります。これにより、CLOBインスタンスのXML文書内の深い部分からデータを抽出することなく、データに迅速かつ直接的にアクセスできるようになるからです。有効テキスト値が4000バイトを超える場合は、WHERE句結合の2つ目のテストにおいて、実表データにアクセスする必要があります。

VALUE列に対する4000バイト上限も、索引キーのサイズも、問合せ結果には何の影響も与えません。これらはパフォーマンスにのみ影響を与えます。

注意:
VALUEに対して作成されたOracle Text CONTEXT索引は、VALUE列が切り捨てられることがあるために、間違った結果を戻す可能性があります。

前述したように、XMLIndexはXML Schemaに基づくデータで使用できます。XML Schemaが特定の要素または属性に対してdefaultValue値を指定し、特定の文書が当該の要素または属性に対して値を指定しない場合、defaultValue値がVALUE列で使用されます。

VALUE列に対する2次索引

XMLIndex索引を作成する際、VALUE列に対して2次索引を指定しない場合でも、VALUE列に対してデフォルトの2次索引が作成されます。このデフォルト索引には、デフォルトのプロパティがあります。具体的には、これはtext(文字列値)データでのみ使用される索引です。

ただし、異なる種類のVALUE索引を作成できます。たとえば、数値の索引が問合せの大半に適している場合は、数値の索引を作成できます。VALUE列に対し、複数の2次索引を作成できます。特定の種類の索引は、それが適切な場合にのみ使用されます。たとえば、数値の索引は、VALUE列が数値である場合にのみ使用されます。その他の値の場合は無視されます。パス表の列の2次索引は、その他の2次索引と同様に扱われます。つまり、これらの索引は変更、削除、不使用としてマーキングするなどが可能です。

関連項目:

- VALUE列に2次索引を作成する例の詳細は、「非構造化コンポーネントを含むXMLIndexの使用」を参照してください。

- PARAMETERS句の構文は、「CREATE INDEXおよびALTER INDEXのPARAMETER句」を参照してください。

XMLIndex非構造化コンポーネントによって索引付けされないXPath式

次のタイプのXPath式は、XMLIndexにより索引付けされません。

- ora:contains以外のXPath関数の適用。特に、ユーザー定義のXPath関数は索引付けされません。

- child、descendant、およびattribute以外の軸(parent、ancestor、following-sibling、preceding-sibling、following、preceding、およびancestor-or-selfの各軸)。

- 共用体演算子|(垂直バー)を使用する式。

XMLIndex索引の作成、削除、変更、および検証

例6-6に示すように、索引タイプをXDB.XMLIndexと宣言して、XMLIndex索引を作成します。

例6-6 XMLType非構造化記憶域でのXMLIndex索引の作成

CREATE INDEX po_xmlindex_ix ON po_clob (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex;

これにより、XMLTypeのpo_clob表に、po_xmlindex_ixという名前のXMLIndex索引が作成されます。索引に含まれるのは非構造化コンポーネントのみで、構造化コンポーネントは含まれません。

XMLIndex索引に構造化コンポーネントを含めるように指定するには、PARAMETERS句にstructured_clauseを含めます。非構造化コンポーネントを含めるように指定するには、PARAMETERS句にpath_table_clauseを含めます。この操作は、XMLIndex索引を作成または変更する場合に可能です。例6-6に示すように、structured_clauseとpath_table_clauseのいずれも指定しない場合は、非構造化コンポーネントのみが含まれます。

XMLIndex索引に非構造化コンポーネントと構造化コンポーネントの両方が含まれる場合は、ALTER INDEXを使用していずれかのコンポーネントを削除できます。

関連項目:

- 「CREATE INDEXおよびALTER INDEXのPARAMETERS句」

- 「structured_clause ::=」

- 「path_table_clause ::=」

- 「drop_path_table_clause ::=」

- 「alter_index_group_clause ::=」

例6-7に示すように、特定のXMLType表(または列)のXMLIndex索引の名前を取得できます。また、適宜DBA_INDEXESまたはALL_INDEXESからINDEX_NAMEを選択することも可能です。

例6-7 特定の表にあるXMLIndex索引の名前の取得

SELECT INDEX_NAME FROM USER_INDEXES
WHERE TABLE_NAME = 'PO_CLOB' AND ITYP_NAME = 'XMLINDEX';

INDEX_NAME
---------------
PO_XMLINDEX_IX

1 row selected.

例6-8に示すように、XMLIndex索引は、他の索引と同様に名前変更または削除できます。この名前変更では、XMLIndex索引の名前のみが変更されます。この処理ではパス表の名前は変更されません。パス表は、個別に名前を変更できます。

例6-8 XMLIndex索引の名前変更と削除

ALTER INDEX po_xmlindex_ix RENAME TO new_name_ix;

DROP INDEX new_name_ix;

同様に、REBUILDなどのALTER INDEXオプションを使用し、他の索引プロパティも変更できます。この点においては、XMLIndexも他の索引タイプと同じです。

XMLIndexのALTER INDEX文のRENAME句は、XMLIndexそのものに対してのみ適用されます。パス表および2次索引の名前を変更するには、これらのオブジェクトの名前を決定し、適切なALTER TABLE文またはALTER INDEX文を直接使用する必要があります。同様に、2次索引の物理プロパティを取得したり、他のなんらかの方法で変更を加えたりする場合は、例6-13の方法に従って2次索引の名前を取得する必要があります。

例6-6に、非構造化記憶域にXMLIndex索引を作成する方法を示します。

関連項目:
PARAMETERS句の構文は、「CREATE INDEXおよびALTER INDEXのPARAMETER句」を参照してください。

非構造化コンポーネントを含むXMLIndexの使用

この項では、(構造化コンポーネントも含まれるかどうかに関係なく)非構造化コンポーネントが含まれるXMLIndex索引で実行可能な操作について説明します。詳細は、「XMLIndex非構造化コンポーネント」を参照してください。

XMLIndex索引に非構造化コンポーネントを含めるには、XMLIndex索引の作成または変更時に、PARAMETERS句でpath_table_clauseを使用します。詳細は「path_table_clause ::=」を参照してください。

構造化コンポーネントを指定しない場合、パス表を指定しなくても、索引に非構造化コンポーネントが含まれます。ただし、一般的にはパス表を指定することをお薦めします。これにより他のXMLIndex操作で参照できる、ユーザー指向の認識可能な名前が含まれるようになります。

例6-9に、非構造化コンポーネントを含むXMLIndex索引の作成時に、パス表(my_path_table)の名前を付ける方法を示します。

例6-9 XMLIndex索引のパス表への名前付け

CREATE INDEX po_xmlindex_ix ON po_clob (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
PARAMETERS ('PATH TABLE my_path_table');

パス表に名前を付けなかった場合、名前はCREATE INDEXに与えた索引名に基づき、システムによって自動的に生成されます。例6-10に、例6-6で作成したXMLIndex索引を使用した例を示します。

例6-10 XMLIndexパス表のシステム生成名の決定

SELECT PATH_TABLE_NAME FROM USER_XML_INDEXES
WHERE TABLE_NAME = 'PO_CLOB' AND INDEX_NAME = 'PO_XMLINDEX_IX';

PATH_TABLE_NAME
------------------------------
SYS67567_PO_XMLINDE_PATH_TABLE

1 row selected.

デフォルトでは、パス表と2次索引の記憶域オプションは、XMLIndex索引が作成された実表の記憶域プロパティから生成されます。例6-11で示すように、索引の作成時にPARAMETERS句を使用すると、異なる記憶域オプションを指定できます。CREATE INDEX(およびALTER INDEX)のPARAMETERS句は、一重引用符(')で囲む必要があります。

関連項目:
PARAMETERS句の構文は、「CREATE INDEXおよびALTER INDEXのPARAMETER句」を参照してください。

例6-11 XMLIndex索引の作成時における記憶域オプションの指定

CREATE INDEX po_xmlindex_ix ON po_clob (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
PARAMETERS
('PATH TABLE po_path_table
(PCTFREE 5 PCTUSED 90 INITRANS 5
STORAGE (INITIAL 1k NEXT 2k MINEXTENTS 3 BUFFER_POOL KEEP)
NOLOGGING ENABLE ROW MOVEMENT PARALLEL 3)
PIKEY INDEX po_pikey_ix (LOGGING PCTFREE 1 INITRANS 3)
VALUE INDEX po_value_ix (LOGGING PCTFREE 1 INITRANS 3)');

XMLIndexは論理的なドメイン索引であり、物理索引ではないため、すべての物理属性はゼロ(0)またはNULLになります。

XMLIndex索引に非構造化コンポーネントと構造化コンポーネントの両方が含まれる場合は、ALTER INDEXを使用して非構造化コンポーネントを削除できます。これを実行するには、パス表を削除します。例6-12に、これを示します。(この場合は、構造化コンポーネントも含むことを前提とします。例6-20では、索引に構造化コンポーネントと非構造化コンポーネントの両方が含まれるようになります。)

例6-12 XMLIndex非構造化コンポーネントの削除

ALTER INDEX po_xmlindex_ix PARAMETERS('DROP PATH TABLE');

例6-11では、パス表に対する記憶域オプションの指定に加え、パス表に対する2次索引にも名前を付けています。

パス表の名前と同様、パス表の列の2次索引の名前は、PARAMETERS句で指定しないかぎり、索引名をベースとして使用して自動的に生成されます。例6-13にこれを示します。これらの名前をパブリック・ビューUSER_IND_COLUMNSで決定する方法も示します。また、pikey索引で3つの列を使用することも示します。

例6-13 XMLIndex索引の2次索引の名前付け

SELECT INDEX_NAME, COLUMN_NAME, COLUMN_POSITION FROM USER_IND_COLUMNS
WHERE TABLE_NAME IN (SELECT PATH_TABLE_NAME FROM USER_XML_INDEXES
WHERE INDEX_NAME = 'PO_XMLINDEX_IX')
ORDER BY INDEX_NAME, COLUMN_NAME;

INDEX_NAME                     COLUMN_NAME  COLUMN_POSITION
------------------------------ ------------ ---------------
SYS67563_PO_XMLINDE_PIKEY_IX   ORDER_KEY                  3
SYS67563_PO_XMLINDE_PIKEY_IX   PATHID                     2
SYS67563_PO_XMLINDE_PIKEY_IX   RID                        1
SYS67563_PO_XMLINDE_VALUE_IX   SYS_NC00006$               1

4 rows selected.

関連項目:
例6-19に、類似するが、さらに複雑なケースを示します。

XMLIndexパス表に対する追加の2次索引の作成

この項では、例6-11で作成したXMLIndexに対し、2次索引を追加で作成します。

XMLIndex索引のパス表のVALUE列に対し、2次索引をいくつでも追加で作成できます。ファンクション索引やOracle Text索引など、様々な種類が可能です。

問合せの処理時に、指定の索引が指定の要素に対して使用されるかどうかは、その索引が当該値に対して適切であるかどうかや、その索引の使用が費用効率に優れているかどうかによって決まります。

例6-14では、SQL関数substrを使用して、パス表のVALUE列にファンクション索引を作成します。問合せにおいて、XML要素のテキスト・ノードに対してsubstrがよく使用される場合は便利な方法です。

例6-14 パス表のVALUE列に対するファンクション索引の作成

CREATE INDEX fn_based_ix ON po_path_table (substr(VALUE, 1, 100));

テキスト・ノードが数値を表す要素が多数ある場合、VALUE列に対して数値索引を作成すると有効です。ただし、例6-14と同じような方法で数値索引を直接作成すると、要素値のいずれかが数値ではない場合にORA-01722エラー(無効な数値)が発生します。これを例6-15に示します。

例6-15 パス表のVALUE列に対する、数値索引の直接作成

CREATE INDEX direct_num_ix ON po_path_table (to_binary_double(VALUE));
CREATE INDEX direct_num_ix ON po_path_table (to_binary_double(VALUE))
*
ERROR at line 1:
ORA-01722: invalid number

ここで必要となるのは、数値の要素に対して使用されるが、数値を持たない要素に対しては無視される索引です。特に、DBMS_XMLINDEXパッケージのcreateNumberIndexプロシージャは、この目的でのみ存在するものです。このプロシージャに、データベース・スキーマの名前、XMLIndex索引、および作成される数値索引を渡します。数値索引の作成は、例6-16に示します。

例6-16 createNumberIndexプロシージャによる、VALUE列に対する数値索引の作成

CALL DBMS_XMLINDEX.createNumberIndex('OE', 'PO_XMLINDEX_IX', 'API_NUM_IX');

このような索引は数値を持たない要素を無視するよう設計されているため、この索引が数値を持たない要素を検出することはありません。非数値要素がある場合に、なんらかの理由によりXMLIndex索引が問合せで使用されなければ、ORA-01722エラーが発生します。ただし、索引が使用されると非数値データは無視されるため、エラーは発生しません。ここでも、索引の使用により結果セットが変わることはありません。結果はまったく同じですが、索引を使用すると、誤ったデータの検出を防ぐことはできます。

日付値の索引の作成は、数値索引の作成と似ています。この場合は、DBMS_XMLINDEX.createDateIndexプロシージャを使用します。例6-17に、これを示します。

例6-17 createDateIndexプロシージャによる、VALUE列に対する日付索引の作成

CALL DBMS_XMLINDEX.createDateIndex('OE', 'PO_XMLINDEX_IX', 'API_DATE_IX',
'dateTime');

例6-18では、Oracle TextのCONTEXT索引をVALUE列に作成します。これは、XML要素のテキスト値に対する全文問合せにおいて便利です。XPath関数ora:containsを使用するXPath述語は、VALUE列のcontains Oracle SQL関数の使用にあわせてリライトされます。CONTEXT索引がVALUE列に対して定義されている場合、述語の評価時に使用されます。Oracle Text索引は、他のすべてのVALUE列の索引に依存しません。

例6-18 パス表のVALUE列に対するOracle Text CONTEXT索引の作成

CREATE INDEX po_otext_ix ON po_path_table (VALUE)
INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS('TRANSACTIONAL');

関連項目:

- VALUE列に対して作成されたOracle Text CONTEXT索引が間違った結果を戻すことがあります。この詳細は、「XMLIndexパス表のVALUE列」を参照してください。

- 「XMLデータに対するOracle Text索引」

例6-19の問合せは、XMLIndex索引のパス表に対して作成されたすべての2次索引を示します。作成された索引は、明確に太字で示されます。特に注意する必要があるのは、VALUE列に作成されたファンクション索引などは、この例のように表示されない点です。これらの索引の列名は、SYS_NC00007$などのシステム生成名になります。そのため、WHERE句でCOLUMN_NAME = 'VALUE'を使用して問合せを実行しても、これらの列を見ることはできません。

例6-19 XMLIndexのパス表上にある、すべての2次索引の表

SELECT c.INDEX_NAME, c.COLUMN_NAME, c.COLUMN_POSITION, e.COLUMN_EXPRESSION
FROM USER_IND_COLUMNS c LEFT OUTER JOIN USER_IND_EXPRESSIONS e
ON (c.INDEX_NAME = e.INDEX_NAME)
WHERE c.TABLE_NAME IN (SELECT PATH_TABLE_NAME FROM USER_XML_INDEXES
WHERE INDEX_NAME = 'PO_XMLINDEX_IX')
ORDER BY c.INDEX_NAME, c.COLUMN_NAME;

INDEX_NAME           COLUMN_NAME  COLUMN_POSITION COLUMN_EXPRESSION
-------------------- ------------ --------------- ----------------------
API_DATE_IX          SYS_NC00009$               1 SYS_EXTRACT_UTC(SYS_XMLCONV("V
ALUE",3,8,0,0,181))
API_NUM_IX           SYS_NC00008$               1 TO_BINARY_DOUBLE("VALUE")
FN_BASED_IX          SYS_NC00007$               1 SUBSTR("VALUE",1,100)
PO_OTEXT_IX          VALUE                      1
PO_PIKEY_IX          ORDER_KEY                  3
PO_PIKEY_IX          PATHID                     2
PO_PIKEY_IX          RID                        1
PO_VALUE_IX          SYS_NC00006$               1 SUBSTRB("VALUE",1,1599)

8 rows selected.

関連項目:

- DBMS_XMLINDEXパッケージのPL/SQLプロシージャcreateNumberIndexおよびcreateDateIndexの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- Oracle Text索引の使用の詳細は、「他の索引に依存しないOracle Text索引」を参照してください。

構造化コンポーネントを含むXMLIndexの使用

XMLIndex索引に構造化コンポーネントを含めるには、XMLIndex索引の作成または変更時に、PARAMETERS句でstructured_clauseを使用します(「structured_clause ::=」を参照)。

structured_clauseでは、索引付けの対象となる構造化アイランドを指定します。キーワードGROUPを使用して、各構造化アイランドを指定します。このためアイランドの構文は構造グループに一致します。明示的にグループを指定しない場合、事前定義済グループDEFAULT_GROUPが使用されます。ALTER INDEXの場合、GROUPキーワードの前に変更操作キーワードを指定します。新しいグループ(アイランド)を作成する場合はADD_GROUPを、グループを削除する場合はDROP_GROUPを指定します。

単に複数のXMLIndex索引を使用するのではなく、1つの索引内で複数のグループを使用する理由を考えてみます。その理由は、XMLIndexがドメイン索引であること、そして特定のデータベース列に対しては特定タイプのドメイン索引を1つしか作成できないことです。

構造グループを定義する(つまり、構造化アイランドに索引を作成する)ための構文は、SQL/XML関数XMLTableを起動するための構文と似ています。リレーショナル列を定義するにはキーワードXMLTableおよびCOLUMNSを使用し、コレクションを処理するにはXMLTableのマルチレベル連鎖を使用します。

例6-20に、非構造化コンポーネントのみを含むXMLIndex索引を作成する方法を示します。PARAMETERS句でパス・ノードに明示的に名前付けしているため、非構造化コンポーネントが作成されます。

例6-20では、ALTER INDEXを使用して、po_itemという名前の構造化コンポーネント(グループ)を追加します。この構造グループには、キーワードXMLTableで指定された2つのリレーショナル表が含まれます。

例6-20 XMLIndex索引: 構造化コンポーネントの追加

CREATE INDEX po_xmlindex_ix ON po_clob (OBJECT_VALUE)
INDEXTYPE IS XDB.XMLIndex PARAMETERS ('PATH TABLE path_tab');

BEGIN
DBMS_XMLINDEX.registerParameter(
'myparam',
'ADD_GROUP GROUP po_item
XMLTable po_idx_tab ''/PurchaseOrder''
COLUMNS reference   VARCHAR2(30)  PATH ''Reference'',
requestor   VARCHAR2(30)  PATH ''Requestor'',
username    VARCHAR2(30)  PATH ''User'',
lineitem    XMLType       PATH ''LineItems/LineItem'' VIRTUAL
XMLTable po_index_lineitem ''/LineItem'' PASSING lineitem
COLUMNS itemno      BINARY_DOUBLE PATH ''@ItemNumber'',
description VARCHAR2(256) PATH ''Description'',
partno      VARCHAR2(14)  PATH ''Part/@Id'',
quantity    BINARY_DOUBLE PATH ''Part/@Quantity'',
unitprice   BINARY_DOUBLE PATH ''Part/@UnitPrice''');
END;
/

ALTER INDEX po_xmlindex_ix PARAMETERS('PARAM myparam');

最上位の表po_idx_tabには、reference、requestor、usernameおよびlineitemの列があります。lineitem列の型はXMLTypeです。この列はコレクションを表しているため、2番目のXMLTable構造体に渡されて、2番目のレベルのリレーショナル表po_index_lineitemを構成します。この表には、列itemno、description、partno、quantityおよびunitpriceが含まれます。

XMLType列にはキーワードVIRTUALが必要です。このキーワードは、XMLType列自体が生成されないことを指定します。つまり、そのデータは、対応するXMLTable表により指定されたリレーショナル列の形式でのみ、XMLIndex索引に格納されます。

1つのXMLTable内に複数のXMLType列を作成することはできません。1つのXMLTable内に複数のXMLType列を入れる場合は、追加のグループを定義する必要があります。

例6-20にも、PARAMETERS句での登録済パラメータ文字列の使用を示します。これはPL/SQLのプロシージャDBMS_XMLINDEX.registerParameterを使用して、myparamという名前のパラメータ文字列を登録します。次にALTER INDEXを使用して、文字列myparamに含まれるように索引パラメータを更新します。

XMLIndex索引に非構造化コンポーネントと構造化コンポーネントの両方が含まれる場合は、ALTER INDEXを使用して構造化コンポーネントを削除できます。これを行うには、構造化コンポーネントを構成するすべての構造グループを削除します。例6-21に、例6-20で追加された構造化コンポーネントを削除する方法を示します。この場合は、その構造グループpo_itemのみを削除します。

例6-21 XMLIndex構造化コンポーネントの削除

ALTER INDEX po_xmlindex_ix PARAMETERS('DROP_GROUP GROUP po_item');

「XMLIndex構造化コンポーネント」の項で説明したように、XMLIndex索引の構造化コンポーネントに使用する表は通常のリレーショナル表なので、標準的なリレーショナル索引を使用すれば、これらの表にも索引を作成できます。

例6-22および例6-23にこれを示します。例6-22では、例6-20のXMLIndex索引に対し、索引コンテンツ表(構造化フラグメント)のreference列にBツリー索引を作成します。例6-23では、description列に対してOracle TextのCONTEXT索引を作成し、そのコンテンツに対して全文問合せを使用します。

例6-22 XMLIndex索引コンテンツ表に対するBツリー索引の作成

CREATE INDEX idx_tab_ref_ix ON po_idx_tab (reference);

例6-23 XMLIndex索引コンテンツ表に対するOracle Text CONTEXT索引

CREATE INDEX idx_tab_desc_ix ON po_index_lineitem (description)
INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS ('transactional');

SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem'
PASSING OBJECT_VALUE RETURNING CONTENT)
FROM po_clob
WHERE XMLExists('/PurchaseOrder/LineItems/LineItem
[ora:contains(Description, "Picnic") > 0]'
PASSING OBJECT_VALUE)
AND XMLExists('/PurchaseOrder[User="SBELL"]' PASSING OBJECT_VALUE);

例6-24に、XMLIndex索引の作成を示します。この索引には、構造化コンポーネントのみが含まれ(パス表句は含まれない)、XMLNAMESPACES句を使用して名前空間を指定します。索引データを圧縮し、表領域SYSAUXを使用することを指定します。この例では、XML Schemaに基づかないデータを含むバイナリXML表po_binxmlを想定しています。

例6-24 構造化コンポーネントのみを含むXMLIndexおよび名前空間の使用

CREATE INDEX po_struct ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
PARAMETERS ('XMLTable po_ptab
(TABLESPACE "SYSAUX" COMPRESS FOR OLTP)
XMLNAMESPACES (DEFAULT ''http://www.example.com/po''),
''/purchaseOrder''
COLUMNS orderdate   DATE          PATH ''@orderDate'',
id          BINARY_DOUBLE PATH ''@id'',
items       XMLType       PATH ''items/item'' VIRTUAL
XMLTable li_tab
(TABLESPACE "SYSAUX" COMPRESS FOR OLTP)
XMLNAMESPACES (DEFAULT ''http://www.example.com/po''),
''/item'' PASSING items
COLUMNS partnum     VARCHAR2(15)  PATH ''@partNum'',
description CLOB          PATH ''productName'',
usprice     BINARY_DOUBLE PATH ''USPrice'',
shipdat     DATE          PATH ''shipDate''');

関連項目:

- 例6-28「2つの述語を使用する問合せに対する構造化XMLIndexコンポーネントの使用」

- 「XMLデータに対するOracle Text索引」

- 「XMLIndexの登録済パラメータ句の使用」

- 「structured_clause ::=」

- XMLTable句のXMLType列の詳細は、「XMLIndex_xmltable_clauseの使用」を参照してください。

- キーワードCOLUMNSおよびVIRTUALの詳細は、「column_clauseの使用」を参照してください。

- 「XMLIndex構造化コンポーネントのデータ型に関する考慮事項」

XMLIndexが使用されるかどうかを判別する方法

特定のXMLIndex索引を使用できるかどうかは、問合せのコンパイル時にOracle Databaseにより決定されます。つまり、索引に対する問合せにその問合せをリライトできるかどうかによって決まります。

非構造化XMLIndexコンポーネントの場合、問合せ内のXPath式が、XMLIndex索引付けに使用するよう指定したパスのサブセットであることをコンパイル時に断定できない場合、索引の非構造化コンポーネントは使用されません。

たとえば、索引付けの際にパス/PurchaseOrder/LineItems//*が含まれる場合、/PurchaseOrder/LineItems/LineItem/Descriptionを含む問合せでは索引を使用できますが、//Descriptionを含む問合せは索引を使用できません。後者は、/PurchaseOrder/LineItemsの子ではない潜在的なDescription要素と一致し、そのDescription要素がデータに出現するかどうかはコンパイル時に判断できません。

特定のXMLIndex索引が問合せの解決に使用されたかどうかを把握するには、問合せの実行計画を検証します。

- 索引の非構造化コンポーネントが使用される場合、そのパス表、順序キー、またはパスIDが実行計画において参照されます。実行計画は、ドメイン索引が使用されていることを直接的に示すことはありません。XMLIndex索引を名前で参照することもありません。例6-25および例6-27を参照してください。

- 索引の構造化コンポーネントが使用される場合、その索引コンテンツ表の1つ以上が実行計画において呼び出されます。例6-28および例6-29を参照してください。

関連項目:

- 『Oracle Database SQL言語リファレンス』

- 『Oracle Databaseパフォーマンス・チューニング・ガイド』

例6-25に、例6-9で作成したXMLIndex索引が特定の問合せで使用される様子を示します。ここで示す実行計画のMY_PATH_TABLEへの参照は、XMLIndex索引(例6-9で作成)が問合せで使用されることを示します。同様に、LOCATOR、ORDER_KEY、およびPATHIDの各列への参照も、同じことを示します。

例6-25 XMLIndex非構造化コンポーネントが使用されるかどうかの確認

SET AUTOTRACE ON EXPLAIN

SELECT XMLQuery('/PurchaseOrder/Requestor' PASSING OBJECT_VALUE RETURNING CONTENT) FROM po_clob
WHERE XMLExists('/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]' PASSING OBJECT_VALUE);

XMLQUERY('/PURCHASEORDER/REQUESTOR'PASSINGOBJECT_VALUERETURNINGCONTENT)
-----------------------------------------------------------------------
<Requestor>Sarah J. Bell</Requestor>

1 row selected.

Execution Plan
. . .
----------------------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name                         | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |                              |     1 |    24 |    28   (4)| 00:00:01 |
|   1 |  SORT GROUP BY                  |                              |     1 |  3524 |            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID   | MY_PATH_TABLE                |     2 |  7048 |     3   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN             | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |     2   (0)| 00:00:01 |
|   4 |  NESTED LOOPS                   |                              |     1 |    24 |    28   (4)| 00:00:01 |
|   5 |   VIEW                          | VW_SQ_1                      |     1 |    12 |    26   (0)| 00:00:01 |
|   6 |    HASH UNIQUE                  |                              |     1 |  5046 |            |          |
|   7 |     NESTED LOOPS                |                              |     1 |  5046 |    26   (0)| 00:00:01 |
|*  8 |      TABLE ACCESS BY INDEX ROWID| MY_PATH_TABLE                |     1 |  3524 |    24   (0)| 00:00:01 |
|*  9 |       INDEX RANGE SCAN          | SYS67616_PO_XMLINDE_VALUE_IX |    73 |       |     1   (0)| 00:00:01 |
|* 10 |      TABLE ACCESS BY INDEX ROWID| MY_PATH_TABLE                |     1 |  1522 |     2   (0)| 00:00:01 |
|* 11 |       INDEX RANGE SCAN          | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |     1   (0)| 00:00:01 |
|  12 |   TABLE ACCESS BY USER ROWID    | PO_CLOB                      |     1 |    12 |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - filter(SYS_XMLI_LOC_ISNODE("SYS_P0"."LOCATOR")=1)
3 - access("SYS_P0"."RID"=:B1 AND "SYS_P0"."PATHID"=HEXTORAW('76E2') )
8 - filter("SYS_P4"."VALUE"='SBELL-2002100912333601PDT' AND "SYS_P4"."PATHID"=HEXTORAW('4F8C')  AND
SYS_XMLI_LOC_ISNODE("SYS_P4"."LOCATOR")=1)
9 - access(SUBSTRB("VALUE",1,1599)='SBELL-2002100912333601PDT')
10 - filter(SYS_XMLI_LOC_ISNODE("SYS_P2"."LOCATOR")=1)
11 - access("SYS_P4"."RID"="SYS_P2"."RID" AND "SYS_P2"."PATHID"=HEXTORAW('4E36')  AND
"SYS_P2"."ORDER_KEY"<"SYS_P4"."ORDER_KEY")
filter("SYS_P4"."ORDER_KEY"<SYS_ORDERKEY_MAXCHILD("SYS_P2"."ORDER_KEY") AND
SYS_ORDERKEY_DEPTH("SYS_P2"."ORDER_KEY")+1=SYS_ORDERKEY_DEPTH("SYS_P4"."ORDER_KEY"))
. . .

例6-26に示すように、このような実行計画からパス表の名前から、XMLIndex索引の名前を取得できます。(これは例6-10の問合せとほぼ反対のケースです。)

例6-26 パス表名からのXMLIndex索引名の取得

SELECT INDEX_NAME FROM USER_XML_INDEXES WHERE PATH_TABLE_NAME = 'MY_PATH_TABLE';

INDEX_NAME
------------------------------
PO_XMLINDEX_IX

1 row selected.

XMLIndexは、SELECTリスト、FROMリスト、および問合せのWHERE句のXPath式で使用でき、SQL/XML関数XMLQuery、XMLTable、XMLExistsおよびXMLCastにおいて有用です。ファンクション索引(および非推奨になったCTXXPath索引)とは異なり、XMLIndex索引は、文書内のXMLフラグメントからデータを抽出する際に使用できます。

例6-27に、これを示します。

例6-27 XMLIndexを使用したXMLフラグメントからのデータ抽出

SET AUTOTRACE ON EXPLAIN

SELECT li.description, li.itemno
FROM po_clob, XMLTable('/PurchaseOrder/LineItems/LineItem'
PASSING OBJECT_VALUE
COLUMNS "DESCRIPTION" VARCHAR(40) PATH 'Description',
"ITEMNO"      INTEGER     PATH '@ItemNumber') li
WHERE XMLExists('/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
PASSING OBJECT_VALUE);

DESCRIPTION                                  ITEMNO
---------------------------------------- ----------
A Night to Remember                               1
The Unbearable Lightness Of Being                 2
Sisters                                           3

3 rows selected.

Execution Plan

----------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name                         | Rows  | Bytes |Cost (%CPU)| Time    |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                              |     1 |  1546 |   30   (4)|00:00:01 |
|*  1 |  FILTER                           |                              |       |       |           |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID     | MY_PATH_TABLE                |     1 |  3524 |    3   (0)|00:00:01 |
|*  3 |    INDEX RANGE SCAN               | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |    2   (0)|00:00:01 |
|*  4 |  FILTER                           |                              |       |       |           |         |
|*  5 |   TABLE ACCESS BY INDEX ROWID     | MY_PATH_TABLE                |     1 |  3524 |    3   (0)|00:00:01 |
|*  6 |    INDEX RANGE SCAN               | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |    2   (0)|00:00:01 |
|   7 |  NESTED LOOPS                     |                              |       |       |           |         |
|   8 |   NESTED LOOPS                    |                              |     1 |  1546 |   30   (4)|00:00:01 |
|   9 |    NESTED LOOPS                   |                              |     1 |    24 |   28   (4)|00:00:01 |
|  10 |     VIEW                          | VW_SQ_1                      |     1 |    12 |   26   (0)|00:00:01 |
|  11 |      HASH UNIQUE                  |                              |     1 |  5046 |           |         |
|  12 |       NESTED LOOPS                |                              |     1 |  5046 |   26   (0)|00:00:01 |
|* 13 |        TABLE ACCESS BY INDEX ROWID| MY_PATH_TABLE                |     1 |  3524 |   24   (0)|00:00:01 |
|* 14 |         INDEX RANGE SCAN          | SYS67616_PO_XMLINDE_VALUE_IX |    73 |       |    1   (0)|00:00:01 |
|* 15 |        TABLE ACCESS BY INDEX ROWID| MY_PATH_TABLE                |     1 |  1522 |    2   (0)|00:00:01 |
|* 16 |         INDEX RANGE SCAN          | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |    1   (0)|00:00:01 |
|  17 |     TABLE ACCESS BY USER ROWID    | PO_CLOB                      |     1 |    12 |    1   (0)|00:00:01 |
|* 18 |    INDEX RANGE SCAN               | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |    1   (0)|00:00:01 |
|* 19 |   TABLE ACCESS BY INDEX ROWID     | MY_PATH_TABLE                |     1 |  1522 |    2   (0)|00:00:01 |
----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(:B1<SYS_ORDERKEY_MAXCHILD(:B2))
2 - filter(SYS_XMLI_LOC_ISNODE("SYS_P2"."LOCATOR")=1)
3 - access("SYS_P2"."RID"=:B1 AND "SYS_P2"."PATHID"=HEXTORAW('28EC')  AND "SYS_P2"."ORDER_KEY">:B2 AND
"SYS_P2"."ORDER_KEY"<SYS_ORDERKEY_MAXCHILD(:B3))
filter(SYS_ORDERKEY_DEPTH("SYS_P2"."ORDER_KEY")=SYS_ORDERKEY_DEPTH(:B1)+1)
4 - filter(:B1<SYS_ORDERKEY_MAXCHILD(:B2))
5 - filter(SYS_XMLI_LOC_ISNODE("SYS_P5"."LOCATOR")=1)
6 - access("SYS_P5"."RID"=:B1 AND "SYS_P5"."PATHID"=HEXTORAW('60E0')  AND "SYS_P5"."ORDER_KEY">:B2 AND
"SYS_P5"."ORDER_KEY"<SYS_ORDERKEY_MAXCHILD(:B3))
filter(SYS_ORDERKEY_DEPTH("SYS_P5"."ORDER_KEY")=SYS_ORDERKEY_DEPTH(:B1)+1)
13 - filter("SYS_P10"."VALUE"='SBELL-2002100912333601PDT' AND "SYS_P10"."PATHID"=HEXTORAW('4F8C')  AND
SYS_XMLI_LOC_ISNODE("SYS_P10"."LOCATOR")=1)
14 - access(SUBSTRB("VALUE",1,1599)='SBELL-2002100912333601PDT')
15 - filter(SYS_XMLI_LOC_ISNODE("SYS_P8"."LOCATOR")=1)
16 - access("SYS_P10"."RID"="SYS_P8"."RID" AND "SYS_P8"."PATHID"=HEXTORAW('4E36')  AND
"SYS_P8"."ORDER_KEY"<"SYS_P10"."ORDER_KEY")
filter("SYS_P10"."ORDER_KEY"<SYS_ORDERKEY_MAXCHILD("SYS_P8"."ORDER_KEY") AND
SYS_ORDERKEY_DEPTH("SYS_P8"."ORDER_KEY")+1=SYS_ORDERKEY_DEPTH("SYS_P10"."ORDER_KEY"))
18 - access("PO_CLOB".ROWID="SYS_ALIAS_4"."RID" AND "SYS_ALIAS_4"."PATHID"=HEXTORAW('3748') )
19 - filter(SYS_XMLI_LOC_ISNODE("SYS_ALIAS_4"."LOCATOR")=1)

Note
-----
- dynamic sampling used for this statement (level=2)

例6-27の問合せの実行計画は、パス表を参照することにより、XMLIndexが使用されることを示します。Oracle内部SQL関数sys_orderkey_depthが使用されることも示します。「非構造化コンポーネントを含むXMLIndexを使用するためのガイドライン」を参照してください。

例6-28に、例6-20で作成したXMLIndex索引が2つのWHERE句述語を使用する問合せに対して選択されることを示す実行計画を示します。非構造化XMLIndexコンポーネントのみが含まれる場合、WHERE内に2つの異なるパスがあるため、この問合せに対してパス表の自己結合が行われます。

例6-28 2つの述語を使用する問合せに対する構造化XMLIndexコンポーネントの使用

EXPLAIN PLAN FOR
SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem' PASSING OBJECT_VALUE RETURNING CONTENT)
FROM po_clob
WHERE XMLExists('/PurchaseOrder/LineItems/LineItem
[ora:contains(Description, "Picnic") > 0]' PASSING OBJECT_VALUE)
AND XMLEXists('/PurchaseOrder[User="SBELL"]' PASSING OBJECT_VALUE);

-------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                         | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                              |     1 |   189 |    22  (14)| 00:00:01 |
|   1 |  SORT GROUP BY               |                              |     1 |  3524 |            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID| PATH_TAB                     |     2 |  7048 |     3   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | SYS67840_PO_XMLINDE_PIKEY_IX |     1 |       |     2   (0)| 00:00:01 |
|*  4 |  HASH JOIN SEMI              |                              |     1 |   189 |    22  (14)| 00:00:01 |
|   5 |   NESTED LOOPS               |                              |    13 |   637 |     4  (25)| 00:00:01 |
|   6 |    SORT UNIQUE               |                              |    13 |   351 |     3   (0)| 00:00:01 |
|*  7 |     TABLE ACCESS FULL        | PO_IDX_TAB                   |    13 |   351 |     3   (0)| 00:00:01 |
|*  8 |    INDEX UNIQUE SCAN         | SYS_C006004                  |     1 |    22 |     0   (0)| 00:00:01 |
|*  9 |   TABLE ACCESS FULL          | PO_INDEX_LINEITEM            |    13 |  1820 |    17   (6)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - filter(SYS_XMLI_LOC_ISNODE("SYS_P0"."LOCATOR")=1)
3 - access("SYS_P0"."RID"=:B1 AND "SYS_P0"."PATHID"=HEXTORAW('3748') )
4 - access("SYS_ALIAS_1"."SYS_NC_OID$"="SYS_ALIAS_3"."OID")
7 - filter("SYS_ALIAS_2"."USERNAME"='SBELL')
8 - access("SYS_ALIAS_1"."SYS_NC_OID$"="SYS_ALIAS_2"."OID")
9 - filter(SYS_XMLCONTAINS("SYS_ALIAS_3"."DESCRIPTION",'Picnic')>0)

Note
-----
- dynamic sampling used for this statement (level=2)
- Unoptimized XML construct detected (enable XMLOptimizationCheck for more information)

30 rows selected.

例6-28で、パス表名path_tabが存在することは、索引の非構造化索引コンポーネントが使用されることを示しています。索引コンテンツ表po_idx_tabが存在することは、構造化索引コンポーネントが使用されることを示しています。

例6-29に、同じXMLIndex索引が、マルチレベルのXMLTable連鎖を使用する問合せに対して取得されることを示す実行計画を示します。非構造化XMLIndexコンポーネントのみが含まれる場合、2つのXMLTableファンクション・コールに2つの異なるパスがあるため、この問合せに対してもパス表の自己結合が行われます。

例6-29 マルチレベル連鎖を使用する問合せに対する構造化XMLIndexコンポーネントの使用

EXPLAIN PLAN FOR
SELECT po.reference, li.*
FROM po_clob p,
XMLTable('/PurchaseOrder' PASSING p.OBJECT_VALUE
COLUMNS reference   VARCHAR2(30)  PATH 'Reference',
lineitem    XMLType       PATH 'LineItems/LineItem') po,
XMLTable('/LineItem' PASSING po.lineitem
COLUMNS itemno      BINARY_DOUBLE PATH '@ItemNumber',
description VARCHAR2(256) PATH 'Description',
partno      VARCHAR2(14)  PATH 'Part/@Id',
quantity    BINARY_DOUBLE PATH 'Part/@Quantity',
unitprice   BINARY_DOUBLE PATH 'Part/@UnitPrice') li
WHERE po.reference = 'SBELL-20021009123335280PDT';

-------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                        |    17 | 20366 |    11   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                |                        |       |       |            |          |
|   2 |   NESTED LOOPS               |                        |    17 | 20366 |    11   (0)| 00:00:01 |
|   3 |    NESTED LOOPS              |                        |     1 |   539 |     3   (0)| 00:00:01 |
|*  4 |     TABLE ACCESS FULL        | PO_IDX_TAB             |     1 |   529 |     3   (0)| 00:00:01 |
|*  5 |     INDEX UNIQUE SCAN        | SYS_C006320            |     1 |    10 |     0   (0)| 00:00:01 |
|*  6 |    INDEX RANGE SCAN          | SYS69412_69421_PKY_IDX |    17 |       |     1   (0)| 00:00:01 |
|   7 |   TABLE ACCESS BY INDEX ROWID| PO_INDEX_LINEITEM      |    17 | 11203 |     8   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

4 - filter("SYS_ALIAS_8"."REFERENCE"='SBELL-20021009123335280PDT')
5 - access("SYS_ALIAS_8"."OID"="P"."SYS_NC_OID$")
6 - access("SYS_ALIAS_8"."KEY"="SYS_ALIAS_9"."PKEY")

Note
-----
- dynamic sampling used for this statement

25 rows selected.

この実行計画は、リレーショナル索引コンテンツ表po_idx_tabおよびpo_index_lineitemへの直接アクセスを示しています。パス表path_tabへのアクセスはまったくありません。

関連項目:
「コストベース・オプティマイザに対するXMLIndexオブジェクトの統計の収集」

XMLIndexの使用の無効化

XMLIndex索引の使用を無効にするには、次のいずれかの方法を使用できます。

- オプティマイザ・ヒント/*+ NO_XML_QUERY_REWRITE */を使用

- オプティマイザ・ヒント/*+ NO_XMLINDEX_REWRITE */を使用

ヒントNO_XML_QUERY_REWRITEおよびNO_XMLINDEX_REWRITEでは、すべてのXMLIndex索引の使用が無効になります。NO_XML_QUERY_REWRITEは、XMLIndexの使用を無効にする他に、XQueryの最適化もすべて無効にします(XMLIndexはXPathリライトの一部です)。

例6-30に、これらのオプティマイザ・ヒントの使用方法を示します。

例6-30 オプティマイザ・ヒントを使用したXMLIndexの無効化

SELECT /*+ NO_XMLINDEX_REWRITE */
count(*) FROM po_clob WHERE XMLExists('$p/*' PASSING OBJECT_VALUE AS "p");

SELECT /*+ NO_XML_QUERY_REWRITE */
count(*) FROM po_clob WHERE XMLExists('$p/*' PASSING OBJECT_VALUE AS "p");

注意:
NO_INDEXオプティマイザ・ヒントは、XMLIndexには適用されません。

関連項目:

- XQueryプラグマora:xq_procおよびora:xq_qryの詳細は「XQueryのオプション機能」。これを使用して、XQueryの最適化を詳細に管理できます。

- バイナリXMLデータのストリーミング評価の詳細は、「Oracle XML DBでのXMLTypeメソッドおよびSQL関数の処理」を参照してください。

XMLIndexパスのサブセット化: 索引付けするパスの指定

非構造化コンポーネントを含むXMLIndex索引は、非常に汎用性が高いという利点があります。索引付けするXPathの位置を指定する必要もなければ、問合せされるXPath式に関する事前の知識も必要ありません。デフォルトでは、非構造化XMLIndex索引では、XMLデータのすべての使用可能なXPath位置に索引が作成されます。

ただし、問い合せる可能性の高いXPath式を認識している場合は、XMLIndexの索引付けの焦点を絞り、パフォーマンスを高めることもできます。索引付けされたノードが少ないほど、索引付けに必要な領域も削減されるため、DML操作中の索引のメンテナンスが向上します。索引付けされたノードの数が少ないほどDDLのパフォーマンスが向上し、パス表が小さいほど問合せのパフォーマンスも向上します。

索引付けされるXMLフラグメントに対応する一連のXPath式(パス)をプルーニングし、可能なすべてのパスのサブセットを指定することで、索引付けの焦点を絞れます。これを行うには、他に2通りの方法があります。

- 除外: 可能なすべてのXPath式を含めるというデフォルト動作を実行した後に、索引付けに不要なものを除外します。

- 包含: 索引付けに使用する空白のXPath式の包含セットにパスを追加します。

CREATE INDEXを使用してXMLIndex索引を作成するとき、またはALTER INDEXを使用して索引を修正するときに、パスのサブセット化を指定できます。いずれの場合でも、文のPARAMETERS句のPATHSパラメータで、サブセット化情報を提供します。除外の場合は、キーワードEXCLUDEを使用します。包含の場合は、ALTER INDEXのときはキーワードINCLUDEを使用し、CREATE INDEXのときはキーワードを使用しません(含めるパスをリストします)。また、PATHSパラメータによってターゲット化されるノードに対し、名前空間マッピングも指定できます。

ALTER INDEXの場合、キーワードINCLUDEまたはEXCLUDEの後にキーワードADDまたはREMOVEを付加すると、キーワードの後に続くパスのリストを包含リストや除外リストに追加するか削除するかを指定できます。たとえば、この文では、索引付けから除外するパスのリストにパス/PurchaseOrder/Referenceを追加します。

ALTER INDEX po_xmlindex_ix REBUILD
PARAMETERS ('PATHS (EXCLUDE ADD (/PurchaseOrder/Reference))');

すべてのパスが含まれるようにXMLIndex索引を変更するには、キーワードINDEX_ALL_PATHSを使用します。「alter_index_paths_clause ::=」を参照してください。

注意:
構造化および非構造化コンポーネントの両方を持つXMLIndex索引を作成した場合、デフォルトで、構造化コンポーネント内で索引付けされているノードはすべて、非構造化コンポーネント内でも索引付けされます。つまり、非構造化コンポーネントから自動的に除外されません。非構造化XMLIndexの索引付けを適用しないようにするには、パスのサブセット化を明示的に使用してそれらを除外する必要があります。

関連項目:
PARAMETERS句の構文は、「CREATE INDEXおよびALTER INDEXのPARAMETER句」を参照してください。

XMLIndexパスのサブセット化の例

この項では、XPath式のサブセットに対し、XMLIndex索引を定義する方法を例示します。

例6-31 CREATE INDEXによるXMLIndexパスのサブセット化

CREATE INDEX po_xmlindex_ix ON po_clob (OBJECT_VALUE) INDEXTYPE IS XDB.XMLINDEX
PARAMETERS ('PATHS (INCLUDE (/PurchaseOrder/LineItems//*
/PurchaseOrder/Reference))');

この文では、次に示すように、最上位要素であるPurchaseOrderおよびその子に対してのみ索引付けする索引を作成します。

- すべてのLineItems要素およびその子孫

- すべてのReference要素

索引に使用される一連の空白のパスに対し、指定のパスを含めていきます。

例6-32 ALTER INDEXによるXMLIndexパスのサブセット化

ALTER INDEX po_xmlindex_ix REBUILD
PARAMETERS ('PATHS (INCLUDE ADD (/PurchaseOrder/Requestor
/PurchaseOrder/Actions/Action//*))');

この文では、索引付けに使用されたパスに対し、2つのパスを追加します。これらのパスは、Requestor要素と、Action要素の子孫(およびその祖先)に対して索引付けします。

例6-33 名前空間接頭辞を使用したXMLIndexパスのサブセット化

XMLIndex索引付けに使用されるXPath式で名前空間接頭辞が使用される場合、NAMESPACE MAPPING句をPATHSリストで使用して接頭辞を指定できます。次に例を示します。

CREATE INDEX po_xmlindex_ix ON po_clob (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
PARAMETERS ('PATHS (INCLUDE (/PurchaseOrder/LineItems//*   /PurchaseOrder/ipo:Reference)
NAMESPACE MAPPING (xmlns="http://xmlns.oracle.com"
xmlns:ipo="http://xmlns.oracle.com/ipo"))');

XMLIndexパスのサブセット化のルール

XMLIndexパスのサブセット化には、次のルールが適用されます。

- パスはchild軸およびdescendant軸のみを参照し、さらに、要素ノードおよび属性ノード、またはその名前(ワイルドカードを使用可能)のみをテストする必要があります。特に、パスには述語を含めないでください。

- パス除外とパス包含を一度に指定できません。いずれかの方法を指定する必要があります。

- パス除外(包含)によって索引が作成された場合は、パス除外(包含)によってのみ修正が可能です。索引の修正は、パスのサブセット化をさらに制限するか、さらに拡張するかのいずれかです。たとえば、特定のパスを含める索引を作成した後に、特定のパスを除外するよう修正することはできません。

非構造化コンポーネントを含むXMLIndexを使用するためのガイドライン

以降に、非構造化コンポーネントを含むXMLIndexを使用するためのガイドラインを示します。これらのガイドラインは、ここで説明する2つの方法によって同じ結果セットが戻される場合にのみ該当します。

- 祖先要素の接頭辞として//を付加しないでください。たとえば、同じ結果セットを戻す場合、/a/b//cではなく、//cを使用します。

- 祖先要素の接頭辞として/*を付加しないでください。たとえば、同じ結果セットを返す場合、/a/*/*ではなく、/*/*/*を使用します。

- WHERE句では、XMLQueryのXMLCastではなく、XMLExistsを使用します。これにより最適化が可能になり、パス表VALUE列に対して副問合せが実際に起動されます。たとえば、次のように記述します。

SELECT count(*) FROM purchaseorder p
WHERE
XMLExists('$p/PurchaseOrder/LineItems/LineItem/Part[@Id="715515011020"]'
PASSING OBJECT_VALUE AS "p");

次のように記述しないでください。

SELECT count(*) FROM purchaseorder p
WHERE XMLCast(XMLQuery('$p/PurchaseOrder/LineItems/LineItem/Part/@Id'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(14))
= "715515011020";

- 可能な場合、SELECT句では、count(XMLCast(XMLQuery(...))ではなく、count(*)を使用します。たとえば、発注書のLineItem要素にDescriptionの子が1つしかないことがわかっている場合は、次のように記述します。

SELECT count(*) FROM po_clob, XMLTable('//LineItem' PASSING OBJECT_VALUE);

次のように記述しないでください。

SELECT count(li.value)
FROM po_clob p, XMLTable('//LineItem' PASSING p.OBJECT_VALUE
COLUMNS value VARCHAR2(30) PATH 'Description') li;

- 問合せのFROMリストで使用されるXPath式の数は、なるべく少なくしてください。たとえば、次のように記述します。

SELECT li.description
FROM po_clob p,
XMLTable('PurchaseOrder/LineItems/LineItem' PASSING p.OBJECT_VALUE
COLUMNS description VARCHAR2(256) PATH 'Description') li;

次のように記述しないでください。

SELECT li.description
FROM po_clob p,
XMLTable('PurchaseOrder/LineItems' PASSING p.OBJECT_VALUE) ls,
XMLTable('LineItems/LineItem'      PASSING ls.OBJECT_VALUE
COLUMNS description VARCHAR2(256) PATH 'Description') li;

- 仮想表(XMLTable SQL/XML関数などで作成)の内部をドリルダウンするために、問合せでXPath式を使用する場合は、sys_orderkey_depth Oracle SQL関数を使用してパス表の順序キーの2次索引を作成します。このような問合せを次に例示します。選択により仮想的な明細項目表li内のDescription要素にナビゲートします。

SELECT li.description
FROM po_clob p,
XMLTable('PurchaseOrder/LineItems/LineItem' PASSING p.OBJECT_VALUE
COLUMNS description VARCHAR2(256) PATH 'Description') li;

このような問合せはsys_orderkey_depth関数によって評価されます。この関数は、order-key値の深度を戻します。順序索引は2列を使用するため、必要となる索引は、ORDER_KEY列およびRID列、およびORDER_KEY値に対して適用されたsys_orderkey_depth関数のコンポジット索引です。次に例を示します。

CREATE INDEX depth_ix ON my_path_table
(RID, sys_orderkey_depth(ORDER_KEY), ORDER_KEY);

関連項目:
sys_orderkey_depthの使用例は、例6-27を参照してください。

構造化コンポーネントを含むXMLIndexの使用のガイドライン

以降に、構造化コンポーネントを含むXMLIndexを使用するためのガイドラインを示します。

- 構造化コンポーネントを含むXMLIndexを使用して、リレーショナル列としてXMLデータを投影および索引付けします。ファンクション索引は使用しないでください。XMLとの使用は非推奨です。「ファンクション索引」を参照してください。

- 構造化コンポーネントが含まれるXMLIndex索引と問合せの間のデータ型の対応の確認。「XMLIndex構造化コンポーネントのデータ型に関する考慮事項」を参照してください。

- XMLTypeデータに関してリレーショナル・ビューを作成する場合(SQL関数XMLTableなどを使用して)、同じリレーショナル列をターゲットとする、構造化されたコンポーネントを持つXMLIndex索引を作成することも考慮してください。第19章「XMLTypeビュー」を参照してください。

- フラグメント抽出と値のフィルタリング(検索)の両方に単一のXQuery式を使用するかわりに、SELECT句でSQL/XML関数XMLQueryを使用し、WHERE句のフラグメントおよびXMLExistsを抽出して値をフィルタリングします。
こうすることで、Oracle XML DBがフラグメント抽出の機能的に、あるいはストリーミング評価を使用して評価できます。値のフィルタリングの場合、こうするとOracle XML DBが適切な構造のコンポーネントを持つXMLIndex索引を取得できます。

- 問合せの結果の順序を設定するには、SQLのORDER BY句とSQL/XML関数XMLTableを使用します。XQueryのorder by句は使用しないでください。構造化されたコンポーネントを含むXMLIndex索引を使用する場合は、特に使用を避けてください。

XMLIndexのパーティション化および並列度

レンジ・パーティション化またはリスト・パーティション化を使用して、XMLType表や、XMLType列が含まれる表をパーティション化する場合、その表にXMLIndex索引を作成することもできます。XMLIndex索引を作成するときにキーワードLOCALを使用すると、索引とその記憶域表すべてが、実表に関連してローカルに同一レベル・パーティション化されます。

キーワードLOCALを使用しない場合は、パーティション化された表にXMLIndex索引を作成できません。また、表をハッシュ・パーティション化する場合は、表にXMLIndex索引を作成できません。

XMLIndex索引の作成または修正時にPARALLEL句(程度は任意)を使用し、索引の作成とメンテナンスを並列的に行えます。実表がパーティション化されている場合や、並列度が有効になっている場合は、これによりDML操作(INSERT、UPDATE、DELETE)と索引DDL操作(CREATE、ALTER、REBUILD)の両方のパフォーマンスを向上させることができます。

索引に並列度を指定すると、問合せサーバー・プロセスそれぞれに個別に記憶域パラメータが適用されるため、記憶域の消費も多くなります。たとえば、INITIAL値が5M、並列度が12で作成された索引は、作成時に少なくとも60Mの記憶域を消費します。

CREATE INDEXおよびALTER INDEXのPARALLEL句の構文は、他のドメイン索引のものと同じです。

{ NOPARALLEL | PARALLEL [ integer ] }

例6-34では、並列度10でXMLIndex索引を作成します。実表がパーティション化されている場合、この索引は同一レベル・パーティション化されます。

例6-34 XMLIndex索引の並列的な作成

CREATE INDEX po_xmlindex_ix ON sale_info (sale_po_clob) INDEXTYPE IS XDB.XMLIndex
LOCAL PARALLEL 10;

例6-34では、パス表と2次索引は、XMLIndex索引そのものと同じ並列度(10)を継承して作成されます。パス表と2次索引に対して個別のPARALLEL句を使用し、異なる並列度を設定することも可能です。例6-35に、これを示します。ここでも、キーワードLOCALにより、実表がパーティション化されている場合、この索引は同一レベル・パーティション化されます。

例6-35 XMLIndexの内部オブジェクトに対する、異なるPARALLEL度の使用

CREATE INDEX po_xmlindex_ix ON sale_info (sale_po_clob) INDEXTYPE IS XDB.XMLIndex
LOCAL PARAMETERS ('PATH TABLE po_path_table (PARALLEL 10)
PIKEY INDEX po_pikey_ix
VALUE INDEX po_value_ix (PARALLEL 5)') NOPARALLEL;

例6-35ではNOPARALLELが指定されているため、XMLIndex索引そのものが連続して作成されます。2次索引po_pikey_ixも連続で移入されます。これは、2次索引に対して明示的に並列度が指定されておらず、XMLIndex索引から並列度が継承されるためです。パス表そのものは並列度を10として作成され2次索引値の列po_value_ixは、明示的な並列度指定を反映し、並列度5として移入されます。

XMLIndex索引、パス表、またはその2次索引に対して指定した並列度は、後続のDML操作および問合せにおいて使用されます。

XMLIndexの並列度を指定できる位置は、PARAMETERS句のカッコ付きの式の中とその後の2箇所です。

関連項目:

- CREATE INDEXのPARALLEL句の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- PARAMETERS句の構文は、「CREATE INDEXおよびALTER INDEXのPARAMETER句」を参照してください。

- 「構造化XMLIndexコンポーネントと非構造化XMLIndexコンポーネント」

XMLIndex索引の非同期(遅延)メンテナンス

この機能は、非構造化コンポーネントのみが含まれるXMLIndex索引に適用されます。構造化コンポーネントが含まれるXMLIndex索引に非同期メンテナンスを指定すると、エラーが発生します。

デフォルトでは、XMLIndex索引はDML操作のたびに更新(メンテナンス)されますので、実表と常に同期化されます。状況によっては、このようなことは必要なく、従来の索引の使用が許可される場合があります。そのような場合、索引メンテナンスのコストを遅延するよう決定し、コミット時のみまたはデータベースの負荷が軽減されているある時期に実行できます。これにより、DMLのパフォーマンスを向上させることができます。また、索引の同期化を行う際に、非同期索引行のバルク・ロードを有効にすると、索引メンテナンスのパフォーマンスを向上させることができます。

DML操作では従来の索引を使用しても、パフォーマンス以外には影響がありません。ただし、問合せ結果に影響を与えることもあります。問合せ時に索引が最新の状態でない場合は、問合せ結果も最新でない可能性があります。実表の1列のみがXMLTypeデータ型であったとしても、その表のすべての問合せには、XMLIndex列のXMLIndex索引の最終同期時のデータベース・データが反映されます。

CREATE INDEX文またはALTER INDEX文のPARAMETERS句を使用し、索引メンテナンスの遅延を指定できます。

XMLIndex索引の同期化を遅延しても、次のデータベース操作により、索引が自動的に同期化されるので注意が必要です。

- 索引に対するDDL操作: ALTER INDEXまたは2次索引の作成

- 実表に対するDDL操作: ALTER TABLEまたは他の索引の作成

表6-7に、同期化オプションと、オプションの指定に使用されるASYNC句の構文をまとめます。ASYNC句は、CREATE INDEXのPARAMETERS句またはXMLIndexのALTER INDEX文で使用されます。

表6-7 索引の同期化

同期化するタイミング

ASYNC句の構文

常時

ASYNC(SYNC ALWAYS)

これがデフォルトの動作です。前のASYNC指定を無効にするため、明示的に指定できます。

コミット時

ASYNC(SYNC ON COMMIT)

定期的

ASYNC(SYNC EVERY "repeat_interval")

repeat_intervalは、DBMS_SCHEDULERのカレンダ構文と同じです。

EVERYを使用するには、CREATE JOB権限が必要です。

手動、オン・デマンド

ASYNC(SYNC MANUAL)

PL/SQLプロシージャDBMS_XMLINDEX.SyncIndexを使用すると、索引を手動で同期化できます。

ASYNC構文のオプションのパラメータであるSTALEは、将来に備えて用意されているものであり、明示的に指定する必要はありません。ALWAYSが使用されていれば、値は常にFALSEになります。それ以外の場合の値はTRUEです。このルールに反して明示的なSTALE値を指定すると、エラーが発生します。

例6-36では、明日から毎週月曜日の午後3時に同期化されるXMLIndex索引を作成します。

例6-36 XMLIndexに対する遅延同期の指定

CREATE INDEX po_xmlindex_ix ON po_clob (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
PARAMETERS ('ASYNC (SYNC EVERY "FREQ=HOURLY; INTERVAL = 1")');

例6-37では、例6-36で作成された索引を手動で同期化します。

例6-37 SYNCINDEXを使用したXMLIndex索引の手動同期化

EXEC DBMS_XMLINDEX.SyncIndex('OE', 'PO_XMLINDEX_IX', REINDEX => TRUE);

XMLIndex索引の同期化が遅延されると、索引に対する最終同期化以降、実表に対して加えられたすべてのDML変更(挿入、更新、削除)は、DML操作当たり1行ずつ、保留中の表に記録されます。この表の名前は、静的なパブリック・ビューUSER_XML_INDEXES、ALL_XML_INDEXES、およびDBA_XML_INDEXESのPEND_TABLE_NAME列の値です。

この表を検証すると、指定のXMLIndex索引を同期化させる最適な時期を決定できます。保留中の表の行数が多くなると、同期化が必要な索引も多くなります。

保留中の表のサイズが大きい場合、SyncIndexのコール時にパラメータREINDEXをTRUEに設定すると、例6-37に示すようにパフォーマンスを向上できます。REINDEXがTRUEの場合は、すべての2次索引が削除され、保留中の表データを一括ロードした後に再作成されます。

関連項目:

- repeat_intervalの構文の詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』のカレンダ構文を参照してください。

- PL/SQLプロシージャDBMS_XMLINDEX.SyncIndexの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

コストベース・オプティマイザに対するXMLIndexオブジェクトの統計の収集

Oracle Databaseのコストベース・オプティマイザにより、使用される索引(ある場合)も含め、所定の問合せをどのように評価すると最も費用効率が高いかが決定します。これを正確に実行するには、様々なデータベース・オブジェクトの統計を収集する必要があります。

XMLIndexについては、通常はXMLIndex索引が定義されている実表に関する統計のみ収集する必要があります(DBMS_STATS.gather_table_statsプロシージャなどを使用)。これにより、XMLIndex索引自体、パス表とその2次索引、および構造化コンポーネント・コンテンツ表とその2次索引に関する統計が自動的に収集されます。

実表の統計を削除すると(DBMS_STATS.delete_table_statsプロシージャを使用)、他のオブジェクトに関する統計も削除されます。同様に、XMLIndex索引に関する統計を収集すると(DBMS_STATS.gather_index_statsプロシージャを使用)、パス表とその2次索引、および構造化コンポーネント・コンテンツ表とその2次索引に関する統計も収集されます。

例6-38では、実表po_clobに関する統計を収集します。XMLIndex索引、パス表、および2次パス表索引に関する統計が自動的に収集されます。

例6-38 XMLIndexオブジェクトに関する統計の自動収集

CALL DBMS_STATS.gather_table_stats(USER, 'PO_CLOB', ESTIMATE_PERCENT => NULL);

関連項目:
XMLIndex索引の統計情報を記録するデータベース・ビューの詳細は、「XMLIndexに関連するデータ・ディクショナリの静的なパブリック・ビュー」を参照してください。

XMLIndexに関連するデータ・ディクショナリの静的なパブリック・ビュー

標準的なデータベース索引に関する情報は、静的なパブリック・ビューUSER_INDEXES、ALL_INDEXES、およびDBA_INDEXESにあります。XMLIndex索引に関する同様の情報も、静的なパブリック・ビューUSER_XML_INDEXES、ALL_XML_INDEXES、およびDBA_XML_INDEXESにあります。

表6-8で、これらの各ビューの列について説明します。

表6-8 XMLIndexの静的なパブリック・ビュー

列名

型

説明

ASYNC

VARCHAR2

非同期索引の更新の仕様です。「XMLIndex索引の非同期(遅延)メンテナンス」を参照してください。

EX_OR_INCLUDE

VARCHAR2

パスのサブセット化:

- FULLY_IX: 索引でパスのサブセット化を使用しません。

- EXCLUDE: 索引で除外のサブセット化のみを使用します。

- INCLUDE: 索引で包含のサブセット化のみを使用します。

INDEX_NAME

VARCHAR2

XMLIndex索引の名前です。

INDEX_OWNER

VARCHAR2

索引の所有者です。USER_XML_INDEXESには使用されません。

INDEX_TYPE

VARCHAR2

索引のコンポーネントのタイプは、STRUCTURED、UNSTRUCTUREDまたはSTRUCTURED AND UNSTRUCTUREDで構成されます。

PARAMETERS

XMLType

索引の作成に使用されたPARAMETERS句の情報。

非構造化XMLIndexコンポーネントが存在する場合、PARAMETERS句には、パスのサブセット化を定義する一連のXPathパスと、同期化されるスケジューラ・ジョブの名前を含めることができます。

構造化コンポーネントが存在する場合、PARAMETERS句には、XMLTable(列を定義するXQuery式を含む)で提供される構造グループの名前と表定義が含まれます。

PATH_TABLE_NAME

VARCHAR2

XMLIndexパス表の名前です。

PEND_TABLE_NAME

VARCHAR2

最後に行われた索引の同期以降の、実表のDML操作を記録する表の名前です。「XMLIndex索引の非同期(遅延)メンテナンス」を参照してください。

TABLE_NAME

VARCHAR2

索引が定義されている実表の名前です。

TABLE_OWNER

VARCHAR2

索引が定義されている実表の所有者です。

これらのビューでは、XMLIndex索引に関する情報が提供されますが、XMLIndex索引で収集される統計に関する情報を提供するカタログ・ビューはありません。この統計情報は、次のビュー間で配信されます。

- USER_INDEXES、ALL_INDEXES、DBA_INDEXES: 列LAST_ANALYZEDでは、XMLIndex索引の最終分析日が提供されます。

- USER_TAB_STATISTICS、ALL_TAB_STATISTICS、DBA_TAB_STATISTICS: 列TABLE_NAMEでは、XMLIndex索引の構造化コンポーネントおよび非構造化コンポーネントの情報が提供されます。構造化コンポーネントまたは非構造化コンポーネントの情報については、パス表またはXMLTable表の名前をTABLE_NAMEとしてそれぞれ使用して問い合せます。

- USER_IND_STATISTICS、ALL_IND_STATISTICS、DBA_IND_STATISTICS: 列INDEX_NAMEでは、XMLIndex索引の2次索引のそれぞれの情報が提供されます。指定された2次索引に関する情報については、その2次索引の名前をINDEX_NAMEとして使用して問い合せます。

CREATE INDEXおよびALTER INDEXのPARAMETERS句

この項では、XMLIndexでのSQL文CREATE INDEXおよびALTER INDEXのPARAMETERS句の使用方法と構文を示します。

関連項目:

- index_attributesの構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- segment_attributes_clauseの構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- table_propertiesの構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- parallel_clauseの構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- CREATE INDEXの構文およびセマンティクスの追加情報は、『Oracle Database SQL言語リファレンス』を参照してください。

- ALTER INDEXの構文およびセマンティクスの追加情報は、『Oracle Database SQL言語リファレンス』を参照してください。

- repeat_intervalの構文の詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』のカレンダ構文を参照してください。

XMLIndexの登録済パラメータ句の使用

CREATE INDEXまたはALTER INDEX文のPARAMETERS句に使用する文字列値には、1000文字の制限があります。この制限を回避するには、パッケージDBMS_XMLINDEX内のPL/SQLプロシージャregisterParameterおよびmodifyParameterを使用できます。

これらのプロシージャごとに、(長さ制限のない)パラメータの文字列と、その文字列の登録に使用する識別子を指定します。次に索引PARAMETERS句で、リテラル文字列ではなく、キーワードPARAMで始まる識別子を指定します。

識別子は、CREATE INDEXまたはALTER INDEX文で使用する前に、登録しておく必要があります。

CREATE INDEXおよびALTER INDEXのPARAMETERS句の構文

XMLIndex_parameters_clause ::=

関連項目:
「XMLIndex_parameters_clauseの使用」

XMLIndex_parameters ::=

関連項目:
「XMLIndex_parameterの使用」

XMLIndex_parameter_clause ::=

unstructured_clause ::=

create_index_paths_clause ::=

関連項目:

- 「PATHS句の使用」

- 「create_index_paths_clauseおよびalter_index_paths_clauseの使用」

alter_index_paths_clause ::=

関連項目:

- 「PATHS句の使用」

- 「create_index_paths_clauseおよびalter_index_paths_clauseの使用」

namespace_mapping_clause ::=

path_table_clause ::=

pikey_clause ::=

関連項目:
「pikey_clause、path_id_clauseおよびorder_key_clauseの使用」

path_id_clause ::=

関連項目:
「pikey_clause、path_id_clauseおよびorder_key_clauseの使用」

order_key_clause ::=

関連項目:
「pikey_clause、path_id_clauseおよびorder_key_clauseの使用」

value_clause ::=

関連項目:
「value_clauseの使用」

drop_path_table_clause ::=

parallel_clause ::=

structured_clause ::=

関連項目:
「groups_clauseおよびalter_index_group_clauseの使用」

async_clause ::=

関連項目:
「async_clauseの使用」

groups_clause ::=

関連項目:
「groups_clauseおよびalter_index_group_clauseの使用」

group_clause ::=

関連項目:
「groups_clauseおよびalter_index_group_clauseの使用」

XMLIndex_xmltable_clause ::=

構文要素XML_namespaces_clauseおよびXQuery_stringは、SQL/XML関数XMLTableの場合と同じです。

関連項目:

- 「XMLIndex_xmltable_clauseの使用」

- 「Oracle XML DBのXMLTABLE SQL/XML関数」

column_clause ::=

構文要素column_clauseは、SQL/XML関数XMLTableのXML_table_columnと似ていますが同じではありません。

関連項目:

- 「column_clauseの使用」

- 「Oracle XML DBのXMLTABLE SQL/XML関数」

alter_index_group_clause ::=

関連項目:
「groups_clauseおよびalter_index_group_clauseの使用」

add_column_clause :==

add_column_options :==

構文要素XML_namespaces_clauseは、SQL/XML関数XMLTableの場合と同じです。「Oracle XML DBのXMLTABLE SQL/XML関数」を参照してください。

drop_column_clause :==

drop_column_options :==

XMLIndex_parameters_clauseの使用

XMLIndex索引を作成するとき、XMLIndex_parameters_clauseがなければ、新しい索引には非構造化コンポーネントのみが含まれます。XMLIndex_parameters_clauseがあってもPARAMETERS引数が空('')であれば結果は同じで、索引には非構造化コンポーネントのみが含められます。

XMLIndex_parameterの使用

XMLIndex_parametersを使用する際には、次の点を考慮する必要があります。

- XMLIndex_parametersでは、XMLIndex_parameter_clauseを1種類当たり最大1回しか使用できません。たとえば、PATHS句を最大で1回、path_table_clauseを最大で1回などです。

- XMLIndexを作成するとき、structured_clauseがなければ、新しい索引には非構造化コンポーネントのみが含められます。structured_clauseが存在すれば、新しい索引には構造化コンポーネントのみが含められます。

PATHS句の使用

PATHS句を使用する際には、次の点を考慮する必要があります。

- CREATE INDEX文では、PATHS句を最大で1回使用できます。つまり、create_index_paths_clauseの後に、PATHSを最大で1回使用できます。

- create_index_paths_clause句はCREATE INDEXでのみ、また、alter_index_paths_clause句はALTER INDEXでのみ使用されます。

create_index_paths_clauseおよびalter_index_paths_clauseの使用

create_index_paths_clauseおよびalter_index_paths_clauseを使用する際には、次の点を考慮する必要があります。

- INDEX_ALL_PATHSキーワードは、すべてのパスが含まれた状態で索引を再構築します。このキーワードは、alter_index_paths_clauseでのみ使用でき、create_index_paths_clauseでは使用できません。

- 索引に対するパスの明示的なリストには、ワイルドカードおよび//を使用できます。

- XPaths_listは1つ以上のXpaths式で構成されるリストです。それぞれのリストには、child軸、descendant軸、名前テスト、およびワイルドカード(*)構造のみが含まれます。

- create_index_paths_clauseからXPaths_listが省略されていると、すべてのパスが索引付けされます。

- XPaths_listのXPath式で使用される一意の名前空間接頭辞に対し、対応する名前空間情報を提供するには、標準的なXML名前空間宣言が必要です。

- 索引を削除した後で必要に応じて作成しなおすと、構文に直接反映されない方法で索引を変更できます。たとえば、パスを含めることで定義される索引を、パスを除外することで定義される索引に変更する場合は、索引を削除した後で、EXCLUDEを使用して作成しなおします。

pikey_clause、path_id_clauseおよびorder_key_clauseの使用

pikey_clause、path_id_clauseおよびorder_key_clauseの各句は、構文的にそれぞれ省略可能です。pikey索引は、pikey_clauseを指定しない場合でも作成されます。パスID索引または順序キー索引を作成するには、path_id_clauseまたはorder_key_clauseをそれぞれ指定する必要があります。

value_clauseの使用

value_clauseを使用する際には、次の点を考慮する必要があります。

- VALUE列は、VARCHAR2(4000)として作成されています。

- value_clause句がキーワードVALUEでのみ構成される場合は、通常のデフォルト属性によって値索引が作成されます。

- path_id_clause句がキーワードPATH IDでのみ構成される場合は、通常のデフォルト属性によってパスID索引が作成されます。

- order_key_clause句がキーワードORDER KEYでのみ構成される場合は、通常のデフォルト属性によって順序キー索引が作成されます。

async_clauseの使用

ASYNC句を使用する際には、次の点を考慮する必要があります。

- この機能は、非構造化コンポーネントのみが含まれるXMLIndex索引のみで使用します。構造化コンポーネントが含まれるXMLIndex索引にASYNC句を指定すると、エラーが発生します。

- ALWAYSとは、各DML文に対して自動同期が行われることを意味します。

- MANUALとは、自動同期が行われないことを意味します。DBMS_XMLINDEX.SyncIndexを使用して、索引を手動同期させる必要があります。

- EVERY repeat_intervalとは、repeat_intervalの間隔で索引を自動同期させることを意味します。repeat_intervalの構文は、PL/SQLパッケージDBMS_SCHEDULERと同じであり、二重引用符(")で囲む必要があります。EVERYを使用するには、CREATE JOB権限が必要です。

- ON COMMITとは、コミット操作の直後に索引を同期させることを意味します。コミットは、同期が完了するまでは戻されません。同期は個別の処理として実行されるため、データがコミットされてから、索引の変更がコミットされるまで短い間隔が生じることがあります。

- STALEはオプションです。値がTRUEの場合は、問合せ結果が失効している可能性があります。値がFALSEの場合は、問合せ結果は常に最新です。デフォルト値と、明示的に指定可能な唯一の値は次のとおりです。

- ALWAYSの場合、STALEはTRUEです。

- ALWAYS以外のASYNCオプションの場合、STALEはFALSEです。

groups_clauseおよびalter_index_group_clauseの使用

groups_clause句はCREATE INDEXでのみ、alter_index_group_clause句はALTER INDEXでのみ使用されます。

XMLIndex_xmltable_clauseの使用

XMLIndex_xmltable_clauseを使用する際には、次の点を考慮する必要があります。

- XMLIndex_xmltable_clause内のXQuery_string式では、XQuery関数ora:view(非推奨)、fn:docまたはfn:collectionを使用できません。

- 特定のXMLIndex_xmltable_clauseにデータ型XMLTypeのcolumn_clauseが複数含まれる場合、Oracle XML DBでエラーが発生します。このような2つの仮想列を定義した場合と同じ結果にするには、個別にgroup_clauseを追加する必要があります。

- XMLIndex_xmltable_clauseではPASSING句はオプションです。この句が存在しない場合、次のようにXMLType列が暗黙的に渡されます。

- パラメータ句の最初のXMLIndex_xmltable_clauseでは、索引付けされるXMLType列が暗黙的に渡されます。(XMLType表に索引を作成する場合、疑似列OBJECT_VALUEが渡されます。)

- それ以降の各XMLIndex_xmltable_clauseについては、その前のXMLIndex_xmltable_clauseのVIRTUAL XMLType列が暗黙的に渡されます。

column_clauseの使用

XMLIndex索引でXMLTableのマルチレベル連鎖を使用する場合、あるレベルのXMLTable表は、その前のレベルのXMLType列に対応します。構文の説明で、キーワードVIRTUALはオプションとして示されています。実際には、これはXMLType列でのみ使用され、その場合は必須です。XMLType列以外に使用するとエラーになります。VIRTUALは、XMLType列自体が生成されないことを指定します。つまり、そのデータは、対応するXMLTable表により指定されたリレーショナル列の形式でのみ、索引に格納されます。

XMLデータに対するOracle Text索引

XMLType列にOracle Text索引を作成できます。Oracle TextのCONTEXT索引では、XMLの全文検索を実行するためのOracle SQL関数containsを使用できます。構造化記憶域では、XPathリライトによりora:contains XPath関数がcontains SQL関数にリライトされることが多いため、このようなケースでもOracle Text索引が使用されます。

関連項目:

- Oracle XML DBでのOracle Text操作の使用方法の詳細は、第12章「XMLデータの全文検索」を参照してください。

- 例6-23「XMLIndex索引コンテンツ表に対するOracle Text CONTEXT索引」

Oracle Text索引の作成および使用

Oracle Text索引を作成するには、CREATE INDEXを使用します。そのとき、例6-39で示すように、CTXSYS.CONTEXTとしてINDEXTYPEを指定します。

例6-39 Oracle Text索引の作成

CREATE INDEX po_otext_ix ON po_clob (OBJECT_VALUE) INDEXTYPE IS CTXSYS.CONTEXT;

XMLType列に対して、containsやscoreなどのOracle Text操作を実行することもできます。例6-40に、Oracle SQL関数containsを使用したOracle Text検索を示します。

例6-40 SQL関数CONTAINを使用したXMLデータの検索

SELECT DISTINCT XMLCast(XMLQuery('$p/PurchaseOrder/ShippingInstructions/address'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(256)) "Address"
FROM po_clob po
WHERE contains(po.OBJECT_VALUE,
'$(Fortieth) INPATH (PurchaseOrder/ShippingInstructions/address)') > 0;

Address
------------------------------
1200 East Forty Seventh Avenue
New York
NY
10024
USA

1 row selected.

この問合せの実行計画は、次の2つの方法で、Oracle Text CONTEXT索引が使用されることを示しています。

- 索引がドメイン索引として明示的に参照されます。

- 述語情報内のOracle SQL関数containsが参照されます。

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------
Plan hash value: 274475732

--------------------------------------------------------------------------------------------
| Id  | Operation                    | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |             |     7 | 14098 |    10  (10)| 00:00:01 |
|   1 |  HASH UNIQUE                 |             |     7 | 14098 |    10  (10)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| PO_CLOB     |     7 | 14098 |     9   (0)| 00:00:01 |
|*  3 |    DOMAIN INDEX              | PO_OTEXT_IX |       |       |     4   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - access("CTXSYS"."CONTAINS"(SYS_MAKEXML('2B0A2483AB140B35E040578C8A173FEC',523
3,"XMLDATA"),'$(Fortieth) INPATH (PurchaseOrder/ShippingInstructions/address)')>0)

20 rows selected.

他の索引に依存しないOracle Text索引

Oracle Textの索引付けは、この章で説明するその他の索引付けに完全に直交しています。contains Oracle SQL関数またはora:contains XPath関数が使用されると、Oracle Text索引を全文検索で使用できます。

例6-41に、同じXMLデータに対してXMLIndex索引とOracle Text索引の両方が定義されているケースを示します。問合せは、例6-40と同じです。Oracle Text索引が、例6-9のXMLIndexパス表のVALUE列に作成されます。

例6-41 Oracle Text索引およびXMLIndex索引の使用

CREATE INDEX po_otext_ix ON my_path_table (VALUE) INDEXTYPE IS CTXSYS.CONTEXT;

EXPLAIN PLAN FOR
SELECT DISTINCT XMLCast(XMLQuery('$p/PurchaseOrder/ShippingInstructions/address'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(256)) "Address"
FROM po_clob po
WHERE contains(po.OBJECT_VALUE,
'$(Fortieth) INPATH (PurchaseOrder/ShippingInstructions/address)') > 0;

-------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                         | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                              |     7 | 14098 |     3  (34)| 00:00:01 |
|   1 |  SORT GROUP BY               |                              |     1 |  3524 |            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID| MY_PATH_TABLE                |     2 |  7048 |     3   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |     2   (0)| 00:00:01 |
|   4 |  HASH UNIQUE                 |                              |     7 | 14098 |     3  (34)| 00:00:01 |
|*  5 |   TABLE ACCESS FULL          | PO_CLOB                      |     7 | 14098 |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - filter(SYS_XMLI_LOC_ISNODE("SYS_P0"."LOCATOR")=1)
3 - access("SYS_P0"."RID"=:B1 AND "SYS_P0"."PATHID"=HEXTORAW('6F7F') )
5 - filter("CTXSYS"."CONTAINS"(SYS_MAKEXML(0,"SYS_ALIAS_1"."XMLDATA"),'$(Fortieth) INPATH
(PurchaseOrder/ShippingInstructions/address)')>0)

Note
-----
- dynamic sampling used for this statement (level=2)
- Unoptimized XML construct detected (enable XMLOptimizationCheck for more information)

24 rows selected.

例6-41の実行計画では、XMLIndex索引とOracle Text索引の両方を参照しており、両方が使用されていることを示しています。

- XMLIndex索引は、パス表MY_PATH_TABLEと、その順序キー索引SYS78942_PO_XMLINDE_ORDKEY_IXによって示されます。

- Oracle Text索引は、述語情報のcontains Oracle SQL関数への参照によって示されます。

脚注の凡例

脚注 1: このマニュアルでは、「構造化」と「非構造化」は一般にXMLType記憶域オプションを指します。データの性質を指すことはそれほど多くありません。「ハイブリッド」は、ある種の埋込みCLOB記憶域を持つオブジェクト・リレーショナル記憶域を示します。「半構造化」は、記憶域に関係なく、XMLコンテンツを指します。非構造化記憶域はCLOBベースの記憶域で、構造化記憶域はオブジェクト・リレーショナル記憶域です。
脚注 2: 実際のパス表の実装は多少異なることがあります。

7 XML Schemaの格納と問合せ: 基本

XML Schema勧告はXML文書のコンテンツおよび構造をXMLで記述するためにWorld Wide Web Consortium (W3C)で作成されました。これには既存のDocument Type Definitions (DTD)をXML Schemaに変換できるように、すべてのDTDの機能が含まれています。XML schemaにはDTDにはない追加機能があります。

この章では、Oracle XML DBでのXML Schemaの使用に関する基本情報を示します。次の操作の実行方法について説明します。

- XML Schemaの登録、更新および削除

- XML Schemaに基づくデータに対する記憶域構造の作成

- XML Schemaデータ型のSQLデータ型へのマッピング

この章の内容は次のとおりです。

- XML SchemaおよびOracle XML DBの概要

- Oracle XML DBでのXML Schemaの使用

- DBMS_XMLSCHEMAを使用したXML Schemaの管理

- XMLTypeのXML Schema関連メソッド

- ローカルXML SchemaおよびグローバルXML Schema

- DOM再現性

- XML変換

- XML Schemaに基づくXMLType表および列の作成

- OracleでのXML Schemaの注釈

- 登録されたXML Schemaの問合せによる注釈の取得

- XML Schemaデータ型のOracle XML DB記憶域へのマッピング

- XML Schemaデータ型のSQLデータ型へのマッピング

関連項目:

- Oracle XML DBでのXML Schemaの使用に関する高度な情報は、第9章「XML Schemaの格納と問合せ: 高度」を参照してください。

- Oracle XML DBでのXPath式の最適化の詳細は、第8章「構造化記憶域のXPathリライト」を参照してください。

- http://www.w3.org/TR/xmlschema-0/ - XML Schemaの概要

XML SchemaおよびOracle XML DBの概要

XML SchemaはXMLで記述されたスキーマ定義言語です。準拠するインスタンス文書の構造とセマンティクスを記述するのに使用できます。たとえば、次のXML Schema定義purchaseOrder.xsdには、XML発注書の構造とその他のプロパティが記述されています。

このマニュアルで、XML SchemaとはXML Schemaインスタンス定義を指します。

例7-1は、purchaseOrderTypeというcomplexTypeおよびこの型のPurchaseOrderグローバル要素を宣言するXML Schemaを示しています。これは、例3-9「発注書XML Schema、purchaseOrder.xsd」で使用したXML Schemaに、太字で示した行を追加したものです。簡略にするため、ここではスキーマの一部(...の部分)を省略しています。

例7-1 XML SchemaインスタンスpurchaseOrder.xsd

<xs:schema
targetNamespace="http://xmlns.oracle.com/xdb/documentation/purchaseOrder"
xmlns:po="http://xmlns.oracle.com/xdb/documentation/purchaseOrder"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0">
<xs:element name="PurchaseOrder" type="po:PurchaseOrderType"/>
<xs:complexType name="PurchaseOrderType">
<xs:sequence>
<xs:element name="Reference" type="po:ReferenceType"/>
<xs:element name="Actions" type="po:ActionsType"/>
<xs:element name="Reject" type="po:RejectionType" minOccurs="0"/>
<xs:element name="Requestor" type="po:RequestorType"/>
<xs:element name="User" type="po:UserType"/>
<xs:element name="CostCenter" type="po:CostCenterType"/>
<xs:element name="ShippingInstructions"
type="po:ShippingInstructionsType"/>
<xs:element name="SpecialInstructions"
type="po:SpecialInstructionsType"/>
<xs:element name="LineItems" type="po:LineItemsType"/>
<xs:element name="Notes" type="po:NotesType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemsType">
<xs:sequence>
<xs:element name="LineItem" type="po:LineItemType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>

...

<xs:simpleType name="DescriptionType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NotesType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="32767"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

例7-2は、XML Schema purchaseOrder.xsdに準拠したXML文書を示しています。

例7-2 purchaseOrder.xml: purchaseOrder.xsdに準拠する文書

<po:PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:po="http://xmlns.oracle.com/xdb/documentation/purchaseOrder"
xsi:schemaLocation=
"http://xmlns.oracle.com/xdb/documentation/purchaseOrder
http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd">
<Reference>SBELL-2002100912333601PDT</Reference>
<Actions>
<Action>
<User>SVOLLMAN</User>
</Action>
</Actions>
<Reject/>
<Requestor>Sarah J. Bell</Requestor>
<User>SBELL</User>
<CostCenter>S30</CostCenter>
<ShippingInstructions>
<name>Sarah J. Bell</name>
<address>400 Oracle Parkway
Redwood Shores
CA
94065
USA
</address>
<telephone>650 506 7400</telephone>
</ShippingInstructions>
<SpecialInstructions>Air Mail</SpecialInstructions>
<LineItems>
<LineItem ItemNumber="1">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="2">
<Description>The Unbearable Lightness Of Being</Description>
<Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="3">
<Description>Sisters</Description>
<Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
</LineItem>
</LineItems>
<Notes>Section 1.10.32 of &quot;de Finibus Bonorum et Malorum&quot;,
written by Cicero in 45 BC

&quot;Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium
doloremque laudantium, totam rem aperiam, eaque ips
...
tiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla
pariatur?&quot;

1914 translation by H. Rackham

&quot;But I must explain to you how all this mistaken idea of denouncing
pleasure and praising pain was born and I will give you a c
...
o avoids a pain that produces no resultant pleasure?&quot;

Section 1.10.33 of &quot;de Finibus Bonorum et Malorum&quot;, written by Cicero
in 45 BC

&quot;At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis
praesentium voluptatum deleniti atque corrupti quos
...
delectus, ut aut reiciendis voluptatibus maiores alias
consequatur aut perferendis doloribus asperiores repellat.&quot;

1914 translation by H. Rackham

&quot;On the other hand, we denounce with righteous indignation and dislike men
who are so beguiled and demoralized by the charms of
...
secure other greater pleasures, or else he endures pains to avoid worse
pains.&quot;
</Notes>
</po:PurchaseOrder>

注意:
使用されているURLhttp://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsdは、データベース内の登録済XMLスキーマを一意に識別する名前です。これはXML Schema文書の場所を示す必要はありません。XML Schemaのターゲット名前空間は、XML Schemaの場所を示すURLとは異なるURLで、要素および型が宣言される抽象名前空間が指定されます。
XML Schemaには、オプションでターゲット・ネームスペースのURLを指定できます。この属性が省略されている場合、XML Schemaにターゲット名前空間はありません。通常、ターゲット名前空間は、XML SchemaのURLと同じです。

XMLインスタンス・ドキュメントには、ルート要素のネームスペース(XML Schemaのターゲットネームスペースと同一)、およびこのルート要素を定義するXML Schemaの場所(URL)が指定されている必要があります。場所は、属性xsi:schemaLocationで指定されます。XML Schemaにターゲットのネームスペースがない場合は、xsi:noNamespaceSchemaLocation属性を使用してXML Schema URLを指定します。

Oracle XML DBでのXML Schemaの使用

Oracle XML DBは、厳密な型指定およびその他の強力なXML Schemaのプロパティを使用し、XMLデータベース・データを安全で効率的に処理します。

注意:
バイナリXML記憶域を使用して格納されたXMLデータを使用すると、DTDを使用して、そこで定義されたXMLエンティティを取得できます。ただし、DTD内の構造や型情報は、Oracle XML DBでは使用されません。使用される情報は、エンティティのみです。

Oracle XML DBはメタデータとして注釈付きXML Schemaを使用します。標準XML Schema定義は、いくつかのOracle名前空間属性で定義された属性とともに使用されます。これらの属性は、データベースへのXMLインスタンス文書のマッピング方法を決定します。これらの属性は、XML Schemaの名前空間とは異なる名前空間に存在するため、注釈付きXML Schemaは、正当なXML Schema文書になります。

関連項目:
http://www.w3.org/2001/XMLSchema

Oracle XML DBをXML Schemaとともに使用する場合、最初にXML Schemaを登録する必要があります。次に、XMLType表、列およびビューの作成中にXMLスキーマURLを使用できます。XML Schema URLはデータベース内でXML Schemaを識別します。PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaのパラメータSCHEMAURLと関連付けられています。

Oracle XML DBでは、次のタスクに対してXML Schemaのサポートが提供されます。

- ローカルおよびグローバルな、W3C準拠のXML Schemaの登録。

- 登録されたXML Schema定義に対するXML文書の検証。

- SQLオブジェクト型からのXML Schemaの生成。

- 他のユーザーが所有するXML Schemaの参照。

- 同じ名前のローカルXML Schemaが存在する場合に行うグローバルXML Schemaの明示的な参照。

- XML Schemaの登録時にXML Schemaから行うデータベース・マッピングの生成。これには、SQLオブジェクト型、コレクション型およびデフォルト表の生成、およびXML Schema属性を使用するマッピング情報の取得が含まれます。

- 複数の許容されるマッピングが存在する場合に行う特定のSQL型マッピングの指定

- 登録されたXML Schemaに基づくXMLType表、ビューおよび列の作成。

- XML Schemaに基づくXMLType表に対する操作および問合せ。

- プロトコル(FTP、HTTP(S)/WebDAV)およびSQL以外の言語を使用して、XML Schemaに基づく文書がOracle XML DBリポジトリに挿入される場合に行う、デフォルト表へのデータの自動挿入。

関連項目:
第3章「Oracle XML DBの使用」

XML Schemaを使用する理由

XMLTypeは、データベースの列と表へのXMLデータの格納を容易にする抽象データ型です。XML SchemaはXMLデータのための追加の記憶域とアクセス・オプションを提供します。XML Schemaを使用して、使用するXML要素および属性、要素のネストの種類およびデータ型を定義することができます。

XML Schemaを使用すると、XMLデータがその目的の定義に準拠していることを検証できます。データはその固有の構造を定義するXML Schemaと照合して検証されます。この定義にはデータ型、許容される項目の出現回数および項目の長さが含まれます。FTPやHTTP(S)などのプロトコルを使用して、XML Schemaに基づく文書をOracle XML DBに格納する場合、XML Schemaの情報は文書の挿入の効率を向上させることができます。事前情報なしにXMLインスタンスを処理しなければならない場合、XML Schemaを使用すると、最適な格納、再現性およびアクセスを予測できます。

構造化されていないXMLデータや半構造化されたデータ、バイナリXMLとして格納されることで構造化されたデータの厳密な型指定など、XML Schemaの利点を活用できます。

XMLデータが高度に構造化されている場合は、オブジェクト・リレーショナル形式で格納することをお薦めします。その場合、XML SchemaはXML(Schema)データ型をSQLデータ型およびオブジェクト・リレーショナルな表および列に効率的にマップするために使用されます。

Oracle XML DBにおけるDTDのサポート

DTDは、XML文書の使用可能な構造を定義する一連の規則です。DTDは、SGMLから書式を導出し、DOCTYPE要素を使用するか、またはDOCTYPE参照を介して外部ファイルを使用してXML文書と関連付けることができるテキスト・ファイルです。オブジェクト・リレーショナル記憶域またはバイナリXML記憶域への構造化マッピングを提供するXML Schemaのサポートに加えて、Oracle XML DBでは、XMLインスタンス・ドキュメントでのDTDの指定もサポートされます。DTDはマッピングの導出には使用されませんが、XMLプロセッサからDTDにアクセスし、解析することはできます。

インラインDTDの定義

XMLインスタンス・ドキュメントにインラインDTDの定義が含まれる場合、その定義はドキュメントの解析時に使用されます。すべてのDTDの検証およびエンティティ宣言の処理は、この時点で行われます。ただし、解析後、実体参照は実際の値で置換され、元の実体参照は失われます。

外部DTDの定義

Oracle XML DBでは、Oracle XML DBリポジトリに格納された外部DTDの定義もサポートされます。/public/flights.dtdなど外部DTDの定義を含むXML文書を処理する必要があるアプリケーションでは、最初に、DTDドキュメントが/public/flights.dtdというパスでOracle XML DBに格納されていることを確認する必要があります。

関連項目:
第21章「Oracle XML DBリポジトリのデータへのアクセス」

DBMS_XMLSCHEMAを使用したXML Schemaの管理

Oracle XML DBでXML Schemaを使用するには、XML SchemaをOracle Databaseに登録しておく必要があります。XML Schemaは、PL/SQLパッケージDBMS_XMLSCHEMAを使用して登録します。

関連項目:
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

DBMS_XMLSCHEMAの主なプロシージャは、次のとおりです。

- registerSchema: XML SchemaをOracle Databaseに登録します。

- deleteSchema: 登録済のXML Schemaを削除します。

- copyEvolve: 登録されたXML Schemaを更新します。第10章「XML Schemaの拡張」を参照してください。

Oracle XML DBへのXML Schemaの登録

プロシージャDBMS_XMLSCHEMA.registerSchemaへの主なパラメータは、次のとおりです。

- SCHEMAURL : XML SchemaのURL。これはOracle XML DB内のXML Schemaに対する一意の識別子です。通常、これはURLの形式ですが、そうでなくてもかまいません。Oracle XML DBでXML SchemaのURLを使用し、スキーマの場所を示すヒントをXML SchemaのURLと一致させることで、インスタンス文書を識別します。Oracle XML DBは、指定したURLで識別されるWebサーバーへのアクセスを試行しません。

注意:
システム定義のXML Schemaと同じSCHEMAURLを使用してXML Schemaを登録することはできません。

- SCHEMADOC: XML Schemaのソース・ドキュメント。この値は、VARCHAR、CLOB、BLOB、BFILE、XMLTypeまたはURITypeです。

- CSID: schemaDocの値がBFILEまたはBLOBの場合の、ソース・ドキュメントのエンコーディングのキャラクタ・セットID。

- OPTIONS: XML Schemaの登録方法を指定するオプション。最も重要なオプションは、REGISTER_BINARYXMLであり、バイナリXML記憶域にXML Schemaが使用されることを示します。もうひとつのオプションはREGISTER_NT_AS_IOTで、これはOCTを索引構成表(IOT)として格納します。

注意:
オプションREGISTER_BINARYXMLを指定する場合は、パラメータGENTYPESもFALSEに設定する必要があります。

関連項目:
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

例7-3のコードは、XML Schemaをhttp://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsdというURLに登録します。この例では、データベース・サーバーのローカル・ファイル・システム上のファイルからソース・ドキュメントを読み取るために、BFILEメカニズムを使用してXML Schemaを登録する方法を示しています。

例7-3 DBMS_XMLSCHEMA.REGISTERSCHEMAを使用したXML Schemaの登録

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd',
SCHEMADOC => bfilename('XMLDIR','purchaseOrder.xsd'),
CSID      => nls_charset_id('AL32UTF8'));
END;
/

XML Schemaを登録する前の文書の削除とリロード

XML Schemaを登録するとき、スキーマを登録しても、XML Schemaを参照するOracle XML DBリポジトリにすでにロードされているインスタンス文書の状態には影響しないことに注意してください。XML Schemaがまだ登録されていなかったため、そのようなインスタンス・ドキュメントは、ロード時にはXML Schemaに基づいていませんでした。それらはスキーマが登録された後も、スキーマに基づかないままです。

スキーマに基づく文書を取得するために、そのようなインスタンス文書は削除し、スキーマの登録後に再ロードする必要があります。

格納とアクセスのインフラストラクチャ

XML Schemaの登録の一部として、Oracle XML DBでは、XML Schemaに準拠するXMLインスタンスの格納、アクセスおよび操作を容易にするいくつかの手順が実行されます。次の手順が含まれます。

- XML Schemaデータ型のOracle XML DB記憶域へのマッピング。XML Schemaに基づくデータが格納される場合、その記憶域データ型はデフォルトのマッピングを使用して(およびオプションで、XML Schema注釈を使用して指定したマッピング情報を使用して)、XML Schemaデータ型から導かれます。バイナリXML記憶域では、XML Schema型はバイナリXMLエンコーディング型にマップされます。オブジェクト・リレーショナル記憶域の場合、XML Schemaの登録により、準拠する文書の構造化記憶域に対する適切なSQLオブジェクト型が作成されます。

- デフォルト表の作成。XML Schema登録により、すべてのグローバル要素のためのデフォルトXMLType表が生成されます。XML Schema注釈を使用すると、表の名前を制御し、表の作成中に使用される列レベルおよび表レベルのSTORAGE句と制約を指定できます。

関連項目:

- XML Schemaデータ型のOracle XML DB記憶域へのマッピング

- 「XML Schemaの登録時に作成されるデフォルト表」

- 「OracleでのXML Schemaの注釈」

XML Schemaの登録後は、XML Schemaインスタンス・メカニズムを使用してXML Schemaを参照する文書を、Oracle XML DBで自動的に処理できます。オブジェクト・リレーショナル形式で格納されるXMLデータの場合、XML Schemaによって定義されたグローバル要素に限定したXMLType表および列を作成できます。

関連項目:
第3章「Oracle XML DBの使用」

XML Schema登録の基本性質

すべてのDDL操作と同様に、XML Schema登録は、非トランザクション的なものです。しかし、登録は、次の意味において、アトミックです。

- 登録が正常に終了した場合、操作は自動コミットされます。

- 登録が失敗した場合、データベースは登録開始前の状態にロールバックされます。

XML Schemaの登録では、オブジェクト型および表が作成される可能性があるため、エラー・リカバリでは作成されたすべての型と表が削除されます。XML Schemaの登録プロセス全体はアトミックであることが保証されます。つまり、正常に終了するか、またはデータベースが登録の開始前の状態に復元されます。

XML Schemaの管理および格納

XML Schema文書自体は、XMLTypeインスタンスとしてOracle XML DBに格納されます。XML Schema関連のXMLType型および表は、Oracle XML DBのインストール・スクリプトcatxdbs.sqlの一部として作成されます。

Oracle XML DBのXML Schemaに対するXML Schemaを、ルートXML Schema XDBSchema.xsdといいます。ルートXML Schemaは、Oracle XML DBで登録できる妥当なXML Schemaを記述しています。Oracle XML DBリポジトリの場所で、/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBSchema.xsdにあるXDBSchema.xsdにアクセスできます。

関連項目:
第34章「Oracle XML DBの管理」

オブジェクト・リレーショナル形式で格納されたXMLデータのためのXML Schema登録のデバッグ

オブジェクト・リレーショナル形式で格納されるXMLデータの場合、PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaを起動する前に次のイベントを設定することで、XML Schema登録で作成されるオブジェクト型および表を監視できます。

ALTER SESSION SET EVENTS = '31098 TRACE NAME CONTEXT FOREVER'

このイベントを設定することで、すべてのCREATE TYPEおよびCREATE TABLE文のログが生成されます。このログは、ユーザー・セッション・トレース・ファイルに書き込まれます。このファイルは通常ORACLE_BASE/diag/rdbms/ORACLE_SID/ORACLE_SID/udumpにあります。このスクリプトは、XML Schemaの登録中の問題を診断するために役立ちます。

関連項目:
「Oracle XML DBでのXML Schemaの使用」

構造化記憶域に対してXML Schema登録時に作成されるSQLデータ型

XML Schemaがオブジェクト・リレーショナル形式で格納されたXMLデータとともに使用するために登録された場合、パラメータGENTYPESがTRUEだと、Oracle XML DBは、準拠XML文書の構造化格納を可能にする適切なSQLオブジェクト型を作成します。デフォルトでは、SQLオブジェクト型はXML Schema登録者のデータベース・スキーマに作成されます。注釈xdb:defaultSchemaが使用されている場合は、Oracle XML DBによって、指定されたデータベース・スキーマを使用してオブジェクト型の作成が試行されます。現行のユーザーがこのオブジェクト型を作成するには、必要な権限を取得している必要があります。

例7-4に、XML Schema purchaseOrder.xsdがOracle XML DBで登録された場合に自動的に作成されるSQLデータ型を示します。

例7-4 XMLType表を格納するためのSQLオブジェクト型の作成

DESCRIBE "PurchaseOrderType1668_T"

"PurchaseOrderType1668_T" is NOT FINAL
Name                 Null?  Type
-------------------- ------ -------------------------------
SYS_XDBPD$                  XDB.XDB$RAW_LIST_T
Reference                   VARCHAR2(30 CHAR)
Actions                     ActionsType1661_T
Reject                      RejectionType1660_T
Requestor                   VARCHAR2(128 CHAR)
User                        VARCHAR2(10 CHAR)
CostCenter                  VARCHAR2(4 CHAR)
ShippingInstructions        ShippingInstructionsTyp1659_T
SpecialInstructions         VARCHAR2(2048 CHAR)
LineItems                   LineItemsType1666_T
Notes                       VARCHAR2(4000 CHAR)

DESCRIBE "LineItemsType1666_T"

"LineItemsType1666_T" is NOT FINAL
Name                 Null? Type
-------------------- ----- -------------------------------
SYS_XDBPD$                 XDB.XDB$RAW_LIST_T
LineItem                   LineItem1667_COLL

DESCRIBE "LineItem1667_COLL"

"LineItem1667_COLL" VARRAY(2147483647) OF LineItemType1665_T
"LineItemType1665_T" is NOT FINAL
Name                Null? Type
------------------- ----- --------------------------------
SYS_XDBPD$                XDB.XDB$RAW_LIST_T
ItemNumber                NUMBER(38)
Description               VARCHAR2(256 CHAR)
Part                      PartType1664_T

注意:
デフォルトでは、SQLオブジェクト型および属性の名前はシステム生成されます。例7-4がその例です。XML SchemaにSQLName属性が含まれていない場合、SQL名はXMLの名前から導出されます。XML Schema注釈を使用すると、ユーザー定義の名前を使用できます(詳細は、「OracleでのXML Schemaの注釈」を参照してください)。

XML Schemaの登録時に作成されるデフォルト表

デフォルト表は、XMLデータのためのXML Schemaの登録の一部として作成できます。このXML Schemaに準拠する文書が、FTPやHTTP(S)など、表が指定されないAPIおよびプロトコルを介して挿入される場合、デフォルト表が非常に役立ちます。この場合、XMLインスタンスはデフォルト表に挿入されます。

例7-5 グローバル要素PurchaseOrderのデフォルト表

DESCRIBE "purchaseorder1669_tab"

Name                        Null? Type
--------------------------- ----- -----------------------
TABLE of
SYS.XMLTYPE(
XMLSchema "http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd"
Element "PurchaseOrder")
STORAGE OBJECT-RELATIONAL TYPE "PurchaseOrderType1668_T"

属性xdb:defaultTableに値を指定すると、その名前でXMLType表が作成されます。それ以外の場合は、内部生成された名前で作成されます。

xdb:tablePropsおよびxdb:columnProps属性を使用して指定されたすべてのテキストが、生成されたCREATE TABLE文に追加されます。

XML Schemaの登録時に生成された内部構造体を使用しない

一般に、XML Schemaの登録時に生成されたSQL構造体は、Oracle XML DB内部にあります。これらをコードで使用しないことをお薦めします。

正確に言うと、生成されたSQLデータ型、ネストされた表、およびに表外の記憶域に関連付けられている表はすべて内部です。これらは、Oracleによっていつでも変更および再定義される、特定のXMLスキーマとオブジェクト・タイプのマッピングに基づいています。

一般的に次が成立します。

- 生成されたSQLデータ型は使用しないでください。

- 生成されたネストされた表または表外へのアクセスまたは変更は行わないでください。

ただし、生成された表のパーティション化などの記憶域オプションは変更できます。また、生成された表に対して索引または制約を作成することはできます。また、利便性のために名前が生成された制約など、Oracle XML DBに付属するXML Schema注釈は自由に使用できます。

大/小文字が区別される生成名

XML Schemaの登録で生成されたSQL表、オブジェクト、属性の名前は、大/小文字が区別されます。たとえば、例7-3では、XML Schema登録時にPurchaseOrder1669_TABという表が自動的に作成されています。この表名は要素名PurchaseOrderから導出されるため、表の名前も大/小文字が混在しています。このため、SQLコードでこの表を参照する際に識別子に引用符を使用("PurchaseOrder1669_TAB")する必要があります。使用しないと、ORA-00942: 表またはビューが存在しませんなどの、オブジェクトが見つからないというエラーが発生します。

登録されたXML Schemaに依存するデータベース・オブジェクト

次のデータベース・オブジェクトは、登録されたXML Schemaに依存します。

- XML Schemaの要素に準拠するXMLType列が含まれる表またはビュー。

- 定義の一部として指定のXML Schemaが含まれるか、またはインポートされるXML Schema。

- XML Schemaを参照するカーソル。これには、パッケージDBMS_XMLGENのファンクション内部の参照が含まれます。このようなカーソルは、一時オブジェクトです。

登録されているすべてのXML Schemaのリスト

例7-6に、PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaを使用してOracle XML DBで登録されているすべてのXML Schemaのリストを取得する方法を示します。ビューUSER_XML_SCHEMAS、ALL_XML_SCHEMAS、USER_XML_TABLESおよびALL_XML_TABLESも調べることができます。

例7-6 登録されたスキーマのデータ・ディクショナリ表

DESCRIBE DBA_XML_SCHEMAS

Name         Null? Type
------------ ----- -----------------------
OWNER              VARCHAR2(30)
SCHEMA_URL         VARCHAR2(700)
LOCAL              VARCHAR2(3)
SCHEMA             XMLTYPE(XMLSchema "http://xmlns.oracle.com/xdb/XDBSchema.xsd"
Element "schema")
INT_OBJNAME        VARCHAR2(4000)
QUAL_SCHEMA_URL    VARCHAR2(767)
HIER_TYPE          VARCHAR2(11)
BINARY             VARCHAR2(3)
SCHEMA_ID          RAW(16)
HIDDEN             VARCHAR2(3)

SELECT OWNER, LOCAL, SCHEMA_URL FROM DBA_XML_SCHEMAS;

OWNER   LOC   SCHEMA_URL
-----   ---   ----------------------
XDB     NO    http://xmlns.oracle.com/xdb/XDBSchema.xsd
XDB     NO    http://xmlns.oracle.com/xdb/XDBResource.xsd
XDB     NO    http://xmlns.oracle.com/xdb/acl.xsd
XDB     NO    http://xmlns.oracle.com/xdb/dav.xsd
XDB     NO    http://xmlns.oracle.com/xdb/XDBStandard.xsd
XDB     NO    http://xmlns.oracle.com/xdb/log/xdblog.xsd
XDB     NO    http://xmlns.oracle.com/xdb/log/ftplog.xsd
XDB     NO    http://xmlns.oracle.com/xdb/log/httplog.xsd
XDB     NO    http://www.w3.org/2001/xml.xsd
XDB     NO    http://xmlns.oracle.com/xdb/XDBFolderListing.xsd
XDB     NO    http://xmlns.oracle.com/xdb/stats.xsd
XDB     NO    http://xmlns.oracle.com/xdb/xdbconfig.xsd
SCOTT   YES   http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd

13 rows selected.

DESCRIBE DBA_XML_TABLES

Name         Null? Type
------------ ----- -----------------------
OWNER              VARCHAR2(30)
TABLE_NAME         VARCHAR2(30)
XMLSCHEMA          VARCHAR2(700)
SCHEMA_OWNER       VARCHAR2(30)
ELEMENT_NAME       VARCHAR2(2000)
STORAGE_TYPE       VARCHAR2(17)
ANYSCHEMA          VARCHAR2(3)
NONSCHEMA          VARCHAR2(3)

SELECT TABLE_NAME FROM DBA_XML_TABLES
WHERE XMLSCHEMA = 'http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd';

TABLE_NAME
---------------------
PurchaseOrder1669_TAB

1 row selected.

XML Schemaの削除

プロシージャDBMS_XMLSCHEMA.deleteSchemaを使用すると、登録されたXML Schemaを削除できます。これにより、次のことが行われます。

1. 現行のユーザーが、Oracle XML DBリポジトリ内のXML Schemaに対応するリソースを削除するための適切な権限を取得していることが確認されます。XML Schemaのリソースに適切なACLを設定することによって、各ユーザーが削除できるXML Schemaを制御できます。

2. 削除されるXML Schemaに依存する表がないかどうかが確認されます。そうした表がある場合は、エラーを表示して削除をキャンセルします。この確認は、オプションdelete_invalidateまたはdelete_cascade_forceの使用時には実行されません。その場合は、エラーは発生しません。

3. Oracle XML DBリポジトリ(フォルダ/sys/schemas)からXML Schema文書を削除します。

4. XML Schema文書がバイナリXMLインスタンスで使用されるために登録されていて、delete_invalidateとdelete_cascade_forceのいずれも使用されない場合を除き、DBA_XML_SCHEMASからXML Schema文書を削除します。

5. delete_cascadeまたはdelete_cascade_forceのいずれかが使用される場合は、デフォルト表をドロップします。delete_cascade_forceが指定されていて、XML Schemaにも依存している他の表にインスタンスがある場合、エラーが発生します。

DBMS_XMLSCHEMA.DELETESCHEMAオプション

プロシージャDBMS_XMLSCHEMA.deleteSchemaのオプションDELETE_OPTIONでは次の値を使用可能です。

- DELETE_RESTRICT: 依存関係が検知されると、エラーを表示し、削除をキャンセルします。これがデフォルトの動作です。

- DELETE_INVALIDATE: 依存関係が検知されてもエラーを表示しません。そのかわり、各依存関係に無効のマークを付けます。

- DELETE_CASCADE: XML Schema登録時に生成されたすべての型とデフォルト表を削除します。デフォルト表以外の表に格納されているXML Schemaに依存するインスタンスがある場合は、エラーを表示します。ただし、ANY_SCHEMAを使用して作成されたXMLType列に格納されているインスタンスについては、そのような場合もエラーを表示しません。バイナリXMLで使用するXML Schemaが登録されている場合は、DBA_XML_SCHEMASからXML Schemaを削除しません。

- DELETE_CASCADE_FORCE: XML Schema登録時に生成されたすべての型とデフォルト表を削除します。デフォルト表以外の表に格納されているXML Schemaに依存するインスタンスがある場合は、エラーを表示しません。そのかわり、各依存関係に無効のマークを付けます。XML SchemaをDBA_XML_SCHEMASから削除します。

関連項目:
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

例7-7はDELETE_CASCADE_FORCEの使用方法を示しています。

例7-7 DBMS_XMLSCHEMA.DELETESCHEMAを使用したXML Schemaの削除

BEGIN
DBMS_XMLSCHEMA.deleteSchema(
SCHEMAURL => 'http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd',
DELETE_OPTION => DBMS_XMLSCHEMA.DELETE_CASCADE_FORCE);
END;
/

バイナリXMLで使用するXML Schemaが登録されている場合、オプションDELETE_RESTRICT(デフォルト値)またはDELETE_CASCADEを使用してXML Schemaを削除しても、DBA_XML_SCHEMASからは削除されません。その結果、XML Schemaを使用して新しいXMLインスタンス・ドキュメントをエンコードすることはできませんが、XML Schemaを参照するOracle XML DB内の既存のドキュメントは、引き続きXML Schemaを使用してデコードできます。

この状況は、DBMS_XMLSCHEMA.purgeSchemaを使用してDBA_XML_SCHEMASからXML Schemaを削除するまで続きます。一般的には、delete_restrictまたはdelete_cascadeを使用することをお薦めします。そのXML Schemaが完全に不要であると確信している場合、DELETE_CASCADE_FORCEでなく、DBMS_XMLSCHEMA.purgeSchemaをコールしてください。

プロシージャpurgeSchemaは、Oracle XML DBからXML Schemaを完全に削除します。特に、DBA_XML_SCHEMASから削除します。DBMS_XMLSCHEMA.purgeSchemaを使用する前に、消去されるXML Schemaを参照している既存のすべてのXML文書が、別のXML Schemaを参照するか、XML Schemaを参照しないように変換されていることを確認してください。そうしない場合、消去後にそれらの文書をデコードできなくなります。

XMLTypeのXML Schema関連メソッド

表7-1に、XML Schemaを操作する際に役立つXMLTypeメソッドを示します。

表7-1 XMLTypeのXML Schema関連メソッド

XMLTypeのメソッド

説明

isSchemaBased()

XMLTypeインスタンスがXML Schemaに基づいている場合は、TRUEが戻されます。それ以外の場合は、FALSEが戻されます。

getSchemaURL()

XMLTypeインスタンスのXML Schema URL。

schemaValidate()
isSchemaValid()
isSchemaValidated()
setSchemaValidated()

XMLTypeインスタンスを登録されたXML Schemaに対して検証します。

第11章「XMLTypeデータの変換および検証」を参照してください。

ローカルXML SchemaおよびグローバルXML Schema

XML Schemaは、ローカルまたはグローバルとして登録できます。

- ローカルなXML Schemaは、デフォルトでは所有者のみが参照できます。

- グローバルなXML Schemaは、デフォルトではすべてのデータベース・ユーザーが参照および使用できます。

XML Schemaを登録する場合、PL/SQLパッケージDBMS_XMLSCHEMAはOracle XML DBリポジトリに対応するリソースを追加します。XML SchemaのURLにより、リポジトリ内のXML Schemaリソースのパス名を判断します(また、PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaのパラメータSCHEMAURLにも関連付けられます)。

注意:
Oracle Enterprise Managerでは、ローカルおよびグローバルに登録されたXML Schemaは、それぞれプライベートおよびパブリックと呼ばれます。

ローカルXML Schema

デフォルトでは、XML SchemaをOracle XML DBに登録すると、登録したユーザーがこのXML Schemaの所有者になります。XML Schema文書への参照は、Oracle XML DBリポジトリに格納されます。このようなXML Schemaは、ローカルとして参照されます。デフォルトでは、これらのスキーマは、所有者であるユーザーのみが使用できます。Oracle XML DBでは、ローカルXML Schemaのリソースは、フォルダ/sys/schemas/usernameに作成されます。残りのリポジトリのパス名は、スキーマのURLから導出されます。

例7-8 ローカルXML Schemaの登録

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd',
SCHEMADOC => bfilename('XMLDIR','purchaseOrder.xsd'),
LOCAL     => TRUE,
GENTYPES  => TRUE,
GENTABLES => FALSE,
CSID      => nls_charset_id('AL32UTF8'));
END;
/

ユーザーQUINEがこのローカルXML Schemaを登録すると、次のパス名が指定されます。

/sys/schemas/QUINE/xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd

データベース・ユーザーがXML SchemaをローカルXML Schemaとして登録するには、このパス名でリソースを作成するための適切な権限およびアクセス制御リスト(ACL)が必要です。

関連項目:
第27章「リポジトリのアクセス制御」

注意:
通常、XMLType表、列またはビューの定義、文書の検証などにXML Schemaを使用できるのは、このXML Schemaの所有者のみです。ただし、Oracle XML DBでは、完全修飾されたXML Schema URLをサポートしています。例: http://xmlns.oracle.com/xdb/schemas/QUINE/xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd。権限のあるユーザーは、この拡張URLを使用して、他のユーザーが所有するXML Schemaを指定できます。

グローバルXML Schema

ローカル・スキーマとは異なり、権限のあるユーザーは、DBMS_XMLSCHEMA登録ファンクションで引数を指定することにより、XML SchemaをグローバルXML Schemaとして登録できます。グローバルXML Schemaはすべてのユーザーが参照できます。これはOracle XML DBリポジトリのフォルダ/sys/schemas/PUBLIC/に格納されます。

注意:
フォルダ/sys/schemas/PUBLICへのアクセスはアクセス制御リスト(ACL)で制御されます。デフォルトでは、このフォルダにはデータベース管理者のみが書込み可能です。グローバルXMLスキーマを登録するには、このフォルダに対する書込み権限が必要です。このフォルダがデフォルトACLによって保護されている場合は、ロールXDBADMINによってこのディレクトリへの書込み権限も提供されます。第27章「リポジトリのアクセス制御」を参照してください。

ローカル・スキーマは、既存のグローバル・スキーマと同じURLに登録できます。ローカル・スキーマは、常に同じ名前(URL)を持つグローバル・スキーマを非表示にします。例7-9に、グローバル・スキーマの登録を示します。

例7-9 グローバルXML Schemaの登録

GRANT XDBADMIN TO QUINE;

Grant succeeded.

CONNECT quine
Enter password: password

Connected.

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd',
SCHEMADOC => bfilename('XMLDIR','purchaseOrder.xsd'),
LOCAL     => FALSE,
GENTYPES  => TRUE,
GENTABLES => FALSE,
CSID      => nls_charset_id('AL32UTF8'));
END;
/

ユーザーQUINEがこのグローバルXML Schemaを登録すると、次のパス名が指定されます。

/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd

データベース・ユーザーがXML Schemaをグローバルとして登録するには、このリソースを作成するための適切な権限(ACLアクセス)が必要です。

DOM再現性

ドキュメント・オブジェクト・モデル(DOM)の再現性とは、DOM検索のために、取得されたXML文書を元のXML文書と同じ構造に保持するという概念です。DOM再現性は、Oracle XML DBに格納されたXML文書の精度および整合性を保証するために必要です。

関連項目:

- 「属性を宣言する際のXML Schema内のSQLType値のオーバーライド」

- 「要素を宣言する際のXML Schema内のSQLType値のオーバーライド」

DOM再現性の概要

DOM再現性は、XMLドキュメント内のすべての情報が、無意味な空白を除いて維持されていることを意味します。DOM再現性がある場合、データベースから取得されたXMLデータは、無意味な空白のみを除いて、データベースに挿入される前と同一の情報を持ちます。「DOM再現性」という用語が使用されるのは、この種類の再現性はDOM検索で特に重要だからです。

XMLデータのバイナリXML記憶域では、重要な情報のすべてがバイナリXML形式にエンコードされ、DOM再現性を保証しています。XMLデータの構造化記憶域では、XML Schemaで宣言された要素および属性は、対応するSQLオブジェクト型の個別の属性にマップされます。ただし、XMLインスタンス・ドキュメント内の次の情報は、これらのオブジェクト属性に格納されません。

- 名前空間宣言

- コメント

- 接頭辞情報

そのかわりに、Oracle XML DBは別の機構を使用してこの情報を追跡し、インスタンス・レベルのメタデータとして記録します。

SYS_XDBPD$と構造化記憶域のDOM再現性

オブジェクト・リレーショナル形式で格納されたXMLデータのDOM再現性を提供するために、Oracle XML DBでは、インスタンス・レベルのメタデータを保持します。このメタデータは、システム定義のバイナリ・オブジェクト属性SYS_XDBPD$を使用して型レベルで追跡されます。このオブジェクト属性を位置指定ディスクリプタまたは短縮してPDと呼びます。PDは、Oracle XML DBの内部でのみ使用する属性です。列PDに直接アクセスしたり、操作しないでください。

他のオブジェクト属性に格納できない情報はすべて、この位置指定ディスクリプタによって格納されます。Oracle XML DBに格納されたすべてのXML文書のDOM再現性を保証するために、PD情報が使用されます。PD情報には、たとえば注文情報、コメント、処理命令、名前空間の接頭辞などがあります。

DOM再現性が不要な場合は、型レベルでXML Schema定義のxdb:maintainDOM属性をfalseに設定し、SYS_XDBPD$の使用を省略できます。

注意:
このマニュアルの多くの例では、簡略化のためSYS_XDBPD$オブジェクト属性を省略しています。ただし、この属性は、XML Schemaの登録処理によって生成されたすべてのSQLオブジェクト型に、位置指定ディスクリプタ(PD)列として常に存在します。
通常は、PD属性を省略しないことをお薦めします。PD列が存在しない場合、コメント、処理命令などの情報が失われる可能性があるためです。

XML変換

Oracle XML DBリポジトリ内のXML文書をXMLTypeインスタンスとして格納できます。これらのインスタンスには、構造化記憶域モデル(オブジェクト・リレーショナル記憶域)、非構造化記憶域モデル(CLOB)、およびバイナリXML記憶域モデルから任意のモデルを使用できます。これらの文書には、様々な(自然)言語に翻訳しなければならない文字列が含まれている場合があります。通常は、元の文字列とその翻訳を両方ともリポジトリに格納します。ユーザーの言語設定に応じて、これらの文字列を取得および操作できます。

注意:
オブジェクト・リレーショナル形式で格納されたXML Schemaは変換できません。

変換のためのXML SchemaとXMLインスタンス・ドキュメントの変更

この項では、XML Schemaと関連のXMLインスタンス・ドキュメントを変換可能にするためにそれらに加える必要がある変更について説明します。

XML Schema内での変換可能な要素の指示

XML Schema内で、変換する要素ごとに属性xdb:translateを指定する必要があります。属性xdb:translateには、次の制限が適用されます。

1. 属性xdb:translateは、simpleContentを持つcomplexType要素にのみ指定できます。ここで、simpleContentは、string型の拡張または制限である必要があります。ただし、complexType要素にxdb:translateフラグが設定されている場合、その子孫にはこのフラグを設定できません。

2. 属性xdb:translateは、単一値要素(1つだけの変換を持つ要素)にのみ設定できます。そのような要素の場合、maxoccursの値は0または1である必要があります。この属性を複数値要素に設定する場合、要素を一意に識別するID属性を要素が持つ必要があります。

XML Schemaの登録時に、PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaは、XML Schemaがこれらの制限を満たしているかを確認します。

XMLインスタンス・ドキュメント内での変換言語属性の指示

次の変換言語属性がサポートされています。

- xml:lang: 変換をサポートするXML Schemaに関連付けられたインスタンス・ドキュメントには、変換言語を指定する必要があります。これは、変換のたびに属性xml:langを使用して注釈を付けることで指定できます。属性xml:langで使用できる値は、IETF RFC 3066で識別される言語識別子です。

- xdb:srclang: 複数値要素、つまり、複数の変換を持つことができる要素には、1つの変換のみをソース言語変換として使用できます。この変換は、属性xdb:srclangによって指定されます。これは、セッション言語が指定されていない場合に戻されるデフォルトの変換です。

XML文書を変換可能にする方法

この項では、変換を指定するXML Schema属性を使用して、サンプル・ドキュメント内の要素を変換可能にします。例7-10は、変換可能でなければならないタイトル文字列を含むドキュメントを定義するXML Schemaを示します。

例7-10 変換の必要があるタイトルを含むドキュメントを定義するXML Schema

<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xdbsc="http://xmlns.oracle.com/xdb/security.xsd"
xmlns:xdb="http://xmlns.oracle.com/xdb.xsd"
targetNamespace="http://xmlns.oracle.com/xdb/security.xsd"
elementFormDefault="qualified" version="1.0">
<annotation>
<documentation>
This XML schema describes the structure of Security Class documents.
</documentation>
</annotation>
<element name="securityClass" xdb:defaultTable="">
<complexType>
<sequence>
<element name="name" type="string"/>
<element name="title" minOccurs="0" maxOccurs="unbounded"/>
<element name="inherits-from" type="QName" minOccurs="0" maxOccurs="unbounded"/>
<element name="privlist" minOccurs="0" maxOccurs="unbounded">
<complexType>
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="xdbsc:privilege"/>
<element ref="xdbsc:aggregatePrivilege"/>
</choice>
</complexType>
</element>
<!-- this "any" contains all application specific information
for a security class in general e.g. reason for creation  -->
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="targetNamespace" type="anyURI" use="required"/>
<!-- all privileges in this security class are under this target namespace -->
</complexType>
</element>
<element name="aggregatePrivilege">
<complexType>
<sequence>
<element name="title" minOccurs="0" maxOccurs="unbounded"/>
<sequence maxOccurs="unbounded">
<element name="privilegeRef">
<complexType>
<attribute name="name" type="QName" use="required"/>
</complexType>
</element>
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<!-- this "any" contains all application specific information
an aggregate privilege e.g. translations  -->
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="string" use="required"/>
</complexType>
</element>
<element name="privilege">
<complexType>
<sequence minOccurs="0">
<element name="title" minOccurs="0" maxOccurs="unbounded"/>
<sequence minOccurs="0" maxOccurs="unbounded">
<element name="columnRef">
<complexType>
<attribute name="schema" type="string" use="required"/>
<attribute name="table" type="string" use="required"/>
<attribute name="column" type="string" use="required"/>
</complexType>
</element>
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<!-- this "any" contains all application specific information
for a privilege e.g. translations  -->
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="string" use="required"/>
</complexType>
</element>
</schema>

例7-11は、例7-10のXML Schemaに関連付けられるドキュメントを示します。

例7-11 変換されていないインスタンス・ドキュメント

<securityClass xmlns="http://xmlns.oracle.com/xdb/security.xsd"
xmlns:is="xmlns.oracle.com/iStore"
xmlns:oa="xmlns.oracle.com/OracleApps"
targetNamespace="xmlns.oracle.com/example">
<name>
securityClassExample
</name>
<title>
Security Class Example
</title>
<inherits-from>is:iStorePurchaseOrder</inherits-from>
<privlist>
<privilege name="privilege1"/>
<aggregatePrivilege name="iStorePOApprover">
<title>
iStore Purchase Order Approver
</title>
<privilegeRef name="is:privilege1"/>
<privilegeRef name="oa:submitPO"/>
<privilegeRef name="oa:privilege3"/>
</aggregatePrivilege>
<privilege name="privilege2">
<title>
secondary privilege
</title>
<columnRef schema="APPS" table="PurchaseOrder" column="POId"/>
<columnRef schema="APPS" table="PurchaseOrder" column="Amount"/>
</privilege>
</privlist>
</securityClass>

最上位のタイトルを変換可能にするには、xdb:translateをtrueに設定します。これは、単一値要素(xdb:maxOccursが1)です。例7-12は、属性xdb:translateがtrueに設定されている新規のXML Schemaを示します。

例7-12 単一値要素の属性xdb:translateを含むXML Schema

<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xdbsc="http://xmlns.oracle.com/xdb/security.xsd"
xmlns:xdb="http://xmlns.oracle.com/xdb.xsd"
targetNamespace="http://xmlns.oracle.com/xdb/security.xsd"
elementFormDefault="qualified" version="1.0">
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
<xs:import namespace-"http://xmlns.oracle.com/xdb"
schemaLocation="http://xmlns.oracle.com/xdb/xmltr.xsd"/>
<annotation>
<documentation>
This XML schema describes the structure of Security Class documents.
</documentation>
</annotation>
<element name="securityClass" xdb:defaultTable="">
<complexType>
<sequence>
<element name="name" type="string"/>
<element ref="titleref" minOccurs="0" maxOccurs="unbounded"
xdb:maxOccurs="1" xdb:translate="true"/>
<element name="inherits-from" type="QName" minOccurs="0" maxOccurs="unbounded"/>
<element name="privlist" minOccurs="0" maxOccurs="unbounded" xdb:maxOccurs="1">
<complexType>
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="xdbsc:privilege"/>
<element ref="xdbsc:aggregatePrivilege"/>
</choice>
</complexType>
</element>
<!-- this "any" contains all application specific information
for a security class in general e.g. reason for creation  -->
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="targetNamespace" type="anyURI" use="required"/>
<!-- all privileges in this security class are under this target namespace -->
</complexType>
</element>
<element name="aggregatePrivilege">
<complexType>
<sequence>
<element name="title" minOccurs="0" maxOccurs="unbounded"/>
<sequence maxOccurs="unbounded">
<element name="privilegeRef">
<complexType>
<attribute name="name" type="QName" use="required"/>
</complexType>
</element>
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<!-- this "any" contains all application specific information
an aggregate privilege e.g. translations  -->
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="string" use="required"/>
</complexType>
</element>
<element name="privilege">
<complexType>
<sequence minOccurs="0">
<element name="title" minOccurs="0" maxOccurs="unbounded"/>
<sequence minOccurs="0" maxOccurs="unbounded">
<element name="columnRef">
<complexType>
<attribute name="schema" type="string" use="required"/>
<attribute name="table" type="string" use="required"/>
<attribute name="column" type="string" use="required"/>
</complexType>
</element>
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<!-- this "any" contains all application specific information
for a privilege e.g. translations  -->
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="string" use="required"/>
</complexType>
</element>
<element name="titleref">
<complexType>
<simpleContent>
<extension base="xs:string">
<attribute ref="xml:lang"/>
<attribute ref="xdb:srclang"/>
</extension>
</simpleContent>
</complexType>
</element>
</schema>

例7-13は、タイトル・テキストを変換した後のインスタンス・ドキュメントを示します。

例7-13 変換後のドキュメント

<securityClass xmlns="http://xmlns.oracle.com/xdb/security.xsd"
xmlns:is="xmlns.oracle.com/iStore"
xmlns:oa="xmlns.oracle.com/OracleApps">
<name>
securityClassExample
</name>
<title xml:lang="en" xdb:srclang="true">
Security Class Example
</title>
<title xml:lang="es">
Security Class Example - Spanish
</title>
<title xml:lang="fr">
Security Class Example - French
</title>
<inherits-from>is:iStorePurchaseOrder</inherits-from>
<privlist>
<privilege name="privilege1"/>
<aggregatePrivilege name="iStorePOApprover">
<title>
iStore Purchase Order Approver
</title>
<privilegeRef name="is:privilege1"/>
<privilegeRef name="oa:submitPO"/>
<privilegeRef name="oa:privilege3"/>
</aggregatePrivilege>
<privilege name="privilege2">
<title>
secondary privilege
</title>
<columnRef schema="APPS" table="PurchaseOrder" column="POId"/>
<columnRef schema="APPS" table="PurchaseOrder" column="Amount"/>
</privilege>
</privlist>
</securityClass>

複数値要素の場合にタイトルを変換可能にするには、xdb:maxOccursをunboundedに設定します。ただし、xdb:translateは、各要素を一意に識別する識別子属性がないかぎり、複数値要素用にtrueに設定できません。例7-14は、title要素に識別子属性idを使用するXML Schemaを示します。

例7-14 複数値要素の属性xdb:translateを含むXML Schema

<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xdbsc="http://xmlns.oracle.com/xdb/security.xsd"
xmlns:xdb="http://xmlns.oracle.com/xdb.xsd"
targetNamespace="http://xmlns.oracle.com/xdb/security.xsd"
elementFormDefault="qualified" version="1.0">
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
<xs:import namespace-"http://xmlns.oracle.com/xdb"
schemaLocation="http://xmlns.oracle.com/xdb/xmltr.xsd"/>
<annotation>
<documentation>
This XML schema describes the structure of Security Class documents.
</documentation>
</annotation>
<element name="securityClass" xdb:defaultTable="">
<complexType>
<sequence>
<element name="name" type="string"/>
<element name="title" minOccurs="0" maxOccurs="unbounded" xdb:maxOccurs="1"/>
<element name="inherits-from" type="QName" minOccurs="0" maxOccurs="unbounded"/>
<element name="privlist" minOccurs="0" maxOccurs="unbounded" xdb:maxOccurs="1">
<complexType>
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="xdbsc:privilege"/>
<element ref="xdbsc:aggregatePrivilege"/>
</choice>
</complexType>
</element>
<!-- this "any" contains all application specific information
for a security class in general e.g. reason for creation  -->
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="targetNamespace" type="anyURI" use="required"/>
<!-- all privileges in this security class are under this target namespace -->
</complexType>
</element>
<element name="aggregatePrivilege">
<complexType>
<sequence>
<element name="titleref" minOccurs="0" maxOccurs="unbounded"
xdb:maxoccurs="unbounded" xdb:translate="true"/>
<sequence maxOccurs="unbounded">
<element name="privilegeRef">
<complexType>
<attribute name="name" type="QName" use="required"/>
</complexType>
</element>
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<!-- this "any" contains all application specific information
an aggregate privilege e.g. translations  -->
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="string" use="required"/>
</complexType>
</element>
<element name="privilege">
<complexType>
<sequence minOccurs="0">
<element name="titleref" minOccurs="0" maxOccurs="unbounded"
xdb:maxoccurs="unbounded" xdb:translate="true"/>
<sequence minOccurs="0" maxOccurs="unbounded">
<element name="columnRef">
<complexType>
<attribute name="schema" type="string" use="required"/>
<attribute name="table" type="string" use="required"/>
<attribute name="column" type="string" use="required"/>
</complexType>
</element>
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<!-- this "any" contains all application specific information
for a privilege e.g. translations  -->
<any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="string" use="required"/>
</complexType>
</element>
<element name="titleref">
<complexType>
<simpleContent>
<extension base="xs:string">
<attribute ref="xml:lang"/>
<attribute ref="xdb:srclang"/>
<attribute name="id" type="integer"/>
</extension>
</simpleContent>
</complexType>
</element>
</schema>

例7-15は、例7-14のXML Schemaに関連付けられたドキュメントを示します。

例7-15 複数値要素を持つXML Schemaの変換済ドキュメント

<securityClass xmlns="http://xmlns.oracle.com/xdb/security.xsd"
xmlns:is="xmlns.oracle.com/iStore"
xmlns:oa="xmlns.oracle.com/OracleApps">
<name>
securityClassExample
</name>
<title>
Security Class Example
</title>
<inherits-from>is:iStorePurchaseOrder</inherits-from>
<privlist>
<privilege name="privilege1"/>
<aggregatePrivilege name="iStorePOApprover">
<title>
iStore Purchase Order Approver
</title>
<privilegeRef name="is:privilege1"/>
<privilegeRef name="oa:submitPO"/>
<privilegeRef name="oa:privilege3"/>
</aggregatePrivilege>
<privilege name="privilege2">
<title id="2" xml:lang="en" xdb:srclang="true">
secondary privilege - english
</title>
<title id="1" xml:lang="fr">
primary privilege - french
</title>
<title id="1" xml:lang="en" xdb:srclang="true">
primary privilege - english
</title>
<columnRef schema="APPS" table="PurchaseOrder" column="POId"/>
<columnRef schema="APPS" table="PurchaseOrder" column="Amount"/>
</privilege>
</privlist>
</securityClass>

変換済のドキュメントに対する操作

変換済のドキュメントに対しては、次の操作を実行できます。

- 挿入: 変換をサポートするXML Schemaにドキュメントが準拠する場合は、それをOracle XML DBに挿入できます。変換を含むドキュメントに対しては、言語情報を提供するか、セッション言語変換を使用できます。

- ドキュメントに言語情報が含まれず、属性xml:langが設定されていない場合、変換にはセッション言語が使用されます。例7-16は、セッション言語が日本語のドキュメントを表します。属性xml:langはsession languageに設定され、属性xdb:srclangはtrueに設定されています。

例7-16 言語情報のないドキュメントの挿入

<securityClass xmlns="http://xmlns.oracle.com/xdb/security.xsd"
xmlns:is="xmlns.oracle.com/iStore"
xmlns:oa="xmlns.oracle.com/OracleApps"
targetNamespace="xmlns.oracle.com/example">
<name>
securityClassExample
</name>
<title>
Security Class Example
</title>
<inherits-from>is:iStorePurchaseOrder</inherits-from>
</securityClass>

例7-17は、Oracle XML DBに挿入された後のドキュメントを示します。

例7-17 リポジトリに挿入された後のドキュメント

<securityClass xmlns="http://xmlns.oracle.com/xdb/security.xsd"
xmlns:is="xmlns.oracle.com/iStore"
xmlns:oa="xmlns.oracle.com/OracleApps"
targetNamespace="xmlns.oracle.com/example">
<name>
securityClassExample
</name>
<title xml:lang="jp" xdb:srclang="true">
Security Class Example
</title>
<inherits-from>is:iStorePurchaseOrder</inherits-from>
</securityClass>

- 言語情報を提供すると、明示的に言語をxdb:srclang=trueとマークするか、属性xdb:srclangの中のセッション言語を使用して、属性xml:langが設定されます。いずれも行わないと、任意の変換が選択され、xdb:srclangがtrueに設定されます。
例7-18は、セッション言語が日本語のドキュメントを表します。

例7-18 言語情報を持つドキュメントの挿入

<securityClass xmlns="http://xmlns.oracle.com/xdb/security.xsd"
xmlns:is="xmlns.oracle.com/iStore"
xmlns:oa="xmlns.oracle.com/OracleApps"
targetNamespace="xmlns.oracle.com/example">
<name>
securityClassExample
</name>
<title xml:lang="en">
Security Class Example
</title>
<title xml:lang="fr">
Security Class Example - FR
</title>
<inherits-from>is:iStorePurchaseOrder</inherits-from>
</securityClass>

例7-19は、Oracle XML DBに挿入された後のドキュメントを示します。

例7-19 挿入後のドキュメント

<securityClass xmlns="http://xmlns.oracle.com/xdb/security.xsd"
xmlns:is="xmlns.oracle.com/iStore"
xmlns:oa="xmlns.oracle.com/OracleApps"
targetNamespace="xmlns.oracle.com/example">
<name>
securityClassExample
</name>
<title xml:lang="en" xdb:srclang="true">
Security Class Example
</title>
<title xml:lang="fr">
Security Class Example - FR
</title>
<inherits-from>is:iStorePurchaseOrder</inherits-from>
</securityClass>

- 問合せ: 変換された要素を伴うノードを問い合せる場合、問合せは変換のデフォルト動作を表示します。問合せの結果に変換のデフォルト動作が適用されるように指定するには、Oracle Xpath関数ora:translateを使用する必要があります。関数の構文は次のとおりです。

Nodeset ora:translate(Nodeset parent, String childname, String childnsp)

パラメータparentは、変換済ノードを検索する先の親ノードです。childnameは子ノード名で、childnspは子ノードのネームスペースのURLです。

関数ora:translateは、親ノードの名前が指定した子ノードの名前と一致する場合に正の整数を戻し、xml:langの値は、セッション言語またはxdb:srclangがtrueの言語と同じです。

XMLQueryなどのSQL関数が変換済のドキュメントに適用されると、セッション言語変換が存在する場合はそれが戻され、存在しない場合はソース言語変換が戻されます。たとえば、次の問合せは、セッション言語変換を戻します。

SELECT XMLQuery('$x/ora:translate(securityClass, "title")'
PASSING x.OBJECT_VALUE AS "x" RETURNING CONTENT)
FROM some_table x;

問合せの出力結果は次のとおりです。

<title xml:lang="fr">
Security Class Example - FR
</title>

特定の言語で結果を取得するには、その言語をXPath式の中で指定します。

SELECT XMLQuery('$x/securityClass/title[@xml:lang="en"]'
PASSING x.OBJECT_VALUE AS "x" RETURNING CONTENT)
FROM some_table x;

問合せの出力結果は次のとおりです。

<title xml:lang="en" xdb:srclang="true">
Security Class Example
</title>

変換済のドキュメントは、テキスト(CLOB)またはバイナリXMLでのみ格納できるため、機能上の評価およびファンクション索引XMLIndex、またはCONTEXT索引を使用した問合せのみが可能です。XMLIndex 索引とCONTEXT索引の問合せすべてに対して、ドキュメントにセッション言語変換が存在する場合はそれが戻され、存在しない場合はソース言語変換が戻されます。ただし、ファンクション索引を使用した問合せの場合は、索引を使用するすべての言語について、明示的なxml:lang述語を持つ索引を作成する必要があります。

XMLSerializeやXDBURITypeなどのSQL関数を使用して完全なドキュメントを取得する場合は、セッション言語変換に一致する変換のみが戻されます。プロトコルに対しては、言語のプリファレンスを設定でき、ドキュメントはその言語でのみ戻されます。

次のPL/SQLプロシージャおよび関数は、XML変換をサポートします。

- DBMS_XMLTRANSLATIONS.translateXML: ドキュメントを指定した言語に変換します。指定した言語変換が存在する場合はそれが戻され、存在しない場合はソース言語変換が戻されます。
たとえば、translateXML(doc, 'fr')と記述して例7-19の変換言語にフランス語を指定する場合、次のコードが戻され、他の変換はすべて無視されます。

securityClass xmlns="http://xmlns.oracle.com/xdb/security.xsd"
xmlns:is="xmlns.oracle.com/iStore"
xmlns:oa="xmlns.oracle.com/OracleApps"
targetNamespace="xmlns.oracle.com/example">
<name>
securityClassExample
</name>
<title xml:lang="fr">
Security Class Example - FR
</title>
<inherits-from>is:iStorePurchaseOrder</inherits-from>
</securityClass>

- DBMS_XMLTRANSLATIONS.enableTranslation、DBMS_XMLTRANSLATIONS.disableTranslation: セッション・レベルで変換の有効化/無効化を行います。問合せは、変換が無効な場合は主ドキュメントに作用し、有効な場合は変換済ドキュメントに作用します。

- DBMS_XMLTRANSLATIONS.getBaseDocument: すべての変換とともに完全なドキュメントを戻します。

- 更新: Oracle SQL関数updateXMLを使用して変換済のノードを更新します。ただし、変換言語を指定せずに変換済ノードを更新しようとした場合、エラーが発生します。次のPL/SQLプロシージャは、変換済のドキュメントへの更新操作をサポートします。

- DBMS_XMLTRANSLATIONS.updateTranslation: この関数は、指定したxpathにある変換を特定の言語で更新します。特定の言語での変換が存在しない場合は、それが挿入されます。

- DBMS_XMLTRANSLATIONS.setSourceLang: このプロシージャは、指定したxpathにあるソース言語を指定した言語に設定します。

XML Schemaに基づくXMLType表および列の作成

Oracle XML DBを使用すると、登録されたXML Schemaによって定義されたグローバル要素に限定したXMLType表および列を作成できます。XMLType列を特定の要素および特定のXML Schemaに制限すると、以降はその要素のスキーマ定義に準拠している文書のみを含めることができます。XMLType表の列は、CREATE TABLE操作に適切なXMLSCHEMAおよびELEMENT句を追加することで、特定の要素およびXML Schemaに制限されます。

図7-1から図7-4に、XMLType表を作成するための構文を示します。

関連項目:
object_propertiesのような構文要素を含むCREATE TABLEの詳しい説明は、『Oracle Database SQL言語リファレンス』。

注意:
各自のデータベース・スキーマと異なるデータベース・スキーマにXMLType表を作成するには、権限CREATE ANY TABLEだけでなく、権限CREATE ANY INDEXも必要です。これは、表の作成時に列OBJECT_IDに一意索引が作成されるためです。列OBJECT_IDには、システム生成のオブジェクト識別子が格納されます。

図7-1 XMLType表の作成: CREATE TABLE

図7-2 XMLType表の作成: XMLType_table

図7-3 XMLType表の作成: table_properties

図7-4 XMLType表の作成: XMLType_virtual_columns

注意:
XMLデータの場合は、仮想列は主にSQLの制約のパーティション化や定義に使用されます。特定のXMLデータにリレーショナル形式でアクセスするためにそれを投影する必要がある場合、SQL/XML関数XMLTableまたはXMLIndexと構造化コンポーネントの使用を考慮してください。関連項目:

- 「仮想列を使用したバイナリXMLデータのパーティション化または制約」

- 「Oracle XML DBのXMLTABLE SQL/XML関数」

- 「XMLIndex構造化コンポーネント」

XPointer表記法のサブセットを使用して、XML Schemaの場所および要素名を含む1つのURLを指定することもできます。第4章「XMLTypeの操作」も参照してください。

例7-20は、2つのCREATE TABLE文を示しています。最初の文は、XMLType表purchaseorder_as_tableを作成します。2番目の文は、XMLType列xml_documentを備えたリレーショナル表purchaseorder_as_columnを作成します。各表で、XMLTypeインスタンスは、URL http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsdで登録したXML Schemaによって定義されたPurchaseOrder要素に限定されます。

例7-20 XML Schemaに基づくXMLType表および列の作成

CREATE TABLE purchaseorder_as_table OF XMLType
XMLSCHEMA "http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd"
ELEMENT "PurchaseOrder";

CREATE TABLE purchaseorder_as_column (id NUMBER, xml_document XMLType)
XMLTYPE COLUMN xml_document
ELEMENT
"http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd#PurchaseOrder";

XMLSchemaおよびElementを指定するには、次の2つの方法があります。

- XMLSchemaおよびElementを別の句として指定する方法

- XPointer表記法でElement句のみを使用する方法

XML Schemaに制限されるXMLType表または列に関連付けられているデータは、数種類の異なる方法で格納できます。

- 分割してオブジェクト・リレーショナル形式(構造化記憶域)で格納

- 単一のCLOB列(非構造化記憶域)を使用してテキストとして格納

- 単一のXML列を使用してバイナリXML形式で格納(バイナリXML記憶域)

XML Schemaに基づくデータのXMLType記憶域オプションの指定

XML Schemaを参照するXMLインスタンス・ドキュメントを格納する表を手動で作成する場合、使用する記憶域オプションを指定できます。特定のXMLType記憶域モデルを指定するには、CREATE TABLE文でSTORE AS句を使用します。それ以外の場合は、XML Schemaの登録時に指定した記憶域モデルが使用されます。登録時に記憶域モデルが指定されなかった場合、オブジェクト・リレーショナル記憶域が使用されます。

この項では、XML Schemaに基づくデータのための記憶域オプションを指定する際に必要な知識について説明します。また、XML Schema注釈を使用して、自動的に作成された表に記憶域オプションを指定することもできます。

関連項目:
「OracleでのXML Schemaの注釈」

XML Schemaに基づくデータのバイナリXML記憶域

STORE AS BINARY_XMLを指定すると、バイナリXML記憶域が使用されます。XML文書が準拠する必要があるXML Schemaを指定する場合、バイナリXMLとして格納されるXMLType表および列を作成するためだけに、そのXML Schemaを使用できます。同じXML Schemaを使用して、オブジェクト・リレーショナル形式あるいはCLOBインスタンスとして格納されるXMLType表および列を作成することはできません。

逆も成り立ちます。登録されたXML Schemaに対してバイナリXML以外の記憶域モデルを使用する場合、そのXML Schemaを使用して作成できるのは、オブジェクト・リレーショナル形式で、またはCLOBインスタンスとして格納されないXMLType表および列のみです。

バイナリXML記憶域は、特にXML Schemaの使用に関して、XMLデータに対する非常に高い柔軟性を提供します。バイナリXMLによるXMLデータのエンコードは、XML Schemaがエンコーディングに使用されるかどうかにより異なります。別のXML Schemaを使用して、同じデータを違う方式でエンコードすることができます。

バイナリXMLデータのエンコーディングでXML Schemaを考慮すると、XML Schemaデータ型が、格納の際にエンコードされる型にマップされます。別の方法として、データがXML Schemaを参照するかどうかに関係なく、スキーマに基づかないバイナリXMLとしてXMLデータをエンコードすることもできます。その場合、参照されているXML Schemaは無視され、XML Schemaデータ型のエンコーディングはありません。

XMLType表または列を作成する場合、バイナリXML記憶域を使用すると、XML Schemaを利用するために、列または表をエンコードする方法を指定できます。以下から選択してください。

- 列または表をスキーマに基づかないバイナリXMLとしてエンコードします。その場合でも列に格納するXMLデータをXML Schemaに準拠させることはできますが、その必要はありません。エンコーディングの目的では、参照されているXML Schemaはすべて無視されます。文書は、挿入または更新時に自動的に検証されません。
その場合でも、スキーマに基づかないバイナリXMLとしてエンコードされた、XML Schemaに基づく文書を明示的に検証することができます。これは、文書を変更または削除する可能性があるため、特定のXML Schemaにあまり密接に結び付けたくない場合という、重要なユースケースを表しています。

- 1つのXML Schemaに準拠する列または表データをエンコードします。すべての行(文書)が同一のXML Schemaに準拠する必要があります。その場合でも、オプションとして、スキーマに基づかない文書も同一の列に格納できるように指定することができます。

- 参照しているあらゆるXML schemaに準拠するように列または表データをエンコードします。各行(文書)は任意のXML Schemaを参照でき、そのXML Schemaを使用してその特定のXML文書をエンコードします。この場合も、オプションとして、スキーマに基づかない文書も同一の列に格納できるように指定することができます。
この方法で、同じXML Schemaの複数のバージョンを使用できます。異なるバージョンに準拠する文書を格納します。それぞれが、参照するXML Schemaに従ってエンコードされます。

エンコーディングにあらゆるXML Schemaを使用できるように指定するには、表を作成する際にオプションALLOW ANYSCHEMAを使用します。

注意:

- ALLOW ANYSCHEMAオプションを使用すると、インスタンス・ドキュメントで参照されるXML Schemaは検証のみに使用されます。問合せ時には使用されません。データの問合せでは、XML Schemaに基づかないデータのように扱われます。

- コピーに基づくXML Schema拡張を使用することが見込まれる場合、オプションALLOW ANYSCHEMAを使用しないことをお薦めします(「コピーに基づくスキーマの拡張の使用」参照)。このオプションを使用する場合、拡張されたXML Schemaにどの行(文書)が準拠するか決定することは不可能です。コピーに基づく拡張時には準拠する行は変換されず、後からデコード可能になることもありません。

ALLOW NONSCHEMAオプションを使用すると、XML Schemaに基づくエンコーディングを使用する表や列に対して、スキーマに基づかない文書も受け入れることができるように指定できます。キーワードXMLSCHEMAがない場合、エンコーディングはスキーマに基づかない文書に対して行われます。キーワードALLOW NONSCHEMAはないが、キーワードXMLSCHEMAがある場合、エンコーディングは、指定された単一のXML Schemaに対して行われます。キーワードALLOW NONSCHEMAはないが、キーワードALLOW ANYSCHEMAがある場合、エンコーディングは、参照されているあらゆるXML Schemaに対して行われます。

XML文書を、文書に対応しないXMLType表または列に挿入しようとすると、エラーが発生します。

可能なオプションについて表7-2にまとめます。

表7-2 バイナリXMLのためのCREATE TABLEエンコード・オプション

記憶域オプション

エンコードの説明

STORE AS BINARY XML

スキーマに基づかないエンコーディングを使用してすべての文書をエンコードします。

STORE AS BINARY XML
XMLSCHEMA ...

参照されたXML Schemaに基づくエンコーディングを使用してすべての文書をエンコードします。

エラーをXML Schemaに準拠しない文書を挿入あるいは更新しようとするとエラーが発生します。

STORE AS BINARY XML
XMLSCHEMA ...
ALLOW NONSCHEMA

参照されたXML Schemaに基づくエンコーディングを使用して、XML Schemaに基づくすべての文書をエンコードします。スキーマに基づかないエンコーディングを使用して、スキーマに基づかないすべての文書をエンコードします。

参照されているXML Schemaに準拠していないXML Schemaに基づく文書を挿入あるいは更新しようとするとエラーが発生します。

STORE AS BINARY XML
ALLOW ANYSCHEMA

文書により参照されたXML Schemaに基づくエンコーディングを使用して、XML Schemaに基づくすべての文書をエンコードします。

登録されたXML Schemaを参照しないか、参照するXML Schemaに準拠しない文書を挿入あるいは更新しようとすると、エラーが発生します。

STORE AS BINARY XML
ALLOW ANYSCHEMA
ALLOW NONSCHEMA

文書により参照されたXML Schemaに基づくエンコーディングを使用して、XML Schemaに基づくすべての文書をエンコードします。スキーマに基づかないエンコーディングを使用して、スキーマに基づかないすべての文書をエンコードします。

参照している登録済XML Schemaに準拠していないXML Schemaに基づく文書を挿入あるいは更新しようとするとエラーが発生します。

注意:
CREATE TABLEをALLOW NONSCHEMAとともに使用し、ALLOW ANYSCHEMAとともには使用しない場合、XML Schemaに基づく文書を含むすべての文書が、XML Schemaに基づかないエンコーディングを使用してエンコードされます。後で、同じ表でALTER TABLEをALLOW ANYSCHEMAとともに使用する場合、ALTER TABLE操作より前に格納された文書のエンコーディングには影響を与えません。このような文書はすべて、XML Schemaを参照するかどうかにかかわらず、XML Schemaに基づかないエンコーディングを使用して引き続きエンコードされます。ALTER TABLE操作より後で表に挿入されるXML Schemaに基づく文書のみが、XML Schemaに基づくエンコーディングを使用してエンコードされます。

XML Schemaに基づくデータの非構造化記憶域

非構造化記憶域を指定するには、表作成時にSTORE AS CLOBを使用します。この場合、すべてのXML文書が単一のCLOB列に格納されます。

例7-21は、XMLType表およびXMLType列を持つ表の作成方法を示しています。ここで、XMLTypeのコンテンツは、登録済のXML Schemaによって定義されたグローバル要素に限定され、XMLTypeのコンテンツは単一のCLOB列を使用して格納されます。

例7-21 XML Schemaに基づくXMLType表および列に対するCLOB記憶域の指定

CREATE TABLE purchaseorder_as_table OF XMLType
XMLTYPE STORE AS CLOB
XMLSCHEMA "http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd"
ELEMENT "PurchaseOrder";

CREATE TABLE purchaseorder_as_column (id NUMBER, xml_document XMLType)
XMLTYPE COLUMN xml_document
STORE AS CLOB
XMLSCHEMA "http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd"
ELEMENT "PurchaseOrder";

STORE AS CLOB句にLOB記憶域パラメータを追加できます。

XML Schemaに基づくデータの構造化記憶域

構造化記憶域では、コレクションはSQL VARRAY値にマップされます。XML コレクションは、maxOccurs > 1であるすべての要素で、複数回出現できます。このようなVARRAYのコンテンツ全体は、デフォルトでOrdered Collection Table(OCT)内に一連の行として格納されます。

例7-22で、追加の記憶オプションの指定について説明します。LineItemコレクションのVARRAYは、表ではなくLOBとして格納されます。USERSは、要素Notesの格納に使用される表領域です。表は、オンライン・トランザクション処理(OLTP)のために圧縮されます。

例7-22 XMLType表および列に対する構造化記憶域オプションの指定

CREATE TABLE purchaseorder_as_table
OF XMLType (UNIQUE ("XMLDATA"."Reference"),
FOREIGN KEY ("XMLDATA"."User") REFERENCES hr.employees (email))
ELEMENT
"http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd#PurchaseOrder"
VARRAY "XMLDATA"."LineItems"."LineItem" STORE AS LOB lineitem_lob
LOB ("XMLDATA"."Notes")
STORE AS (TABLESPACE USERS ENABLE STORAGE IN ROW
STORAGE(INITIAL 4K NEXT 32K))
COMPRESS FOR OLTP;

CREATE TABLE purchaseorder_as_column (
id NUMBER,
xml_document XMLType,
UNIQUE (xml_document."XMLDATA"."Reference"),
FOREIGN KEY (xml_document."XMLDATA"."User") REFERENCES hr.employees (email))
XMLTYPE COLUMN xml_document
XMLSCHEMA "http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd"
ELEMENT "PurchaseOrder"
VARRAY xml_document."XMLDATA"."LineItems"."LineItem" STORE AS LOB lineitem_lob
LOB (xml_document."XMLDATA"."Notes")
STORE AS (TABLESPACE USERS ENABLE STORAGE IN ROW
STORAGE(INITIAL 4K NEXT 32K))
COMPRESS FOR OLTP;

注意:
Oracle Database 11gR2より前のリリースでは、CREATE TABLEのデフォルトの動作は、表としてではなく、LOBとして格納されたVARRAYを使用してコレクションを格納していました。

注意:
親のXMLType表または列に圧縮を指定する場合、すべての子孫XMLType Ordered Collection Tables(OCT)も同様に圧縮されます。

関連項目:

- XML Schema注釈を使用した記憶域オプションの指定については、「Oracle XML Schema注釈」

- OLTPの圧縮については、『Oracle Database SQL言語リファレンス』

XMLType表または列のすべてのVARRAYをLOBまたは表として格納するように指定する必要がある場合は、便利な方法として、構文のSTORE ALL VARRAYS AS句の後に、LOBSまたはTABLESをそれぞれ使用できます。これは、コレクションごとに複数のVARRAY...STORE AS句を使用する方法の代替策となる便利な方法です。例7-23に、これを示します。

例7-23 STORE ALL VARRAYS ASの使用

CREATE TABLE purchaseorder_as_table OF XMLType (UNIQUE ("XMLDATA"."Reference"),
FOREIGN KEY ("XMLDATA"."User") REFERENCES hr.employees (email))
ELEMENT
"http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd#PurchaseOrder"
STORE ALL VARRAYS AS LOBS;

STORE ALL VARRAYS ASを使用して指定した格納方式は、対応するXML Schemaでxdb:storeVarrayAsTableを使用して指定した格納方式よりも優先されます。

関連項目:

- デフォルト表を使用したコレクション記憶域の詳細は、「オブジェクト・リレーショナルなXMLType記憶域の場合のコレクション格納方法の制御」を参照してください。

- STORE ALL VARRAYS AS LOBSの使用方法の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

XMLType表および列に対するリレーショナル制約の指定

構造化記憶域を使用してXMLデータを格納する場合は、XML文書内で1回のみ出現する要素および属性に対して、標準的なリレーショナル制約を指定できます。例7-22に、表の作成時にオブジェクト・リレーショナル表記法を使用して一意制約と外部キー制約を定義する方法を示します。

非構造化記憶域を使用するXMLType表および列には、制約を定義できません。

関連項目:

- バイナリXML形式で格納されているXMLデータに制約を定義する方法の詳細は、「仮想列を使用したバイナリXMLデータのパーティション化または制約」を参照してください。

- 「属性の親要素への一意制約の追加」

OracleでのXML Schemaの注釈

XML Schemaに注釈を付けることによって、XML Schema登録処理によって生成されるオブジェクトおよび表に影響を与えることができます。これを行うには、Oracle特有の属性を、XML Schemaによって宣言されるcomplexType、elementおよびattributeの定義に追加します。

Oracle XML DBによって使用される大部分のXML属性は、名前空間http://xmlns.oracle.com/xdbに属します。XMLデータをバイナリXML形式でエンコードするために使用されるXML属性は、名前空間http://xmlns.oracle.com/2004/CSXに属します。XML Schemaの注釈の処理を単純化するために、名前空間接頭辞はXML Schemaのルート要素で宣言することをお薦めします。

XMLスキーマ注釈の一般的な使用

XML Schemaに注釈を付ける一般的な理由は、次のとおりです。

- XMLデータの構造化記憶域に対してPL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaで作成された表やオブジェクト、オブジェクト属性の名前が、わかりやすくすべてのアプリケーション・ネーミング標準に準拠することを保証するため。この場合は、パラメータGENTYPESまたはGENTABLESをTRUEに設定します。

- XML Schemaとデータベース内の既存のオブジェクトおよび表との間をマップするため。この場合は、パラメータGENTYPESまたはGENTABLESをFALSEに設定します。

- SQLで直接作業する場合、引用符で囲まれた識別子を使用する必要のある、大/小文字の混在する名前が生成されないようにします。

- 文書が相互に関連する再帰的なXPath問合せの場合に、構造化記憶域のXPathリライトを可能にします。これは、再帰的なXMLデータをターゲットとしているXPath式の引数を使用する、SQL/XMLアクセスおよび問合せ関数の特定の用途に適用されます。

最も一般的に使用されるXML Schema注釈は、次のとおりです。

- xdb:defaultTable: GENTABLESパラメータがTRUEの場合に、各グローバル要素に生成されるデフォルトの表の名前。この注釈を空の文字列""に設定すると、該当する要素にデフォルトの表が生成されなくなります。

- xdb:SQLName: XML Schemaに定義されている各要素または属性に対応するSQLオブジェクト属性の名前。

- xdb:SQLType: complexType定義の場合、対応するオブジェクト・タイプ。simpleType定義では、XML Schemaデータ型とSQLデータ型間のデフォルト・マッピングをオーバーライドするためにSQLTypeを使用します。SQLTypeは、無制限の文字列をVARCHAR(4000) CHAR値(デフォルト)ではなく、CLOB値として格納する必要がある場合に定義するのが、一般的な使用方法です。注意: データ型NCHAR、NVARCHAR、またはNCLOBは、SQLType注釈の値としては使用できません。

- xdb:SQLCollType - 要素のコレクションを管理するVARRAY型を指定するために使用します。

- xdb:maintainDOM - 指定されているcomplexType定義のDOM再現性を維持する必要があるかどうかを判断するために使用します。

- xdb:storeVarrayAsTable - XML Schemaのルート要素を指定します。すべてのコレクションをOrdered Collection Table(OCT)として格納するために使用します。maxOccurs > 1で指定されている各要素に対して、1つのOCTが作成されます。OCTは、システム生成の名前で作成されます。storeVarrayAsTableのデフォルト値はtrueです。

これらの属性のいずれにも、値を指定する必要はありません。Oracle XML DBにより、デフォルトで、XML Schemaの登録プロセス中に適切な値が提供されます。ただし、構造化記憶域を使用する場合、少なくとも最上位のSQL型の名前を指定し、後で参照できるようにすることをお薦めします。

XML Schema注釈の例

例7-24は、例7-1のXML Schemaのリストの一部であり、最も重要ないくつかのOracle XML DB注釈が含まれるように修正を加えています。

例7-24 一般的なスキーマ注釈の使用

<xs:schema
targetNamespace="http://xmlns.oracle.com/xdb/documentation/purchaseOrder"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
xmlns:po="http://xmlns.oracle.com/xdb/documentation/purchaseOrder"
version="1.0"
xdb:storeVarrayAsTable="true">  <xs:element name="PurchaseOrder" type="po:PurchaseOrderType"
xdb:defaultTable="PURCHASEORDER"/>
<xs:complexType name="PurchaseOrderType" xdb:SQLType="PURCHASEORDER_T">
<xs:sequence>
<xs:element name="Reference" type="po:ReferenceType" minOccurs="1"
xdb:SQLName="REFERENCE"/>
<xs:element name="Actions" type="po:ActionsType"
xdb:SQLName="ACTION_COLLECTION"/>
<xs:element name="Reject" type="po:RejectionType" minOccurs="0"/>
<xs:element name="Requestor" type="po:RequestorType"/>
<xs:element name="User" type="po:UserType" minOccurs="1"
xdb:SQLName="EMAIL"/>
<xs:element name="CostCenter" type="po:CostCenterType"/>
<xs:element name="ShippingInstructions"
type="po:ShippingInstructionsType"/>
<xs:element name="SpecialInstructions" type="po:SpecialInstructionsType"/>
<xs:element name="LineItems" type="po:LineItemsType"
xdb:SQLName="LINEITEM_COLLECTION"/>
<xs:element name="Notes" type="po:NotesType" xdb:SQLType="CLOB"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemsType" xdb:SQLType="LINEITEMS_T">
<xs:sequence>
<xs:element name="LineItem" type="po:LineItemType" maxOccurs="unbounded"
xdb:SQLCollType="LINEITEM_V" xdb:SQLName="LINEITEM_VARRAY"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemType" xdb:SQLType="LINEITEM_T">
<xs:sequence>
<xs:element name="Description" type="po:DescriptionType"/>
<xs:element name="Part" type="po:PartType"/>
</xs:sequence>
<xs:attribute name="ItemNumber" type="xs:integer"/>
</xs:complexType>
<xs:complexType name="PartType" xdb:SQLType="PART_T" xdb:maintainDOM="false">
<xs:attribute name="Id">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="10"/>
<xs:maxLength value="14"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Quantity" type="po:moneyType"/>
<xs:attribute name="UnitPrice" type="po:quantityType"/>
</xs:complexType>
</xs:schema>

schema要素にはxdb名前空間の宣言が含まれます。これには注釈xdb:storeVarrayAsTable = "true" (デフォルト値)も含まれます。これによりXML Schema内のすべてのコレクションがOrdered Collection Table(OCT)を使用して管理されるようになります。

グローバル要素PurchaseOrderの定義には、この要素に関連付けられているデフォルトの表名をpurchaseorderに指定するdefaultTable注釈が含まれています。

グローバルな複合型PurchaseOrderTypeの定義には、生成されるSQLオブジェクトの型名をpurchaseorder_tに指定するSQLType注釈が含まれています。この種の定義には、次の注釈が使用されます。

- 要素Referenceの定義には、XML要素Referenceに対応するSQL属性をreferenceという名前にするSQLName注釈が指定されています。

- 要素Actionsの定義には、XML要素Actionsに対応するSQL属性の名前をaction_collectionにするSQLName注釈が指定されています。

- 要素USERの定義には、XML要素Userに対応するSQL属性の名前をemailにするSQLName注釈が指定されています。

- 要素LineItemsの定義は、XML要素LineItemsに対応するSQL属性の名前をlineitem_collectionにするSQLName注釈が指定されています。

- 要素Notesの定義には、XML要素Notesに対応するSQL属性のデータ型をCLOBにするSQLType注釈が指定されています。

グローバルな複合型LineItemTypeの定義には、生成されるSQLオブジェクトの型名をlineitem_tに指定するSQLType注釈が含まれています。この種の定義には、次の注釈が使用されます。

- LineItem要素の定義には、XML要素LineItemsに対応するSQL属性のデータ型の名前をlineitem_varrayにするSQLName注釈と、コレクションを管理するSQLオブジェクトの型名をlineitem_vにするSQLCollName注釈が指定されています。

グローバルな複合型LineItemsTypeの定義には、生成されるSQLオブジェクトの型名をlineitems_tに指定するSQLType注釈が含まれています。

複合型PartTypeの定義には、SQLオブジェクトの型名をpart_tに指定するSQLType注釈が含まれています。注釈xdb:maintainDOM = "false"も含まれ、Oracle XML DBでこのデータ型に基づく要素のDOM再現性を保持する必要がないことを指定します。

例7-25は、注釈付きXML Schemaの登録で作成された表およびオブジェクトの一部を示しています。

例7-25 注釈付きXML Schemaの登録

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd',
SCHEMADOC => bfilename('XMLDIR', 'purchaseOrder.Annotated.xsd'),
LOCAL     => TRUE,
GENTYPES  => TRUE,
GENTABLES => TRUE,
CSID      => nls_charset_id('AL32UTF8'));
END;
/

SELECT table_name, xmlschema, element_name FROM USER_XML_TABLES;

TABLE_NAME     XMLSCHEMA                             ELEMENT_NAME
-------------  -----------------------------------   -------------
PURCHASEORDER  http://xmlns.oracle.com/xdb/documen   PurchaseOrder
tation/purchaseOrder.xsd

1 row selected.

DESCRIBE purchaseorder

Name                            Null? Type
------------------------------  ----- -----------------
TABLE of SYS.XMLTYPE(XMLSchema
"http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd"
ELEMENT "PurchaseOrder") STORAGE Object-relational TYPE "PURCHASEORDER_T"

DESCRIBE purchaseorder_t

PURCHASEORDER_T is NOT FINAL
Name                 Null? Type
-------------------- ----- --------------------------
SYS_XDBPD$                 XDB.XDB$RAW_LIST_T
REFERENCE                  VARCHAR2(30 CHAR)
ACTION_COLLECTION          ACTIONS_T
REJECT                     REJECTION_T
REQUESTOR                  VARCHAR2(128 CHAR)
EMAIL                      VARCHAR2(10 CHAR)
COSTCENTER                 VARCHAR2(4 CHAR)
SHIPPINGINSTRUCTIONS       SHIPPING_INSTRUCTIONS_T
SPECIALINSTRUCTIONS        VARCHAR2(2048 CHAR)
LINEITEM_COLLECTION        LINEITEMS_T
Notes                      CLOB

DESCRIBE lineitems_t
LINEITEMS_T is NOT FINAL
Name                 Null? Type
-------------------- ----- --------------------------
SYS_XDBPD$                 XDB.XDB$RAW_LIST_T
LINEITEM_VARRAY            LINEITEM_V

DESCRIBE lineitem_v

LINEITEM_V VARRAY(2147483647) OF LINEITEM_T
LINEITEM_T is NOT FINAL
Name                 Null? Type
-------------------- ----- --------------------------
SYS_XDBPD$                 XDB.XDB$RAW_LIST_T
ITEMNUMBER                 NUMBER(38)
DESCRIPTION                VARCHAR2(256 CHAR)
PART                       PART_T

DESCRIBE part_t

PART_T is NOT FINAL
Name                 Null? Type
-------------------- ----- --------------------------
ID                         VARCHAR2(14 CHAR)
QUANTITY                   NUMBER(12,2)
UNITPRICE                  NUMBER(8,4)

SELECT table_name, parent_table_column FROM USER_NESTED_TABLES
WHERE parent_table_name = 'purchaseorder';

TABLE_NAME                       PARENT_TABLE_COLUMN
----------                       -----------------------
SYS_NTNOHV+tfSTRaDTA9FETvBJw==   "XMLDATA"."LINEITEM_COLLECTION"."LINEITEM_VARRAY"
SYS_NTV4bNVqQ1S4WdCIvBK5qjZA==   "XMLDATA"."ACTION_COLLECTION"."ACTION_VARRAY"

2 rows selected.

次に、XML Schema登録の結果を示します。

- purchaseorderという表が作成されました。

- purchaseorder_t、lineitems_t、lineitem_v、lineitem_tおよびpart_tという型が作成されました。これらの型で定義された属性は、SQLName注釈の指定に従って名前が付けられます。

- purchaseorder_tによって定義されたNotes属性のデータ型は、CLOBになります。

- 型part_tに、位置指定ディスクリプタ(PD)属性は含まれていません。

- LineItemおよびAction要素のコレクションを管理するために、Ordered Collection Table(OCT)が作成されました。

使用できるOracle XML DBのXML Schema注釈

表7-3、表7-4および表7-5に要素および属性の宣言で指定できるOracle XML DBの注釈を示します。接頭辞csxがあるもの以外のすべての注釈は、構造化記憶域に対して登録されたXML Schemaに適用できます。これには、オブジェクト・リレーショナル形式で格納されるハイブリッド記憶域の一部が含まれます。

次の注釈は、非構造化記憶域に対して登録されたXML Schemaに適用されます。

- xdb:defaultTable

- xdb:defaultTableSchema

次の注釈は、バイナリXML記憶域に対して登録されたXML Schemaに適用されます。

- xdb:defaultTable

- xdb:defaultTableSchema

- xdb:tableProps

表7-3 要素内の注釈

属性

値

デフォルト

説明

xdb:columnProps

任意の列STORAGE句

NULL

デフォルトのCREATE TABLE文に挿入される列STORAGE句を指定します。主に、SQL表にマップされる要素(最上位の要素の宣言および表外の要素の宣言)に有効です。

xdb:defaultTable

表の名前

要素名に基づきます。

このXML SchemaのXMLインスタンスを格納する必要があるSQL表の名前を指定します。これは、表の名前が指定されていないAPIおよびプロトコル(FTP、HTTP(S)など)を使用してXMLを挿入する場合に最も有効です。構造化記憶域およびバイナリXML記憶域に適用されます。

xdb:defaultTableSchema

任意のSQLユーザー名

XML Schemaを登録するユーザー

xdb:defaultTableによって指定された型を所有するデータベース・ユーザー(データベース・スキーマ)の名前を指定します。構造化記憶域およびバイナリXML記憶域に適用されます。

xdb:maintainDOM

true | false

TRUE

trueの場合、この要素のインスタンスは出力でDOM再現性が保持されるように格納されます。これは、要素の順序の他に、すべてのコメント、処理命令、ネームスペース宣言などが保持されることを意味します。

falseの場合は、出力で入力と同じDOM操作が保持されない場合があります。

xdb:maintainOrder

true | false

TRUE

trueの場合(一般的に推奨、デフォルト値)、コレクションはVARRAYにマップされます(LOBまたはOrdered Collection Tableに格納されます)。

falseの場合、コレクションは順序付けられていない表にマップされ、ドキュメント内の順序は保持されません。

xdb:maxOccurs

任意の正の整数

1

要素が出現できる回数の最大値を指定します。値がunboundedの場合、最大出現回数は無制限です。

xdb:SQLCollSchema

任意のSQLユーザー名

XML Schemaを登録するユーザー

xdb:SQLCollTypeによって指定された型を所有するデータベース・ユーザー(データベース・スキーマ)の名前を指定します。

xdb:SQLCollType

任意のSQLコレクション型

要素名から生成された名前

このXML要素に対応するSQLコレクション型の名前。XML要素は、maxOccurs > 1と指定されている必要があります。

xdb:SQLInline

true | false

TRUE

trueの場合、この要素は埋込みオブジェクト属性(maxOccurs > 1の場合はコレクション)として表内に格納されます。

falseの場合は、REF値(maxOccurs>1の場合はREF値のコレクション)が格納されます。SQLでインラインがサポートされない特定の状況(循環参照など)では、この属性は強制的にfalseになります。

xdb:SQLName

SQL識別子

要素名

このXML要素にマップされるSQLオブジェクト内での属性の名前。

xdb:SQLSchema

任意のSQLユーザー名

XML Schemaを登録するユーザー

SQLTypeによって指定された型を所有するデータベース・ユーザー(データベース・スキーマ)の名前を指定します。

xdb:SQLType

任意のSQLデータ型脚注 1 。ただしNCHAR、NVARCHARおよびNCLOBを除きます。

要素名から生成された名前

このXML要素の宣言に対応するSQL型の名前。

xdb:srclang

true | false

TRUE

trueの場合、指定の言語変換がデフォルトの変換として使用されます。

xdb:tableProps

任意の表STORAGE句

NULL

デフォルトのCREATE TABLE文に追加されるTABLE STORAGE句を指定します。主に、グローバルな要素および表外の要素に有効です。構造化記憶域およびバイナリXML記憶域に適用されます。

xdb:translate

true | false

TRUE

trueの場合、この要素のインスタンスが変換されます。この要素をtrueに設定するには、maxOccurs属性が<=1である必要があります。

脚注1 「XML Schemaデータ型のSQLデータ型へのマッピング」を参照してください。

関連項目:
オブジェクト・リレーショナル記憶域のXMLType表を手動で作成する場合の記憶域オプションの指定については、「XML Schemaに基づくデータの構造化記憶域」を参照してください。

表7-4 グローバルなcomplexType要素を宣言する要素内の注釈

属性

値

デフォルト

説明

xdb:maintainDOM

true | false

TRUE

trueの場合、この要素のインスタンスは出力でDOM再現性が保持されるように格納されます。これは、要素の順序の他に、すべてのコメント、処理命令、ネームスペース宣言などが保持されることを意味します。

falseの場合は、出力で入力と同じDOM操作が保持されない場合があります。

xdb:SQLSchema

任意のSQLユーザー名

XML Schemaを登録するユーザー

SQLTypeによって指定された型を所有するデータベース・ユーザー(データベース・スキーマ)の名前を指定します。

xdb:SQLType

任意のSQLデータ型脚注 1 。ただしNCHAR、NVARCHARおよびNCLOBを除きます。

要素名から生成された名前

このXML要素の宣言に対応するSQL型の名前。

脚注1 「XML Schemaデータ型のSQLデータ型へのマッピング」を参照してください。

表7-5 XML Schema宣言内の注釈

属性

値

デフォルト

説明

xdb:mapUnboundedStringToLob

true | false

FALSE

trueの場合は、デフォルトで、無制限の文字列がCLOBインスタンスにマップされます。同様に、デフォルトで、無制限のバイナリ・データがBLOB値にマップされます。

falseの場合は、無制限の文字列がVARCHAR2(4000)値にマップされ、無制限のバイナリ・コンポーネントがRAW(2000)値にマップされます。

xdb:storeVarrayAsTable

true | false

TRUE

trueの場合は、VARRAYが表(OCT)として格納されます。

falseの場合は、VARRAYがLOBに格納されます。

関連項目:
xdb:maxOccurs、xdb:translateおよびxdb:srclangの詳細は、「変換のためのXML SchemaとXMLインスタンス・ドキュメントの変更」を参照してください。

構造化記憶域に対するXML Schema注釈のガイドライン

オブジェクト・リレーショナル形式で格納されるXMLTypeデータ(構造化記憶域)では、パフォーマンスを最適化するために注意深い計画が求められます。エンティティ関連モデル、索引付け、データ型、表パーティションなどの通常のリレーショナル・データについても、同様の点を考慮することが求められます。

XPathリライトを有効にし、最適なパフォーマンスを達成するには、XML Schema注釈を使用してこのような多くの設計選択を実装します。この項では、オブジェクト・リレーショナル形式で格納されるXMLTypeデータの使用を最適化するための注釈のガイドラインについて説明します。

関連項目:

- 表7-3「要素内の注釈」

- 第8章「構造化記憶域のXPathリライト」

未使用の最上位要素に不要な表作成の回避

XML Schema登録では、XML Schemaで定義される最上位の要素ごとに、デフォルトで、最上位の表が作成されます。そのような要素の中には、XML Schemaに準拠するXMLインスタンスの最上位要素として使用されるものもあります。それ以外の要素は使用されません。これは、たとえば、REFターゲットとして使用するために最上位にするXML Schemaの要素に共通です。

対応するXMLインスタンスの最上位でXML Schemaの最上位の要素が使用されない場合は、注釈xdb:defaultTable = ""をXML Schemaの要素に追加することで、関連する不要な表を作成せずに済みます。この属性の空の値により、デフォルト表の作成を回避できます。

デフォルト表に対する独自の名前の提供

チューニング用に、対象の問合せの実行計画の出力を検証します。この出力は、オブジェクト・リレーショナル形式で格納されているXMLTypeデータの基礎となる表を参照します。これらの表には、システム生成された名前がデフォルトで含まれます。対象とする表の場合は特に、独自の表名を指定することをお薦めします。これを行うには、注釈xdb:defaultTableを使用します。

関連項目:
「XML Schemaの登録時に作成されるデフォルト表」

不要な場合のDOM再現性の無効化

XML Schemaの登録では、DOM再現性が維持されるように、XMLデータを格納する表がデフォルトで生成されます。多くの場合、これはデータ中心のXMLデータのDOM再現性が必要でない場合です。かわりに、DOM再現性を維持しないオブジェクト・リレーショナル表を使用することで、格納、問合せおよびデータ変更のパフォーマンスを改善できます。これを行うには、注釈xdb:maintainDOM = "false"を使用します。

関連項目:
「DOM再現性」

順序が関係ない場合のUnordered Collection要素の使用

コレクション要素間の順序が重要でない場合は、注釈xdb:maintainOrder = "false"を使用します。これにより、XPathリライトの最適化が可能になり、一般的に問合せの実行効率が向上します。

タイムスタンプ・データ型を使用した時間関連要素の注釈

アプリケーションとタイムゾーン・インジケータの連動が必要な場合は、xs:time型およびxs:dateTime型のXMLSschema要素に、xdb:SQLType = "TIMESTAMP WITH TIME ZONE"の注釈を指定します。これによって、タイムゾーン・インジケータが含まれている値の格納、取出しおよび比較を実行できます。

表および列のプロパティの追加

XMLデータの基礎となる表または列に、パーティションや表領域、圧縮句などの追加のプロパティが必要な場合は、注釈xdb:tablePropsまたはxdb:columnPropsを使用し、それらの注釈を指定します。これにより、主キーまたは制約を追加できます。たとえば、オンライン・トランザクション処理(OLTP)のために表の圧縮を行うには、tableProps属性を使用してCOMPRESS FOR OLTPを追加します。

関連項目:
XMLType表および列を手動で作成する際のOLTP圧縮の指定の例は例7-22

大規模コレクションの表外格納

complexTypeによって定義された要素と属性の総数が1000に達すると、その型のインスタンスがデータベースに格納される場合、生成されるSQLオブジェクトを管理できる単一の表を作成することはできません。大規模コレクションがある場合は、1つの表でこのような1000列の上限にぶつかる可能性があります。

注釈xdb:defaultTableおよびxdb:SQLInlineを使用すると、このようなコレクション要素を表外に格納するように指定できます。つまり、これらのデータは個別の表に格納され、主となるコレクション表に格納されるのは、その表の行の参照のみです。表外の表の名前を指定するには、xdb:defaultTableを使用します。表外に格納するには、大規模コレクションの各要素に注釈xdb:SQLInline = "false"を指定します。

関連項目:

- 「大規模なXML Schemaの操作」

- 「表外に格納するための注釈属性SQLInLineのfalse設定」

登録されたXML Schemaの問合せによる注釈の取得

登録済のXML Schemaのバージョンには、Oracle XML DB注釈の完全なセットが含まれています。例7-8および例7-9に示されているように、登録されているXML Schemaの場所は、XML Schemaがローカル・スキーマかグローバル・スキーマかによって異なります。

ユーザーが指定した注釈、またはスキーマの登録処理で追加された注釈の値に対して、登録されているXML Schemaの問合せが可能です。例7-26は、XMLデータの構造化記憶域に対してXML Schemaで宣言されているグローバルなcomplexType定義、およびそれに対応するSQLオブジェクト型とDOM再現性値を示しています。

例7-26 登録されたXML Schemaからのメタデータの問合せ

SELECT ct.xmlschema_type_name, ct.sql_type_name, ct.dom_fidelity
FROM RESOURCE_VIEW,
XMLTable(
XMLNAMESPACES (
'http://xmlns.oracle.com/xdb/XDBResource.xsd' AS "r",
'http://xmlns.oracle.com/xdb/documentation/purchaseOrder' AS "po",
'http://www.w3.org/2001/XMLSchema' AS "xs",
'http://xmlns.oracle.com/xdb' AS "xdb"),
'/r:Resource/r:Contents/xs:schema/xs:complexType' PASSING RES
COLUMNS
xmlschema_type_name VARCHAR2(30) PATH '@name',
sql_type_name       VARCHAR2(30) PATH '@xdb:SQLType',
dom_fidelity        VARCHAR2(6)  PATH '@xdb:maintainDOM') ct
WHERE
equals_path(
RES,
'/sys/schemas/SCOTT/xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd')
=1;

XMLSCHEMA_TYPE_NAME        SQL_TYPE_NAME            DOM_FIDELITY
-------------------------  -----------------------  ------------
PurchaseOrderType          PURCHASEORDER_T          true
LineItemsType              LINEITEMS_T              true
LineItemType               LINEITEM_T               true
PartType                   PART_T                   true
ActionsType                ACTIONS_T                true
RejectionType              REJECTION_T              true
ShippingInstructionsType   SHIPPING_INSTRUCTIONS_T  true

7 rows selected.

XML Schemaデータ型のOracle XML DB記憶域へのマッピング

XML Schemaに準拠するXMLデータの型は、XML Schemaデータ型により決まります。このXMLデータがOracle XML DBに格納される場合、その記憶域データ型はデフォルトのマッピングを使用して(およびオプションで、XML Schema注釈を使用して指定したマッピング情報を使用して)、XML Schemaデータ型から導かれます。

記憶域に対して使用するデータ型を指定しない場合、Oracle XML DBは登録時に、デフォルトのマッピングを使用して適切にXML Schemaに注釈を付けます。こうすると、登録されたXML Schemaに、データ型注釈の完全なセットが含まれます。

- 非構造化記憶域では、データ型マッピングは重要ではありません。XMLデータはすべて、単一CLOBとして一緒に格納されます。

- 構造化記憶域では、XML Schemaデータ型がSQLデータ型にマップされます。

- バイナリXML記憶域では、XML Schemaデータ型はOracle XML DBバイナリXMLエンコーディング型にマップされます。

関連項目:
「XML Schemaデータ型のSQLデータ型へのマッピング」

図7-5に、Oracle XML DBで、XML文書およびXML Schemaに指定されたマッピングを使用して、XML Schemaに基づくXMLType表を作成する方法を示します。XML Schemaで指定された格納方式に応じて、XMLインスタンス・ドキュメントは、バイナリXML形式またはCLOB値として単一のXMLType列に格納されるか、複数のオブジェクト・リレーショナル列を使用して格納されます。

図7-5 Oracle XML DBによるXML Schemaに基づくXMLType表のマッピング方法

XML Schemaデータ型のSQLデータ型へのマッピング

この項では、PL/SQLパッケージDBMS_XMLSCHEMAを使用して、XML Schema属性および要素のデータ型をSQLデータ型にマップする方法について説明します。

注意:
XML Schema登録時に、XML Schemaデータ型からマップされるSQLデータ型に直接アクセスしないでください。これらのSQL型はOracle XML DBの実装の一部です。ユーザーが使用できるように公開されたものではありません。
オラクル社は製品パッチなどで、実装をいつでも変更する権利を留保します。オラクル社によるそうした変更は、XMLの抽象的概念に従うアプリケーションには影響しませんが、それらのデータ型に直接アクセスするアプリケーションには影響を与えることがあります。

XML Schemaデータ型のSQLへのマッピングの例

例7-27に、XML Schemaデータ型をSQLデータ型にマッピングする単純な例を示します。属性SQLTypeを使用してデータ型のマッピングを指定します。また、属性SQLNameを使用して、様々なXML要素および属性に使用されるオブジェクト属性を指定します。

例7-27 属性SQLTypeを使用したXML Schemaデータ型のSQLデータ型へのマッピング

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
version="1.0"
xdb:storeVarrayAsTable="true">
<xs:element name="PurchaseOrder" type="PurchaseOrderType" xdb:defaultTable="PURCHASEORDER"/>
<xs:complexType name="PurchaseOrderType" xdb:SQLType="PURCHASEORDER_T">
<xs:sequence>
<xs:element name="Reference" type="ReferenceType" minOccurs="1" xdb:SQLName="REFERENCE"/>
<xs:element name="Actions" type="ActionsType" xdb:SQLName="ACTIONS"/>
<xs:element name="Reject" type="RejectionType" minOccurs="0" xdb:SQLName="REJECTION"/>
<xs:element name="Requestor" type="RequestorType" xdb:SQLName="REQUESTOR"/>
<xs:element name="User" type="UserType" minOccurs="1" xdb:SQLName="USERID"/>
<xs:element name="CostCenter" type="CostCenterType" xdb:SQLName="COST_CENTER"/>
<xs:element name="ShippingInstructions" type="ShippingInstructionsType"
xdb:SQLName="SHIPPING_INSTRUCTIONS"/>
<xs:element name="SpecialInstructions" type="SpecialInstructionsType"
xdb:SQLName="SPECIAL_INSTRUCTIONS"/>
<xs:element name="LineItems" type="LineItemsType" xdb:SQLName="LINEITEMS"/>
<xs:element name="Notes" type="po:NotesType" xdb:SQLType="CLOB"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemsType" xdb:SQLType="LINEITEMS_T">
<xs:sequence>
<xs:element name="LineItem" type="LineItemType" maxOccurs="unbounded"
xdb:SQLName="LINEITEM" xdb:SQLCollType="LINEITEM_V"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemType" xdb:SQLType="LINEITEM_T">
<xs:sequence>
<xs:element name="Description" type="DescriptionType"
xdb:SQLName="DESCRIPTION"/>
<xs:element name="Part" type="PartType" xdb:SQLName="PART"/>
</xs:sequence>
<xs:attribute name="ItemNumber" type="xs:integer" xdb:SQLName="ITEMNUMBER"
xdb:SQLType="NUMBER"/>
</xs:complexType>
<xs:complexType name="PartType" xdb:SQLType="PART_T">
<xs:attribute name="Id" xdb:SQLName="PART_NUMBER" xdb:SQLType="VARCHAR2">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="10"/>
<xs:maxLength value="14"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Quantity" type="moneyType" xdb:SQLName="QUANTITY"/>
<xs:attribute name="UnitPrice" type="quantityType" xdb:SQLName="UNITPRICE"/>
</xs:complexType>

...

<xs:complexType name="ActionsType" xdb:SQLType="ACTIONS_T">
<xs:sequence>
<xs:element name="Action" maxOccurs="4" xdb:SQLName="ACTION" xdb:SQLCollType="ACTION_V">
<xs:complexType xdb:SQLType="ACTION_T">
<xs:sequence>
<xs:element name="User" type="UserType" xdb:SQLName="ACTIONED_BY"/>
<xs:element name="Date" type="DateType" minOccurs="0" xdb:SQLName="DATE_ACTIONED"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RejectionType" xdb:SQLType="REJECTION_T">
<xs:all>
<xs:element name="User" type="UserType" minOccurs="0" xdb:SQLName="REJECTED_BY"/>
<xs:element name="Date" type="DateType" minOccurs="0" xdb:SQLName="DATE_REJECTED"/>
<xs:element name="Comments" type="CommentsType" minOccurs="0" xdb:SQLName="REASON_REJECTED"/>
</xs:all>
</xs:complexType>
<xs:complexType name="ShippingInstructionsType" xdb:SQLType="SHIPPING_INSTRUCTIONS_T">
<xs:sequence>
<xs:element name="name" type="NameType" minOccurs="0" xdb:SQLName="SHIP_TO_NAME"/>
<xs:element name="address" type="AddressType" minOccurs="0" xdb:SQLName="SHIP_TO_ADDRESS"/>
<xs:element name="telephone" type="TelephoneType" minOccurs="0" xdb:SQLName="SHIP_TO_PHONE"/>
</xs:sequence>
</xs:complexType>
...
</xs:schema>

XML Schema属性データ型のSQLへのマッピング

属性の宣言では、次のいずれかを使用してXML Schemaデータ型を指定できます。

- 基本型

- このXML Schemaまたは外部のXML Schema内で宣言されたグローバルなsimpleType

- このXML Schemaまたは外部のXML Schema内で宣言されたグローバル属性に対する参照(ref="..")

- ローカルなsimpleType

SQLデータ型および関連付けられた情報(長さおよび精度)、メモリーのマッピングの情報は、属性の基礎となるsimpleTypeから導出されます。

属性を宣言する際のXML Schema内のSQLType値のオーバーライド

入力XML Schema文書にSQLTypeの値を明示的に指定できます。この場合、指定するデータ型はスキーマ検証で使用されます。これによって、次の特定の形式のオーバーライドが可能になります。

- デフォルトのSQLデータ型がSTRINGの場合、CHAR、VARCHARまたはCLOBでオーバーライドできます。

- デフォルトのSQLデータ型がRAWの場合は、RAWまたはBLOBでオーバーライドできます。

XML Schema要素データ型のSQLへのマッピング

要素の宣言では、次のいずれかを使用してXML Schemaデータ型を指定できます。

- 属性の宣言に対して型を指定する方法のいずれか。「XML Schema属性データ型のSQLへのマッピング」を参照してください。

- このXML Schema文書または外部のXML Schema内で指定されたグローバルなcomplexType

- このXML Schema文書または外部のXML Schema内に存在するグローバル要素(ref="...")

- ローカルなcomplexType

要素を宣言する際のXML Schema内のSQLType値のオーバーライド

デフォルトでは、complexTypeに基づく要素は、各サブ要素および属性に対応するオブジェクト属性が含まれるSQLオブジェクト型にマップされます。入力XML SchemaにSQLType属性を明示的に指定することによって、このマッピングをオーバーライドできます。この場合、SQLTypeに対して次の値が使用できます。

- VARCHAR2

- RAW

- CLOB

- BLOB

これらの値によって、格納されたXMLデータはデータベース内でテキスト形式で表されます。

たとえば、SQLTypeをVARCHAR2からCLOBにオーバーライドするには、xmlns:xdb="http://xmlns.oracle.com/xdb"を使用してからxdb:SQLType = "CLOB"を使用してxdb名前空間を宣言します。

特別な場合の処理を次に示します。

- 要素の宣言に使用されるcomplexType値、およびcomplexType内で宣言された要素の処理中に循環が検出された場合、SQLInline属性は強制的にfalseに設定され、正しいSQLマッピングはREF XMLTYPEに設定されます。

- maxOccurs > 1の場合は、VARRAY型を作成できます。

- SQLInline ="true"の場合は、要素型が事前にSQL型に決定しているVARRAY型が作成されます。VARRAYのカーディナリティは、属性maxOccursの値に基づきます。属性SQLCollTypeを使用してVARRAY型の名前をユーザーが指定するか、そうしない場合は要素名から導出されます。

- SQLInline = "false"の場合、SQLデータ型はXDB.XDB$XMLTYPE_REF_LIST_Tに設定されます。これは、XMLTypeインスタンスを参照するREF値の配列を表す事前に定義されたデータ型です。

- 要素がグローバル要素の場合、またはSQLInline = "false"の場合は、デフォルト表が作成されます。デフォルト表の名前をユーザーが指定するか、そうしない場合は要素名から導出されます。

関連項目:
simpleType値およびcomplexType値からSQLへのマッピングの詳細は、第9章「XML Schemaの格納と問合せ: 高度」を参照してください。

SQLへのsimpleTypeのマッピング

この項では、XML Schema定義によってXML Schema simpleTypeをSQLオブジェクト型にマップする方法について説明します。図7-6に、この例を示します。

図7-6 simpleTypeのマッピング: XML文字列からSQLのVARCHAR2またはCLOB

表7-6から表7-9までに、XML Schema定義に指定された、SQLへのXML Schema simpleTypeのデフォルトのマッピングを示します。次に例を示します。

- XML Schemaの基本型は最も近いSQLデータ型にマップされます。たとえば、DECIMAL、POSITIVEINTEGERおよびFLOATは、すべてSQLのNUMBERにマップされます。

- XML Schemaの列挙型は、単一RAW(n)オブジェクト属性を持つSQLオブジェクト型にマップされます。nの値は、列挙の宣言で使用可能な値の数によって決定されます。

- XML Schemaのリストまたは共用体型はSQL文字列(VARCHAR2またはCLOB)データ型にマップされます。

表7-6 SQLへのXML Schema文字列データ型のマッピング

XML Schema文字列型

lengthまたはmaxLengthファセット

デフォルトSQLデータ型

互換性のあるSQLデータ型

文字列

n

n < 4000の場合はVARCHAR2(n)、それ以外の場合はVARCHAR2(4000)

CHAR、CLOB

文字列

-

mapUnboundedStringToLob = "false"の場合は、VARCHAR2(4000)、CLOB

CHAR、CLOB

表7-7 SQLへのXML Schemaバイナリ・データ型(hexBinary/base64Binary)のマッピング

XML Schemaバイナリ型

lengthまたはmaxLengthファセット

デフォルトSQLデータ型

互換性のあるSQLデータ型

hexBinary、base64Binary

n

n < 2000の場合はRAW(n)、それ以外の場合はRAW(2000)

RAW、BLOB

hexBinary、base64Binary

-

mapUnboundedStringToLob = "false"の場合はRAW(2000)、BLOB

RAW、BLOB

表7-8 SQLへのXML Schema数値基本型のデフォルトのマッピング

XML Schema simpleType

デフォルトSQLデータ型

指定されたtotalDigits (m)、fractionDigits(n)

互換性のあるSQLデータ型

float

NUMBER

NUMBER(m+n,n)

FLOAT、DOUBLE、BINARY_FLOAT

double

NUMBER

NUMBER(m+n,n)

FLOAT、DOUBLE、BINARY_DOUBLE

decimal

NUMBER

NUMBER(m+n,n)

FLOAT、DOUBLE

integer

NUMBER

NUMBER(m+n,n)

NUMBER

nonNegativeInteger

NUMBER

NUMBER(m+n,n)

NUMBER

positiveInteger

NUMBER

NUMBER(m+n,n)

NUMBER

nonPositiveInteger

NUMBER

NUMBER(m+n,n)

NUMBER

negativeInteger

NUMBER

NUMBER(m+n,n)

NUMBER

long

NUMBER(20)

NUMBER(m+n,n)

NUMBER

unsignedLong

NUMBER(20)

NUMBER(m+n,n)

NUMBER

int

NUMBER(10)

NUMBER(m+n,n)

NUMBER

unsignedInt

NUMBER(10)

NUMBER(m+n,n)

NUMBER

short

NUMBER(5)

NUMBER(m+n,n)

NUMBER

unsignedShort

NUMBER(5)

NUMBER(m+n,n)

NUMBER

byte

NUMBER(3)

NUMBER(m+n,n)

NUMBER

unsignedByte

NUMBER(3)

NUMBER(m+n,n)

NUMBER

表7-9 XML Schema日時データ型のSQLへのマッピング

XML Schema日時型

デフォルトSQLデータ型

互換性のあるSQLデータ型

dateTime

TIMESTAMP

TIMESTAMP WITH TIME ZONE、DATE

time

TIMESTAMP

TIMESTAMP WITH TIME ZONE、DATE

date

DATE

TIMESTAMPWITHTIMEZONE

gDay

DATE

TIMESTAMPWITHTIMEZONE

gMonth

DATE

TIMESTAMPWITHTIMEZONE

gYear

DATE

TIMESTAMPWITHTIMEZONE

gYearMonth

DATE

TIMESTAMPWITHTIMEZONE

gMonthDay

DATE

TIMESTAMPWITHTIMEZONE

duration

VARCHAR2(4000)

なし

表7-10 SQLへのその他のXML Schema基本および派生データ型のデフォルトのマッピング

XML Schema基本および派生型

デフォルトSQLデータ型

互換性のあるSQLデータ型

boolean

RAW(1)

VARCHAR2

language(文字列)

VARCHAR2(4000)

CLOB、CHAR

NMTOKEN(文字列)

VARCHAR2(4000)

CLOB、CHAR

NMTOKENS(文字列)

VARCHAR2(4000)

CLOB、CHAR

Name(文字列)

VARCHAR2(4000)

CLOB、CHAR

NCName(文字列)

VARCHAR2(4000)

CLOB、CHAR

ID

VARCHAR2(4000)

CLOB、CHAR

IDREF

VARCHAR2(4000)

CLOB、CHAR

IDREFS

VARCHAR2(4000)

CLOB、CHAR

ENTITY

VARCHAR2(4000)

CLOB、CHAR

ENTITIES

VARCHAR2(4000)

CLOB、CHAR

NOTATION

VARCHAR2(4000)

CLOB、CHAR

anyURI

VARCHAR2(4000)

CLOB、CHAR

anyType

VARCHAR2(4000)

CLOB、CHAR

anySimpleType

VARCHAR2(4000)

CLOB、CHAR

QName

XDB.XDB$QNAME

なし

normalizedString

VARCHAR2(4000)

なし

token

VARCHAR2(4000)

なし

サポートされないNCHAR、NVARCHARおよびNCLOBのSQLType値

Oracle XML DBでは、NCHAR、NVARCHARおよびNCLOBは、属性SQLTypeの値としてサポートされません。XML要素または属性の型にNCHAR、NVARCHARまたはNCLOBを指定できません。また、ユーザー独自のデータ型を提供する場合は、これらのデータ型を使用しないでください。

関連項目:
付録B「Oracle XML DBの制限」

simpleType: SQLのVARCHAR2またはCLOBへのXML文字列のマッピング

XML Schemaで、XML Schemaデータ型が、maxLengthが4000未満の文字列に指定されている場合、このデータ型は、指定された長さのVARCHAR2オブジェクト属性にマップされます。ただし、XML SchemaにmaxLengthが指定されていない場合は、LOBのみにマップできます。これは、ほとんどの文字列の値が小さく、LOBを必要とする値がわずかである場合は、あまり効率的ではありません。

関連項目:
表7-6「XML Schema文字列データ型のSQLへのマッピング」

タイムゾーンの操作

次のXML Schemaデータ型では、オプションのタイムゾーン・インジケータをリテラル値の一部として使用できます。

- xsd:dateTime

- xsd:time

- xsd:date

- xsd:gYear

- xsd:gMonth

- xsd:gDay

- xsd:gYearMonth

- xsd:gMonthDay

デフォルトの場合、XML Schema登録では、xsd:dateTimeとxsd:timeはSQLデータ型TIMESTAMPにマップされ、他のすべてのデータ型はSQLデータ型DATEにマップされます。SQLデータ型TIMESTAMPとDATEには、タイムゾーン・インジケータを使用できません。

アプリケーションとタイムゾーン・インジケータの連動が必要な場合は、属性SQLTypeを使用して、SQL型をTIMESTAMP WITH TIME ZONEに指定してください。これによって、タイムゾーン・インジケータが含まれている値の適切な格納および取出しを実行できます。次に例を示します。

<element name="dob" type="xsd:dateTime"
xdb:SQLType="TIMESTAMP WITH TIME ZONE"/>
<attribute name="endofquarter" type="xsd:gMonthDay"
xdb:SQLType="TIMESTAMP WITH TIME ZONE"/>

値の最後にZを使用したUTCタイムゾーンの指定

XML Schemaでは、UTCタイムゾーンを表すために、タイムゾーン・コンポーネントにZを指定できます。最後にZが付く値をSQL TIMESTAMP WITH TIME ZONE列に格納すると、そのタイムゾーンは実質的に+00:00として格納されます。したがって、取得したタイムゾーン値の最後には、元のZではなく、+00:00が付いています。たとえば、入力XML文書の値が1973-02-12T13:44:32Zの場合、出力は1973-02-12T13:44:32.000000+00:00になります。

SQLへのcomplexTypeのマッピング

XML Schemaを使用すると、次のようにcomplexTypeがSQLオブジェクト型にマップされます。

- complexType内で宣言されたXML属性は、SQLオブジェクト属性にマップされます。XML属性を定義するsimpleTypeによって、対応するオブジェクト属性のSQLデータ型が決定されます。

- complexType内で宣言されたXML要素も、SQLオブジェクト属性にマップされます。XML要素を定義するsimpleTypeまたはcomplexTypeによって、対応するオブジェクト属性のSQLデータ型が決定されます。

属性maxOccurs > 1でXML要素が宣言されると、そのXML要素はSQLのcollection(オブジェクト)属性にマップされます。collectionは、VARRAY値(デフォルト、推奨)または順序付けられていない表(属性xdb:maintainOrderがfalseに設定されている場合)になります。VARRAY値のデフォルトの記憶域はOrdered Collection Table(OCT)です。属性xdb:storeVarrayAsTableをfalseに設定することによって、かわりにLOB記憶域を選択できます。

complexTypeのXML Schema宣言での属性の指定

グローバルなcomplexTypeに基づく要素が存在する場合は、complexType宣言にSQLTypeおよびSQLSchema属性の両方を指定する必要があります。また、要素の宣言内に同じSQLTypeおよびSQLSchema属性を必要に応じて含めることもできます。

グローバルなcomplexTypeに属性SQLTypeを指定しない場合、内部生成された名前を持つSQLType属性がOracle XML DBによって作成されます。このグローバルな型を参照する要素では、SQLTypeに異なる値を指定できません。次のコードが許容されます。

<xs:complexType name="LineItemsType" xdb:SQLType="LINEITEMS_T">
<xs:sequence>
<xs:element name="LineItem" type="LineItemType" maxOccurs="unbounded"
xdb:SQLName="LINEITEM" xdb:SQLCollType="LINEITEM_V"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemType" xdb:SQLType="LINEITEM_T">
<xs:sequence>
<xs:element name="Description" type="DescriptionType"
xdb:SQLName="DESCRIPTION"/>
<xs:element name="Part" type="PartType" xdb:SQLName="PART"/>
</xs:sequence>
<xs:attribute name="ItemNumber" type="xs:integer" xdb:SQLName="ITEMNUMBER"
xdb:SQLType="NUMBER"/>
</xs:complexType>
<xs:complexType name="PartType" xdb:SQLType="PART_T">
<xs:attribute name="Id" xdb:SQLName="PART_NUMBER" xdb:SQLType="VARCHAR2">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="10"/>
<xs:maxLength value="14"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Quantity" type="moneyType" xdb:SQLName="QUANTITY"/>
<xs:attribute name="UnitPrice" type="quantityType" xdb:SQLName="UNITPRICE"/>
</xs:complexType>

8 構造化記憶域のXPathリライト

この章では、Oracle XML DBの構造化(オブジェクト・リレーショナル)記憶域のXPathリライトの基礎について説明します。様々なSQL関数のXPath式引数のリライトについて詳しく説明します。

この章の内容は次のとおりです。

- 構造化記憶域のXPathリライトの概要

- リライトされるXPath式のサンプル

- 実行計画を使用したXPath問合せの分析および最適化

関連項目:
「XQuery用のパフォーマンス・チューニング」

構造化記憶域のXPathリライトの概要

Oracle XML DBでは、XPath式を使用する問合せ(たとえば、XPath(XQuery)式を引数として取るXMLQuery、XMLTable、XMLExists、updateXMLなどのSQL関数を使用する問合せ)を最適化できることがよくあります。XPath式はXML文書に対して評価されますが、このときメモリー内でそのXML文書が構成されることはありません。

この最適化をXPathリライトと呼びます。これはXML問合せの最適化の適切なサブセットで、XPath式でないXQuery式(FLWOR式など)の最適化も行われます。また列に索引が存在する場合、XPathリライトによって、オプティマイザによる問合せの評価にその索引を使用できるようになります。

Oracle XML DBによってリライトできるXPath式は、Oracle XML DBでサポートされているXPath式の適切なサブセットです。機能性を損わずにXPath式をリライトできる場合は、リライト可能なXPath式を使用してください。

XPathリライトは、次のような状況(またはこれらの状況の組合せ)で可能です。

- XMLTypeデータがオブジェクト・リレーショナル形式の列または表(構造化記憶域)に格納されている場合、またはリレーショナル・データに基づいてXMLTypeビューが構築されている場合。

- XMLIndex索引を使用する場合。「XMLIndex」を参照してください。

- XMLTypeデータがバイナリXMLとして格納されている場合。ストリーミング評価の詳細は、「Oracle XML DBでのXMLTypeメソッドおよびSQL関数の処理」を参照してください。

この章では、第1のケースである、構造化XMLデータまたはXMLTypeビューを使用する問合せのリライトについて説明します。XMLTypeビューは、XML Schemaに基づくビューでも、XML Schemaに基づかないビューでもかまいません。XMLTypeデータの構造化記憶域は常に、XML Schemaに基づいています。この章の例は、XML Schemaに基づく表に関するものです。

例8-1は、XPath式を使用する単純な問合せのXPathリライトを示しています。

例8-1 XPathリライト

SELECT po.OBJECT_VALUE FROM purchaseorder po
WHERE XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(128))
= 'Sarah J. Bell';

XMLCast(XMLQuery...))式は、発注書の要求者情報が格納される、基礎となるリレーショナル列にリライトされます。この問合せは次のようにリライトされます脚注1。

SELECT OBJECT_VALUE FROM purchaseorder p
WHERE CAST (p."XMLDATA"."REQUESTOR" AS VARCHAR2(128)) = 'Sarah J. Bell';

リライトされるXPath式のサンプル

表8-1は、XPathリライトでリライトされるいくつかのXPath式を示しています。

表8-1 基礎となるSQL構造体にリライトされるXPath式のサンプル

変換されるXPath式

説明

単純なXPath式(childおよびattribute軸のみを持つ式):

/PurchaseOrder/@Reference

/PurchaseOrder/Requestor

属性自体が単純なスカラー型またはオブジェクト型である場合、オブジェクト型の属性のみに対して全検索が行われます。

コレクション全検索式:

/PurchaseOrder/LineItems/LineItem/Part/@Id

コレクション式の全検索が行われます。サポートされる軸は、child軸およびattribute軸のみです。CREATE INDEX操作の間にSQL関数が使用される場合、コレクションの全検索はサポートされません。

述語:

[Requestor = "Sarah J. Bell"]

XPathの述語は、SQL述語にリライトされます。

リスト索引(位置指定述語):

LineItem[1]

コレクションのn番目の項目にアクセスするように索引がリライトされます。

ワイルド・カード全検索:

/PurchaseOrder/*/Part/@Id

ワイルドカードを1つ以上の単純なXPath式に変換できる場合は、リライトされます。

descendant軸(XML Schemaに基づくデータのみ)、再帰なし:

/PurchaseOrder//Part/@Id

ワイルド・カード式と同様です。descendant軸は、1つ以上の単純なXPath式にマップできる場合にリライトされます。

descendant軸(XML Schemaに基づくデータのみ)、再帰あり:

/PurchaseOrder//Part/@Id

両方の条件を満たす場合、descendant軸はリライトされます。

- このXPath式が展開される単純なXPath式は、すべて同じ表外の表にマップされます。

- このXPath式が展開されない単純なXPath式はすべて、その表外の表にはマップされません。

XPath関数

一部のXPath関数がリライトされます。これらの関数には、not、floor、ceiling、substringおよびstring-lengthがあります。

関連項目:
XQuery式のリライトの詳細は、「XQuery用のパフォーマンス・チューニング」を参照してください。

実行計画を使用したXPath問合せの分析および最適化

この項では、XPath式を使用する問合せで、次の操作を実行するための実行計画を使用する場合のガイドラインについて説明します。

- 問合せ計画の分析による、XPathリライトが行われるかどうかの判断。

- 2次索引を使用した問合せ実行の最適化。

これらのガイドラインを一緒に使用し、適用されるすべての事項を考慮します。

この章の残りの部分にも当てはまりますが、この項は、オブジェクト・リレーショナル形式(構造化記憶域)で格納されるXMLTypeデータのみに適用されます。

オブジェクト・リレーショナル記憶域のXPathリライトとは、XPath式で定義されるXMLフラグメントを選択する問合せが、基礎となるオブジェクト・リレーショナル表および列のSQL SELECT文にリライトされることです。基礎となるこれらの表には、表外の表を含めることができます。

関連項目:
「表外の表に対するXPathリライト」

ガイドライン: 実行計画内のXML関数に対する基礎となる表の検索

リライトされた問合せの実行計画は、問合せ対象のXMLTypeデータの基礎となるオブジェクト・リレーショナル表および列を参照します。

基礎となる表の名前は、XML要素または属性名から導出された場合、または適用されるXML Schemaによりxdb:defaultTable注釈を使用して明示的に名前が付けられる場合に、意味を持つ場合があります。そうでない場合、名前はシステムにより生成され、明確な意味を持ちません。これらの名前には、対応するXML要素または属性の名前はを反映されません。また、システム生成の列の一部は非表示です。SQL describeコマンドを使用すると、それらは表示できません。その場合でも実行計画には表示されます。

リライトされていない問合せの計画には、実表の名前のみが表示され、通常は、XMLExistsなどのユーザー・レベルXML関数を参照します。問合せが最適化されているかどうかを判断するには、この違いを調べてください。実行計画に表示されるXML関数名は、実際には内部名(XMLEXISTS2など)で、ユーザー・レベルの名前と多少異なることがあります。

例8-2に、Oracle XML DBがXPathリライトを実行できない場合に生成される実行計画の出力の種類を示します。ここでの計画はSQL/XML関数XMLExistsを使用する問合せに対するものです。計画の出力に、対応する内部関数XMLExists2があり、これは問合せがリライトされないことを示します。

例8-2 XPathリライトを実行しない場合に生成される実行計画

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(XMLEXISTS2('$p/PurchaseOrder[User="SBELL"]' PASSING BY VALUE
SYS_MAKEXML('61687B202644E297E040578C8A175C1D',4215,"PO"."XMLEXTRA","PO"."X
MLDATA") AS "p")=1)

この場合、Oracle XML DBは、問合せのWHERE句で指定した他の条件に基いて、事前フィルタされた結果セットを構成します。次に、この潜在的な結果セットの行をフィルタして、結果セットに属する行を決定します。フィルタリングでは、各文書でDOMが構築され、機能評価が実行され(DOM APIにより定義されたメソッドを使用)、各文書が結果セットのメンバーかどうかが判断されます。

ガイドライン: 実行計画で認識するためのデフォルト表の名前付け

XML Schemaを設計する場合は、注釈xdb:defaultTableを使用して、基礎となる表に名前を付けます。この表はパフォーマンスが重要な問合せで選択する要素に対応します。これにより、実行計画でそれらを容易に識別できるようになり、問合せがリライトされたかどうかがわかります。

ガイドライン: 述語でターゲットとなっている列に対する索引の作成

XPathリライトから生成された問合せには、SQL述語(WHERE句)が含まれる場合があります。これは、元の問合せでXPath述語が使用されない場合や、元の問合せにSQL WHERE句がない場合でも発生することがあります。

この場合は、SQL述語のターゲットとなる列に対して索引を作成したり、その列の関数適用に対して索引を作成することで、パフォーマンスを向上できる場合があります。例8-1は、WHERE句を含む問合せのXPathリライトを示しています。例8-3は、この問合せの実行計画からの述語情報を示しています。

例8-3 実行計画の分析による列と索引の対応の特定

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(CAST("PURCHASEORDER"."SYS_NC00021$" AS VARCHAR2(128))='Sarah
J. Bell' AND SYS_CHECKACL("ACLOID","OWNERID",xmltype('<privilege
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd DAV:http://xmlns.oracle.com/xdb/dav.xsd
"><read-properties/><read-contents/></privilege>'))=1)

述語情報では、発注書SYS_NC0021$の要求者情報が格納される、基礎となるリレーショナル列のSQL関数castの使用に合せて、XMLCast(XMLQuery...))式がリライトされることを示します。この列名はシステム生成されます。適用されるXML Schemaでは、注釈SQLNameを使用してこの列REQUESTORに名前を付けますが、実行計画では、システム生成されたこの名前を参照します。

これらの2つの名前(ユーザー定義およびシステム生成)は同じ列を参照するため、いずれかの名前を使用して、この列に対してBツリー索引を作成できます。また、extractValueショートカットを使用し、発注書の要求者データをターゲットとするXPath式を指定することで索引を作成することもできます。例8-4は、述語でターゲットとなっている列に対してBツリー索引を作成する3つの同等の方法を示しています。

例8-4 述語でターゲットとなっている列に対する索引の作成

CREATE INDEX requestor_index ON purchaseorder ("SYS_NC00021$");

CREATE INDEX requestor_index ON purchaseorder ("XMLDATA"."REQUESTOR");

CREATE INDEX requestor_index ON purchaseorder
(extractvalue(OBJECT_VALUE, '/PurchaseOrder/Requestor'));

ただし、この問合せでは、リライトされた問合せの式に一致するファンクション式を使用してファンクション索引を作成することをお薦めします。例8-5に、これを示します。

例8-5 述語でターゲットとなっている列に対するファンクション索引の作成

CREATE INDEX requestor_index ON purchaseorder
(cast("XMLDATA"."REQUESTOR" AS VARCHAR2(128)));

例8-6は、索引が取り出されることを示す実行計画を示しています。

例8-6 索引が選択されていることを示す実行計画

-----------------------------------------------------------------------------------------------
| Id  | Operation                   | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                 |     1 |   524 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| PURCHASEORDER   |     1 |   524 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | REQUESTOR_INDEX |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(SYS_CHECKACL("ACLOID","OWNERID",xmltype('<privilege
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd
DAV:http://xmlns.oracle.com/xdb/dav.xsd">
<read-properties/><read-contents/></privilege>'))=1)
2 - access(CAST("SYS_NC00021$" AS VARCHAR2(128))='Sarah J. Bell')

この問合せの場合では、元のファンクション式によってXMLCastがXMLQueryに適用され、単一要素のRequestorがターゲットになります。これは、CREATE INDEX文でこうしたファンクション式をショートカットとして直接使用できる特殊なケースです。基礎となるスカラー・データ上に索引を作成するように、その文がリライトされます。例8-7はXPath式をターゲットとしており、対応するオブジェクト・リレーショナル列をターゲットとする例8-5と同じ結果になります。

例8-7 述語でターゲットとなっている列に対するファンクション索引の作成

CREATE INDEX requestor_index
ON purchaseorder po
(XMLCast(XMLQuery('$p/PurchaseOrder/Requestor' PASSING po.OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(128)));

関連項目:
XMLQueryに適用されるXMLCastのショートカットおよび単一のデータに索引付けするためのextractValueショートカットの使用方法の詳細は、「繰り返し使用しないtext()ノードまたは属性値の索引付け」を参照してください。

ガイドライン: Ordered Collection表に対する索引の作成

Ordered Collection TableまたはXMLTypeインスタンスとしてコレクションが格納されている場合は、コレクションのメンバーに直接アクセスできます。コレクションの各メンバーは表内の行になるため、SQLで直接アクセスできます。

このようなコレクション・メンバーに索引付けすることによって、パフォーマンスを向上できます。これを実行するには、コレクションXML要素またはその属性、および疑似NESTED_TABLE_IDに対応するオブジェクト属性に対して、コンポジット索引を作成します。

例8-8では、部品番号717951002372(Id属性の値が717951002372のPart要素)の発注を含む文書からReference要素を検索する問合せの実行計画を示します。LineItem要素のコレクションは、Ordered Collection Table、lineitem_tableに行として格納されています。

注意:
例8-8では、サンプル・データベース・スキーマOEのpurchaseorder表を使用しません。例3-13で定義したpurchaseorder表を使用します。この表はコレクション要素LineItem用のlineitem_tableという名前のOrdered Collection Table (OCT)を使用します。

例8-8 コレクション要素の選択の実行計画

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Reference'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(4000)) "Reference"
FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder/LineItems/LineItem/Part[@Id="717951002372"]'
PASSING OBJECT_VALUE AS "p");

-------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                        |     1 |   122 |    16  (13)| 00:00:01 |
|   1 |  NESTED LOOPS                |                        |       |       |            |          |
|   2 |   NESTED LOOPS               |                        |     1 |   122 |    16  (13)| 00:00:01 |
|   3 |    SORT UNIQUE               |                        |     1 |    50 |    14   (8)| 00:00:01 |
|*  4 |     TABLE ACCESS FULL        | LINEITEM_TABLE         |     1 |    50 |    14   (8)| 00:00:01 |
|*  5 |    INDEX UNIQUE SCAN         | LINEITEM_TABLE_MEMBERS |     1 |       |     0   (0)| 00:00:01 |
|   6 |   TABLE ACCESS BY INDEX ROWID| PURCHASEORDER          |     1 |    72 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

4 - filter("SYS_NC00009$" IS NOT NULL AND "SYS_NC00011$"='717951002372')
5 - access("NESTED_TABLE_ID"="PURCHASEORDER"."SYS_NC0003400035$")

実行計画は、Ordered Collection Table、lineitem_tableの全体スキャンを示しています。この計画は、purchaseorder表内の文書の数が数百しかなければ許容されますが、表内に数千または数百万の文書がある場合は許容されません。

このような問合せのパフォーマンスを改善するには、属性Idの値を指定した疑似列NESTED_TABLE_IDに直接アクセスできる索引を作成します。しかし、Oracle XML DBでは、XPath式を直接使用してコレクションに対する索引を作成することはできません。索引を作成するには、LineItem要素の管理に使用するSQLオブジェクトの構造を理解する必要があります。その情報に基づいて、従来のオブジェクト・リレーショナルSQLを使用して必要な索引を作成できます。

ここでは、要素LineItemはオブジェクト・タイプlineitem_tのインスタンスとして格納されています。また、要素PartはSQLデータ型part_tのインスタンスとして格納されています。XML属性Idは、オブジェクト属性part_numberにマップされています。これらの情報に基づいて、例8-9に示すように、属性part_numberおよび疑似列NESTED_TABLE_IDに対するコンポジット索引を作成できます。この索引によって、必要な部品を参照するLineItem要素が含まれた発注書に直接アクセスできます。

例8-9 Ordered Collection Tableに直接アクセスするための索引の作成

CREATE INDEX lineitem_part_index ON lineitem_table l (l.part.part_number, l.NESTED_TABLE_ID);

ガイドライン: XMLOptimizationCheckを使用した、問合せがリライトされない理由の特定

問合せが最適化されていない場合、システム変数XMLOptimizationCheckを使用して理由を特定できます。

関連項目:
「XQueryの最適化の診断: XMLOptimizationCheck」

脚注の凡例

脚注1: この例では、サンプルのデータベース・スキーマOEとその表purchaseorderを使用しています。この表のXML Schemaには、REQUESTORなどのSQLオブジェクト属性名を指定するために、属性SQLNameで注釈が付けられています(例3-10を参照)。このような注釈を使用しないと、例では、p."XMLDATA".".REQUESTOR"ではなくp."XMLDATA"."Requestor"が使用されます。

9 XML Schemaの格納と問合せ: 高度

この章では、構造化されたXML Schemaに基づくXMLTypeオブジェクトを格納するための高度なテクニックについて説明します。

関連項目:

- Oracle XML DBでのXML Schemaの使用に関する基本情報は、第7章「XML Schemaの格納と問合せ: 基本」を参照してください。

- Oracle XML DBでのXPath式の最適化の詳細は、第8章「構造化記憶域のXPathリライト」を参照してください。

- XML SchemaをOracle XML DBに登録した後、更新する方法の詳細は、第10章「XML Schemaの拡張」を参照してください。

- http://www.w3.org/TR/xmlschema-0/ - XML Schemaの概要

この章の内容は次のとおりです。

- DBMS_XMLSCHEMA.GENERATESCHEMAを使用したXML Schemaの生成

- 属性の親要素への一意制約の追加

- 表外に格納するための注釈属性SQLInLineのfalse設定

- 表外の表へのコレクションの格納

- オブジェクト・リレーショナル形式で格納されたXMLTypeの表および列のパーティション化

- 完全修飾されたXML Schema URL

- ラージ・オブジェクト(LOB)へのXMLフラグメントのマッピング

- Oracle XML DBでのcomplexTypeの拡張および制限

- XML Schema: 循環依存の操作

- 再帰的スキーマのサポート

- コレクションでの大規模な文書のロードおよび取得

DBMS_XMLSCHEMA.GENERATESCHEMAを使用したXML Schemaの生成

XML Schemaは、デフォルトのマッピングを使用して、オブジェクト・リレーショナル型から自動で生成できます。パッケージDBMS_XMLSCHEMA内のPL/SQL関数generateSchemaおよびgenerateSchemasは、オブジェクト型の名前が含まれる文字列と、Oracle XML DBのXML Schemaが含まれる文字列を取ります。

- 関数generateSchemaはXML Schemaを含むXMLTypeを戻します。オプションで、指定したオブジェクト型により参照されるすべての型、または最上位のみに限定した型に対するXML Schemaを生成できます。

- 関数generateSchemasも同様ですが、XMLSequenceType値を戻す点が異なります。これはXMLTypeインスタンスのVARRAYで、それぞれは異なる名前空間に相当するXML Schemaです。優先XML Schemaの場所のルートURLを指定する、追加のオプション引数も指定できます。
http://xmlns.oracle.com/xdb/schemas/<schema>.xsd

generateSchemaとgenerateSchemasは両方とも、Oracle XML DB注釈を持つXML Schemaを戻します。

例9-1に、オブジェクト型の定義、employee_t、およびそのオブジェクト型のXML Schemaを生成するgenerateSchemaの起動について示します。

例9-1 関数GENERATESCHEMAを使用したXML Schemaの生成

CREATE TYPE employee_t AS OBJECT(empno NUMBER(10),
ename VARCHAR2(200),
salary NUMBER(10,2));

SELECT DBMS_XMLSCHEMA.generateSchema('T1', 'EMPLOYEE_T') FROM DUAL;

DBMS_XMLSCHEMA.GENERATESCHEMA('T1', 'EMPLOYEE_T')
------------------------------------------------------------------------
<xsd:schema targetNamespace="http://ns.oracle.com/xdb/T1"
xmlns="http://ns.oracle.com/xdb/T1"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb
http://xmlns.oracle.com/xdb/XDBSchema.xsd">
<xsd:element name="EMPLOYEE_T" type="EMPLOYEE_TType"
xdb:SQLType="EMPLOYEE_T" xdb:SQLSchema="T1"/>
<xsd:complexType name="EMPLOYEE_TType">
<xsd:sequence>
<xsd:element name="EMPNO" type="xsd:double" xdb:SQLName="empno"
xdb:SQLType="NUMBER"/>
<xsd:element name="ENAME" type="xsd:string" xdb:SQLName="ename"
xdb:SQLType="VARCHAR2"/>
<xsd:element name="SALARY" type="xsd:double" xdb:SQLName="salary"
xdb:SQLType="NUMBER"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

生成されたXML Schemaは、要素EMPLOYEE_Tおよび複合型EMPLOYEE_TTypeを宣言します。名前空間http://xmlns.oracle.com/xdbからの注釈を使用します。

関連項目:
「XML Schemaに基づくXMLType表および列の作成」

属性の親要素への一意制約の追加

XML Schemaに基づいてXMLType表を作成した後、属性の親要素に一意制約を追加する方法を考えてみます。たとえば、自己循環する要素(コレクション)の属性に基づいて一意キーを作成することが考えられます。複数回出現する要素に制約を作成するには、VARRAYをOrdered Collection Table(OCT)として格納します。したがって、OCTに対して制約を作成できます。

例9-2に示すXML Schemaを使用すると、要素<PhoneNumber>の属性Noが複数回出現します。この例は、指定のインスタンス・ドキュメント内で同一の電話番号を繰り返せないことを保証する一意制約を追加する方法を示しています。

例9-2 属性の親要素への一意制約の追加

BEGIN DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'emp.xsd',
SCHEMADOC => '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<xs:element name="Employee" xdb:SQLType="EMP_TYPE">
<xs:complexType>
<xs:sequence>
<xs:element name="EmployeeId" type="xs:positiveInteger"/>
<xs:element name="PhoneNumber" maxOccurs="10"/>
<xs:complexType>
<xs:attribute name="No" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>',
LOCAL     => FALSE,
GENTYPES  => FALSE);
END;/

PL/SQL procedure successfully completed.

CREATE TABLE emp_tab OF XMLType
XMLSCHEMA "emp.xsd" ELEMENT "Employee"
VARRAY XMLDATA."PhoneNumber" STORE AS TABLE phone_tab;

Table created.

ALTER TABLE phone_tab ADD UNIQUE (NESTED_TABLE_ID, "No");

Table altered.

INSERT INTO emp_tab
VALUES(XMLType('<Employee>
<EmployeeId>1234</EmployeeId>
<PhoneNumber No="1234"/>
<PhoneNumber No="2345"/>
</Employee>').createSchemaBasedXML('emp.xsd'));

1 row created.

INSERT INTO emp_tab
VALUES(XMLType('<Employee>
<EmployeeId>3456</EmployeeId>
<PhoneNumber No="4444"/>
<PhoneNumber No="4444"/>
</Employee>').createSchemaBasedXML('emp.xsd'));

これによって、予期した結果が戻ります。

*
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.SYS_C002136) violated

この例の制約は、個々のコレクションに対して適用され、すべてのインスタンスには適用されません。制約は、コレクションID列を持つ連結索引を作成することで適用されます。全インスタンス・ドキュメントのコレクションすべてに制約を適用するには、コレクションID列を省略します。

注意:
バイナリXMLとして格納されたXMLTypeデータに対する一意キーまたは外部キーの制約としてのみ、機能上の制約を作成できます。

表外に格納するための注釈属性SQLInLineのfalse設定

デフォルトでは、XMLTypeデータがオブジェクト・リレーショナル形式で格納される場合、子XML要素は埋込みSQLオブジェクト属性にマップされます。ただし、表外に格納することによってパフォーマンスが向上する場合もあります。そのような場合は、XML Schema注釈(属性)xdb:SQLInlineをfalseに設定すると、REF属性が埋め込まれたSQLオブジェクト型がOracle XML DBによって生成されます。REFは、表外に格納されるXMLフラグメントに対応するXMLTypeの他のインスタンスを指します。また、デフォルトのXMLType表が作成され、この表に表外のフラグメントが格納されます。

図9-1に、表外に格納するためのSQLへのcomplexTypeのマッピングを示します。

図9-1 表外に格納するためのSQLへのcomplexTypeのマッピング

注意:
Oracle Database 11gリリース2(11.2.0.2)以降では、結果がan out-of-line tableとなるXML Schemaを使用するXMLType表を1つだけ作成できます。同じXML Schemaを使用する2つめの表を作成しようとすると、エラーが発生します。

例9-3 表外に格納するためのSQLInLineのfalse設定

DECLARE
doc VARCHAR2(3000) :=
'<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.oracle.com/emp.xsd"
xmlns:emp="http://www.oracle.com/emp.xsd"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<complexType name="EmpType" xdb:SQLType="EMP_T">
<sequence>
<element name="Name" type="string"/>
<element name="Age" type="decimal"/>
<element name="Addr"
xdb:SQLInline="false"
xdb:defaultTable="ADDR_TAB">
<complexType xdb:SQLType="ADDR_T">
<sequence>
<element name="Street" type="string"/>
<element name="City" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<element name="Employee" type="emp:EmpType"
xdb:defaultTable="EMP_TAB"/>
</schema>';
BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL        => 'emp.xsd',
SCHEMADOC        => doc,
ENABLE_HIERARCHY => DBMS_XMLSCHEMA.ENABLE_HIERARCHY_NONE);
END;
/

例9-3では、要素Addrの属性xdb:SQLInlineの値はfalseです。結果のSQLオブジェクト型obj_t2には、埋込みREFオブジェクト属性を含むXMLType列があります。REF属性は、表addr_tabのSQLオブジェクト型obj_t1のXMLTypeインスタンスを指します。表addr_tabは表外に格納されます。列streetおよびcityが含まれます。

このXML Schemaを登録すると、Oracle XML DBによって、例9-4の型およびXMLType表が生成されます。

例9-4 生成されたXMLType表および型

DESCRIBE emp_tab
Name                          Null?    Type
----------------------------- -------- ----------------------------------------------------------
TABLE of SYS.XMLTYPE(XMLSchema "emp.xsd" Element "Employee") STORAGE Object-relational TYPE "EMP_T"

DESCRIBE addr_tab
Name                          Null?    Type
----------------------------- -------- --------------------------------------------------------
TABLE of SYS.XMLTYPE(XMLSchema "emp.xsd" Element "Addr") STORAGE Object-relational TYPE "ADDR_T"

DESCRIBE emp_t
emp_t is NOT FINAL
Name                          Null?    Type
----------------------------- -------- --------------------
SYS_XDBPD$                             XDB.XDB$RAW_LIST_T
Name                                   VARCHAR2(4000 CHAR)
Age                                    NUMBER
Addr                                   REF OF XMLTYPE

DESCRIBE addr_t
Name                          Null?    Type
----------------------------- -------- --------------------
SYS_XDBPD$                             XDB.XDB$RAW_LIST_T
Street                                 VARCHAR2(4000 CHAR)
City                                   VARCHAR2(4000 CHAR)

表emp_tabには全従業員の情報が格納され、表外の、表addr_tabに格納されている住所情報を指すオブジェクト参照が含まれています。

このモデルのメリットは、表外の表(addr_tab)を直接問い合せ、住所情報を参照できることです。例9-5は、全従業員について固有の都市情報を取得するために、表addr_tabを直接問い合せる場合を示しています。

例9-5 表外の表の問合せ

INSERT INTO emp_tab
VALUES
(XMLType('<x:Employee
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:x="http://www.oracle.com/emp.xsd"
xsi:schemaLocation="http://www.oracle.com/emp.xsd emp.xsd">
<Name>Abe Bee</Name>
<Age>22</Age>
<Addr>
<Street>A Street</Street>
<City>San Francisco</City>
</Addr>
</x:Employee>'));

INSERT INTO emp_tab
VALUES
(XMLType('<x:Employee
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:x="http://www.oracle.com/emp.xsd"
xsi:schemaLocation="http://www.oracle.com/emp.xsd emp.xsd">
<Name>Cecilia Dee</Name>
<Age>23</Age>
<Addr>
<Street>C Street</Street>
<City>Redwood City</City>
</Addr>
</x:Employee>'));
. . .

SELECT DISTINCT XMLCast(XMLQuery('/Addr/City' PASSING OBJECT_VALUE AS "."
RETURNING CONTENT)
AS VARCHAR2(20))
FROM addr_tab;

CITY
-------------
Redwood City
San Francisco

この格納モデルのデメリットは、Employee要素全体を取得するために、住所に関する別の表にアクセスする必要がある点です。

表外の表に対するXPathリライト

表外に格納されている要素を含むXPath式はリライトできます。リライトされた問合せでは、表外の表との結合が行われます。例9-6は、そのような問合せを示したものです。

例9-6 表外の表のXPathリライト

SELECT XMLCast(XMLQuery('declare namespace x = "http://www.oracle.com/emp.xsd"; (: :)
/x:Employee/Name' PASSING OBJECT_VALUE RETURNING CONTENT)
AS VARCHAR2(20))
FROM emp_tab
WHERE XMLExists('declare namespace x = "http://www.oracle.com/emp.xsd"; (: :)
/x:Employee/Addr[City="San Francisco"]' PASSING OBJECT_VALUE);

XMLCAST(XMLQUERY(...
--------------------
Abe Bee
Eve Fong
George Hu
Iris Jones
Karl Luomo
Marina Namur
Omar Pinano
Quincy Roberts

8 rows selected.

ここでのXQuery式はSQL EXISTS副問合せにリライトされています。これは表addr_tabを問い合せ、表addr_tab内のオブジェクト識別子列を使用して表emp_tabと結合します。オプティマイザは表emp_tabおよびaddr_tabの全表スキャンを使用します。addr_tabに多数のエントリがある場合、例9-7に示すように、cityに索引を作成することで、この問合せの効率を高めることができます。例9-6と同じ問合せの実行計画の断片は、cityの索引が取り出されることを示しています。

例9-7 表外の表での索引の使用

CREATE INDEX addr_city_idx
ON addr_tab (extractValue(OBJECT_VALUE, '/Addr/City'));

|   2 |   TABLE ACCESS BY INDEX ROWID| ADDR_TAB      |     1 |  2012 |     1   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | ADDR_CITY_IDX |     1 |       |     1   (0)| 00:00:01 |
|   4 |   TABLE ACCESS FULL          | EMP_TAB       |    16 | 32464 |     2   (0)| 00:00:01 |

注意:
オブジェクト・リレーショナルに格納されているXMLType表でオプティマイザの統計を収集する場合、XML Schemaで定義されたすべての表、つまりUSER_XML_TABLES内のすべての表で統計を収集することをお薦めします。そのためには、プロシージャDBMS_STATS.gather_schema_statsを使用するか、対象の各表に対してDBMS_STATS.gather_table_statsを使用します。これによりオプティマイザは、XMLTypeデータを格納するために使用されているすべての依存表について情報を取得できます。

関連項目:
第8章「構造化記憶域のXPathリライト」

表外の表へのコレクションの格納

表外に格納するコレクション項目もマップできます。この場合、親要素には、単一のREF列ではなく、コレクションのメンバーを指すREF値のVARRAYが挿入されます。たとえば、各従業員の住所リストがあり、そのリストが例9-8に示すように表外の記憶域にマップされているとします。

例9-8 コレクションの表外格納

DECLARE
doc VARCHAR2(3000) :=
'<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.oracle.com/emp.xsd"
xmlns:emp="http://www.oracle.com/emp.xsd"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<complexType name="EmpType" xdb:SQLType="EMP_T">
<sequence>
<element name="Name" type="string"/>
<element name="Age" type="decimal"/>
<element name="Addr" xdb:SQLInline="false"
maxOccurs="unbounded" xdb:defaultTable="ADDR_TAB">
<complexType xdb:SQLType="ADDR_T">
<sequence>
<element name="Street" type="string"/>
<element name="City" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<element name="Employee" type="emp:EmpType"
xdb:defaultTable="EMP_TAB"/>
</schema>';
BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL        => 'emp.xsd',
SCHEMADOC        => doc,
ENABLE_HIERARCHY => DBMS_XMLSCHEMA.ENABLE_HIERARCHY_NONE);
END;
/

このXML Schemaの登録中に、Oracle XML DBでは例9-3に示すように、表emp_tabおよびaddr_tab、型emp_tおよびaddr_tが生成されます。しかし、このときは、例9-9に示すように、型emp_tには単一のREF属性ではなく、住所を指すREF値のVARRAYが含まれます。

例9-9 生成された表外のコレクション型

DESCRIBE emp_t
emp_t is NOT FINAL
Name                                   Null?    Type
-------------------------------------- -------- --------------------------
SYS_XDBPD$                                      XDB.XDB$RAW_LIST_T
Name                                            VARCHAR2(4000 CHAR)
Age                                             NUMBER
Addr                                            XDB.XDB$XMLTYPE_REF_LIST_T

デフォルトでは、XML Schema属性storeVarrayAsTableは値trueを持ち、これはREF値のVARRAYが表外の中間表に格納されることを意味します。XML Schemaの登録では、取り上げた表および型の作成に加えて、REF値のリストを格納する中間表も作成されるということです。この表にはシステムが生成した名前が付けられますが変更することができます。これは索引を作成する場合などに役立つことがあります。

例9-10 REF値の中間表名の変更

DECLARE
gen_name VARCHAR2 (4000);
BEGIN
SELECT TABLE_NAME INTO gen_name FROM USER_NESTED_TABLES
WHERE PARENT_TABLE_NAME = 'EMP_TAB';
EXECUTE IMMEDIATE 'RENAME "' || gen_name || '"TO emp_tab_reflist';
END;
/

DESCRIBE emp_tab_reflist
Name                    Null?    Type
----------------------- -------- ----------------
COLUMN_VALUE                     REF OF XMLTYPE

例9-11は、サンフランシスコを拠点とする全従業員の名前と居住している町を選択する問合せを示しています。この例では、City要素で住所表を問い合せ、従業員表を使用して逆方向に結合します。示されている実行計画の断片は、表emp_tab_reflistとemp_tabの間の結合を示しています。

例9-11 表外のコレクションのXPathリライト

SELECT em.name, ad.street
FROM emp_tab,
XMLTable(XMLNAMESPACES ('http://www.oracle.com/emp.xsd' AS "x"),
'/x:Employee' PASSING OBJECT_VALUE
COLUMNS name   VARCHAR2(20) PATH 'Name') em,
XMLTable(XMLNAMESPACES ('http://www.oracle.com/emp.xsd' AS "x"),
'/x:Employee/Addr' PASSING OBJECT_VALUE
COLUMNS street VARCHAR2(20) PATH 'Street',
city   VARCHAR2(20) PATH 'City') ad
WHERE ad.city = 'San Francisco';

NAME                 STREET
-------------------- --------------------
Abe Bee              A Street
Eve Fong             E Street
George Hu            G Street
Iris Jones           I Street
Karl Luomo           K Street
Marina Namur         M Street
Omar Pinano          O Street
Quincy Roberts       Q Street

8 rows selected.

|   4 |    TABLE ACCESS FULL         | EMP_TAB_REFLIST |    32 |   640 |     2   (0)| 00:00:01 |
|   5 |   TABLE ACCESS BY INDEX ROWID| EMP_TAB         |     1 |    29 |     1   (0)| 00:00:01 |
|*  6 |    INDEX UNIQUE SCAN         | SYS_C005567     |     1 |       |     0   (0)| 00:00:01 |

パフォーマンスを向上するには、REF値の索引を中間表emp_tab_reflistに作成します。これによって、Oracle XML DBは、住所表を問い合せて、関連する行へのオブジェクト参照(REF)を取得し、そのオブジェクト参照をREF値のリストが格納されている中間表に結合し、従業員表を使用してその中間表を逆方向に結合することができます。

REFに範囲指定または参照制約がある場合にのみ、REF値に索引を作成できます。範囲指定されたREF列には、特定の表内のオブジェクトへのポインタのみが格納されます。表emp_tab_reflistのREF値は、表addr_tab内のオブジェクトのみを参照するので、例9-12に示すように、REF列に有効範囲制約および索引を作成できます。

例9-12 REFへの索引を使用した表外のコレクションのXPathリライト

ALTER TABLE emp_tab_reflist ADD SCOPE FOR (COLUMN_VALUE) IS addr_tab;
CREATE INDEX reflist_idx ON emp_tab_reflist (COLUMN_VALUE);

例9-11と同じ問合せの実行計画の断片は、reflist_idxが取り出されることを示しています。

|   4 |    TABLE ACCESS BY INDEX ROWID| EMP_TAB_REFLIST |     1 |    20 |     1   (0)| 00:00:01 |
|*  5 |     INDEX RANGE SCAN          | REFLIST_IDX     |     1 |       |     0   (0)| 00:00:01 |
|   6 |   TABLE ACCESS BY INDEX ROWID | EMP_TAB         |       |       |            |          |
|*  7 |    INDEX UNIQUE SCAN          | SYS_C005567     |     1 |       |     0   (0)| 00:00:01 |

問合せ内のより選択的な述語が従業員表にある場合、REF値のVARRAYを表emp_tab内に格納するために、XML Schema属性storeVarrayAsTableをfalseに設定することができます。表内にVARRAYを格納することにより、2つの表emp_tabおよびaddr_tabに関連する問合せが、常にemp_tabから実行されるように、効率的に強制します。このため、住所表から逆方向の結合を行う効率的な方法はありません。この方法は従業員数が多い場合には不適切です。コストがかかる表emp_tabの全表スキャンが含まれるためです。

オブジェクト・リレーショナル形式で格納されたXMLTypeの表および列のパーティション化

この項では、構造化記憶域を使用して(つまり、オブジェクト・リレーショナル形式で)格納されたXMLデータについて説明します。

リスト、レンジまたはハッシュのパーティション化を使用してXMLType表やXMLType列が含まれる表をパーティション化すると、デフォルトでデータ内のOrdered Collections Tables(OCT)や表外の表もそれに応じて自動的にパーティション化されます。

この同一レベル・パーティション化は、OCTや表外の表のパーティション化がその親表(実表)のパーティション化スキームに準拠することを意味します。実表のパーティションごとに、対応する子表パーティションが存在します。子要素は、その親要素の実表パーティションに対応する子表パーティションに格納されます。

デフォルトでは、実表パーティションの記憶域属性が、対応する子表のパーティションにも使用されます。特定の子表パーティションについて、これらの記憶域属性を上書きできます。

同様に、デフォルトではOCTパーティションの名前はその実表(親表)と同じですが、この動作は使用する名前を指定することで上書きできます。表外の表パーティション名は、常に親表(実表またはOCT)のパーティションと同じです。

注意:

- オブジェクト・リレーショナル形式で格納されたXMLTypeデータの同一レベル・パーティション化は、Oracle Database 11gリリース1(11.1)より前のリリースでは使用できません。

- 表外に格納されたXMLTypeデータの同一レベル・パーティション化は、Oracle Database 11gリリース2(11.2.0.2)より前のリリースでは使用できません。そのリリース以降、表外に格納された表は共有されません。同じXML Schemaに基づく最上位の表は、そのスキーマが表外の表を指定する場合、2つ作成できません。

キーワードGLOBALをCREATE TABLE文で指定すると、OCTのパーティション化を防ぐことができます。(Oracle Database 11gリリース1(11.1)以降は、デフォルト動作でキーワードLOCALが使用されます)。パーティション化されていないコレクション表からパーティション化されたコレクション表に変換する方法の詳細は、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照してください。

表外の表のパーティション化を防いで、表外の共有を可能にするには、イベント31178をレベル0x200で有効にします。

ALTER SESSION SET EVENTS '31178 TRACE NAME CONTEXT FOREVER, LEVEL 0x200'

関連項目:

- OCTの詳細は、「オブジェクト・リレーショナルなXMLType記憶域の場合のコレクション格納方法の制御」を参照してください。

- キーワードGLOBALおよびLOCALを使用してパーティション付きの表を作成する方法の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

XMLTypeデータのパーティション化の例

XMLType実表のパーティション化情報を指定するには、次の2つの方法があります。

- XML Schemaの登録時にXML Schema注釈xdb:tablePropsを使用

- 表の作成時にCREATE TABLEを使用

例9-13および例9-14に、これを示します。これら2つの例では、結果はまったく同じです。実表purchaseorderが、レンジを指定するためにReference要素を使用してパーティション化されます。明細項目の子表が、実表に対して同一レベルでパーティション化されます。

例9-13は、実表および明細項目の子表をパーティション化するように注釈が付けられた、発注書XML SchemaのPurchaseOrder要素を示します。

例9-13 XML Schemaの登録時のパーティション化情報の指定

<xs:element name="PurchaseOrder" type="PurchaseOrderType"
xdb:defaultTable="PURCHASEORDER"
xdb:tableProps =
"VARRAY XMLDATA.LINEITEMS.LINEITEM
STORE AS TABLE lineitem_table
((PRIMARY KEY (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
PARTITION BY RANGE (XMLDATA.Reference)
(PARTITION p1 VALUES LESS THAN (1000)
VARRAY XMLDATA.LINEITEMS.LINEITEM
STORE AS TABLE lineitem_p1 (STORAGE (MINEXTENTS 13)),
PARTITION p2 VALUES LESS THAN (2000)
VARRAY XMLDATA.LINEITEMS.LINEITEM
STORE AS TABLE lineitem_p2 (STORAGE (MINEXTENTS 13)))"/>

例9-14では、例9-13と同じパーティション化を、実表purchaseorderの作成時に指定しています。

例9-14 表の作成時のパーティション化情報の指定

CREATE TABLE purchaseorder OF XMLType
XMLSCHEMA "http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd"
ELEMENT "PurchaseOrder"
VARRAY "XMLDATA"."LINEITEMS"."LINEITEM" STORE AS TABLE lineitem_table
((PRIMARY KEY (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
PARTITION BY RANGE (XMLDATA.Reference)
(PARTITION p1 VALUES LESS THAN (1000)
VARRAY "XMLDATA"."LINEITEMS"."LINEITEM" STORE AS TABLE lineitem_p1
(STORAGE (MINEXTENTS 13)),
PARTITION p2 VALUES LESS THAN (2000)
VARRAY  "XMLDATA"."LINEITEMS"."LINEITEM" STORE AS TABLE lineitem_p2
(STORAGE (MINEXTENTS 13)));

また例9-13と例9-14は、個々の子表のパーティションのオブジェクト格納オプションを指定する方法も示しています。この場合は、STORAGE句で、子表の各パーティションごとに最初に14Mのエクステントを割り当てることを指定しています。

関連項目:

- 「注釈付きの発注書XML Schema、purchaseOrder.xsd」

- 例3-13「XML Schemaに準拠したXMLType表の作成」

- オブジェクト・リレーショナル形式のデータのパーティション化の詳細は、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照してください。

- パーティション化の詳細は、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照してください。

パーティション・メンテナンス

子表のパーティションの定義やメンテナンスは、手動で行う必要はありません。実表(親表)に対してパーティション・メンテナンスを実行すると、対応するメンテナンスが子表に対しても自動的に実行されます。

ただし、実表に対してのみパーティション・メンテナンスを実行するというのは一般的なルールで、例外もあります。次のような場合は、子表に対してメンテナンスを実行します。

- コレクション・パーティションのデフォルトの物理記憶域属性を変更する場合

- コレクション・パーティションの物理記憶域属性を変更する場合

- コレクション・パーティションを別のセグメント(または別の表領域のセグメント)に移動する場合

- コレクション・パーティションの名前を変更する場合

たとえば、実表の表領域を変更した場合、その変更はその子表パーティションにカスケード処理されません。子表の表領域を変更するには、子表パーティションに対してALTER TABLE MODIFY PARTITIONを手動で使用する必要があります。

前述の例外的な操作を除き、パーティション・メンテナンスは、実表に対してのみ実行します。パーティションの追加、削除および分割などの操作を行います。

子表では、オンラインでのパーティション再定義もサポートされています。実表のオンラインでの再定義の際に、パーティション化されていない子表を、パーティション化された子表にコピーできます。通常は、新しく定義した子表の索引と制約を保護するために、PL/SQLプロシージャDBMS_REDEFINITION.copy_table_dependentsのパラメータ値copy_indexes => 0およびcopy_constraints => falseを指定します。

関連項目:

- SQL文ALTER TABLEの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- PL/SQLパッケージDBMS_REDEFINITIONを使用したオンラインでのパーティション再定義の詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

完全修飾されたXML Schema URL

デフォルトでは、XML Schema URLは、データベースの現行のユーザーの範囲内で参照されます。XML Schema URLは、まず現在のデータベース・ユーザーが所有するローカルのXML Schemaの名前として解決されます。

- 対応するXML Schemaがない場合、グローバルXML Schemaの名前として解決されます。

- 対応するグローバルXML Schemaもない場合、Oracle XML DBでエラーが発生します。

特定のXML Schemaの明示的な参照を可能にするため、Oracle XML DBでは、完全修飾されたXML Schema URLという概念をサポートしています。XML Schema URLの一部として、XML Schemaを所有するデータベース・ユーザーの名前が指定されます。完全修飾されたXML Schema URLは、Oracle XML DBの名前空間に属します。

http://xmlns.oracle.com/xdb/schemas/<database-user>/<schemaURL-minus-protocol>

たとえば、URLがhttp://www.example.com/po.xsdの登録済のグローバルXML Schemaがあり、ユーザーQUINEに、同じURLの登録済のローカルXML Schemaがあるとします。別のユーザーは、完全修飾されたXML SchemaのURLを使用して、次のとおりQUINEが所有するスキーマを参照できます。

http://xmlns.oracle.com/xdb/schemas/QUINE/www.example.com/po.xsd

グローバルXML Schemaの完全修飾されたURLは次のとおりです。

http://xmlns.oracle.com/xdb/schemas/PUBLIC/www.example.com/po.xsd

関連項目:
「ローカルXML SchemaおよびグローバルXML Schema」

ラージ・オブジェクト(LOB)へのXMLフラグメントのマッピング

複合要素をCLOBまたはBLOBとして使用できるように、SQLデータ型を指定できます。たとえば、図9-2では、XMLフラグメント全体がLOB属性に格納されます。これは、XML文書に問合せがほとんど行われない部分があり、通常、これらの部分の取出しおよび格納が全体的に行われている場合に有効です。XMLフラグメントをLOBとして格納することによって、解析、分解および再組立てのオーバーヘッドを軽減できます。

例9-15では、注釈SQLType = "CLOB"を使用して、XML Schemaで要素Addrを定義しています。

例9-15 Oracle XML DBのXML Schema: LOBへのcomplexTypeのXMLフラグメントのマッピング

DECLARE
doc VARCHAR2(3000) :=
'<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.oracle.com/emp.xsd"
xmlns:emp="http://www.oracle.com/emp.xsd"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<complexType name="Employee" xdb:SQLType="OBJ_T">
<sequence>
<element name="Name" type="string"/>
<element name="Age" type="decimal"/>
<element name="Addr" xdb:SQLType="CLOB">
<complexType >
<sequence>
<element name="Street" type="string"/>
<element name="City" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</schema>';
BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.oracle.com/PO.xsd',
SCHEMADOC => doc);
END;

このXML Schemaを登録すると、Oracle XML DBによって、次の型およびXMLType表が生成されます。

CREATE TYPE obj_t AS OBJECT(SYS_XDBPD$ XDB.XDB$RAW_LIST_T,
Name VARCHAR2(4000),
Age NUMBER,
Addr CLOB);

図9-2 キャラクタ・ラージ・オブジェクト(CLOB)へのcomplexTypeのXMLフラグメントのマッピング

Oracle XML DBでのcomplexTypeの拡張および制限

XML Schemaでは、complexTypeの値はcomplexContentおよびsimpleContentに基づいて宣言されます。

- simpleContentは、simpleTypeの拡張として宣言されます。

- complexContentは、次のいずれかとして宣言されます。

- ベース型

- complexTypeの拡張

- complexTypeの制限

この項では、Oracle XML DBのcomplexTypeに対する拡張および制限について説明します。

XML SchemaでのcomplexTypeの宣言: 継承の処理

complexTypeの場合、次のとおりOracle XML DBによってXML Schemaで継承が処理されます。

- 他の複合型を拡張するように宣言された拡張型の場合、ベース型に対応するSQL型が現在のSQL型のスーパータイプとして指定されます。サブcomplexTypeに宣言された追加属性および要素のみが、サブ・オブジェクト型に属性として追加されます。

- 他の複合型を制約するように宣言された拡張型の場合、サブ複合型に対するSQL型がそのベース型のSQL型と同じになるように設定されます。これは、SQLでは継承メカニズムを介したオブジェクト型の制限がサポートされないためです。すべての制約は、XML Schemaでの制限によるものです。

例9-16は、AddressというベースcomplexType、およびUSAddress、IntlAddressという2つの拡張を定義するXML Schemaの登録を示しています。

例9-16 XML Schemaでの継承: complexTypeの拡張としてのcomplexContent

DECLARE
doc VARCHAR2(3000) :=
'<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<xs:complexType name="Address" xdb:SQLType="ADDR_T">
<xs:sequence>
<xs:element name="street" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="USAddress" xdb:SQLType="USADDR_T">
<xs:complexContent>
<xs:extension base="Address">
<xs:sequence>
<xs:element name="zip" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="IntlAddress" final="#all" xdb:SQLType="INTLADDR_T">
<xs:complexContent>
<xs:extension base="Address">
<xs:sequence>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>';
BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.oracle.com/PO.xsd',
SCHAMEDOC => doc);
END;

注意:
対応するcomplexTypeでfinal属性が指定されるため、型intladdr_tはfinal型として作成されます。デフォルトでは、すべてのcomplexTypesを他の型から拡張および制約できるため、すべてのSQLオブジェクト型がfinalではない型として作成されます。

CREATE TYPE addr_t AS OBJECT(SYS_XDBPD$ XDB.XDB$RAW_LIST_T,
"street" VARCHAR2(4000),
"city" VARCHAR2(4000)) NOT FINAL;
CREATE TYPE usaddr_t UNDER addr_t ("zip" VARCHAR2(4000)) NOT FINAL;
CREATE TYPE intladdr_t UNDER addr_t ("country" VARCHAR2(4000)) FINAL;

例9-17は、ベースのcomplexTypeのAddress、およびcountry属性を指定できないようにする制限型LocalAddressを定義するXML Schemaの登録を示しています。

例9-17 XML Schemaでの継承: complexTypeの制限

DECLARE
doc varchar2(3000) :=
'<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<xs:complexType name="Address" xdb:SQLType="ADDR_T">
<xs:sequence>
<xs:element name="street" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="zip" type="xs:string"/>
<xs:element name="country" type="xs:string" minOccurs="0"
maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LocalAddress" xdb:SQLType="USADDR_T">
<xs:complexContent>
<xs:restriction base="Address">
<xs:sequence>
<xs:element name="street" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="zip" type="xs:string"/>
<xs:element name="country" type="xs:string"
minOccurs="0" maxOccurs="0"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:schema>';
BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.oracle.com/PO.xsd',
SCHEMADOC => doc);
END;

SQLでの継承は制限の概念がサポートされないため、制限されたcomplexTypeに対応するSQLデータ型は、親オブジェクト型の空のサブタイプになります。例9-17のXML Schemaでは、Oracle XML DBによって次のSQL型が生成されます。

CREATE TYPE addr_t AS OBJECT (SYS_XDBPD$ XDB.XDB$RAW_LIST_T,
"street"   VARCHAR2(4000),
"city"     VARCHAR2(4000),
"zip"      VARCHAR2(4000),
"country"  VARCHAR2(4000)) NOT FINAL;
CREATE TYPE usaddr_t UNDER addr_t;

complexTypeのマッピング: simpleContentからオブジェクト型

simpleContent宣言に基づく複合型は、XML属性に対応する属性および本体の値に対応する追加のSYS_XDBBODY$属性を持つオブジェクト型にマップされます。本体属性のデータ型は、本体の型を定義するsimpleTypeに基づきます。

例9-18 XML SchemaのcomplexType: simpleContentへのcomplexTypeのマッピング

DECLARE
doc VARCHAR2(3000) :=
'<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.oracle.com/emp.xsd"
xmlns:emp="http://www.oracle.com/emp.xsd"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<complexType name="name" xdb:SQLType="OBJ_T">
<simpleContent>
<restriction base="string">
</restriction>
</simpleContent>
</complexType>
</schema>';
BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.oracle.com/emp.xsd',
SCHEMADOC => doc);
END;

例9-18のXML Schemaでは、Oracle XML DBによって次の型が生成されます。

CREATE TYPE obj_t AS OBJECT(SYS_XDBPD$ XDB.XDB$RAW_LIST_T,
SYS_XDBBODY$ VARCHAR2(4000));

complexTypeのマッピング: anyおよびanyAttribute

Oracle XML DBでは、要素の宣言であるanyおよび属性の宣言であるanyAttributeは、作成されたオブジェクト型のVARCHAR2属性(またはオプションでラージ・オブジェクト(LOB))にマップされます。オブジェクト属性によって、any宣言に一致するXMLフラグメントのテキストが格納されます。

- コンテンツが指定された名前空間に属するように、namespace属性を使用してコンテンツを制限できます。

- any要素宣言内のprocessContents属性は、any宣言に一致するコンテンツに必要な検証レベルを示します。

例9-19のコードでは、オブジェクト型obj_tで、any要素が宣言されて列SYS_XDBANY$にマップされます。また、属性processContentsがany宣言に一致するコンテンツを検証しないことも宣言されます。

例9-19 XML Schema: any/anyAttributeへのcomplexTypeのマッピング

DECLARE
doc VARCHAR2(3000) :=
'<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.oracle.com/any.xsd"
xmlns:emp="http://www.oracle.com/any.xsd"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<complexType name="Employee" xdb:SQLType="OBJ_T">
<sequence>
<element name="Name" type="string"/>
<element name="Age" type="decimal"/>
<any namespace="http://www/w3.org/2001/xhtml"
processContents="skip"/>
</sequence>
</complexType>
</schema>';
BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.oracle.com/emp.xsd',
SCHEMADOC => doc);
END;

例9-19のXML Schemaでは、Oracle XML DBによって次の型が生成されます。

CREATE TYPE obj_t AS OBJECT(SYS_XDBPD$ XDB.XDB$RAW_LIST_T,
Name VARCHAR2(4000),
Age NUMBER,
SYS_XDBANY$ VARCHAR2(4000));

XML Schema: 循環依存の操作

W3C XML Schema勧告では、complexTypesおよびグローバル要素に再帰的参照を挿入できます。たとえば、complexType定義に、同じcomplexTypeに基づく要素を含めることができます。またはグローバル要素に自己参照を含めることができます。いずれの場合も、直接または間接的な参照にできます。この種の構造では、対象の要素が再帰的階層で無限に出現する可能性があるインスタンス・ドキュメントを使用できます。

例9-20 循環依存を使用したXML Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="person" type="personType" xdb:defaultTable="PERSON_TABLE"/>
<xs:complexType name="personType" xdb:SQLType="PERSON_T">
<xs:sequence>
<xs:element name="descendant" type="personType" minOccurs="0"
maxOccurs="unbounded" xdb:SQLName="DESCENDANT"
xdb:defaultTable="DESCENDANT_TABLE"/>
</xs:sequence>
<xs:attribute name="personName" use="required" xdb:SQLName="PERSON_NAME">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:schema>

例9-20のXML Schemaには、循環依存が含まれています。complexType personTypeは、personName属性およびdescendant要素のコレクションで構成されます。descendant要素は、personTypeの実体として定義されます。

XML Schemaの循環依存のためのパラメータGenTablesのTRUE設定

Oracle XML DBでは、この種の構造を定義するXML Schemaをサポートしています。循環を検出して使用不可にし、XML Schema登録時に作成された別々のXMLType表に再帰的要素を行として格納することで、このサポートを実現しています。

したがって、この種の構造を定義するXML Schemaを登録する場合は、パラメータgenTablesがTRUEに設定されていることが重要です。再帰的要素の格納に使用する表の名前は、XML Schemaにxdb:defaultTable注釈を追加することで指定できます。

XML SchemaでのcomplexTypeの宣言: 循環の処理

SQLオブジェクト型では、循環を使用できません。オブジェクト型の生成時、循環が完了した時点でREF属性を設定することによって、XML Schemaでの循環が使用不可になります。このように、データの一部は表外に格納されていても、親であるXML文書の一部として取得されます。

注意:
Oracle Database 11gリリース2(11.2.0.2)以降では、結果がan out-of-line tableとなるXML Schemaを使用するXMLType表を1つだけ作成できます。同じXML Schemaを使用する2つめの表を作成しようとすると、エラーが発生します。

XML Schemaでは、複合型の定義間に循環を設定できます。図9-3にこれを示します。複合型CT1の定義は別の複合型CT2を参照でき、CT2の定義は最初の型CT1を参照します。

XML Schemaでは、複合型の定義間に循環を設定できます。例9-21では、長さが2の循環が作成されます。

例9-21 XML Schema: complexType間での循環

DECLARE
doc VARCHAR2(3000) :=
'<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<xs:complexType name="CT1" xdb:SQLType="CT1">
<xs:sequence>
<xs:element name="e1" type="xs:string"/>
<xs:element name="e2" type="CT2"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CT2" xdb:SQLType="CT2">
<xs:sequence>
<xs:element name="e1" type="xs:string"/>
<xs:element name="e2" type="CT1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>';
BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.oracle.com/emp.xsd',
SCHEMADOC => doc);
END;

SQL型では、型の定義で循環を使用できません。ただし、REF(参照)オブジェクト属性を伴う循環など、弱い循環はサポートされます。必要に応じて強制的にSQLInline="false"を設定することで循環を回避し、循環するXML Schema定義はSQLオブジェクト型にマップされます。これによって、弱いSQL循環が作成されます。

例9-21のXML Schemaでは、Oracle XML DBによって次の型が生成されます。

CREATE TYPE ct1 AS OBJECT (SYS_XDBPD$  XDB.XDB$RAW_LIST_T,
"e1"        VARCHAR2(4000),
"e2"        REF XMLType) NOT FINAL;
CREATE TYPE ct2 AS OBJECT (SYS_XDBPD$  XDB.XDB$RAW_LIST_T,
"e1"        VARCHAR2(4000),
"e2"        CT1) NOT FINAL;

図9-3 同じXML Schemaの異なるcomplexType間での相互参照

循環する複合型に、自己参照する複合型の宣言が含まれる場合があります。例9-22では、SectionT型が自己参照しています。

例9-22 XML Schema: complexType間での循環、自己参照

DECLARE
doc VARCHAR2(3000) :=
'<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<xs:complexType name="SectionT" xdb:SQLType="SECTION_T">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:choice maxOccurs="unbounded">
<xs:element name="body" type="xs:string"
xdb:SQLCollType="BODY_COLL"/>
<xs:element name="section" type="SectionT"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:schema>';
BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.oracle.com/section.xsd',
SCHEMADOC => doc);
END;

例9-22のXML Schemaでは、Oracle XML DBによって次の型が生成されます。

CREATE TYPE body_coll AS VARRAY(32767) OF VARCHAR2(4000);
CREATE TYPE section_t AS OBJECT (SYS_XDBPD$  XDB.XDB$RAW_LIST_T,
"title"     VARCHAR2(4000),
"body"      BODY_COLL,
"section"   XDB.XDB$REF_LIST_T) NOT FINAL;

注意:
例9-22では、オブジェクト属性sectionはXMLTypeインスタンスへのREF参照のVARRAYとして宣言されます。埋込みセクションが複数存在する可能性があるので、属性はVARRAYになります。これはSQLオブジェクトの循環が構成されないようにするためにも、属性はXMLTypeインスタンスのREF参照のVARRAYになります。

complexTypeによる自己参照の方法

http://www.oracle.com/PO.xsdによって識別されるXML Schemaが登録されているとします。この場合、XMLType表のmyPOsを作成し、このXML Schemaの要素PurchaseOrderに準拠するインスタンスをオブジェクト・リレーショナル形式で格納できます。

CREATE TABLE purchaseorder OF XMLType
ELEMENT "http://www.oracle.com/PO.xsd#PurchaseOrder";

図9-4に、スキーマでのcomplexTypeの自己参照の方法を示します。

図9-4 XML Schema内での複合型の自己参照

関連項目:
「XML Schema間での循環参照」

PurchaseOrder要素がマップされているオブジェクト型に対応する、非表示の列が作成されます。また、ネームスペース宣言など、最上位インスタンスのデータを格納するためのXMLEXTRAオブジェクト列が作成されます。XMLEXTRAは、内部での使用に予約されています。

XML Schema間での循環参照

XML Schemaどうしを、通常の方法で逐次的に登録できないように、相互に依存させることができます。そのようなXML Schemaの説明を図9-5に示します。

図の上半分は、3つのXML Schema間の間接循環参照の例を示しています。

図の下半分は、2つのXML Schema間の循環依存の例を示しています。最初に、この簡単な例の詳細を説明します。

図9-5 XML Schema間での循環参照

他のXML Schemaを含むXML Schemaは、その含まれるXML Schemaが存在しない場合には作成できません。xm40a.xsdが存在しない場合、例9-23のXML Schema xm40.xsdの登録は失敗します。

例9-23 存在しないXML Schemaを含むXML Schema

BEGIN DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'xm40.xsd',
SCHEMADOC => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:my="xm40"
targetNamespace="xm40">
<include schemaLocation="xm40a.xsd"/>
<!-- Define a global complextype here -->
<complexType name="Company">
<sequence>
<element name="Name" type="string"/>
<element name="Address" type="string"/>
</sequence>
</complexType>
<!-- Define a global element depending on included schema -->
<element name="Emp" type="my:Employee"/>
</schema>',
LOCAL     => TRUE,
GENTYPES  => TRUE,
GENTABLES => TRUE);
END;
/

ただし、例9-24に示すように、オプションFORCE => TRUEを指定した場合は、XML Schema xm40.xsdを作成できます。

例9-24 FORCEオプションを使用したXML Schema xm40.xsdの登録

BEGIN DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'xm40.xsd',
SCHEMADOC => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:my="xm40"
targetNamespace="xm40">
<include schemaLocation="xm40a.xsd"/>
<!-- Define a global complextype here -->
<complexType name="Company">
<sequence>
<element name="Name" type="string"/>
<element name="Address" type="string"/>
</sequence>
</complexType>
<!-- Define a global element depending on included schema -->
<element name="Emp" type="my:Employee"/>
</schema>',
LOCAL     => TRUE,
GENTYPES  => TRUE,
GENTABLES => TRUE,
FORCE     => TRUE);
END;
/

ただし、例9-25のように、XML Schema xm40.xsdを使用しようとすると失敗します。

例9-25 循環するXML Schemaを使用した表作成の試行

CREATE TABLE foo OF XMLType XMLSCHEMA "xm40.xsd" ELEMENT "Emp";

例9-26に示すように、FORCEオプションを使用してxm40a.xsdも登録すると、CREATE TABLE文で示されるように、両方のXML Schemaを使用できます。

例9-26 FORCEオプションを使用したXML Schema xm40a.xsdの登録

BEGIN DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'xm40a.xsd',
SCHEMADOC => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:my="xm40"
targetNamespace="xm40">
<include schemaLocation="xm40.xsd"/>
<!-- Define a global complextype here -->
<complexType name="Employee">
<sequence>
<element name="Name" type="string"/>
<element name="Age" type="positiveInteger"/>
<element name="Phone" type="string"/>
</sequence>
</complexType>
<!-- Define a global element depending on included schema -->
<element name="Comp" type="my:Company"/>
</schema>',
LOCAL     => TRUE,
GENTYPES  => TRUE,
GENTABLES => TRUE,
FORCE     => TRUE);
END;
/

CREATE TABLE foo  OF XMLType XMLSCHEMA "xm40.xsd"  ELEMENT "Emp";
CREATE TABLE foo2 OF XMLType XMLSCHEMA "xm40a.xsd" ELEMENT "Comp";

したがって、相互に依存するこれらのXML Schemaを登録するには、次のように各スキーマのDBMS_XMLSCHEMA.registerSchemaでFORCEパラメータを使用する必要があります。

1. xm40.xsdを、FORCEモードをTRUEに設定して登録します。

DBMS_XMLSCHEMA.registerSchema("xm40.xsd", "<schema ...", ..., FORCE => TRUE)

この時点では、xm40.xsdを使用できません。

2. xm40a.xsdを、FORCEモードをTRUEに設定して登録します。

DBMS_XMLSCHEMA.registerSchema("xm40a.xsd", "<schema ...", ..., FORCE => TRUE)

これによってxm40.xsdが自動的にコンパイルされ、両方のXML Schemaが有効になります。

再帰的スキーマのサポート

REFを表外の表の再帰構造に格納すると、コンパイル時に構造の深さがわからないので、そのような文書に対するXPath問合せが容易にリライトできないというデメリットがあります。このようなXPath問合せのリライトを有効にするには、すべての再帰構造でDOCID列を使用してルート文書へのポインタを格納し、問合せが表外の上を直接使用して、この列を使用して後戻り結合できるようにします。

例9-27に、再帰的XML Schemaを示します。

例9-27 再帰的XML Schema

<schema targetNamespace="AbcNS" xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:abc="AbcNS" xmlnm:xdb="http://xmlns.oracle.com.xdb">
<element name="AbcCode" xdb:defaultTable="ABCCODETAB">
<complexType>
<sequence>
<element ref="abc:AbcSection"/>
</sequence>
</complexType>
</element>

<element name="AbcSection">
<complexType>
<sequence>
<element name="ID" type="integer"/>
<element name="Contents" type="string"/>
<element ref="abc:AbcSection"/>
</sequence>
</complexType>
</element>
</schema>

文書が相互に関連する再帰的な問合せは、'//'を含むXPath式またはXQuery式、およびXMLTypeインスタンスを受け入れるSQL関数を使用する問合せです。文書が相互に関連する再帰的な問合せは、次の条件の両方を満たすことが問合せのコンパイル時に決定できる場合は、リライトできます。

- XPath式またはXQuery式のターゲットとなるXMLTypeインスタンスのすべてのフラグメントが単一の表外の表に存在すること。

- XMLTypeインスタンスの他のフラグメントが同じ表外の表に存在しないこと。

リライトされた問合せは、DOCID列に基づいて表外の表と結合されます。

'//'を持つその他の問合せもリライトできます。たとえば、スキーマの異なるセクションにある、すべて同じ型のaddress要素がいくつかある場合に、ドキュメント内の場所を特定せずに'//'を持つすべてのaddress要素を頻繁に問合せする場合は、リライトが発生する可能性があります。

スキーマの登録中に、追加のDOCID列が表外のXMLType表に生成されます。この列には文書のOID (Object Identifier Values)つまりルート要素が格納されます。この列はデータが表に挿入されると自動的に移入されます。DOCID列を含む表をエクスポートし、後でそれをインポートできます。

一般的な表外の要素間でのdefaultTableの共有

同じ修飾名(名前空間およびローカル名)と同じ型の表外の要素は、同じデフォルト表に格納されます。特殊な場合として、循環型要素構造のルート要素も表外およびサブ要素と同じ表の中に格納できます(ルート要素も表外に格納されている場合)。

デフォルト表を共有する両方の要素は表外の要素である必要があります。つまり、表外の要素のデフォルト表は最上位要素の表と同じにできません。同じにするには、両方の要素にxdb:SQLInline = "false"を指定し、両方の要素に同じ値を持つ明示的なxdb:defaultTable属性を指定します。

例9-28は、表外の表がABCSECTIONTABに格納されているXML Schemaを示しています。

例9-28 表外の表

<schema targetNamespace="AbcNS" xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:abc="AbcNS" xmlns:xdb="http://xmlns.oracle.com/xdb">
<element name="AbcCode" xdb:defaultTable="ABCCODETAB">
<complexType>
<sequence>
<element ref="abc:AbcSection" xdb:SQLInline="false"/>
</sequence>
</complexType>
</element>

<element name="AbcSection" xdb:defaultTable="">
<complexType>
<sequence>
<element name="ID" type="integer"/>
<element name="Contents" type="string"/>
<element ref="abc:AbcSection" xdb:SQLInline="false"
xdb:defaultTable="ABCSECTIONTAB"/>
</sequence>
</complexType>
</element>
</schema>

例9-28の表外のAbcSection要素は、両方とも同じデフォルト表ABCSECTIONTABを共有しています。

ただし、例9-29は、デフォルト表の無効な共有を示しており、再帰的要素(XyZSection)は同じ表外の表を共有しません。

例9-29 デフォルト表の無効な共有

<schema targetNamespace="XyzNS" xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xyz="XyzNS" xmlns:xdb="http://xmlns.oracle.com/xdb">
<element name="XyzCode" xdb:defaultTable="XYZCODETAB">
<complexType>
<sequence>
<element name="CodeNumber" type="integer" minOccurs="0"/>
<element ref="xyz:XyzChapter" xdb:SQLInline="false"/>
<element ref="xyz:XyzPara" xdb:SQLInline="false" />
</sequence>
</complexType>
</element>

<element name="XyzChapter" xdb:defaultTable="XYZCHAPTAB">
<complexType>
<sequence>
<element name="Title" type="string"/>
<element ref="xyz:XyzSection" xdb:SQLInline="false"
xdb:defaultTable="XYZSECTIONTAB"/>
</sequence>
</complexType>
</element>

<element name="XyzPara" xdb:defaultTable="XYZPARATAB">
<complexType>
<sequence>
<element name="Title" type="string"/>
<element ref="xyz:XyzSection" xdb:SQLInline="false"
xdb:defaultTable="Other_XYZSECTIONTAB"/>
</sequence>
</complexType>
</element>

<element name="XyzSection">
<complexType>
<sequence>
<element name="ID" type="integer"/>
<element name="Contents" type="string"/>
<element ref="xyz:XyzSection" xdb:defaultTable="XYZSECTIONTAB"/>
</sequence>
</complexType>
</element>
</schema>

次の問合せはリライトできません。

SELECT XMLQuery('//XyzSection' PASSING OBJECT_VALUE RETURNING CONTENT)
FROM xyzcode;

DOCIDが存在する場合の問合せのリライト

// XPath式を処理する前に、同じ要素が複数回出現していないか確認します。//の下にあるすべての出現が同じdefaultTableを共有する場合、DOCIDを使用した表に対して問合せをリライトできます。//の下ではなく、その表を共有しているルートの下に、同じ要素の出現が他にある場合、問合せはリライトできません。たとえば、次の要素構造を考えます。

<Book>が<Chapter>および<Part>を含む。<Part>が<Chapter>を含む。

両方の<Chapter>要素が表外に格納されており、同じデフォルト表を共有しているとします。/Book//Chapterという問合せは、<Book>の下にあるすべての<Chapter>要素は同じデフォルト表を共有するので、<Chapter>要素のデフォルト表に対してリライトできます。このため、このXPath問合せは、文書が相互に関連する再帰的なXPath問合せです。

ただし、<Part>の下にあるすべての<Chapter>要素が同じ表を共有している場合でも、/Book/Part//Chapterのような問合せはリライトできません。その理由は、<Book>(同様にその表を共有しているドキュメント・ルート)の下に別の<Chapter>があるからです。

例9-28のXML Schemaで説明したように、DOCIDが存在する状況で//AbcSectionの抽出を行う場合を考えます。

SELECT XMLQuery('//AbcSection' PASSING OBJECT_VALUE RETURNING CONTENT)
FROM abccodetab;

両方のAbcSection要素が、同じ表abcsectiontabに格納されています。抽出は、基礎となるabcsectiontab表に対して適用されます。

DOCIDが存在する状況で次の問合せを考えます。

SELECT XMLQuery('/AbcCode/AbcSection//AbcSection'
PASSING OBJECT_VALUE RETURNING CONTENT)
FROM abccodetab;

前述の例とこの例の両方で、アクセス可能なすべてのAbcSection要素が同じ表外の表に格納されています。ただし、/AbcCode/AbcSectionにある最初のAbcSection要素は、この問合せでは取得できません。結合条件は、親ドキュメント内の異なる位置を区別できないDOCIDなので、表abcsectiontabに対する直接の問合せでは正しい結果が得られません。この場合、文書が相互に関連する再帰的なXPathではないので、問合せのリライトは発生しません。この最上位のAbcSectionがその他とともに表外に格納されていない場合、問合せをリライトできます。

DOCID列の作成の無効化

DBMS_XMLSCHEMA.registerSchemaを呼び出す際、OPTIONSパラメータを指定することで、DOCID列の作成を無効化できます。これにより、スキーマ登録時に生成されるすべてのXMLType表でDOCIDの作成が無効化されます。

OPTIONSパラメータは、データ型PLS_INTEGERの入力パラメータです。デフォルト値は0で、この場合オプションは使用されません。列DOCIDの生成を継承するには、パラメータOPTIONSをDBMS_XMLSCHEMA.REGISTER_NODOCID(つまり1)に設定してください。

関連項目:
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

コレクションでの大規模な文書のロードおよび取得

構成ファイル/xdbconfig.xmlには、ロード操作で使用されるメモリー量を制御するパラメータがあります。これにより、次の条件が満たされた場合は、ロード処理を最適化できます。

- 文書は次のいずれかの方法でロードされます。

- プロトコル(FTP、HTTP(S)、DAV)

- PL/SQL関数DBMS_XDB.createResource

- SQLのINSERT文をXMLType表に使用(XMLType列を除く)

- 文書がXML Schemaに基づいており、大規模なコレクション(maxoccursが大きな数に設定されている要素)を含んでいること。

- 文書のコレクションはOCTとして格納されていること。これがデフォルトの動作です。

次の場合は、最適化が部分的になることがあります。

- 実表にトリガーがある。

- 実表がパーティション化されている。

- コレクションが表外に格納されている(SQLのINSERTのみに適用)。

この最適化の背景にある基本概念は、最適化によって、メモリーとの間で行うコレクションのスワップを、限定されたサイズで可能にすることです。この概念を示すために、発注書XML Schemaに準拠した次の例を考えてみます。

<PurchaseOrder>
<LineItem itemID="1">
...
</LineItem>
.
.
<LineItem itemID="10240">
...
</LineItem>
</PurchaseOrder>

この発注書文書には、10240のLineItem要素のコレクションが含まれています。文書全体をメモリー内で作成し、それをディスクにプッシュすると、メモリーが過度に使用され、場合によってはシステム・メモリーの不足によってロードの障害につながることがあります。これを避けるには、ロード可能ユニットという限定されたメモリー・チャンク内に文書を作成します。

例では、各明細項目が1KBのメモリーを必要とし、それぞれに512KBのロード可能ユニットを使用することにします。それぞれのロード可能ユニットは512の明細項目を含み、こうしたユニットが約20あります。ドキュメントのメモリー表現全体を常に2MB以下にする必要がある場合は、メモリー内に保持されるロード可能ユニットがいつでも4ユニット以下となるようにする必要があります。LRUメカニズムを使用して、ロード可能ユニットをスワップ・アウトできます。

ロード可能ユニットのサイズおよび文書のサイズの限度を制御することで、ロードまたは取得時のメモリー使用量およびパフォーマンスをチューニングできます。通常、ロード可能ユニット・サイズが大きいほど、ディスク・アクセス回数は少なくなりますが、より多くのメモリーを消費します。これはパラメータxdbcore-loadableunit-sizeにより制御されます。デフォルト値は16 KBです。文書に割り当てるメモリーの量は、xdbcore-xobmem-boundパラメータで指定できます。デフォルト値は1 MBです。これらのパラメータの値はキロバイトで指定します。つまり、xdbcore-xobmem-boundのデフォルト値は1024で、xdbcore-loadableunit-sizeのデフォルト値は16です。これらはメモリーを最適に使用する方法に関してシステムにガイドを提供するソフトな制限です。

FTPを使用して文書がロードされる場合、ロード可能ユニット(LU)が作成されてディスクにフラッシュされるパターンは次のようになります。

No LUs
Create LU1[LineItems(LI):1-512]
LU1[LI:1-512], Create LU2[LI:513-1024]
.
.
LU1[LI:1-512],...,Create LU4[LI:1517:2028]    <-   Total memory size = 2M
Swap Out LU1[LI:1-512], LU2[LI:513-1024],...,LU4[LI:1517-2028], Create LU5[LI:2029-2540]
Swap Out LU2[LI:513-1024], LU3, LU4, LU5, Create LU6[LI:2541-2052]
.
.
.
Swap Out LU16, LU17, LU18, LU10, Create LU20[LI:9729-10240]
Flush LU17,LU18,LU19,LU20

xdbcoreパラメータ設定に関するガイドライン

一般に、アドレス指定可能なPGが1GBある場合は、PGAの10分の1を文書に割り当てます。アドレス指定可能なPGAが100MBある場合は、その10分の1をxobcore-xobmem-boundに設定します。文書の完全な取得およびロードでは、xdbcore-loadableunit-sizeをxobcore-xobmem-boundにできるかぎり近づけてください。

最初はxdbcore-loadableunit-sizeをxdbcore-xobmem-bound(50MB)の半分の値に設定します。続いて文書をロードしてみます。

メモリーが不足したらxdbcore-xobmem-boundを下げ、xdbcore-loadableunot-sizeをその値の半分に設定します。このようにして、文書が正常にロードされるまで続けます。

ロードに成功したら、パフォーマンスをよくするためにxdbcore-loadableunit-sizeを上げます。xdbcore-loadableunit-sizeがxdbcore-xobmem-boundと等しい場合は、さらにパフォーマンスを向上させるために両方のパラメータを大きくします。

10 XML Schemaの拡張

この章では、XML SchemaをOracle XML DBに登録した後、更新する方法について説明します。XML Schemaの拡張とは、登録したXML Schemaを更新する処理です。

この章の内容は次のとおりです。

- XML Schemaの拡張の概要

- コピーに基づくスキーマの拡張の使用

- インプレースのXML Schemaの拡張の使用

Oracle XML DBでは、W3C XML Schema勧告をサポートしています。XML Schemaに準拠するXMLインスタンス・ドキュメントは、SQLおよびプロトコル(FTP、HTTP(S)、WebDAVなど)を使用して格納および取得できます。XML Schemaは、XML文書の構造指定に加え、XMLとオブジェクト・リレーショナル記憶域間のマッピングを判断します。

関連項目:
第7章「XML Schemaの格納と問合せ: 基本」

XML Schemaの拡張の概要

Oracle XML DBとともにXML Schemaを使用している開発者にとって、XML文書の内容や構造の変更にどのように対応するかが大きな課題です。環境によっては、新たな法規制、社内の要求または外部の機会などによって生じる変更の必要性の頻度は高く、広範囲にわたる場合があります。たとえば、XML Schema定義に新しい要素や属性を追加したり、データ型を変更したり、出現回数の最小要件や最大要件を調整したりする必要が生じる場合があります。

そのような場合、既存のインスタンス・ドキュメント(データ)を有効にしたまま(または、有効にして)、既存のアプリケーションの稼働中に、新規要件に対応するようにXML Schemaを拡張する必要があります。

既存のドキュメントにこだわらない場合は、単にXML Schemaに依存するXMLType表を削除して古いXML Schemaを削除し、同じURLで新しいXMLを登録できます。ただしほとんどの場合、既存のドキュメントを新規XML Schemaに対応するように変換して保持する必要があります。

Oracle XML DBは次の2種類のスキーマ拡張をサポートしています。

- コピーに基づくスキーマの拡張では、スキーマに準拠するすべてのインスタンス・ドキュメントはデータベースの一時領域にコピーされます。古いスキーマは削除され、変更されたスキーマが登録されます。インスタンス・ドキュメントは、一時領域から新規領域に挿入されます。

- インプレースのスキーマの拡張では、既存のデータのコピー、削除、挿入が不要のため、コピーに基づく拡張よりも高速に実行できます。ただし、コピーに基づく拡張にはない制限があります。
一般的に、インプレースの拡張は、記憶域モデルの変更がなく、変更により既存のドキュメントが無効にならない場合(既存のドキュメントが新規スキーマに準拠している場合、または準拠可能な場合)に許可されます。制限およびガイドラインの詳細は、「インプレースのXML Schemaの拡張の使用」を参照してください。

コピーに基づく拡張にはDBMS_XMLSCHEMA.copyEvolve、インプレースの拡張にはDBMS_XMLSCHEMA.inPlaceEvolveというPL/SQLプロシージャがそれぞれ用意されています。この章では、各プロシージャの使用方法について説明し、それに関連するスキーマの拡張方法のガイドラインを提示します。

コピーに基づくスキーマの拡張の使用

PL/SQLパッケージDBMS_XMLSCHEMAのプロシージャcopyEvolveを使用して、コピーに基づくXML Schemaの拡張を実行します。プロシージャcopyEvolveは、既存のXMLインスタンス・ドキュメントをバックアップのために一時XMLType表にコピーし、古いバージョンのXML Schemaを削除し(関連インスタンス・ドキュメントも削除します)、新しいバージョンを登録して、バックアップしたインスタンス・ドキュメントを新規XMLType表にコピーします。問題が発生した場合、バックアップ・コピーはリストアされます。「プロシージャDBMS_XMLSCHEMA.COPYEVOLVEでのエラー発生時のロールバック」を参照してください。

プロシージャcopyEvolveを使用すると、既存のXMLインスタンス・ドキュメントの有効性を保持しながら、登録されたXML Schemaを拡張できます。

コピーに基づく拡張の使用例

例10-1は、例3-10の発注書XML Schemaの修正バージョンのリストの一部を示します。完全な修正スキーマのリストは、例A-2を参照してください。この例では、太字のテキストが新規部分、または元のスキーマと異なる部分です。

例10-1 修正された発注書XML Schema

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
version="1.0">
<xs:element
name="PurchaseOrder" type="PurchaseOrderType"
xdb:defaultTable="PURCHASEORDER"
xdb:columnProps=
"CONSTRAINT purchaseorder_pkey PRIMARY KEY (XMLDATA.reference),
CONSTRAINT valid_email_address FOREIGN KEY (XMLDATA.userid)
REFERENCES hr.employees (EMAIL)"
xdb:tableProps=
"VARRAY XMLDATA.ACTIONS.ACTION STORE AS TABLE ACTION_TABLE
((CONSTRAINT action_pkey PRIMARY KEY (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
VARRAY XMLDATA.LINEITEMS.LINEITEM STORE AS TABLE LINEITEM_TABLE
((constraint LINEITEM_PKEY primary key (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
lob (XMLDATA.NOTES) STORE AS (ENABLE STORAGE IN ROW STORAGE(INITIAL 4K NEXT 32K))"/>
<xs:complexType name="PurchaseOrderType" xdb:SQLType="PURCHASEORDER_T">
<xs:sequence>
<xs:element name="Actions" type="ActionsType" xdb:SQLName="ACTIONS"/>
<xs:element name="Reject" type="RejectionType" minOccurs="0" xdb:SQLName="REJECTION"/>
<xs:element name="Requestor" type="RequestorType" xdb:SQLName="REQUESTOR"/>
<xs:element name="User" type="UserType" xdb:SQLName="USERID"/>
<xs:element name="CostCenter" type="CostCenterType" xdb:SQLName="COST_CENTER"/>
<xs:element name="BillingAddress" type="AddressType" minOccurs="0"
xdb:SQLName="BILLING_ADDRESS"/>
<xs:element name="ShippingInstructions" type="ShippingInstructionsType"
xdb:SQLName="SHIPPING_INSTRUCTIONS"/>
<xs:element name="SpecialInstructions" type="SpecialInstructionsType"
xdb:SQLName="SPECIAL_INSTRUCTIONS"/>
<xs:element name="LineItems" type="LineItemsType" xdb:SQLName="LINEITEMS"/>
<xs:element name="Notes" type="NotesType" minOccurs="0" xdb:SQLType="CLOB"
xdb:SQLName="NOTES"/>
</xs:sequence>
<xs:attribute name="Reference" type="ReferenceType" use="required" xdb:SQLName="REFERENCE"/>
<xs:attribute name="DateCreated" type="xs:dateTime" use="required"
xdb:SQLType="TIMESTAMP WITH TIME ZONE"/>
</xs:complexType>
<xs:complexType name="LineItemsType" xdb:SQLType="LINEITEMS_T">
<xs:sequence>
<xs:element name="LineItem" type="LineItemType" maxOccurs="unbounded" xdb:SQLName="LINEITEM"
xdb:SQLCollType="LINEITEM_V"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemType" xdb:SQLType="LINEITEM_T">
<xs:sequence>
<xs:element name="Part" type="PartType" xdb:SQLName="PART"/>
<xs:element name="Quantity" type="quantityType"/>
</xs:sequence>
<xs:attribute name="ItemNumber" type="xs:integer" xdb:SQLName="ITEMNUMBER"
xdb:SQLType="NUMBER"/>
</xs:complexType>
<xs:complexType name="PartType" xdb:SQLType="PART_T">
<xs:simpleContent>
<xs:extension base="UPCCodeType">
<xs:attribute name="Description" type="DescriptionType" use="required"
xdb:SQLName="DESCRIPTION"/>
<xs:attribute name="UnitCost" type="moneyType" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="ReferenceType">
<xs:restriction base="xs:string">
<xs:minLength value="18"/>
<xs:maxLength value="30"/>
</xs:restriction>
</xs:simpleType>

. . .

<xs:complexType name="RejectionType" xdb:SQLType="REJECTION_T">
<xs:all>
<xs:element name="User" type="UserType" minOccurs="0" xdb:SQLName="REJECTED_BY"/>
<xs:element name="Date" type="DateType" minOccurs="0" xdb:SQLName="DATE_REJECTED"/>
<xs:element name="Comments" type="CommentsType" minOccurs="0" xdb:SQLName="REASON_REJECTED"/>
</xs:all>
</xs:complexType>
<xs:complexType name="ShippingInstructionsType" xdb:SQLType="SHIPPING_INSTRUCTIONS_T">
<xs:sequence>
<xs:element name="name" type="NameType" minOccurs="0" xdb:SQLName="SHIP_TO_NAME"/>
<xs:choice>
<xs:element name="address" type="AddressType" minOccurs="0"/>
<xs:element name="fullAddress" type="FullAddressType" minOccurs="0"
xdb:SQLName="SHIP_TO_ADDRESS"/>
</xs:choice>
<xs:element name="telephone" type="TelephoneType" minOccurs="0" xdb:SQLName="SHIP_TO_PHONE"/>
</xs:sequence>
</xs:complexType>

. . .

<xs:simpleType name="NameType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="FullAddressType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>

. . .

<xs:simpleType name="DescriptionType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="AddressType" xdb:SQLType="ADDRESS_T">
<xs:sequence>
<xs:element name="StreetLine1" type="StreetType"/>
<xs:element name="StreetLine2" type="StreetType" minOccurs="0"/>
<xs:element name="City" type="CityType"/>
<xs:choice>
<xs:sequence>
<xs:element name="State" type="StateType"/>
<xs:element name="ZipCode" type="ZipCodeType"/>
</xs:sequence>
<xs:sequence>
<xs:element name="Province" type="ProvinceType"/>
<xs:element name="PostCode" type="PostCodeType"/>
</xs:sequence>
<xs:sequence>
<xs:element name="County" type="CountyType"/>
<xs:element name="Postcode" type="PostCodeType"/>
</xs:sequence>
</xs:choice>
<xs:element name="Country" type="CountryType"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="StreetType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="128"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CityType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="64"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="StateType">
<xs:restriction base="xs:string">
<xs:minLength value="2"/>
<xs:maxLength value="2"/>
<xs:enumeration value="AK"/>
<xs:enumeration value="AL"/>
<xs:enumeration value="AR"/>

. . . -- A value for each US state abbreviation

<xs:enumeration value="WY"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ZipCodeType">
<xs:restriction base="xs:string">
<xs:pattern value="\d{5}"/>
<xs:pattern value="\d{5}-\d{4}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CountryType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="64"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CountyType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="32"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PostCodeType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="12"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ProvinceType">
<xs:restriction base="xs:string">
<xs:minLength value="2"/>
<xs:maxLength value="2"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NotesType">
<xs:restriction base="xs:string">
<xs:maxLength value="32767"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UPCCodeType">
<xs:restriction base="xs:string">
<xs:minLength value="11"/>
<xs:maxLength value="14"/>
<xs:pattern value="\d{11}"/>
<xs:pattern value="\d{12}"/>
<xs:pattern value="\d{13}"/>
<xs:pattern value="\d{14}"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

copyEvolveパラメータおよびエラー

プロシージャDBMS_XMLSCHEMA.copyEvolveのシグネチャは、次のとおりです。

procedure copyEvolve(schemaURLs       IN XDB$STRING_LIST_T,
newSchemas       IN XMLSequenceType,
transforms       IN XMLSequenceType := NULL,
preserveOldDocs  IN BOOLEAN := FALSE,
mapTabName       IN VARCHAR2 := NULL,
generateTables   IN BOOLEAN := TRUE,
force            IN BOOLEAN := FALSE,
schemaOwners     IN XDB$STRING_LIST_T := NULL
parallelDegree   IN PLS_INTEGER := 0,
options          IN PLS_INTEGER := 0);

表10-1に、各パラメータについて説明します。表10-2に、このプロシージャに関連するエラーについて説明します。

表10-1 プロシージャDBMS_XMLSCHEMA.COPYEVOLVEのパラメータ

パラメータ

説明

schemaURLs

拡張するXML SchemaのURLのVARRAY(VARCHAR2(4000)のVARRAY)。これには依存スキーマも含まれます。forceパラメータがTRUEでない場合、URLは依存の順序にする必要があります。つまりVARRAY内でURL Aの後にURL Bがある場合は、スキーマAはスキーマBに依存できませんが、スキーマBはスキーマAに依存できます。

newSchemas

新しいXML Schema文書(XMLTypeインスタンス)のVARRAY。対応するURLと同じ順序で正確に指定します。XML Schemaでの変更が不要な場合は、未変更のXML Schemaを指定します。

transforms

XML Schemaに基づく文書を新しいスキーマに準拠させるために、その文書に適用されるXSL文書(XMLTypeインスタンス)のVARRAY。対応するURLと同じ順序で正確に指定します。変換が不要な場合は、このパラメータを指定する必要はありません。

preserveOldDocs

このパラメータがTRUEの場合、スキーマ拡張の終了時に古いデータを保持する一時表は削除されません。「プロシージャCOPYEVOLVEの使用時のガイドライン」も参照してください。

mapTabName

古いXMLType表または列の名前を対応する一時表の名前にマッピングする表の名前を指定します。

generateTables

このパラメータのデフォルトはTRUEです。FALSEの場合、新しいXML Schemaを登録した後にXMLType表または列は生成されません。FALSEの場合、preserveOldDocsはTRUE、mapTabNameはNULL以外の値である必要があります。

force

このパラメータがTRUEの場合、新しいスキーマの登録でのエラーは無視されます。スキーマ間に循環依存がある場合は、登録時にエラーが発生した場合にも各スキーマが格納されるように、このフラグをTRUEに設定します。

schemaOwners

スキーマ所有者名のVARRAY。対応するURLと同じ順序で正確に指定します。

parallelDegree

データのコピーの段階で、PARALLELヒントに使用される並列度を指定します。並列度が0の場合(デフォルト値)PARALLELヒントはデータ・コピー文にありません。

options

その他のオプション。オプションは、COPYEVOLVE_BINARY_XMLのみです。このオプションでは、バイナリXMLデータの新規XML Schemaを登録し、バイナリXMLを含む新規の表または列を記憶域モデルとして作成します。

表10-2 プロシージャDBMS_XMLSCHEMA.COPYEVOLVEに関連するエラー

エラー番号とメッセージ

原因

処置

30942 XML Schema Evolutionエラーです。スキーマ'<schema_url>'、表"<owner_name>.<table_name>"、列'<column_name>'

指定のXML Schemaに準拠する指定のXMLType表または列で、拡張中にエラーが発生しました。表の場合は列名が空になります。このエラーの後に続くエラー・メッセージも参照してください。

このエラーと後続の特定エラーに示されているスキーマ、表および列の情報に基づいて、適切な処置を実行します。

30943 XML Schema '<schema_url>'は、XML Schema '<schema_url>'に依存しています

依存XML Schemaがまったく指定されていないか、またはスキーマが依存順序に指定されていません。つまり、スキーマS1がスキーマSに依存している場合、SはS1よりも前に出現する必要があります。

以前にスキーマのリストに指定されていないスキーマを挿入するか、またはスキーマの指定順序を修正します。その後、操作を再試行します。

30944 XML Schema '<schema_url>'(表<owner_name>.<table_name>、列'<column_name>')のロールバック中にエラーが発生しました

指定のXML Schemaに準拠する指定のXMLType表または列で、XML Schema拡張のロールバック中にエラーが発生しました。表の場合は列名が空になります。このエラーの後に続くエラー・メッセージも参照してください。

このエラーと後続の特定エラーに示されているスキーマ、表および列の情報に基づいて、適切な処置を実行します。

30945 マッピング表'<table_name>'を作成できませんでした

XML Schema拡張中にマッピング表を作成できませんでした。このエラーの後に続くエラー・メッセージも参照してください。

指定した名前の表が存在しないことを確認してから、操作を再試行します。

30946 XML Schema Evolutionの警告: 一時表がクリーンアップされていません

スキーマが拡張された後、一時表のクリーンアップでエラーが発生しました。スキーマの拡張は正常に終了しています。

一時表を削除する必要がある場合は、マッピング表を使用して一時表の名前を取得し、その一時表を削除します。

プロシージャCOPYEVOLVEの制限事項

プロシージャDBMS_XMLSCHEMA.copyEvolveを使用する際は、次の制限事項を考慮してください。

- 拡張するスキーマに依存しているXMLType表に関連する索引、トリガー、制約、行レベルのセキュリティ(RLS)ポリシーおよび他のメタデータは保持されません。これらは、拡張後に再度作成する必要があります。

- 最上位要素名が変更される場合は、copyEvolveの実行終了後にいくつかの手順が必要です。詳細は、「最上位要素名の変更」を参照してください。

- コピーに基づく拡張は、拡張するいずれかのスキーマに依存しているXMLType属性を保持するオブジェクト型の列を備えた表がある場合には、使用できません。たとえば、次の表を参照してください。

CREATE TYPE t1 AS OBJECT (n NUMBER, x XMLType);
CREATE TABLE tab1 (e NUMBER, o t1) XMLType
COLUMN o.x XMLSchema "s1.xsd" ELEMENT "Employee";

最上位要素Employeeを含むXML SchemaがURL s1.xsdに登録されていると仮定します。XMLType属性xを持つ列oを含む表tab1がXML Schemaに依存しているので、このXML Schemaは拡張できません。copyEvolveはXMLTypeオブジェクト属性を処理しないことに注意してください。そのような場合はエラーが発生します。

プロシージャCOPYEVOLVEの使用時のガイドライン

次は、プロシージャDBMS_XMLSCHEMA.copyEvolveの使用に適用される一般的なガイドラインです。この項の後半では、特定のコンテキストに適用される個別のガイドラインについても説明します。

1. ごみ箱をオフにして、削除した表がごみ箱にコピーされないようにします。

ALTER SESSION SET RECYCLEBIN=off;

2. 拡張されるXML Schemaに依存するXML Schemaを識別します。次の問合せを使用して、依存するXML SchemaのURLを取得できます。schema_to_be_evolvedは拡張されるスキーマで、owner_of_schema_to_be_evolvedはその所有者(データベース・ユーザー)です。

SELECT dxs.SCHEMA_URL, dxs.OWNER
FROM DBA_DEPENDENCIES dd, DBA_XML_SCHEMAS dxs
WHERE dd.REFERENCED_NAME = (SELECT INT_OBJNAME
FROM DBA_XML_SCHEMAS
WHERE SCHEMA_URL = schema_to_be_evolved
AND OWNER = owner_of_schema_to_be_evolved)
AND dxs.INT_OBJNAME = dd.NAME;

多くの場合、依存XML Schemaでの変更は不要です。ただし、依存XML Schemaの変更が必要な場合は、それらのXML Schemaの新しいバージョンも用意する必要があります。

3. 既存のインスタンス・ドキュメントが新しいXML Schemaに準拠していない場合、インスタンス・ドキュメントへの適用時にXSLスタイル・シートを指定する必要があります。これにより新しいスキーマに準拠するようにインスタンス・ドキュメントが変換されます。手順2で識別したXML Schemaごとにこれを行う必要があります。この変換では、新しいXML Schemaのすべての最上位要素に準拠するようにドキュメントが処理されます。

4. プロシージャDBMS_XMLSCHEMA.copyEvolveをコールして、XML SchemaのURL、新しいスキーマおよび変換スタイルシートを指定します。

最上位要素名の変更

プロシージャDBMS_XMLSCHEMA.copyEvolveでは、最上位要素は削除されず、新しいXML Schemaでもその名前は変更されていないことを前提としています。新しいXML Schemaでそのような変更がある場合、パラメータgenerateTablesをFALSEに、パラメータpreserveOldDocsをTRUEに設定して、プロシージャcopyEvolveをコールできます。この方法では、新しい表は生成されず、古いドキュメント(バックアップ・コピー)を保持する一時表はプロシージャの最後で削除されません。その場合、古いドキュメントを適切な形式で格納し、一時表を削除できます。これらのパラメータの使用の詳細は、「copyEvolveパラメータおよびエラー」を参照してください。

デフォルト表以外の表のユーザー作成の仮想列

デフォルト表でない表では、コピーに基づく拡張では作成した仮想列は再作成されません。列が必要な場合、preserveOldDocsパラメータをTRUEに設定して表を作成し、プロシージャcopyEvolveが完了した後に古いドキュメントをコピーします。

XML Schemaとその依存が同時セッションで使用されないようにする方法

XML Schemaの拡張処理では、同時セッションでXML Schemaとその依存を使用しないようにしてください。拡張処理の開始時に、他の同時セッションがこのスキーマに対する共有ロックを保持していた場合、プロシージャDBMS_XMLSCHEMA.copyEvolveは、排他ロックを取得できるように、これらのセッションによるロックのリリースを待機します。ただし、このロックは、残りの処理を継続できるようにただちにリリースされます。

プロシージャDBMS_XMLSCHEMA.COPYEVOLVEでのエラー発生時のロールバック

プロシージャDBMS_XMLSCHEMA.copyEvolveでは、正常に実行が完了する場合と、エラーが発生する場合があります。エラーが発生した場合は、できるかぎり多くの操作をロールバックしようとします。XML Schemaの拡張には、多くのデータベースDDL文が含まれます。エラーが発生した場合、補正DDL文が実行され、その地点までに実行されたすべての手順を取り消します。古い表またはスキーマが削除された場合、再作成されますが、表、列、記憶域のプロパティおよび表や列に関連する補助構造(索引、トリガー、制約およびRLSポリシーなど)は失われます。

不十分な権限に起因するロールバックの失敗

場合によっては、コピーに基づく拡張の操作はロールバックできません。たとえば、新規XML Schemaに関係のない理由で表の作成に失敗した場合は、ロールバックする方法がありません。その理由には、不十分な権限による失敗などがあります。一時表はpreserveOldDocsがFALSEに設定されている場合にも削除されないため、データはリカバリできます。mapTabNameパラメータがNULLの場合、マッピング表はXDB$MAPTABの後に順序番号が続く名前となります。正確な表名は、次の問合せを使用して確認できます。

SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME LIKE 'XDB$MAPTAB%';

XML Schemaの拡張に必要な権限

コピーに基づくXML Schemaの拡張では、データ型の削除や作成が必要な場合があります。したがって、DROP TYPE、CREATE TYPEおよびALTER TYPEなどの型に関連する権限が必要です。

スキーマを拡張するには、拡張に関係するXML Schemaを削除および登録する権限が必要です。拡張するスキーマに準拠するXMLType表に対するすべての権限が必要です。XMLType列については、対応する表に対するALTER TABLE権限が必要です。他のデータベース・スキーマ内にXML Schemaに基づくXMLType表または列が存在する場合は、次のような権限が必要です。

- CREATE ANY TABLE

- CREATE ANY INDEX

- SELECT ANY TABLE

- UPDATE ANY TABLE

- INSERT ANY TABLE

- DELETE ANY TABLE

- DROP ANY TABLE

- ALTER ANY TABLE

- DROP ANY INDEX

他のデータベース・スキーマに属するXML Schemaに基づくXMLType表または列がある場合は、これらのすべての権限をデータベース・スキーマ所有者に付与しなくてすむように、データベース管理者が拡張を実行することをお薦めします。

スタイルシートを使用した既存のXMLインスタンス・ドキュメントの更新

登録済のXML Schemaを変更した後は、そのXML Schemaを使用していた既存のXMLインスタンス・ドキュメントも更新する必要があります。更新するには、各インスタンス・ドキュメントにXSLTスタイルシートを適用します。このスタイルシートは、古いXML Schemaと新しいXML Schemaの差分を表します。

例10-2はファイルevolvePurchaseOrder.xsl内のスタイルシートです。これによって、古いXML Schemaを使用していた既存の発注書が新しいXML Schemaを使用するように変換されます。

例10-2 evolvePurchaseOrder.xsl: インスタンス・ドキュメントを更新するスタイルシート

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:template match="/PurchaseOrder">
<PurchaseOrder>
<xsl:attribute name="xsi:noNamespaceSchemaLocation">
http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd
</xsl:attribute>
<xsl:for-each select="Reference">
<xsl:attribute name="Reference">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:variable name="V264_394" select="'2004-01-01T12:00:00.000000-08:00'"/>
<xsl:attribute name="DateCreated">
<xsl:value-of select="$V264_394"/>
</xsl:attribute>
<xsl:for-each select="Actions">
<Actions>
<xsl:for-each select="Action">
<Action>
<xsl:for-each select="User">
<User>
<xsl:value-of select="."/>
</User>
</xsl:for-each>
<xsl:for-each select="Date">
<Date>
<xsl:value-of select="."/>
</Date>
</xsl:for-each>
</Action>
</xsl:for-each>
</Actions>
</xsl:for-each>
<xsl:for-each select="Reject">
<Reject>
<xsl:for-each select="User">
<User>
<xsl:value-of select="."/>
</User>
</xsl:for-each>
<xsl:for-each select="Date">
<Date>
<xsl:value-of select="."/>
</Date>
</xsl:for-each>
<xsl:for-each select="Comments">
<Comments>
<xsl:value-of select="."/>
</Comments>
</xsl:for-each>
</Reject>
</xsl:for-each>
<xsl:for-each select="Requestor">
<Requestor>
<xsl:value-of select="."/>
</Requestor>
</xsl:for-each>
<xsl:for-each select="User">
<User>
<xsl:value-of select="."/>
</User>
</xsl:for-each>
<xsl:for-each select="CostCenter">
<CostCenter>
<xsl:value-of select="."/>
</CostCenter>
</xsl:for-each>
<ShippingInstructions>
<xsl:for-each select="ShippingInstructions">
<xsl:for-each select="name">
<name>
<xsl:value-of select="."/>
</name>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="ShippingInstructions">
<xsl:for-each select="address">
<fullAddress>
<xsl:value-of select="."/>
</fullAddress>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="ShippingInstructions">
<xsl:for-each select="telephone">
<telephone>
<xsl:value-of select="."/>
</telephone>
</xsl:for-each>
</xsl:for-each>
</ShippingInstructions>
<xsl:for-each select="SpecialInstructions">
<SpecialInstructions>
<xsl:value-of select="."/>
</SpecialInstructions>
</xsl:for-each>
<xsl:for-each select="LineItems">
<LineItems>
<xsl:for-each select="LineItem">
<xsl:variable name="V22" select="."/>
<LineItem>
<xsl:for-each select="@ItemNumber">
<xsl:attribute name="ItemNumber">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:for-each select="$V22/Part">
<xsl:variable name="V24" select="."/>
<xsl:for-each select="@Id">
<Part>
<xsl:for-each select="$V22/Description">
<xsl:attribute name="Description">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:for-each select="$V24/@UnitPrice">
<xsl:attribute name="UnitCost">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:value-of select="."/>
</Part>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="$V22/Part">
<xsl:for-each select="@Quantity">
<Quantity>
<xsl:value-of select="."/>
</Quantity>
</xsl:for-each>
</xsl:for-each>
</LineItem>
</xsl:for-each>
</LineItems>
</xsl:for-each>
</PurchaseOrder>
</xsl:template>
</xsl:stylesheet>

プロシージャCOPYEVOLVEの使用時の例

例10-3では、修正されたXML Schemaおよび拡張XSLスタイルシートをOracle XML DBリポジトリにロードします。

例10-3 修正されたXML SchemaおよびXSLスタイルシートのロード

DECLARE
res BOOLEAN;
BEGIN
res := DBMS_XDB.createResource(               -- Load revised XML schema
'/source/schemas/poSource/revisedPurchaseOrder.xsd',
bfilename('XMLDIR', 'revisedPurchaseOrder.xsd'),
nls_charset_id('AL32UTF8'));
res := DBMS_XDB.createResource(               -- Load revised XSL style sheet
'/source/schemas/poSource/evolvePurchaseOrder.xsl',
bfilename('XMLDIR', 'evolvePurchaseOrder.xsl'),
nls_charset_id('AL32UTF8'));
END;/

例10-4は、プロシージャDBMS_XMLSCHEMA.copyEvolveを使用し、XSLスタイルシートevolvePurchaseOrder.xslによってXML Schema purchaseOrder.xsdをrevisedPurchaseOrder.xsdに拡張する方法を示しています。

例10-4 DBMS_XMLSCHEMA.COPYEVOLVEを使用したXML Schemaの更新

BEGIN
DBMS_XMLSCHEMA.copyEvolve(
xdb$string_list_t('http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd'),
XMLSequenceType(XDBURIType('/source/schemas/poSource/revisedPurchaseOrder.xsd').getXML()),
XMLSequenceType(XDBURIType('/source/schemas/poSource/evolvePurchaseOrder.xsl').getXML()));
END;

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[1]'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) line_item
FROM purchaseorder po
WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2003030912333601PDT"]'
PASSING po.OBJECT_VALUE AS "p");

LINE_ITEM
------------------------------------------------------------------------------
<LineItem ItemNumber="1">
<Part Description="A Night to Remember" UnitCost="39.95">715515009058</Part>
<Quantity>2</Quantity>
</LineItem>

同じ問合せにより、スキーマの拡張前に次の結果が生成されます。

LINE_ITEM
----------------------------------------------------------
<LineItem ItemNumber="1">
<Description>A Night to Remember</Description>
<Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
</LineItem>

プロシージャDBMS_XMLSCHEMA.copyEvolveは、既存のインスタンス・ドキュメントの妥当性を保持しながら、登録されているXML Schemaを拡張します。

注意:
プロシージャDBMS_XMLSCHEMA.copyEvolveを実行する前に、すべての登録済XML Schemaとそれに準拠するすべてのXML文書を必ずバックアップしてください。プロシージャcopyEvolveでは、登録済のXML Schemaに準拠するすべての文書が削除されます。

まず、プロシージャcopyEvolveがXML Schemaに基づくXMLType表および列のデータを一時表にコピーします。次に元の表および列を削除し、古いXML Schemaを削除します。新しいXML Schemaを登録した後、XMLType表および列を作成し、それにデータを移入しますが(パラメータGENTABLESがFALSEの場合を除く)、索引、制約、トリガーおよび行レベル・セキュリティ(RLS)ポリシーなどの補助構造は作成しません。プロシージャcopyEvolveは次のように表および列を作成します。

- 新しいスキーマの登録時に、デフォルトの表を作成します。

- 次の書式の文で、デフォルト表ではない表を作成します。

CREATE TABLE table_name OF XMLType OID 'oid'   XMLSCHEMA schema_url ELEMENT element_name

OIDは、削除前の元の表のOIDです。

- 次の書式の文を使用して、XMLType列を追加します。

ALTER TABLE table_name ADD (column_name XMLType) XMLType COLUMN
column_name XMLSCHEMA schema_url ELEMENT element_name

対応する古いスキーマの登録で型が生成されていた場合は、新しいXML Schemaの登録時に型が生成されます。拡張前にグローバルだったXML Schemaは、拡張後もグローバルになります。同様に、拡張前にローカルだったXML Schemaは、拡張後もローカル(同じユーザーが所有)になります。パラメータpreserveOldDocsをTRUEに設定することで、古いドキュメントを含む一時表を保持するオプションがあります。すべての一時表は現行ユーザーのデータベース・スキーマ内に作成されます。XMLType表には、表10-3で示すような列が一時表に存在します。

表10-3 XML Schemaの拡張: XMLType表の一時表の列

名前

型

コメント

Data

CLOB

CLOB形式の古い表からのXML文書。

OID

RAW(16)

古い表で対応する行のOID。

ACLOID

RAW(16)

この列は、古い表が階層に対応している場合のみ存在します。古い表で対応する行のACLOID。

OWNERID

RAW(16)

この列は、古い表が階層に対応している場合のみ存在します。古い表で対応する行のOWNERID。

XMLType列には、表10-4で示すような列が一時表に存在します。

表10-4 XML Schemaの拡張: XMLType列の一時表の列

名前

型

コメント

Data

CLOB

CLOB形式の古い列からのXML文書。

RID

ROWID

この列が含まれる表の対応する行のROWID。

プロシージャCopyEvolveは、古い表または列名から、mapTabNameパラメータで指定された個別の表に対応する一時表名へのマッピングに関する情報を格納します。preserveOldDocsがTRUEの場合、mapTabNameパラメータは、NULL以外の値であり、かつ現行ユーザーのスキーマに存在しない表名である必要があります。マッピング表の各行には、古い表または列の1つに関する情報が含まれます。表10-5に、マッピング表の列を示します。

表10-5 プロシージャcopyEvolveのマッピング表

列名

列の型

コメント

SCHEMA_URL

VARCHAR2(700)

この表または列が一致するスキーマのURL。

SCHEMA_OWNER

VARCHAR2(30)

スキーマの所有者。

ELEMENT_NAME

VARCHAR2(256)

この表または列が一致する要素。

TABLE_NAME

VARCHAR2(65)

表の修飾名(<owner_name>.<table_name>)。

TABLE_OID

RAW(16)

表のOID。

COLUMN_NAME

VARCHAR2(4000)

列の名前(XMLType表の場合はNULL)。

TEMP_TABNAME

VARCHAR2(30)

この表または列のデータを保持する一時表の名前。

GENTABLESパラメータにFALSEを指定することで、新しいXML Schemaの登録後、表または列の生成を回避できます。GENTABLESがFALSEの場合は、パラメータPRESERVEOLDDOCSをTRUEにし、パラメータMAPTABNAMEをNULL以外の値にする必要があります。これによって、古い表のデータが消失しません。これは、「copyEvolveパラメータおよびエラー」の説明のとおり、プロシージャで表を作成する必要がない場合に役立ちます。

デフォルトでは、すべてのXML Schemaは、現行ユーザーが所有していると想定しています。そうでない場合は、schemaOwnersパラメータで各XML Schemaの所有者を指定する必要があります。

関連項目:
ALTER TABLEの完全な説明は、『Oracle Database SQL言語リファレンス』を参照してください。

インプレースのXML Schemaの拡張の使用

インプレースのXML Schemaの拡張では、既存データをコピー、削除、再挿入せずにXML Schemaを変更します。そのため、インプレースの拡張は、コピーに基づく拡張よりも高速に行うことができます。ただし、インプレースの拡張には、コピーに基づく拡張にはない制限がいくつかあります。

プロシージャ DBMS_XMLSCHEMA.inPlaceEvolveを使用して、インプレースの拡張を実行します。このプロシージャを使用して、XML Schema差分ドキュメントを指定することにより、既存のXML Schemaに加えられた変更を識別し、オプションで、拡張プロセスに適用されるフラグを指定します。

インプレースの拡張では、diffXML文書で指定された変更を適用することによる新しいバージョンのXML Schemaの構成、新しいXML Schemaの検証(XML Schemaの場合はXML Schemaに対して)、DDL文の構成による、XML Schemaに関連付けられたXMLインスタンス・ドキュメントを格納するのに使用されるディスク構造の拡張、それらのDDL文の実行、および旧バージョンのXML Schemaの新バージョンへの置換が、この順序で実行されます。新しいバージョンのXML Schemaが妥当なスキーマでなかった場合、インプレースの拡張は失敗します。

インプレースのXML Schemaの拡張の制限

インプレースのXML Schemaの拡張ではデータをコピーしないため、XML Schemaへの任意の変更は許可されません。この項では、一定の変更が許可されない理由について説明します。インプレースの拡張でサポートされている変更のリストは、「インプレースXML拡張でサポートされる操作」を参照してください。

インプレース拡張を使用する際の主要な制限は一般に、指定されたXML Schemaが、下位互換にのみインプレース拡張できることという要件として記述できます。つまり、下位互換とは、指定のXML Schemaに対して検証される可能性のあるすべてのインスタンス・ドキュメントは、そのXML Schemaの将来の(拡張)バージョンでも同様に検証される必要があります。

これは既存のインスタンス・ドキュメントに限らず、すべての可能な準拠インスタンス・ドキュメントに適用されます。バイナリXMLとして格納されたXMLデータの場合、下位互換性は、バイナリXML処理に影響を与えるXML Schema注釈は拡張中に変更できないことも意味します。下位互換性については項「下位互換性の制約」で説明します。

この一般的な下位互換性制限に加え、インプレースの拡張には他の制約もあります。それについては項「インプレース拡張のその他の制限」で説明します。

下位互換性の制約

この項で説明する制約は、拡張されたXML Schemaの下位互換性を保証するため、以前のXML Schemaを満足させる可能なインスタンス・ドキュメントはすべて、新しいスキーマを満足させます。

ディスク上のデータ・レイアウトの変更

XML Schemaへの一定の変更は、関連付けられるディスク上のインスタンス・ドキュメントのレイアウトが変更されるため許可されていません。これはオブジェクト・リレーショナル記憶域の場合と同様、記憶域のレイヤーがXML Schemaから導出された情報と密に統合されている場合に一般的な状況です。

そのような例の1つは、オブジェクト・リレーショナル記憶域のマッピングとして登録されたXML Schemaで、1つの複合型を2つの複合型に分割することで拡張されます。例10-5では、複合型ShippingInstructionsTypeが2つの複合型Person-NameとContact-Infoに分割され、ShippingInstructionsType複合型は削除されます。

例10-5 1つの複合型の2つの複合型への分割

このコードの抜粋は、元のShippingInstructionsType型と新規のPerson-Name型およびContact-Info型の定義を示しています。

<complexType name="ShippingInstructionsType">
<sequence>
<element name="name"   type="NameType" minOccurs="0"/>
<element name="address" type="AddressType" minOccurs="0"/>
<element name="telephone" type="TelephoneType" minOccurs="0"/>
</sequence>
</complexType>

<complexType name="Person-Name">
<sequence>
<element name="name" type="NameType" minOccurs="0"/>
</sequence>
</complexType>

<complexType name="Contact-Info">
<sequence>
<element name="address" type="AddressType" minOccurs="0"/>
<element name="telephone" type="TelephoneType" minOccurs="0"/>
</sequence>
</complexType>

このXML Schemaに関連付けられているインスタンス・ドキュメントがないため、データのコピーが不要な場合でも、今後のインスタンス・ドキュメントに対応するために既存の表のレイアウトを変更する必要があります。

XMLスキーマ構造体の再順序付け

インスタンス・ドキュメントのDOMの再現性に影響を及ぼすような方法では、スキーマ要素の再順序付けにインプレースの拡張を使用できません。たとえば、複合型定義での<sequence>要素内の要素の順序は変更できません。具体的には、複合型ShippingInstructionsTypeでその子要素をname、address、telephoneの順にする必要がある場合、順序をname、telephone、addressに変更するためにインプレースの拡張は使用できません。

コレクションから非コレクションへの変更

コレクションから非コレクションへの変更に、インプレースの拡張は使用できません。例としては、1より大きいmaxOccurs値から1であるmaxOccurs値への変更が考えられます。複合型からの要素の削除では、コレクションから非コレクションへの拡張が必要となる場合、インプレースの拡張は使用できません。

複合型要素内のモデルの変更

モデルは次の要素のうちの1つです。group、choice、sequenceまたはall。complexType要素内では、インプレース拡張を使用して、新しいモデルを追加することや既存のモデルを別の型のモデルで置き換える(たとえば、choice要素をsequence要素で置き換える)ことはできません。しかし、グローバルgroup要素を追加、つまりcomplexType要素以外のgroup要素を追加できます。

インプレース拡張のその他の制限

この項では、拡張されたXML Schemaの下位互換性以外の理由で必要なXML Schemaインプレース拡張の制限について説明します。

xdb名前空間の属性の変更

属性xdb:defaultTableを除き、名前空間http://xmlns.oracle.com/xdbのどの属性(事前定義された接頭辞xdbを持つもの)の変更にもインプレースの拡張は使用できません。

非コレクションからコレクションへの変更

XMLデータがオブジェクト・リレーショナル形式で格納されている場合、インプレースの拡張を使用して非コレクション・オブジェクト型をコレクション・オブジェクト型に変更することはできません。たとえば、複合型へ既存の要素と同じ名前の要素を追加する(または、最初の型を継承している別の型へ追加する)とします。

インプレースのXML Schema拡張でサポートされる操作

この項では、インプレース・スキーマ拡張でサポートされる操作について説明します。サポートされる操作のこのリストは、必ずしも完全ではありません。ここにリストされている操作のうち、指定した、特定のコンテキストでは許可されないものもあります。特に、ここで説明する一部の操作は、バイナリXMLとともに使用されるXML Schemaでは許可されません。

- 複合型またはグループへのオプション要素の追加: 常に許可されます。たとえば、複合型定義へのオプション要素shipmethodの追加を次に示します。

<xs:complexType name="ShippingInstructionsType">
<xs:sequence>
<xs:element name="name" type="NameType" minOccurs="0"/>
<xs:element name="address" type="AddressType" minOccurs="0"/>
<xs:element name="telephone" type="TelephoneType" minOccurs="0"/>
<xs:element name = "shipmethod" type = "xs:string" minOccurs = "0"/>
</xs:sequence>
</xs:complexType>

- 複合型または属性グループへのオプション属性の追加: 常に許可されます。たとえば、複合型定義へのオプション属性shipbydateの追加を次に示します。

<xs:complexType name="ShippingInstructionsType">
<xs:sequence>
<xs:element name="name" type="NameType" minOccurs="0"/>
<xs:element name="address" type="AddressType" minOccurs="0"/>
<xs:element name="telephone" type="TelephoneType" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="shipbydate" type="DateType" use="optional"/>
</xs:complexType>

- 単純型から単純な内容を含む複合型への変換: 記憶域モデルがバイナリXMLの場合のみサポートされます。

- 既存のmaxLength要素のvalue属性の変更: 常に許可されます。現在の値より大きい値に変更することはできますが、小さい値には変更できません。

- enumeration値の追加: enumeration値は、enumerationリストの末尾にのみ新たに追加できます。

- グローバル要素の追加: 常に許可されます。たとえば、スキーマ定義へのグローバル要素PurchaseOrderCommentの追加を次に示します。

<xs:schema ...>
...
<xs:element name="PurchaseOrderComment" type="string" xdb:defaultTable=""/>
..
</xs:schema>

- グローバル属性の追加: 常に許可されます。

- グローバル複合型の追加または削除: 常に許可されます。たとえば、スキーマ定義へのグローバル複合型ComplexAddressTypeの追加を次に示します。

<xs:schema ...>
....
<xs:complexType name="ComplexAddressType">
<xs:sequence>
<xs:element name="street" type="string"/>
<xs:element name="city" type="string"/>
<xs:element ref="zip" type="positiveInteger"/>
<xs:element name="country"  type="string"/>
</xs:sequence>
</xs:complexType>
...
</xs:schema>

- グローバル単純型の追加または削除: 常に許可されます。

- minOccurs属性値の変更: minOccurs値は減少のみ許可されます。

- maxOccurs属性値の変更: maxOccursの値はバイナリXML形式で格納されるデータにかぎり、増加のみ許可されます。つまり、オブジェクト・リレーショナル形式で格納されているデータのmaxOccurs属性は変更できません。

- グローバル・グループまたは属性グループの追加または削除: 常に許可されます。たとえば、型定義へのInstructionsグループの追加を次に示します。

<xsd:schema ...>
...
<xsd:group name="Instructions">
<xsd:sequence>
<xsd:element name="ShippingInstructions" type="ShippingInstructionsType"/>
<xsd:element name="SpecialInstructions" type=" SpecialInstructionsType"/>
</xsd:sequence>
</xsd:group>
...
</xsd:schema>

- xdb:defaultTable属性値の変更: 常に許可されます。xdb名前空間内の他の属性に対する変更は許可されません。

- コメントまたは処理命令の追加、変更、削除: 常に許可されます。

インプレースのXML Schema拡張の使用時のガイドライン

インプレースのXML Schema拡張には、次のガイドラインが適用されます。

- インプレースXML Schemaの拡張を実行する前に、次のことを行います。

- 拡張されるXML Schemaのすべての既存データ(インスタンス・ドキュメント)をバックアップします。

注意:
結果が想定外になる場合に備えて、インプレースのXML Schema拡張を実行する前に、必ずデータをバックアップしてください。インプレース拡張の後は、ロールバックできません。拡張時にエラーが発生した場合や、大きな失敗があり操作全体の再実行が必要な場合、元のデータのバックアップ・コピーに戻せる必要があります。

- トレースのみを使用してドライ・ランを実行します。実際にXML Schemaが拡張されたり、インスタンス文書が更新されたりすることなく、拡張時に実行される更新操作のトレースが生成されます。これを実行するには、flagパラメータ値をINPLACE_TRACEにのみ設定します。INPLACE_EVOLVEは使用しないでください。
予行演習を実行した後でトレース・ファイルをチェックし、リストされたDDL操作が本当に意図したとおりであることを確認します。

- インプレースXML Schemaの拡張を実行した後で、次のことを行います。
データをキャッシュするクライアントを使用してデータベースにアクセスしている場合、または当てはまるかどうか不明な場合は、クライアントを再起動します。そうしないと、引き続き拡張前のバージョンのXML Schemaがローカルに使用され、予想外の結果になる可能性があります。

関連項目:
トレース・ファイルの使用の詳細は、『Oracle Database管理者ガイド』を参照してください。

inPlaceEvolveパラメータ

プロシージャDBMS_XMLSCHEMA.inPlaceEvolveのシグネチャは、次のとおりです。

procedure inPlaceEvolve(schemaURL IN VARCHAR2,
diffXML   IN XMLType,
flags     IN NUMBER);

表10-6に、各パラメータについて説明します。

表10-6 プロシージャDBMS_XMLSCHEMA.INPLACEEVOLVEのパラメータ

パラメータ

説明

schemaURL

拡張するXML SchemaのURL(VARCHAR2)。

diffXML

xdiff XML Schemaに準拠するXML文書(XMLTypeインスタンス)であり、適用する変更と、変更を適用するXML Schema内の箇所を指定します。このパラメータのドキュメント作成に関する詳細は、「diffXMLパラメータのドキュメントの作成」を参照してください。

flags

プロシージャの動作を制御するビット・マスク。次に示すこのマスクのビット値を個別に設定し、それらを合計し、全体の影響を定義できます。デフォルトのflags値は1で(ビット1がオン、ビット2がオフ)、インプレース拡張が実行され、トレースが書き込まれないことを意味します。

- INPLACE_EVOLVE (値1、つまりビット1がオン): インプレースXML Schema拡張を実行します。新しいXML Schemaを構成、検証します(XML Schemaの場合はXML Schemaに対して)。インスタンス・ドキュメントのディスク構造を拡張するのに必要なDDL文を構成します。DDL文を実行します。古いXML Schemaを新しいXML Schemaに置き換えます。

- INPLACE_TRACE(値2、つまりビット2がオン):インプレース進化に必要なすべてのステップを実行します。ただしDDL文の実行および新しいXMLスキーマによる古いXMLスキーマの上書きは除きます。DDL文と新しいXML Schemaの両方をトレース・ファイルに書き込みます。

つまり、それぞれのビットがXML Schemaを構成、検証し、インスタンス・ドキュメントの基礎となるディスク構造の拡張に必要な手順を決定します。また、次の点があげられます。

- ビットINPLACE_EVOLVEはそれらの拡張手順を実行し、旧バージョンのXML Schemaを新バージョンに置換します。

- ビットINPLACE_TRACEは拡張手順と新しいXML Schemaをトレース・ファイルに保存します(拡張手順を実行しません)。

プロシージャDBMS_XMLSCHEMA.inPlaceEvolveでは、次の場合にエラーが発生します。

- XPath式が無効であるか、構文が正しいもののXML Schema内のノードをターゲットにしていない場合。

- diffXML文書がxdiff XML Schemaに準拠していない場合。

- 変更によってXML Schemaが無効になるか、整形式でなくなる場合。

- 生成されたDDL文(CREATE TYPE、ALTER TYPEなど)の実行時に問題が発生した場合。

- XMLType表に関連する索引オブジェクトが不安定な状態にあり、その原因がパーティション管理操作の可能性がある場合。

diffXMLパラメータのドキュメントの作成

プロシージャDBMS_XMLSCHEMA.inPlaceEvolveへのdiffXMLパラメータの値は、インプレースの拡張においてXML Schemaに適用される変更を指定したXML文書(XMLTypeインスタンス)となります。このdiffXML文書には、古いXML Schemaと新規の(拡張の結果となる予定の)XML Schemaとの間の変更を示す一連の操作が含まれます。diffXML文書で指定された変更は、この順序で適用されます。

diffXMLパラメータで使用されるXML文書を作成する必要があります。これを行うには、次のいずれかの方法を実行します。

- XMLDiff JavaBean(oracle.xml.differ.XMLDiff)

- xmldiffコマンドライン・ユーティリティ

- SQL関数XMLDiff

diffXML文書はxdiff XML Schemaに準拠している必要があります。

この項の後半では、xdiff XML Schemaに準拠するドキュメント内の操作例を示します。

関連項目:

- 「xdiff.xsd: スキーマをインプレース拡張と比較するためのXML Schema」

- XMLDiff JavaBeansの使用に関する詳細は、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。

- xmldiffコマンドライン・ユーティリティに関する詳細は、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。

- SQL関数XMLDiffに関する詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

diffXMLの操作と例

この項では、プロシージャDBMS_XMLSCHEMA.inPlaceEvolveのためにdiffXML文書で指定されたいくつかの操作について説明します。xdiff XML Schemaに準拠したXML文書の例も示します。

複合型への新規属性の追加、グループへの新規要素の追加など、サポートされているほとんどの変更において、<append-node>要素が使用されています。

<insert-node-before>要素は、指定された型のノードを特定のノードの前に挿入する必要があることを指定します。xpath属性は、特定のノードの位置を指定し、node-type属性は挿入されるノードの型を指定します。挿入されるノードは、<content>子要素で指定されます。<insert-node-before>要素は、主にコメントの挿入、命令の処理、およびannotation要素の変更と追加に使用されます。

<delete-node>要素は、特定のXPath(xpath属性で指定)のあるノードをそのすべての子とともに削除することを指定しています。たとえば、この要素はコメントやannotation要素の削除に使用できます。また、この要素を<append-node>または<insert-node-before>とともに使用し、既存のノードを変更できます。

例10-6は、次の変更を指定するdiffXMLパラメータのXML文書を示しています。

- 複合型PartTypeの削除。

- 最大長28での複合型PartTypeの追加。

- ShippingInstructions要素の前へのコメントの追加。

- 必須要素shipmethodのShippingInstructions要素への追加。

例10-6 diffXMLパラメータ・ドキュメント

<xd:xdiff  xmlns="http://www.w3c.org/2001/XMLSchema"
xmlns:xd="http://xmlns.oracle.com/xdb/xdiff.xsd"
xmlns:xsi="http://www.w3c.org/2001/XMLSchema-Instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/xdiff.xsd
http://xmlns.oracle.com/xdb/xdiff.xsd">
<xd:delete-node xpath="/schema/complexType[@name=&quote;PartType&quote;]//maxLength/>
<xd:append-node
parent-xpath = "/schema/complexType[@name=&quote;PartType&quote;]//restriction"
node-type = "element">
<xd:content>
<xs:maxLength value = "28"/>
</xd:content>
</xd:append-node>
<xd:insert-node-before
xpath="/schema/complexType[@name =&quote;ShippingInstructionsType&quote;]/sequence"
node-type="comment">
<xd:content>
<!-- A type representing instructions for shipping -->
</xd:content>
</xd:insert-node-before>
<xd:append-node
parent-xpath="/schema/complexType[@name=&quote;ShippingInstructionsType&quote;]/sequence"
node-type="element">
<xd:content>
<xs:element name = "shipmethod" type = "xs:string" minOccurs = "1"/>
</xd:content>
</xd:append-node>
</xd:xdiff>

11 XMLTypeデータの変換および検証

この章では、XSLTスタイル・シートを使用してXMLTypeデータを変換するための、SQL関数およびXMLType APIについて説明します。XMLTypeインスタンスのXML Schemaに対する検証に使用できる関数およびAPIについても説明します。

この章の内容は次のとおりです。

- XMLTypeインスタンスの変換

- XMLTRANSFORMおよびXMLType.transform()の例

- XMLTypeインスタンスの検証

- XMLTypeとして格納されたXMLデータの検証例

XMLTypeインスタンスの変換

XML文書には構造はありますが形式はありません。XML文書に形式を追加するには、Extensible Stylesheet Language (XSL)を使用できます。XSLはXMLセマンティクスの表示方法を提供します。XML要素をHTMLなどの他のフォーマット言語またはマークアップ言語にマップできます。

Oracle XML DBでは、Oracle DatabaseのXMLType表、列またはビューに格納されているXMLTypeインスタンスまたはXMLデータは、XSLスタイルシートおよびXMLTypeメソッドtransform()を使用して、HTML、XMLおよびその他のマークアップ言語に(フォーマット)変換できます。このプロセスは、W3CのXSLT 1.0勧告に準拠しています。

XMLTypeインスタンスは、次の方法で変換できます。

- データベースでOracle SQL関数XMLTransform(またはXMLTypeメソッドtransform())を使用する。

- XSLT Processor for Javaなどの中間層でOracle XML Developer's Kitの変換オプションを使用する。

関連項目:

- 第3章「Oracle XML DBの使用」、「XSL変換とOracle XML DB」

- 「PL/SQL XSLT Processor for XMLType(DBMS_XSLPROCESSOR)」

SQL関数XMLTRANSFORMおよびXMLTypeメソッドTRANSFORM()

図11-1に、Oracle SQL関数XMLtransformの構文を示します。この関数は引数としてXMLTypeインスタンスとXSLTスタイルシートを受け取ります。スタイルシートはXMLTypeインスタンスまたはVARCHAR2文字列リテラルのいずれかです。スタイルシートをインスタンスに適用し、XMLTypeインスタンスを戻します。

図11-1 XMLTRANSFORMの構文

Oracle SQL関数XMLtransformのかわりにXMLTypeメソッドtransform()を使用することもできます。どちらも機能は同じです。

図11-2に、XSLTスタイルシートを使用してXMLtransformがXML文書を変換する方法を示します。XSLTスタイルシートで指定したように、処理された出力をXML、HTMLなどで戻します。データベース内にXMLTypeとして格納されたXML文書の取得または生成時は、通常はXMLtransformを使用します。

関連項目:
第1章「Oracle XML DBの概要」の図1-1「XMLType記憶域およびOracle XML DBリポジトリ」

図11-2 XMLTRANSFORMの使用

XMLTRANSFORMおよびXMLType.transform()の例

この項では、Oracle SQL関数XMLtransformおよびXMLTypeメソッドtransform()を使用して、XMLTypeとして格納されているXMLデータを様々な形式に変換する方法について説明します。

例11-1では、この章の他の例を実行するために必要なXML Schemaおよび表を設定します。ここに示したdeleteSchemaのコールは、XML Schemaの作成前に既存のスキーマがないようにするためのものです。そのようなスキーマが存在しない場合は、deleteSchemaでエラーが発生します。

例11-1 XML Schemaの登録およびXMLデータの挿入

BEGIN
-- Delete the schema, if it already exists.
DBMS_XMLSCHEMA.deleteSchema('http://www.example.com/schemas/ipo.xsd',4);
END;
/
BEGIN
-- Register the schema
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.example.com/schemas/ipo.xsd',
SCHEMADOC => '<schema targetNamespace="http://www.example.com/IPO"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:ipo="http://www.example.com/IPO">
<!-- annotation>
<documentation xml:lang="en">
International Purchase order schema for Example.com
Copyright 2000 Example.com. All rights reserved.
</documentation>
</annotation -->
<element name="purchaseOrder" type="ipo:PurchaseOrderType"/>
<element name="comment" type="string"/>
<complexType name="PurchaseOrderType">
<sequence>
<element name="shipTo"     type="ipo:Address"/>
<element name="billTo"     type="ipo:Address"/>
<element ref="ipo:comment" minOccurs="0"/>
<element name="items"      type="ipo:Items"/>
</sequence>
<attribute name="orderDate" type="date"/>
</complexType>
<complexType name="Items">
<sequence>
<element name="item" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="productName" type="string"/>
<element name="quantity">
<simpleType>
<restriction base="positiveInteger">
<maxExclusive value="100"/>
</restriction>
</simpleType>
</element>
<element name="USPrice"    type="decimal"/>
<element ref="ipo:comment" minOccurs="0"/>
<element name="shipDate"   type="date" minOccurs="0"/>
</sequence>
<attribute name="partNum" type="ipo:SKU" use="required"/>
</complexType>
</element>
</sequence>
</complexType>
<complexType name="Address">
<sequence>
<element name="name"    type="string"/>
<element name="street"  type="string"/>
<element name="city"    type="string"/>
<element name="state"   type="string"/>
<element name="country" type="string"/>
<element name="zip"     type="string"/>
</sequence>
</complexType>
<simpleType name="SKU">
<restriction base="string">
<pattern value="[0-9]{3}-[A-Z]{2}"/>
</restriction>
</simpleType>
</schema>',
LOCAL     => TRUE,
GENTYPES  => TRUE);
END;
/

-- Create table to hold XML instance documents
DROP TABLE po_tab;

CREATE TABLE po_tab (id NUMBER, xmlcol XMLType)
XMLType COLUMN xmlcol
XMLSCHEMA "http://www.example.com/schemas/ipo.xsd"
ELEMENT "purchaseOrder";

INSERT INTO po_tab
VALUES(1, XMLType(
'<?xml version="1.0"?>
<ipo:purchaseOrder
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ipo="http://www.example.com/IPO"
xsi:schemaLocation="http://www.example.com/IPO
http://www.example.com/schemas/ipo.xsd"
orderDate="1999-12-01">
<shipTo>
<name>Helen Zoe</name>
<street>121 Broadway</street>
<city>Cardiff</city>
<state>Wales</state>
<country>UK</country>
<zip>CF2 1QJ</zip>
</shipTo>
<billTo>
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Old Town</city>
<state>CA</state>
<country>US</country>
<zip>95819</zip>
</billTo>
<items>
<item partNum="833-AA">
<productName>Lapis necklace</productName>
<quantity>1</quantity>
<USPrice>99.95</USPrice>
<ipo:comment>Want this for the holidays!</ipo:comment>
<shipDate>1999-12-05</shipDate>
</item>
</items>
</ipo:purchaseOrder>'));

例11-2に、SQL関数XMLtransformおよびDBURITypeを使用してスタイルシートを取得する方法を示します。DBURITypeの詳細は、第20章「URIを介したデータのアクセス」を参照してください。

例11-2 XMLTRANSFORMおよびDBURITYPEを使用したスタイルシートの取得

DROP TABLE stylesheet_tab;

CREATE TABLE stylesheet_tab (id NUMBER, stylesheet XMLType);

INSERT INTO stylesheet_tab
VALUES (1,
XMLType(
'<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<td>
<xsl:choose>
<xsl:when test="count(child::*) > 1">
<xsl:call-template name="nested"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="name(.)"/>:<xsl:value-of
select="text()"/>
</xsl:otherwise>
</xsl:choose>
</td>
</xsl:template>
<xsl:template match="*" name="nested" priority="-1" mode="nested2">
<b>
<!-- xsl:value-of select="count(child::*)"/ -->
<xsl:choose>
<xsl:when test="count(child::*) > 1">
<xsl:value-of select="name(.)"/>:<xsl:apply-templates
mode="nested2"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="name(.)"/>:<xsl:value-of
select="text()"/>
</xsl:otherwise>
</xsl:choose>
</b>
</xsl:template>
</xsl:stylesheet>'));

SELECT XMLSerialize(DOCUMENT XMLtransform(x.xmlcol, y.stylesheet)
AS varchar2(1000))
AS result FROM po_tab x, stylesheet_tab y WHERE y.id = 1;

これにより、次の出力が生成されます(ここでは、読みやすくするためにフォーマット出力で示しています)。

RESULT
---------------------------------------------------------
<td>
<b>ipo:purchaseOrder:
<b>shipTo:
<b>name:Helen Zoe</b>
<b>street:100 Broadway</b>
<b>city:Cardiff</b>
<b>state:Wales</b>
<b>country:UK</b>
<b>zip:CF2 1QJ</b>
</b>
<b>billTo:
<b>name:Robert Smith</b>
<b>street:8 Oak Avenue</b>
<b>city:Old Town</b>
<b>state:CA</b>
<b>country:US</b>
<b>zip:95819</b>
</b>
<b>items:</b>
</b>
</td>

例11-3に、格納されているスタイルシートを使用して、XMLTypeインスタンスを変換する例を示します。例11-3では、例11-2と異なり、格納されているスタイルシートをスカラー副問合せを使用して取得します。

例11-3 XMLTRANSFORMおよび副問合せを使用したスタイルシートの取得

SELECT XMLSerialize(DOCUMENT
XMLtransform(
x.xmlcol,
(SELECT stylesheet FROM stylesheet_tab WHERE id = 1))
AS VARCHAR2(1000))
AS result FROM po_tab x;

例11-4では、一時スタイルシートを使用したXMLTypeインスタンスの変換においてXMLTypeメソッドtransform()を使用します。

例11-4 一時スタイルシートでのメソッドTRANSFORM()の使用

SELECT XMLSerialize(
DOCUMENT
x.xmlcol.transform(
XMLType('<?xml version="1.0" ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<td>
<xsl:choose>
<xsl:when test="count(child::*) > 1">
<xsl:call-template name="nested"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select =
"name(.)"/>:<xsl:value-of select="text()"/>
</xsl:otherwise>
</xsl:choose>
</td>
</xsl:template>
<xsl:template match="*" name="nested" priority="-1"
mode="nested2">
<b>
<!-- xsl:value-of select="count(child::*)"/ -->
<xsl:choose>
<xsl:when test="count(child::*) > 1">
<xsl:value-of select="name(.)"/>:
<xsl:apply-templates mode="nested2"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select =
"name(.)"/>:<xsl:value-of select="text()"/>
</xsl:otherwise>
</xsl:choose>
</b>
</xsl:template>
</xsl:stylesheet>'))
AS varchar2(1000))
FROM po_tab x;

XMLTypeインスタンスの検証

多くの場合、特定のXML文書が整形式であることに加えて、その文書が特定のXML Schemaに準拠するかどうか(特定のXML Schemaに対して妥当であるかどうか)を認識する必要があります。

バイナリXMLとして格納されたXML Schemaに基づくデータは、挿入または更新時に必ず自動的に完全に検証されます。この検証にはDOMの構築は必要ありません。これはストリーミングを使用して実行され、メモリーの使用を効率的にかつ最小限にします。

オブジェクト・リレーショナル形式で格納されるXMLTypeデータの場合は、完全な検証にDOMの構築が必要なため、メモリー管理の面でコストがかかります。このため、Oracle XML DBは、オブジェクト・リレーショナル形式で格納されるデータが挿入または更新されるときに、完全な検証を自動的には実行しません。

ただし、オブジェクト・リレーショナル形式で格納するためにXMLデータを分解する過程で、Oracle XML DBはXML文書の構造がXML Schemaから導出されたSQLデータ型の定義に準拠しているか確認するため、部分的な検証を実行します。

オブジェクト・リレーショナル形式で格納されたXMLTypeデータに完全な検証が必要であれば、クライアントで検証してからデータベースに挿入したり、更新することを考慮してください。

XML文書で記録された有効性状態を完全に検証または操作するために、次のものを使用できます。

- Oracle SQL関数XMLIsValidおよびXMLTypeメソッドIsSchemaValid() - 検証プロセスを無条件に実行します。検証状態は記録されません。次の値を戻します。

- 文書が有効と判断される場合は1。

- 文書が無効と判断される場合または文書の妥当性が判断できない場合は、0。

- XMLTypeメソッドSchemaValidate(): 検証のステータスが0(デフォルト)の場合、検証プロセスを実行します。文書が有効だと判断されると、検証ステータスは1に設定されます(それ以外の場合、ステータスは0のままです)。

- XMLTypeメソッドisSchemaValidated(): XMLTypeインスタンスの記録済の検証状態を戻します。

- XMLTypeメソッドsetSchemaValidated(): XMLTypeインスタンスの検証状態を設定(記録)します。

検証状態では、次のように妥当性がわかります。

- 1は、文書が有効と判断されることを示します。

- 0は、文書の妥当性が不明であることを示します。検証チェックで文書が無効であるように判断される可能性がありますが、文書が無効であると記録されるわけではありません。検証状態が0と記録された場合にわかるのは、文書の妥当性が不明であることのみです。

関連項目:

- 「XML Schemaの部分検証と全体検証の比較」

- Oracle SQL関数XMLIsValidの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- XMLTypeメソッドIsSchemaValid()、IsSchemaValidated()、SchemaValidate()およびsetSchemaValidated()の詳細は『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

XMLTypeとして格納されたXMLデータの検証例

この項の各例に、Oracle SQL関数XMLIsValidと、XMLTypeメソッドisSchemaValid()およびschemaValidate()を使用して、Oracle XML DBにXMLTypeとして格納されているXMLデータを検証する方法を示します。

例11-5および例11-6に、PL/SQLメソッドisSchemaValid()を使用して、XML Schemaに対してXMLインスタンスを検証する方法を示します。

例11-5 SQLでメソッドISSCHEMAVALID()を使用したXMLの検証

SELECT x.xmlcol.isSchemaValid('http://www.example.com/schemas/ipo.xsd',
'purchaseOrder')
FROM po_tab x;

例11-6 PL/SQLでメソッドISSCHEMAVALID()を使用したXMLの検証

DECLARE
xml_instance XMLType;
BEGIN
SELECT x.xmlcol INTO xml_instance FROM po_tab x WHERE id = 1;
IF xml_instance.isSchemaValid('http://www.example.com/schemas/ipo.xsd') = 0
THEN raise_application_error(-20500, 'Invalid Instance');
ELSE DBMS_OUTPUT.put_line('Instance is valid');
END IF;
END;
/
Instance is valid

PL/SQL procedure successfully completed.

XMLTypeメソッドschemaValidate()をINSERTおよびUPDATEトリガー内で使用すると、表に格納されているすべてのインスタンスがXML Schemaに対して検証されたことを確認できます。例11-7に、これを示します。

例11-7 トリガー内でメソッドSCHEMAVALIDATE()を使用したXMLの検証

DROP TABLE po_tab;
CREATE TABLE po_tab OF XMLType
XMLSCHEMA "http://www.example.com/schemas/ipo.xsd" ELEMENT "purchaseOrder";

CREATE TRIGGER emp_trig BEFORE INSERT OR UPDATE ON po_tab FOR EACH ROW

DECLARE
newxml XMLType;
BEGIn
newxml := :new.OBJECT_VALUE;
XMLTYPE.schemavalidate(newxml);
END;
/

例11-8では、Oracle SQL関数XMLIsValidを使用して、次の操作を実行します。

- XMLTypeインスタンスが指定されたXML Schemaに準拠していることの確認

- CHECK制約を使用した、受信したXML文書が妥当であることの確認

例11-8 CHECK制約内でXMLISVALIDを使用したXMLの妥当性のチェック

DROP TABLE po_tab;
CREATE TABLE po_tab OF XMLType
(CHECK(XMLIsValid(OBJECT_VALUE) = 1))
XMLSCHEMA "http://www.example.com/schemas/ipo.xsd" ELEMENT "purchaseOrder";

注意:
「XMLTypeインスタンスの検証」の項で示した検証の関数およびプロシージャを使用すると、簡単に妥当性チェックを実行できます。これらのうち、schemaValidateのみが、エラーの発生時に検証が失敗した理由を示します。

12 XMLデータの全文検索

この章では、Oracleを使用したXMLの全文検索について説明します。Oracle SQL関数containsおよびOracle XPath関数ora:containsの使用方法についても説明します。これらはOracle Databaseにより使用され、XMLデータの全文検索を実行する2つの関数です。

関連項目:
Oracle Textの詳細は、『Oracle Textリファレンス』および『Oracle Textアプリケーション開発者ガイド』を参照してください。

この章の内容は次のとおりです。

- XMLの全文検索の概要

- 全文検索の例について

- CONTAINSおよびora:containsの概要

- CONTAINS SQL関数

- ora:contains XQuery関数

- Text Path BNFの仕様

- 全文XMLのサポートの例

XMLの全文検索の概要

Oracleは、Oracle Databaseにより管理される文書の全文検索をサポートしています。

文書がXMLの場合は、その文書のXML構造を使用して全文検索を限定できます。たとえば、全文検索を使用してワード"electric"が含まれる発注書をすべて検索するとします。発注書がXML形式の場合は、コメント内にワード"electric"が含まれるすべての発注書を検索するか、または明細項目の下にあるコメント内にワード"electric"が含まれるすべての発注書を検索するかして、検索内容を限定できます。

XML文書がXMLType型の場合は、その文書のXML構造を使用して問合せの結果を投影できます。たとえば、コメント内にワード"electric"が含まれるすべての発注書を検索した後で、コメント全体を戻すか、またはワード"electric"が含まれるコメントのみを戻すことができます。

全文検索と他の検索タイプの比較

全文検索は、構造化検索や部分文字列検索と次の点で異なります。

- 全文検索では、部分文字列ではなく単語全体が検索されます。文字列"law"が含まれるコメントの部分文字列検索を行うと、"my lawn is going wild"が含まれるコメントが戻されます。ワード"law"の全文検索では、このコメントは戻されません。

- 全文検索では、部分文字列検索ではサポートできない言語ベースとワードベースの検索がいくつかサポートされています。たとえば、言語ベースの検索を使用すると、"mouse"と言語語幹が同じワードを含むすべてのコメントを検索でき、Oracle Textでは"mouse"と"mice"が検索されます。ワードベースの検索の例では、"wild"を含む5ワード以内にワード"lawn"があるすべてのコメントを検索できます。

- 全文検索には通常、関連性の概念が含まれています。たとえば、ワード"lawn"が含まれるすべてのコメントを全文検索する場合、ある結果は他の結果より関連性が高い場合があります。関連性は通常、検索ワード(または類似ワード)の文書内での出現回数に関連しています。

XMLデータの検索

XML検索は、非構造化文書の検索とは異なります。非構造化文書の検索では通常、一連の文書を検索して、指定したテキスト述語を満たす文書を戻します。XML検索では多くの場合、XML文書の構造を使用して検索を限定します。また、検索を満たす文書の一部のみを戻す場合があります。

全文検索およびXML構造を使用した文書の検索

全文検索とXML構造が含まれる検索の実行方法には、次の2通りがあります。

- Oracle SQL関数containsを使用して、全文述語内に構造を含める方法:

WHERE contains(doc, 'electric INPATH (/purchaseOrder/items/item/comment)') > 0

関数containsはSQLの拡張機能であり、すべての問合せで使用できます。CONTEXT全文索引が必要です。

- ora:contains XPath関数を使用して、構造内に全文述語を含める方法:

'/purchaseOrder/items/item/comment[ora:contains(text(), "electric")>0]'

XPath関数ora:containsはXPathの拡張機能であり、SQL/XML関数XMLQuery、XMLTableまたはXMLExistsのコールで使用できます。

全文検索の例について

この項では、この章の例について詳細に説明します。

ロールおよび権限

例を実行するには、データベース・ロールCTXAPP、CONNECT、RESOURCEが必要です。また、CTXSYSパッケージCTX_DDLに対するEXECUTE権限も必要です。

全文検索の例に使用するスキーマおよびデータ

この章の例は、W3Cの「XML Schema Part 0: Primer」にある「The Purchase Order Schema」に基づいています。

関連項目:
http://www.w3.org/TR/xmlschema-0/#POSchema

例で使用しているデータは、「発注書のXML文書、po001.xml」の文書からのものです。

この章の例で使用している表は、「CREATE TABLE文」「CREATE TABLE文」で定義されています。ただし、パフォーマンスの例の一部は、より大きい表(purchase_orders_xmltype_big)に基づいており、この表はダウンロード可能なバージョンにのみ含まれています。http://www.w3.org/TR/xmlschema-0/#po.xmlを参照してください。

一部の例は、データ型VARCHAR2を使用しています。XMLType型を使用するものもあります。VARCHAR2を使用している例はすべて、XMLTypeを使用することもできます。

CONTAINSおよびora:containsの概要

この項の内容は次のとおりです。

- SQL関数CONTAINSの概要

- XPath関数ora:containsの概要

- CONTAINSおよびora:containsの比較

SQL関数CONTAINSの概要

Oracle SQL関数containsは、[schema.]columnがtext_queryと一致する行の正数を戻し、一致しない場合は0(ゼロ)を戻します。それ以外の場合は、0(ゼロ)を戻します。型CONTEXTの索引が必要です。検索対象の列にCONTEXT索引がない場合、containsではエラーが発生します。

CONTAINS構文

contains([schema.]column, text_query VARCHAR2 [,label NUMBER])
RETURN NUMBER

例12-1に、Oracle SQL関数containsを使用した一般的な問合せを示します。表purchase_ordersで、doc列に単語"lawn"が含まれ、idが25よりも小さい値の各行のidが戻されます。

例12-1 Oracle SQL関数CONTAINSを使用した単純な問合せ

SELECT id FROM purchase_orders WHERE contains(doc, 'lawn') > 0 AND id < 25;

docは、一連のXML文書が含まれる列であるとします。この場合、docに対して、そのXML構造を使用して問合せを限定する全文検索を実行できます。例12-2の問合せでは、表purchaseordersで、XML要素commentのtext()ノードにワード"lawn"が含まれるdoc列のid値が戻されます。

例12-2 CONTAINSおよびWITHINを使用した問合せの制限

SELECT id FROM purchase_orders WHERE contains(doc, 'lawn WITHIN comment') > 0;

INPATH演算子およびXPath式を使用すると、XML構造によるさらに複雑な限定を適用できます。例12-3の問合せでは、XPath式/purchaseOrder/items/item/commentのターゲットとなるcomment要素のtext()ノードに、ワード"electric"が含まれる発注書が検索されます。

例12-3 CONTAINSおよびINPATHを使用した問合せの制限

SELECT id FROM purchase_orders
WHERE contains(doc, 'electric INPATH (/purchaseOrder/items/item/comment)') > 0;

XPath関数ora:containsの概要

XPath関数ora:containsは、XQuery式内のXPath式や、SQL/XML関数XMLQuery、XMLTable、XMLExistsのコールで使用できます。これは、全文述語を伴う構成検索を制限する場合に使用されます。標準のメカニズムを使用してXPathを拡張する、Oracle XML DB名前空間ora内のユーザー定義関数です。索引は不要ですが、索引を使用することでパフォーマンスを向上できます。

ora:contains構文

ora:contains(input_text NODE*, text_query STRING
[,policy_name STRING]
[,policy_owner STRING])

関数ora:containsはinput_textがtext_queryと一致した場合は正の整数を戻し(数字が大きいほど、一致の関連性は高くなります)、一致しない場合はゼロを戻します。XQuery式で使用される場合、XQueryの戻り型はxs:integer()です。XQuery式の外部でXPath式で使用される場合、XPathの戻り型はnumberです。

引数input_textは単一のテキスト・ノードまたは属性に対して評価される必要があります。ora:containsのtext_queryの構文およびセマンティクスはcontainsのtext_queryと同じですが、次の制限事項があります。

- 引数text_queryに構造演算子(WITHIN、INPATHまたはHASPATH)を含めることはできません。

- スコア重み付け演算子weightを使用した場合、重みは無視されます。

例12-4は、XMLExistsのXPathパラメータにおけるora:containsのコールを示しています。Oracle XML DBネームスペースを表すものとして、接頭辞oraを宣言するネームスペース宣言に注意してください。

例12-4 複雑な任意のテキスト問合せを使用したora:contains

SELECT id
FROM purchase_orders_xmltype
WHERE
XMLExists(
'declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder/comment
[ora:contains(text(), "($lawns AND wild) OR flamingo") > 0]'
PASSING doc AS "d");

関連項目:
ora:contains XPath関数の詳細は、「ora:contains XQuery関数」を参照してください。

CONTAINSおよびora:containsの比較

Oracle SQL関数containsおよびOracle XPath関数ora:containsでは、いずれもXML構造の検索と全文検索を組み合せることができます。これらの主な違いは次のとおりです。

Oracle SQL関数containsの特性は、次のとおりです。

- 実行するにはCONTEXT索引が必要です。索引がない場合はエラーが発生します。

- 索引検索を実行し、通常非常に高速です。

- (Oracle SQL関数scoreを使用して)スコアを戻します。

- ノードではなく文書(表の行)に基づいて検索を限定します。

- XML構造ベースの投影(XML文書の一部を抽出)には使用できません。

Oracle XPath関数ora:containsの特性は、次のとおりです。

- 索引は不要ですが、索引を使用することでパフォーマンスを向上できます。

- 非索引検索であるため、大量のリソースを消費する場合があります。

- 格納方法および索引付け方法に関する考慮事項からアプリケーション・ロジックを分離しています。

- スコアを戻しません。

- XML構造ベースの投影(XML文書の一部を抽出)に使用できます。

XML文書で、単純なXML構造の制約を指定している場合など、高速な索引ベースの全文検索を実行する場合は、Oracle SQL関数containsを使用します。XPathナビゲーションと組み合せた全文検索の柔軟性が必要な場合(索引がない場合も含めて)、または投影は必要でスコアは不要な場合は、Oracle XPath関数ora:containsを使用します。

CONTAINS SQL関数

この項の内容は次のとおりです。

- SQL関数CONTAINSを使用した全文検索

- SCORE SQL関数

- CONTAINS検索の範囲の限定

- CONTAINS結果の投影

- CONTEXT索引を使用した索引付け

SQL関数CONTAINSを使用した全文検索

Oracle SQL関数containsの2番目の引数text_queryは、全文検索を指定する文字列です。text_queryには、SQL/MMの全文標準に基づいた独自の言語があります。

関連項目:

- ISO/IEC 13249-2:2000、「Information technology - Database languages - SQL Multimedia and Application Packages - Part 2: Full-Text」、International Organization For Standardization、2000

- text_query言語の演算子の詳細は、『Oracle Textリファレンス』を参照してください。

この項の後半の例では、全文検索の優れた機能をいくつか示します。使用可能な2、3の演算子を使用します。例の問合せでは、テキスト索引(索引タイプCTXSYS.CONTEXT)を使用してVARCHAR2列(PURCHASE_ORDERS.doc)が検索されます。

全文ブール演算子AND、ORおよびNOT

text_query言語では、AND、ORおよびNOTの任意の組合せがサポートされています。優先順位はカッコを使用して制御できます。ブール演算子は次のいずれの方法でも記述できます。

- AND、OR、NOT

- and、or、not

- &, |, ~

NOTは単項演算子ではなくバイナリであることに注意してください。式alpha NOT(beta)はalpha AND unary-not(beta)と同等で、unary-notは単項否定を表します。

関連項目:
containsおよびora:containsで使用できる演算子の詳細は、『Oracle Textリファレンス』を参照してください。

例12-5 単純なブール演算子を使用したCONTAINS問合せ

SELECT id FROM purchase_orders WHERE contains(doc, 'lawn AND wild') > 0;

例12-6 複雑なブールを使用したCONTAINS問合せ

SELECT id FROM purchase_orders
WHERE contains(doc, '((lawn OR garden) AND (wild OR flooded)) NOT(flamingo)')
> 0;

全文ステミング: $

text_query言語では、語幹検索がサポートされています。例12-7では、"lawns"と同じ言語語幹のワードが含まれるすべての文書が戻されるため、"lawn"または"lawns"が検索されます。ステミング演算子は、ドル記号($)で記述されます。

例12-7 ステミングを使用したCONTAINS問合せ

SELECT id FROM purchase_orders WHERE contains(doc, '$(lawns)') > 0;

ブールとステミング演算子の組合せ

例12-8に示すように、text_query言語の演算子を組み合せることができます。

例12-8 複雑な問合せ式を使用したCONTAINS問合せ

SELECT id FROM purchase_orders
WHERE contains(doc, '($lawns AND wild) OR flamingo') > 0;

関連項目:
text_query演算子の完全なリストは、『Oracle Textリファレンス』を参照してください。

SCORE SQL関数

Oracle SQL関数scoreはOracle SQL関数containsに関連します。関数scoreは問合せ内のどの場所でも使用できます。これは関連性を測定するもので、大規模なドキュメント・セット全体を全文検索するときに特に有効です。関数scoreは通常、問合せ結果の一部として戻されるか、ORDER BY句で使用されるか、あるいはその両方です。

SCORE構文

score(label NUMBER) RETURN NUMBER

例12-9のscore(10)では、結果セット内の各行に対するスコアが戻されます。Oracle SQL関数scoreは、関数containsの特定のコールに関する結果セット内の行の関連性を戻します。scoreのコールは、LABEL(この場合は番号10)によってcontainsのコールにリンクされます。

例12-9 SCOREを使用した単純なCONTAINS問合せ

SELECT score(10), id FROM purchase_orders
WHERE contains(doc, 'lawn', 10) > 0 AND score(10) > 2
ORDER BY score(10) DESC;

関数scoreは、対応するcontainsで、テキスト索引で規定された一致規則に従ってtext_query引数がinput_textと一致しない場合は、常に0を戻します。containsのtext_queryがinput_textと一致した場合、scoreは、0より大きく100以下の数値を戻します。この数値は、input_textに対するtext_queryの関連性を示します。数値が大きいほど、一致精度が高いことを意味します。

containsのtext_queryがHASPATH演算子およびText Pathのみで構成されている場合、HASPATHは完全一致をテストするため、スコアは0または100になります。

関連項目:
スコアの計算方法の詳細は、『Oracle Textリファレンス』を参照してください。

CONTAINS検索の範囲の限定

Oracle SQL関数containsでは、デフォルトで文書全体が全文検索されます。前述の例で、構造による限定のない"lawn"の検索では、発注書内のどこかにワード"lawn"があるすべての発注書が検索されます。

XML構造を使用してcontains問合せを限定する方法は、次の3通りあります。

- WITHIN

- INPATH

- HASPATH

注意:
この説明では、セクションはXMLノードと同じであると考えてください。

WITHIN構造演算子

WITHIN演算子は、問合せをXML文書内のあるセクションに限定します。コメント・セクションのどこかにワード"lawn"が含まれている発注書を検索するには、WITHINを使用します。セクション名の大/小文字は区別されます。

例12-10 WITHIN

SELECT id FROM purchase_orders WHERE contains(DOC, 'lawn WITHIN comment') > 0;

ネストしたWITHIN

WITHINをネストすると、問合せをさらに限定できます。例12-11では、セクション"comment"内にワード"lawn"が含まれ、"lawn"の出現箇所がセクション"item"内にもあるすべての文書が検索されます。

例12-11 ネストしたWITHIN

SELECT id FROM purchase_orders
WHERE contains(doc, '(lawn WITHIN comment) WITHIN item') > 0;

例12-11では行が戻されません。使用する発注書サンプルには、コメント内にワード"lawn"が含まれています。しかし、項目内の唯一のコメントは"Confirm this is electric"です。そのため、ネストしたWITHIN問合せでは行が戻されません。

WITHIN(属性の場合)

属性内を検索することもできます。例12-12では、purchaseOrder要素のorderDate属性にワード"10"が含まれているすべての発注書が検索されます。

例12-12 属性内のWITHIN

SELECT id FROM purchase_orders
WHERE contains(doc, '10 WITHIN purchaseOrder@orderDate') > 0;

デフォルトでは、マイナス記号(-)は単語セパレータとして処理されます。つまり、"1999-10-20"は3つの単語、"1999"、"10"および"20"として処理されます。したがって、この問合せでは1行戻されます。

属性内のテキストは、主検索可能文書の一部ではありません。text_queryをWITHIN purchaseOrder@orderDateで修飾せずに10を検索すると、行は戻されません。

属性は、ネストしたWITHINでは検索できません。

WITHINおよびAND

コメント・セクション内にlawnとelectricの2つのワードが含まれる発注書を検索するとします。purchaseOrderにはコメント・セクションが複数ある場合があります。このため、この問合せの作成方法は2通りあり、異なる結果となります。

両方のワードが含まれ、各ワードがあるコメント・セクション内に出現する発注書を検索する場合は、例12-13のような問合せを作成します。

例12-13 WITHINおよびAND: あるコメント・セクション内の2つのワード

SELECT id FROM purchase_orders
WHERE contains(doc, '(lawn WITHIN comment) AND (electric WITHIN comment)') > 0;

purchaseOrderデータに対してこの問合せを実行すると、1行戻されます。この例ではカッコは必要ありませんが、使用すると問合せがわかりやすくなります。

両方のワードが含まれ、両方のワードが同じコメント内に出現する発注書を検索する場合は、例12-14のような問合せを作成します。

例12-14 WITHINおよびAND: 同じコメント内の2つのワード

SELECT id FROM purchase_orders
WHERE contains(doc, '(lawn AND electric) WITHIN comment') > 0;

例12-14の問合せでは、行が戻されません。例12-15の問合せのように、lawn AND electricを囲むカッコを外すと、1行戻されます。

例12-15 WITHINおよびAND: カッコを付けない場合

SELECT id FROM purchase_orders
WHERE contains(doc, 'lawn AND electric WITHIN comment') > 0;

演算子WITHINの優先順位はANDより高いため、例12-15は例12-16と同じように解析されます。

例12-16 WITHINおよびAND: 演算子優先順位を示すカッコ

SELECT id FROM purchase_orders
WHERE contains(doc, 'lawn AND (electric WITHIN comment)') > 0;

セクションの定義

前述の例では、セクション内を検索するためにWITHIN演算子を使用しました。次のセクションを指定できます。

- パス・セクションまたはゾーン・セクション
これは、ノードの子孫であるテキスト・ノードのすべてを、間を空白で区切って文書順に連結したものです。ノードからゾーン・セクションに変換するには、ノードをシリアライズしてすべてのタグを空白で置換する必要があります。パス・セクションの有効範囲と動作はゾーン・セクションと同じですが、パス・セクションでは INPATHおよびHASPATH構造演算子を使用した問合せがサポートされます。

- フィールド・セクション
ゾーン・セクションと同じですが、文書内の繰返しノードが空白で区切られて単一のセクションに連結されます。

- 属性セクション

- 特殊セクション(文または段落)

関連項目:
特殊セクションの詳細は、『Oracle Textリファレンス』を参照してください。

INPATH構造演算子

演算子WITHINは、構造による単純な限定をtext_queryで表す簡単で直観的な方法です。豊富なXML構造を使用する問合せでは、ネストしたWITHIN演算子のかわりに、演算子INPATHとText Pathを使用できます。

演算子INPATHでは、左側にtext_queryを記述し、右側にカッコで囲んだText Pathを記述します。例12-17では、パス/purchaseOrder/items/item/comment内で単語"electric"が含まれるpurchaseOrdersが検索されます。

例12-17 全文述語内の構造: INPATH

SELECT id FROM purchase_orders
WHERE contains(doc, 'electric INPATH (/purchaseOrder/items/item/comment)') > 0;

例12-17の検索範囲は、Text Pathで示されたセクションです。例12-18の問合せでは例12-17の問合せよりも範囲の広いパスを使用しますが、同じように1行しか戻されません。

例12-18 全文述語内の構造: INPATH

SELECT id FROM purchase_orders
WHERE contains(doc, 'electric INPATH (/purchaseOrder/items)') > 0;

Text Path

Text Pathの構文とセマンティクスは、W3CのXPath 1.0勧告に基づいています。単純なパス式はサポートされますが(省略構文のみ)、関数はサポートされません。以降の各例は、一般的な変形例を示しています。

関連項目:

- W3CのXPath 1.0勧告の詳細は、http://www.w3.org/TR/xpathを参照してください。

- Text Pathの文法については、「Text Path BNFの仕様」を参照してください。

例12-19では、属性partNumが"872-AA"と等しいitem要素の子であるcomment要素内にワード"electric"が含まれるすべての発注書が検索されます。つまり、ルート・ノードからいくつか下のレベルのitems要素の子です。

例12-19 複雑なパス式を使用したINPATH(1)

SELECT id FROM purchase_orders
WHERE contains(doc, 'electric INPATH (//items/item[@partNum="872-AA"]/comment)')
> 0;

例12-20では、3番目のレベルであるitem要素(またはその子孫)内に単語"lawnmower"が含まれ、すべてのレベルにcomment要素があるすべての発注書が検索されます。この問合せでは1行戻されます。問合せの有効範囲はcomment要素ではなく、子孫としてcomment要素を持つ一連のitems要素であることに注意してください。

例12-20 複雑なパス式を使用したINPATH(2)

SELECT id FROM purchase_orders
WHERE contains(doc, 'lawnmower INPATH (/*/*/item[.//comment])') > 0;

Text PathとXPathの比較

Text Path言語は、XPath言語と次の点で異なります。

- すべてのXPath演算子がText Path言語に含まれているわけではありません。

- XPathの組込み関数はText Path言語に含まれていません。

- Text Path言語の演算子は大/小文字が区別されません。

- フィルタ内(カッコ内)で=を使用した場合、一致はテキスト一致規則に従います。
大/小文字の区別、正規化、ストップワードおよび空白の規則はテキスト索引の定義によって異なります。この相違を強調するために、この種類の等価性をこのマニュアルではテキスト等値と呼びます。

- 名前空間サポートはText Path言語に含まれていません。
名前空間接頭辞(存在する場合)など、要素名は文字列として処理されます。そのため、同じ名前空間URIにマップされている2つの異なる名前空間接頭辞は、Text Path言語では等価として処理されません。

- Text Pathでは、コンテキストは常に文書のルート・ノードです。
したがって、発注データpurchaseOrder/items/item、/purchaseOrder/items/itemおよび./purchaseOrder/items/itemはすべて等価です。

- 属性値内を検索する場合は、属性の直接の親を指定する必要があります(ワイルド・カードは使用できません)。

- Text Pathはワイルド・カード(*)で終了できません。

関連項目:
Text Pathの文法については、「Text Path BNFの仕様」を参照してください。

ネストしたINPATH

INPATH式はネストできます。Text Pathのコンテキストは常にルート・ノードです。ネストしたINPATHの場合も変わりません。

例12-21では、任意のレベルのcomment要素にワード"electric"が含まれる発注書が検索されます。このワードの出現箇所は、最上位レベルpurchaseOrder要素の子であるitem要素内でもあります。

例12-21 ネストしたINPATH

SELECT id FROM purchase_orders
WHERE contains(doc,
'(electric INPATH (//comment)) INPATH (/purchaseOrder/items)')
> 0;

このネストしたINPATH問合せは、例12-22に示すように、簡潔に記述できます。

例12-22 リライト済のネストしたINPATH

SELECT id FROM purchase_orders
WHERE contains(doc, 'electric INPATH (/purchaseOrder/items//comment)') > 0;

HASPATH構造演算子

演算子HASPATHで使用するオペランドはText Pathのみで、カッコで囲み、右側に記述します。=述語などを使用して、特定のパス内に特定のセクションが含まれる文書を検索するときは、HASPATHを使用します。これは全文検索ではなく、パス検索です。セクションが存在するかどうかの確認、またはセクションの内容の照合はできますが、ワード検索はできません。データ型がXMLTypeの場合は、構造演算子HASPATHではなくSQL/XML関数XMLExistsの使用を考慮してください。

例12-23では、USPriceを持つ項目があるpurchaseOrdersが検索されます。

例12-23 単純なHASPATH

SELECT id FROM purchase_orders
WHERE contains(DOC, 'HASPATH (/purchaseOrder//item/USPrice)') > 0;

例12-24では、"148.95"とテキスト等値であるUSPriceを持つ項目があるpurchaseOrdersが検索されます。

関連項目:
テキスト等値の説明は、「Text PathとXPathの比較」を参照してください。

例12-24 HASPATHの等値式

SELECT id FROM purchase_orders
WHERE contains(doc, 'HASPATH (/purchaseOrder//item/USPrice="148.95")') > 0;

HASPATHは、INPATHなど他のcontains演算子と組み合せることができます。例12-25では、文書の任意の場所にワード electricを含み、148.95とテキスト等値であるUSPriceを持つitemがあり、かつpurchaseOrder属性orderDate内に10が含まれるpurchaseOrdersが検索されます。

例12-25 HASPATHと他の演算子の組合せ

SELECT id FROM purchase_orders
WHERE contains(doc,
'electric
AND HASPATH (/purchaseOrder//item/USPrice="148.95")
AND 10 INPATH (/purchaseOrder/@orderDate)')
> 0;

CONTAINS結果の投影

WHERE句内にcontains式を使用したSQL問合せの結果は常に、行のセット(および多くの場合score情報)、または問合せと一致する行全体の投影です。

contains式を満たす各XML文書の一部のみを戻すには、SQL/XML関数XMLQueryを使用します。この項の例では、XMLType表purchase_orders_xmltypeが使用されます。

例12-26では、最上位レベルのpurchaseOrder要素の子孫であるcomment要素内にワード"electric"が含まれるpurchaseOrderが検索されます。各結果の行IDを戻すかわりに、XMLQueryを使用してcomment要素のみを戻します。

例12-26 CONTAINS問合せの結果の範囲指定

SELECT XMLQuery('declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder//comment'
PASSING doc AS "d" RETURNING CONTENT) "Item Comment"
FROM purchase_orders_xmltype
WHERE CONTAINS(doc, 'electric INPATH (/purchaseOrder//comment)') > 0;

例12-26の結果は、要素commentの2つのインスタンスです。関数containsは、comment要素内に単語"electric"が含まれている行(ID = 1の行)を示します。関数XMLQueryは文書内のその行にある要素commentのインスタンスをすべて抽出します。purchaseOrder要素には要素 commentのインスタンスが2つあり、問合せではその両方が戻されます。

これは希望の結果と異なる場合があります。contains式を満たすcomment要素の実例のみを問合せで戻す場合は、XMLQueryに渡されるXQuery式でその述語を繰り返す必要があります。これには、XPath関数ora:containsを使用します。例12-27に、これを示します。

例12-27 ora:containsを使用したCONTAINS問合せ結果の投影

SELECT XMLQuery('declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder/items/item/comment
[ora:contains(text(), "electric") > 0]'
PASSING doc AS "d" RETURNING CONTENT) "Item Comment"
FROM purchase_orders_xmltype
WHERE CONTAINS(doc, 'electric INPATH (/purchaseOrder/items/item/comment)') > 0;

CONTEXT索引を使用した索引付け

この項の内容は次のとおりです。

- CONTEXT索引の概要

- CONTAINSにおけるCONTEXT索引の効果

- CONTEXT索引プリファレンス

- セクション・グループの概要

CONTEXT索引の概要

汎用の全文索引タイプは、データベース・ユーザーCTXSYSが所有するCONTEXT索引タイプです。デフォルトの全文索引を作成するには、例12-28に示すように、通常のSQL CREATE INDEXコマンドを使用し、句INDEXTYPE IS CTXSYS.CONTEXTを追加します。

例12-28 表PURCHASE_ORDERSの単純なCONTEXT索引

CREATE INDEX po_index ON purchase_orders(doc)
INDEXTYPE IS CTXSYS.CONTEXT;

全文索引を作成するときには、多数の選択肢があります。これらの選択肢は、索引付けプリファレンスとして表されます。索引付けプリファレンスを使用するには、例12-29に示すように、CREATE INDEXにPARAMETERS句を追加します。

関連項目:
「CONTEXT索引プリファレンス」

例12-29 パス・セクション・グループを使用したXMLType表の単純なCONTEXT索引

CREATE INDEX po_index ON purchase_orders(doc)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('section group CTXSYS.PATH_SECTION_GROUP');

Oracle Textには、CTXCATやCTXRULEなどの他の索引タイプが用意されていますが、この章では説明しません。

関連項目:
CONTEXT索引の詳細は、『Oracle Textリファレンス』を参照してください。

XMLType表のCONTEXT索引

CONTEXT索引は、テキストが含まれた任意のデータに対して作成できます。例12-28では、VARCHAR2列に対するCONTEXT索引が作成されます。型がCHAR、VARCHAR、VARCHAR2、BLOB、CLOB、BFILE、XMLTypeまたはURITypeの列にCONTEXT索引を作成する構文は同じです。例12-30では、XMLType型の列に対するCONTEXT索引が作成されます。セクション・グループはデフォルトでPATH_SECTION_GROUPに設定されます。

例12-30 XMLType列の単純なCONTEXT索引

CREATE INDEX po_index_xmltype ON purchase_orders_xmltype(doc)
INDEXTYPE IS CTXSYS.CONTEXT;

XMLType表がある場合は、例12-31に示すように、オブジェクト構文を使用してCONTEXT索引を作成する必要があります。

例12-31 XMLType表の単純なCONTEXT索引

CREATE INDEX po_index_xmltype_table
ON purchase_orders_xmltype_table (OBJECT_VALUE)
INDEXTYPE IS CTXSYS.CONTEXT;

例12-32に示すように、表を問合せできます。

例12-32 XMLType表のCONTAINS問合せ

SELECT XMLCast(XMLQuery(
'declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$p/purchaseOrder/@orderDate'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS DATE) "Order Date"
FROM purchase_orders_xmltype_table po
WHERE contains(po.OBJECT_VALUE, 'electric INPATH (/purchaseOrder//comment)')
> 0;

CONTEXT索引のメンテナンス

ほとんどの全文索引と同様に、CONTEXT索引は非同期です。索引付けされたデータが変更された場合、CONTEXT索引は、プロシージャをコールして索引を同期化するなど、なんらかの処理を行うまで変更されません。

CONTEXT索引は、時間経過とともに断片化する可能性があります。断片化した索引では通常より多くの領域が使用されるため、問合せが遅くなります。CONTEXT索引を最適化(断片化解消)する方法はたくさんあります。

関連項目:
CONTEXT索引のメンテナンスの詳細は、『Oracle Textリファレンス』を参照してください。

ロールおよび権限

CONTEXT索引の作成に特別な権限は必要ありません。プリファレンスの作成と削除、およびOracle TextのPL/SQLパッケージの使用には、CTXAPPロールが必要です。また、CTXSYSパッケージCTX_DDLに対するEXECUTE権限も必要です。

CONTAINSにおけるCONTEXT索引の効果

Oracle SQL関数containsを使用するには、CONTEXT型の索引を作成する必要があります。containsをコールしたとき、最初の引数で指定された列にCONTEXT型の索引がない場合は、エラーが発生します。

text_queryの構文およびセマンティクスは、CONTEXT索引の作成時に選択した内容によって異なります。次に例を示します。

- ワードとしてカウントする対象

- 最も一般的なワードを処理対象とするかどうか

- 最も一般的なワード

- テキスト検索で大/小文字を区別するかどうか

- テキスト検索にキーワードの他にテーマ(概念)を含めることができるかどうか

CONTEXT索引プリファレンス

プリファレンスは、索引付けに関する選択肢の集合と考えることができます。プリファレンスには、セクション・グループ、データストア、フィルタ、ワードリスト、ストップリストおよび記憶域が含まれます。この項では、検索で大/小文字を区別するためのレクサー・プリファレンスの設定方法を示します。

プリファレンスを作成するには、プロシージャCTX_DDL.create_preference(またはCTX_DDL.create_stoplist)を使用します。プロシージャCTX_DDL.set_attributeを使用して新規プリファレンスの属性を設定することによって、そのプリファレンス・グループのデフォルトの選択肢をオーバーライドします。その後、CREATE INDEXのPARAMETERS文字列内にpreference type preference_nameを含めることによって、CONTEXT索引でプリファレンスを使用します。

プリファレンスを作成すると、それを使用して索引をいくつでも作成できます。

検索で大/小文字を区別する方法

containsを使用した全文検索では、デフォルトで大/小文字が区別されません。つまり、文書内のワードに対してtext_query内のワードを照合する際に、大/小文字は考慮されません。ただし、セクション名および属性名は常に、大/小文字が区別されます。

全文検索で大/小文字を区別する場合は、CONTEXT索引の作成時にそのように選択する必要があります。例12-33では1行戻されます。これは、text_query内の"HURRY"が、デフォルトの大/小文字が区別されない索引が設定されたpurchaseOrder内の"Hurry"と一致するためです。

例12-33 CONTAINS: デフォルトの大/小文字を区別しない一致

SELECT id FROM purchase_orders
WHERE contains(doc, 'HURRY INPATH (/purchaseOrder/comment)') > 0;

例12-34では、属性mixed_caseがTRUEに設定された新しいレクサー・プリファレンスmy_lexerが作成されます。この例では、printjoin文字も"-"、"!"、","に設定されます。CONTEXT索引の作成およびポリシーの作成に同じプリファレンスを使用できます。

関連項目:
レクサー属性の完全なリストは、『Oracle Textリファレンス』を参照してください。

例12-34 大/小文字混合のプリファレンスの作成

BEGIN
CTX_DDL.create_preference(PREFERENCE_NAME  =>  'my_lexer',
OBJECT_NAME      =>  'BASIC_LEXER');

CTX_DDL.set_attribute(PREFERENCE_NAME  =>  'my_lexer',
ATTRIBUTE_NAME   =>  'mixed_case',
ATTRIBUTE_VALUE  =>  'TRUE');

CTX_DDL.set_attribute(PREFERENCE_NAME  =>  'my_lexer',
ATTRIBUTE_NAME   =>  'printjoins',
ATTRIBUTE_VALUE  =>  '-,!');
END;
/

例12-35では、新しいmy_lexerレクサー・プレファレンスを使用してCONTEXT索引が作成されます。ここではプレファレンスpreference-case-mixedが使用されます。

例12-35 PURCHASE_ORDERS表のCONTEXT索引、大/小文字混合

CREATE INDEX po_index ON purchase_orders(doc)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS('lexer my_lexer section group CTXSYS.PATH_SECTION_GROUP');

例12-33では、text_query内の"HURRY"がpurchaseOrder内の"Hurry"と一致しないため、行は戻されません。例12-36では、text_queryの"Hurry"がpurchaseOrder内のワード"Hurry"と正確に一致するため、1行戻されます。

例12-36 CONTAINS: 大/小文字混合の(正確な)一致

SELECT id FROM purchase_orders
WHERE contains(doc, 'Hurry INPATH (/purchaseOrder/comment)') > 0;

セクション・グループの概要

CONTEXT索引の作成時に行う選択の1つにセクション・グループがあります。セクション・グループ・インスタンスは、セクション・グループ・タイプに基づいています。セクション・グループ・タイプでは、文書の構造の種類、およびその構造の索引付け方法(したがって検索方法)が指定されます。セクション・グループ・インスタンスによって、索引付けされる構造要素が指定される場合もあります。ほとんどのユーザーは、デフォルトのセクション・グループまたは事前定義のセクション・グループのいずれかを使用します。

セクション・グループ・タイプの選択

XMLの検索で有効なセクション・グループ・タイプは、次のとおりです。

- PATH_SECTION_GROUP
問合せでWITHIN、INPATHおよびHASPATHを使用し、すべてのセクションを問合せの有効範囲とする場合はこのタイプを選択します。

- XML_SECTION_GROUP
問合せでWITHINを使用するが、INPATHおよびHASPATHは使用せず、明示的に定義されたセクションのみを問合せの有効範囲とする場合は、このタイプを選択します。XML_SECTION_GROUPセクション・グループ・タイプでは、ZONEセクションの他にFIELDセクションがサポートされます。状況によっては、FIELDセクションの方が問合せのパフォーマンスが大幅に向上する場合があります。

- AUTO_SECTION_GROUP
問合せでWITHINを使用するが、INPATHおよびHASPATHは使用せず、大部分のセクションを問合せの有効範囲とする場合は、このタイプを選択します。デフォルトでは、すべてのセクションが索引付けされます(問合せの限定に使用可能)。一部のセクションには索引付けしないことを指定できます(STOPセクションを定義)。

- NULL_SECTION_GROUP
XMLセクションを定義しない場合は、このタイプを選択します。

その他のセクション・グループ・タイプは、次のとおりです。

- BASIC_SECTION_GROUP

- HTML_SECTION_GROUP

- NEWS_SECTION_GROUP

XMLの全文検索要件がある大部分のユーザーは、PATH_SECTION_GROUPを使用することをお薦めします。一部のユーザーには、FIELDセクションを使用するXML_SECTION_GROUPの使用が適している場合もあります。この選択によって、通常、問合せパフォーマンスが向上し、索引が小さくなりますが、フィールド化構造の文書に限定されます(検索可能なノードは、繰返しのないすべてのリーフ・ノードです)。

関連項目:
XML_SECTION_GROUPセクション・グループ・タイプの詳細は、『Oracle Textリファレンス』を参照してください。

セクション・グループの選択

索引で使用するセクション・グループを選択するときは、選択したセクション・グループ・タイプに基づいて、提供されているセクション・グループを選択するか、デフォルトを使用するか、または新しいセクション・グループを作成するかを選択できます。

セクション・グループ・タイプPATH_SECTION_GROUP、AUTO_SECTION_GROUPおよびNULL_SECTION_GROUPには、提供されているセクション・グループがあります。提供されているセクション・グループの所有者はCTXSYSで、名前はセクション・グループ・タイプと同じです。たとえば、セクション・グループ・タイプPATH_SECTION_GROUPの提供されているセクション・グループはCTXSYS.PATH_SECTION_GROUPです。

セクション・グループ・タイプXML_SECTION_GROUPには提供されているセクション・グループがありません。これは、デフォルトのXML_SECTION_GROUPは空であり、無意味であるためです。セクション・グループ・タイプXML_SECTION_GROUPを使用する場合は、新しいセクション・グループを作成し、セクションとして組み込む各ノードを指定する必要があります。

XMLType型のデータにCONTEXT索引を作成した場合、デフォルトのセクション・グループは、提供されているセクション・グループCTXSYS.PATH_SECTION_GROUPです。データがVARCHARまたはCLOBの場合、デフォルトのセクション・グループはCTXSYS.NULL_SECTION_GROUPです。

関連項目:
独自のセクション・グループを作成する方法は、『Oracle Textリファレンス』を参照してください。

セクション・グループを索引と関連付けるには、例12-37のように、PARAMETERS文字列にsection group <section group name>を追加します。

例21-37 パス・セクション・グループを使用したpurchase_orders表の単純なCONTEXT索引

CREATE INDEX po_index ON purchase_orders(doc)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('section group CTXSYS.PATH_SECTION_GROUP');

ora:contains XQuery関数

関数ora:containsは、SQL/XML関数XMLQuery、XMLTableおよびXMLExistsのXQuery式の引数で使用するために、Oracleによって定義されたXQuery(XPath)関数です。

ora:containsを使用する場合は、Oracle XML DB名前空間xmlns:ora="http://xmlns.oracle.com/xdb"に接頭辞oraをマップする名前空間宣言も指定する必要があります。

関数ora:containsは数値を戻します。スコアは戻しません。text_queryがinput_textと一致した場合、正数を戻します。そうでない場合は0(ゼロ)を戻します。

XQuery関数ora:containsを使用した全文検索

ora:containsの引数text_queryは、全文検索を指定する文字列です。ora:containsのtext_queryはcontainsのtext_queryと同じですが、次の制限事項があります。

- ora:containsのtext_queryには、構造演算子WITHIN、INPATHまたはHASPATHを含めることができません。

- ora:containsのtext_queryには、スコア重み付け演算子weight(*)を含めることができますが、重みは無視されます。

ora:containsのtext_queryに次のいずれかを含めた場合は、その問合せでCONTEXT索引を使用できません。

- スコアベースの演算子MINUS(-)またはthreshold(>)

- 選択的なコーパスベースの拡張演算子FUZZY(?)またはsoundex(!)

関連項目:
「XPathリライトおよびCONTEXT索引」

例12-4に、ブール演算子と$(ステミング)を任意に組み合せた全文検索を示します。

関連項目:

- 全文演算子の詳細は、「関数CONTAINSを使用した全文検索」を参照してください。

- containsおよびora:containsで使用できる演算子の完全なリストは、『Oracle Textリファレンス』を参照してください。

一致規則は、ポリシーpolicy_owner.policy_nameで定義されます。policy_ownerの指定がない場合、ポリシー所有者はデフォルトで現行ユーザーに設定されます。policy_nameとpolicy_ownerの両方が指定されない場合、ポリシーはデフォルトでCTXSYS.DEFAULT_POLICY_ORACONTAINSに設定されます。

ora:contains問合せの範囲の限定

XPath式でora:containsを使用する場合、有効範囲は引数input_textで定義されます。この引数は、現在のXPathのコンテキスト内で評価されます。結果が単一のテキスト・ノードまたは属性の場合、そのノードはora:contains検索のターゲットです。input_textが単一のテキスト・ノードまたは属性に対して評価されない場合は、エラーが発生します。

ポリシーによって、ora:containsの一致規則が決定されます。ora:containsのデフォルト・ポリシーに関連付けられたセクション・グループの型はNULL_SECTION_GROUPです。

ora:containsはXPath式のどこでも使用でき、そのinput_text引数は単一のテキスト・ノードまたは属性に対して評価されるXPath式です。

ora:contains結果の投影

各XML文書の一部のみを戻す場合は、関数XMLQueryを使用してノード順序を投影し、その結果にXMLCastを適用してノードのスカラー値を投影します。

例12-38では、ワード"lawn"を含むcommentがある各発注書のorderDateが戻されます。

例12-38 XMLQueryおよびXMLExistsでのora:containsの使用

SELECT XMLCast(XMLQuery(
'declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder/@orderDate'
PASSING doc AS "d" RETURNING CONTENT)
AS DATE) "Order date"
FROM purchase_orders_xmltype
WHERE XMLExists(
'declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder/comment
[ora:contains(text(), "($lawns AND wild) OR flamingo") > 0]'
PASSING doc AS "d");

関数XMLExistsは、ワード"lawn"の入ったcommentがpurchaseOrder要素に含まれる行(文書)に結果を限定します。その後、関数XMLQueryが、それらのpurchaseOrder要素から属性orderDateの値を戻します。関数XMLCastは、この結果をSQL DATE値としてキャストします。

//commentが抽出されていれば、WHERE句と一致したコメントのみではなく、両方のコメントがサンプル・ドキュメントから戻されます。

関連項目:
例12-26「CONTAINS問合せの結果の範囲指定」

ora:contains問合せのポリシー

列のCONTEXT索引によって、その列に対するcontains問合せのセマンティクスが決まります。ora:containsはサポートしている索引に依存しないため、ora:contains問合せを実行するときは、同様の選択肢を多数提供する他の方法を検索する必要があります。ポリシーは、ora:contains問合せに関連付けることができるプリファレンスの集合であり、索引付けに関する選択でcontainsユーザーに提供される内容と同じようなセマンティクス制御を提供します。

ora:contains問合せのポリシーの概要

Oracle SQL関数containsを使用すると、索引付けのプリファレンスが問合せのセマンティクスに影響を与えます。プロシージャCTX_DDL.create_preference(またはCTX_DDL.create_stoplist)を使用して、プリファレンスを作成します。プロシージャCTX_DDL.set_attributeを使用して新規プリファレンスの属性を設定することによって、デフォルトの選択肢をオーバーライドします。その後、CREATE INDEXのPARAMETERS文字列内にpreference_type preference_nameを含めることによって、CONTEXT索引でプリファレンスを使用します。

関連項目:
「CONTEXT索引プリファレンス」

ora:containsにはサポートしている索引がないため、問合せにプリファレンスを適用するには、別のメカニズムが必要です。そのメカニズムはポリシーであり、プリファレンスの集合で構成されます。これはora:containsのパラメータとして使用されます。

ポリシーの例: 提供されているストップリスト

例12-39では、空のストップワード・リストを持つポリシーが作成されます。

例12-39 ora:containsで使用するポリシーの作成

BEGIN
CTX_DDL.create_policy(POLICY_NAME  =>  'my_nostopwords_policy',
STOPLIST     =>  'CTXSYS.EMPTY_STOPLIST');
END;
/

わかりやすいように、このポリシーは空のストップリストで構成されており、所有者はユーザーCTXSYSです。このポリシーに組み込む新しいストップリストを作成するか、またはCONTEXT索引用に作成したストップリスト(またはレクサー)定義を再利用できます。

最も一般的なワード(ストップワード)も含めてすべてのワードを検索するには、ora:contains式でこのポリシーを参照してください。例12-40では、"is"はデフォルトでストップワードであり問合せできないため、コメントは戻されません。

例12-40 ora:containsを使用したストップワードの検索

SELECT id FROM purchase_orders_xmltype
WHERE XMLExists(
'declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder/comment[ora:contains(text(), "is") > 0]'
PASSING doc AS "d");

例12-41では、空のストップワード・リストを指定するために、例12-39で作成されたポリシーが使用されます。この問合せでは"is"が検索され、コメントが1つ戻されます。

例12-41 ora:containsおよびポリシーmy_nostopwords_policyを使用したストップワードの検索

SELECT id FROM purchase_orders_xmltype
WHERE XMLExists(
'declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder/comment
[ora:contains(text(), "is", "MY_NOSTOPWORDS_POLICY") > 0]'
PASSING doc AS "d");

例12-41では、ポリシーmy_nostopwords_policyを使用します。例12-39では、このポリシーの名前は暗黙的にすべて大文字になります。XPathでは大/小文字が区別されるため、XPath述語内でこのポリシーは、my_nostopwords_policyではなくMY_NOSTOPWORDS_POLICYのように、すべて大文字を使用して記述する必要があります。

ora:containsでのポリシーの効果

ora:containsポリシーは、text_queryの一致セマンティクスに影響を与えます。ora:containsポリシーには、レクサー、ストップリスト、ワードリスト・プリファレンスまたはこれらの組合せが含まれる場合があります。CONTEXT索引の作成に使用できる他のプリファレンスは、ora:containsには適用できません。プリファレンスの効果は次のとおりです。

- ワードリスト・プリファレンスによって、ステミング演算子のセマンティクスが改良されます。

- ストップリスト・プリファレンスによって、一般的であるために索引付け(検索可能に)しないワードが定義されます。

- レクサー・プリファレンスによって、ワードのトークン化および一致方法が定義されます。たとえば、ワードの一部としてカウントする文字および一致で大/小文字を区別するかどうかが定義されます。

関連項目:

- 事前定義のストップリストを使用したポリシーの作成例は、「ポリシーの例: 提供されているストップリスト」を参照してください。

- 大/小文字区別のポリシーの例は、「ポリシーの例: ユーザー定義レクサー」を参照してください。

ポリシーの例: ユーザー定義レクサー

特定のワードが含まれる文書を検索する場合は通常、検索で大/小文字を区別しない方法が使用されます。大/小文字を区別する検索を実行すると、予期した結果を得られない場合があリます。たとえば、"baby monitor"という句が含まれるpurchaseOrdersを検索する場合、使用しているサンプル文書では"Baby Monitor"と記述されているというだけの理由で、この文書の検索が行われないとは予測しません。

ora:containsを使用した全文検索では、デフォルトで大/小文字が区別されません。ただし、セクション名および属性名は常に、大/小文字が区別されます。

全文検索で大/小文字を区別する場合は、ポリシーの作成時にそのように選択する必要があります。次の手順を使用します。

1. プロシージャCTX_DDL.create_preference(またはCTX_DDL.create_stoplist)を使用して、プリファレンスを作成します。

2. プロシージャCTX_DDL.set_attributeを使用して新規プリファレンスの属性を設定することによって、そのプリファレンス・オブジェクトのデフォルトの選択肢をオーバーライドします。

3. そのプリファレンスをCTX_DDL.create_policyのパラメータとして使用します。

4. 問合せではora:containsの3番目の引数として、ポリシー名を使用します。

プリファレンスを作成した後は、そのプリファレンスを他のポリシーまたはCONTEXT索引の定義で再利用できます。すべてのora:contains問合せで、任意のポリシーを使用できます。

例12-42では1行戻されます。これは、text_query内の"HURRY"が、デフォルトの大/小文字が区別されない索引が設定されたpurchaseOrder内の"Hurry"と一致するためです。

例12-42 ora:contains、デフォルトの大/小文字の区別

SELECT id FROM purchase_orders_xmltype
WHERE XMLExists(
'declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder/comment[ora:contains(text(), "HURRY") > 0]'
PASSING doc AS "d");

例12-43では、属性mixed_caseがTRUEに設定された新しいレクサー・プリファレンスmy_lexerが作成されます。この例では、printjoin文字も"-"、"!"、","に設定されます。CONTEXT索引の作成およびポリシーの作成に同じプリファレンスを使用できます。

関連項目:
レクサー属性の完全なリストは、『Oracle Textリファレンス』を参照してください。

例12-43 大/小文字混合のプリファレンスの作成

BEGIN
CTX_DDL.create_preference(PREFERENCE_NAME  =>  'my_lexer',
OBJECT_NAME      =>  'BASIC_LEXER');
CTX_DDL.set_attribute(PREFERENCE_NAME  =>  'MY_LEXER',
ATTRIBUTE_NAME   =>  'MIXED_CASE',
ATTRIBUTE_VALUE  =>  'TRUE');
CTX_DDL.set_attribute(PREFERENCE_NAME  =>  'my_lexer',
ATTRIBUTE_NAME   =>  'printjoins',
ATTRIBUTE_VALUE  =>  '-,!');
END;
/

例12-44では、新規ポリシーmy_policyが作成され、レクサーのみが指定されます。他のプリファレンスはすべてデフォルトに設定されます。例12-44では、preference-case-mixedが使用されます。

例12-44 大/小文字混合の(大/小文字が区別されない)ポリシーの作成

BEGIN
CTX_DDL.create_policy(POLICY_NAME  => 'my_policy',
LEXER        => 'my_lexer');
END;
/

例12-45では、問合せで新規ポリシーが使用されます。text_query内の"HURRY"はpurchaseOrder内の"Hurry"と一致しないため、行は戻されません。

例12-45 ora:contains、大/小文字の区別(1)

SELECT id FROM purchase_orders_xmltype
WHERE XMLExists(
'declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder/comment
[ora:contains(text(), "HURRY", "my_policy") > 0]'
PASSING doc AS "d");

例12-46では、text_queryの"Hurry"がcomment要素内のテキスト"Hurry"と正確に一致するため、1行戻されます。

例12-46 ora:contains、大/小文字の区別(2)

SELECT id FROM purchase_orders_xmltype
WHERE XMLExists(
'declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder/comment[ora:contains(text(), "Hurry") > 0]'
PASSING doc AS "d");

ポリシーのデフォルト

ora:containsのポリシーの引数はオプションです。省略した場合、問合せではデフォルトのポリシーCTXSYS.DEFAULT_POLICY_ORACONTAINSが使用されます。

ora:containsで使用するポリシーを作成するときは、すべてのプリファレンスを指定する必要はありません。たとえば、例12-44では、レクサー・プリファレンスのみが指定されていました。指定されないプリファレンスについては、CREATE_POLICYによって次のデフォルトのプリファレンスが使用されます。

- CTXSYS.DEFAULT_LEXER

- CTXSYS.DEFAULT_STOPLIST

- CTXSYS.DEFAULT_ WORDLIST

ポリシーの作成では、CONTEXT索引の作成が索引メタデータのコピー・セマンティクスに従うのと同様に、プリファレンスとその属性のコピー・セマンティクスに従います。

ora:containsのパフォーマンス

ora:containsのXPath関数は、サポートしている索引に依存しません。ora:containsは非常に柔軟性があります。しかし、索引のない大量のデータを検索する場合、大量のリソースを消費することもあります。この項では、XPath関数ora:containsを使用するXPath式が含まれる問合せのパフォーマンスを最大にする方法を説明します。

注意:
ファンクション索引はXML問合せの高速化にも非常に有効ですが、一般的にテキスト問合せには適用できません。

この項の例では、表purchase_orders_xmltype_bigが使用されます。この表には、purchase_orders_xmltypeと同じ表構造とXML Schemaがありますが、約1,000行が格納されています。各行には、(id列に)一意のIDと、/purchaseOrder/items/item/comment内に少しずつ異なるテキストが含まれています。示されている実行計画は、SQL*PlusコマンドAUTOTRACEを使用して生成されたものです。実行計画は、SQLコマンドTRACEおよびTKPROFを使用しても生成できます。コマンドAUTOTRACE、traceおよびtkprofについては、この章で説明しません。

この項の内容は次のとおりです。

- 問合せでの1次フィルタの使用

- XPathリライトおよびCONTEXT索引

問合せでの1次フィルタの使用

ora:containsは、処理のコストが比較的かかるため、可能な場合は1次フィルタを組み込んだ問合せの作成をお薦めします。この結果、ora:containsで処理される行数が最小化されます。

例12-47では、実行計画からわかるように、表内の各行が検査(全表スキャン)されます。この例で、ora:containsは各行に対して評価されます。

例12-47 大規模な表のora:contains

SELECT id FROM purchase_orders_xmltype_big
WHERE XMLExists(
'declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder/comment[ora:contains(text(), "constitution") > 0]'
PASSING doc AS "d");

Execution Plan
------------------------------------------------------------------------------------------------
| Id | Operation                       | Name                      |Rows|Bytes|Cost(%CPU)| Time|
------------------------------------------------------------------------------------------------
|   0| SELECT STATEMENT                |                           |  32|64480|686(38)|00:00:09|
|*  1| FILTER                          |                           |    |     |       |        |
|   2|TABLE ACCESS FULL                |PURCHASE_ORDERS_XMLTYPE_BIG|1161|2284K| 140(3)|00:00:02|
|*  3|COLLECTION ITERATOR PICKLER FETCH| XMLSEQUENCEFROMXMLTYPE    |    |     |       |        |
------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter( EXISTS (SELECT 0 FROM TABLE() "KOKBF$" WHERE
SYS_XMLCONTAINS(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_XQEXTRACT(SYS_XQCON2SEQ(VALUE(KOKBF$)),
'/comment/text()'),1,50),50,1,0),'constitution')>0))
3 - filter(SYS_XMLCONTAINS(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_XQEXTRACT(SYS_XQCON2SEQ(VALUE(KOKBF$)),
'/comment/text()'),1,50),50,1,0),'constitution')>0)

Note
-----
- dynamic sampling used for this statement

例12-48のように、列idに対して索引を作成し、例12-49のように、選択性の高い述語idを問合せに追加すると、実行計画に示すように、索引idによって実行処理が起動されます。関数ora:containsは、idが5未満の行でのみ実行されます。

例12-48 IDのBツリー索引

CREATE INDEX id_index ON purchase_orders_xmltype_big(id);

例12-49 大規模な表のora:contains(追加の述語を使用)

SELECT id FROM purchase_orders_xmltype_big
WHERE XMLExists(
'declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder/comment[ora:contains(text(), "constitution") > 0]'
PASSING doc AS "d")
AND id > 5;

Execution Plan
-----------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                      |Rows| Bytes |Cost(%CPU)| Time|
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                           |  1 |  2015 |8  (13)|00:00:01|
|*  1 |  TABLE ACCESS BY INDEX ROWID|PURCHASE_ORDERS_XMLTYPE_BIG|  1 |  2015 |8  (13)|00:00:01|
|*  2 |   INDEX RANGE SCAN          |ID_INDEX                   | 10 |       |2   (0)|00:00:01|
-----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(EXISTSNODE(SYS_MAKEXML("PURCHASE_ORDERS_XMLTYPE_BIG"."SYS_NC00003$
"),'/purchaseOrder/items/item/comment[ora:contains(text(), "constitution") >
0]','xmlns:ora="http://xmlns.oracle.com/xdb"')=1)
2 - access("ID">5)

Note
-----
- dynamic sampling used for this statement

XPathリライトおよびCONTEXT索引

Oracle Databaseでは、XPath式を使用する問合せを最適化することがあります。このXPathリライトは、問合せの最適化の一部として自動的に行われます。

Oracle XQuery関数ora:containsはサポートしている索引に依存しませんが、XPathリライトが行われる際には多くの場合、高いパフォーマンスを得るためにora:containsは既存のCONTEXT索引を使用します。

関連項目:

- XPathリライトのメリットの詳細は、「XQuery式とXPath式の自動リライト」を参照してください。

- オブジェクト・リレーショナル記憶域のXPathリライトの全般的な説明は、第8章「構造化記憶域のXPathリライト」を参照してください。

例12-50 ora:containsでの"electric"の検索

SELECT id FROM purchase_orders_xmltype
WHERE XMLExists(
'declare namespace ora = "http://xmlns.oracle.com/xdb"; (: :)
$d/purchaseOrder/items/item/comment
[ora:contains(text(), "electric") > 0]'
PASSING doc AS "d");

例12-50のXPath式の単純評価では、列docの各セルがその式と一致しているかどうかをテストします。

しかし、docがXML Schemaに基づいており、purchaseOrder文書がオブジェクト・リレーショナル表に物理的に格納されている場合は、列comment(存在する場合)に直接アクセスし、そこで各セルが"electric"と一致しているかどうかをテストするほうが効率的です。

ora:containsの最初の引数が単一のリレーショナル列にマップされている場合、完全なXPath式をXML文書全体に適用するかわりに、ora:containsをその列に適用することができます。この結果、索引が含まれていない場合でも、問合せのパフォーマンスが大幅に向上します。

ora:containsをCONTEXT索引を持つ列にマップするテキスト・ノードまたは属性とともに使用している場合、その索引を基礎となる列のデータに適用することがあります。CONTEXT索引をオブジェクト・リレーショナルXMLTypeデータとともに使用するには、次の両方の条件を満たす必要があります。

- ora:containsのターゲット(input_text)は、親ノードが列にマップされている単一のテキスト・ノード、または列にマップされている属性の必要があります。列は(Ordered Collection Table内の列も含めて)、単一のリレーショナル列である必要があります。

- 「ora:contains問合せのポリシー」で説明したように、索引付けに関する選択内容(contains用)およびポリシーの選択内容(ora:contains用)は問合せのセマンティクスに影響を与えます。単純な違いは、索引ベースのcontainsでは大/小文字が区別される検索であるのに対して、ora:containsでは大/小文字が区別されない検索が指定される点です。ora:containsおよびリライトされたcontainsのセマンティクスが同じになるように、ora:containsのポリシーがCONTEXT索引の索引に関する選択内容と正確に一致する必要があります。

ora:containsのポリシーとCONTEXTの索引の両方で、NULL_SECTION_GROUPセクション・グループ・タイプを使用する必要もあります。ora:containsポリシーのデフォルトのセクション・グループはctxsys.NULL_SECTION_GROUPです。

最後に、CONTEXT索引は通常非同期です。ワード"dog"が含まれる新しい文書を追加した場合にCONTEXT索引を同期化しないと、"dog"のcontains問合せでその文書が戻されません。しかし、同じデータに対するora:contains問合せでは戻されます。ora:containsとリライトされたcontainsで常に同じ結果が戻されるようにするには、PARAMETERS文字列にTRANSACTIONALキーワードを指定してCONTEXT索引を作成します。

関連項目:
パラメータTRANSACTIONALを指定してALTER INDEXを使用してトランザクション型のCONTEXT索引を作成する方法については、『Oracle Textリファレンス』を参照してください

XMLQuery、XMLTableまたはXMLExistsを使用した問合せ。XPathにはora:containsが含まれ、ora:containsポリシーがCONTEXT索引の索引に関する選択内容と正確に一致し、次のいずれかの条件が当てはまる場合、XPathリライト対象とみなすことができます。

- XMLデータはobject-relationallyに格納されます。最初のora:contains引数(input_text)が、親ノードが単一のリレーショナル列にマップされている単一のテキスト・ノードであるか、または単一のリレーショナル列にマップされている属性である場合。その列には、トランザクション型のCONTEXT索引があります。

- XMLデータがXMLIndex索引によって索引付けされたバイナリXMLで、非構造化XMLIndexコンポーネントのパス表VALUE列または構造化XMLIndexコンポーネントのスカラー値列にCONTEXT索引があります。
CONTEXT索引が非トランザクション型の場合は、XQuery拡張式プラグマora:use_text_indexを使用して、CONTEXT索引の使用を強制する必要もあります。例12-51に、これを示します。

例12-51 XQueryプラグマora:use_text_indexをora:containsとともに使用する

CREATE INDEX po_otext_ix ON my_path_table (VALUE) INDEXTYPE IS CTXSYS.CONTEXT;

EXPLAIN PLAN FOR
SELECT DISTINCT XMLCast(XMLQuery('$p/PurchaseOrder/ShippingInstructions/address'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
AS VARCHAR2(256)) "Address"
FROM po_binxml po
WHERE XMLExists(
'$p/PurchaseOrder/ShippingInstructions/address
[(# ora:use_text_index #) {ora:contains(., "$(Fortieth)")} > 0]'
PASSING po.OBJECT_VALUE AS "p");

----------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name                         | Rows | Bytes|Cost (%CPU)| Time   |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                              |    1 | 3046 |   12  (17)|00:00:01|
|   1 |  SORT GROUP BY                       |                              |    1 | 3524 |           |        |
|*  2 |   TABLE ACCESS BY INDEX ROWID BATCHED| MY_PATH_TABLE                |    2 | 7048 |    3   (0)|00:00:01|
|*  3 |    INDEX RANGE SCAN                  | SYS89559_PO_XMLINDE_PIKEY_IX |    1 |      |    2   (0)|00:00:01|
|   4 |  HASH UNIQUE                         |                              |    1 | 3046 |   12  (17)|00:00:01|
|   5 |   NESTED LOOPS                       |                              |    1 | 3046 |    8  (13)|00:00:01|
|   6 |    SORT UNIQUE                       |                              |    1 | 3034 |    6   (0)|00:00:01|
|*  7 |     TABLE ACCESS BY INDEX ROWID      | MY_PATH_TABLE                |    1 | 3034 |    6   (0)|00:00:01|
|*  8 |      DOMAIN INDEX                    | PO_OTEXT_IX                  |      |      |    4   (0)|00:00:01|
|   9 |    TABLE ACCESS BY USER ROWID        | PO_BINXML                    |    1 |   12 |    1   (0)|00:00:01|
----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - filter(SYS_XMLI_LOC_ISNODE("SYS_P3"."LOCATOR")=1)
3 - access("SYS_P3"."RID"=:B1 AND "SYS_P3"."PATHID"=HEXTORAW('6F7F'))
7 - filter("SYS_P1"."PATHID"=HEXTORAW('6F7F') AND SYS_XMLI_LOC_ISNODE("SYS_P1"."LOCATOR")=1)
8 - access("CTXSYS"."CONTAINS"("SYS_P1"."VALUE",'$(Fortieth)')>0)

Note
-----
- dynamic sampling used for this statement (level=2)

28 rows selected.

Text Path BNFの仕様

HasPathArg           ::=    LocationPath
|  EqualityExpr
InPathArg            ::=    LocationPath
LocationPath         ::=    RelativeLocationPath
|  AbsoluteLocationPath
AbsoluteLocationPath ::=    ("/" RelativeLocationPath)
|  ("//" RelativeLocationPath)
RelativeLocationPath ::=    Step
|  (RelativeLocationPath "/" Step)
|  (RelativeLocationPath "//" Step)
Step                 ::=    ("@" NCName)
|  NCName
|  (NCName Predicate)
|  Dot
|  "*"
Predicate            ::=    ("[" OrExp "]")
|  ("[" Digit+ "]")
OrExpr               ::=    AndExpr
|  (OrExpr "or" AndExpr)
AndExpr              ::=    BooleanExpr
|  (AndExpr "and" BooleanExpr)
BooleanExpr          ::=    RelativeLocationPath
|  EqualityExpr
|  ("(" OrExpr ")")
|  ("not" "(" OrExpr ")")
EqualityExpr         ::=    (RelativeLocationPath "=" Literal)
|  (Literal "=" RelativeLocationPath)
|  (RelativeLocationPath "=" Literal)
|  (Literal "!=" RelativeLocationPath)
|  (RelativeLocationPath "=" Literal)
|  (Literal "!=" RelativeLocationPath)
Literal              ::=    (DoubleQuote [~"]* DoubleQuote)
|  (SingleQuote [~']* SingleQuote)
NCName               ::=    (Letter |  Underscore) NCNameChar*
NCNameChar           ::=    Letter
|  Digit
|  Dot
|  Dash
|  Underscore
Letter               ::=    ([a-z] | [A-Z])
Digit                ::=    [0-9]
Dot                  ::=    "."
Dash                 ::=    "-"
Underscore           ::=    "_"

全文XMLのサポートの例

この項の内容は次のとおりです。

- 発注書のXML文書、po001.xml

- CREATE TABLE文

- 全文検索する発注書XML Schemaの例

発注書のXML文書、po001.xml

例12-52 発注書のXML文書、po001.xml

<?xml version="1.0" encoding="UTF-8"?>
<purchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="xmlschema/po.xsd"
orderDate="1999-10-20">
<shipTo country="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Mill Valley</city>
<state>CA</state>
<zip>90952</zip>
</shipTo>
<billTo country="US">
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Old Town</city>
<state>PA</state>
<zip>95819</zip>
</billTo>
<comment>Hurry, my lawn is going wild!</comment>
<items>
<item partNum="872-AA">
<productName>Lawnmower</productName>
<quantity>1</quantity>
<USPrice>148.95</USPrice>
<comment>Confirm this is electric</comment>
</item>
<item partNum="926-AA">
<productName>Baby Monitor</productName>
<quantity>1</quantity>
<USPrice>39.98</USPrice>
<shipDate>1999-05-21</shipDate>
</item>
</items>
</purchaseOrder>

CREATE TABLE文

例12-53 表PURCHASE_ORDERSの作成

CREATE TABLE purchase_orders (id NUMBER, doc VARCHAR2(4000));

INSERT INTO purchase_orders (id, doc)
VALUES (1,
'<?xml version="1.0" encoding="UTF-8"?>
<purchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="xmlschema/po.xsd"
orderDate="1999-10-20">
<shipTo country="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Mill Valley</city>
<state>CA</state>
<zip>90952</zip>
</shipTo>
<billTo country="US">
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Old Town</city>
<state>PA</state>
<zip>95819</zip>
</billTo>
<comment>Hurry, my lawn is going wild!</comment>
<items>
<item partNum="872-AA">
<productName>Lawnmower</productName>
<quantity>1</quantity>
<USPrice>148.95</USPrice>
<comment>Confirm this is electric</comment>
</item>
<item partNum="926-AA">
<productName>Baby Monitor</productName>
<quantity>1</quantity>
<USPrice>39.98</USPrice>
<shipDate>1999-05-21</shipDate>
</item>
</items>
</purchaseOrder>');
COMMIT;

例12-54 表PURCHASE_ORDERS_XMLTYPEの作成

CREATE TABLE purchase_orders_xmltype (id  NUMBER, doc XMLType);

INSERT INTO purchase_orders_xmltype (id, doc)
VALUES (1,
XMLTYPE ('<?xml version="1.0" encoding="UTF-8"?>
<purchaseOrder
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="po.xsd"
orderDate="1999-10-20">
<shipTo country="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Mill Valley</city>
<state>CA</state>
<zip>90952</zip>
</shipTo>
<billTo country="US">
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Old Town</city>
<state>PA</state>
<zip>95819</zip>
</billTo>
<comment>Hurry, my lawn is going wild!</comment>
<items>
<item partNum="872-AA">
<productName>Lawnmower</productName>
<quantity>1</quantity>
<USPrice>148.95</USPrice>
<comment>Confirm this is electric</comment>
</item>
<item partNum="926-AA">
<productName>Baby Monitor</productName>
<quantity>1</quantity>
<USPrice>39.98</USPrice>
<shipDate>1999-05-21</shipDate>
</item>
</items>
</purchaseOrder>'));
COMMIT;

例12-55 表PURCHASE_ORDERS_XMLTYPE_TABLEの作成

CREATE TABLE purchase_orders_xmltype_table OF XMLType;

INSERT INTO purchase_orders_xmltype_table
VALUES (
XMLType ('<?xml version="1.0" encoding="UTF-8"?>              <purchaseOrder
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="xmlschema/po.xsd"
orderDate="1999-10-20">
<shipTo country="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Mill Valley</city>
<state>CA</state>
<zip>90952</zip>
</shipTo>
<billTo country="US">
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Old Town</city>
<state>PA</state>
<zip>95819</zip>
</billTo>
<comment>Hurry, my lawn is going wild!</comment>
<items>
<item partNum="872-AA">
<productName>Lawnmower</productName>
<quantity>1</quantity>
<USPrice>148.95</USPrice>
<comment>Confirm this is electric</comment>
</item>
<item partNum="926-AA">
<productName>Baby Monitor</productName>
<quantity>1</quantity>
<USPrice>39.98</USPrice>
<shipDate>1999-05-21</shipDate>
</item>
</items>
</purchaseOrder>'));
COMMIT;

全文検索する発注書XML Schemaの例

例12-56 全文検索する発注書XML Schemaの例

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Purchase order schema for Example.com.
Copyright 2000 Example.com. All rights reserved.
</xsd:documentation>
</xsd:annotation>
<xsd:element name="purchaseOrder" type="PurchaseOrderType"/>
<xsd:element name="comment" type="xsd:string"/>
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
<xsd:complexType name="USAddress">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
<xsd:complexType name="Items">
<xsd:sequence>
<xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="quantity">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="USPrice" type="xsd:decimal"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="partNum" type="SKU" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<!-- Stock Keeping Unit, a code for identifying products -->
<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

第III部

XMLType APIの使用

第III部では、Oracle XML DBのXMLType PL/SQL、Java、C APIおよびOracle Data Provider for .NET(ODP.NET)を使用して、XMLデータにアクセスして操作する方法を説明します。次の章で構成されます。

- 第13章「PL/SQL APIs for XMLType」

- 第14章「PL/SQLパッケージDBMS_XMLSTORE」

- 第15章「Java DOM API for XMLType」

- 第16章「C API for XMLの使用」

- 第17章「Oracle XML DBでのOracle Data Provider for .NETの使用」

13 PL/SQL API for XMLType

この章では、PL/SQLでのAPI for XMLTypeの使用方法を説明します。

この章の内容は次のとおりです。

- PL/SQL API for XMLTypeの概要

- PL/SQL DOM API for XMLType(DBMS_XMLDOM)

- PL/SQL Parser API for XMLType(DBMS_XMLPARSER)

- PL/SQL XSLT Processor for XMLType(DBMS_XSLPROCESSOR)

- PL/SQL Translation API for XMLType(DBMS_XMLTRANSLATIONS)

Overview of PL/SQL API for XMLTypeの概要

この章では、PL/SQL Application Program Interface(API)for XMLTypeについて説明します。内容は次のとおりです。

- PL/SQLドキュメント・オブジェクト・モデル(DOM)API for XMLType(パッケージDBMS_XMLDOM): XMLTypeオブジェクトにアクセスするために使用します。XML Schemaに基づく文書およびXML Schemaに基づかない文書にアクセスできます。データベースを起動する前に、ファイル(initialization.ORA)に読取り元ディレクトリおよび書込み先ディレクトリを指定する必要があります。次に例を示します。

UTL_FILE_DIR=/mypath/insidemypath

読取り元ファイルおよび書込み先ファイルは、サーバーのファイル・システムに存在する必要があります。

DOMは、XML文書の動的メモリー内ツリーベースのオブジェクト表現です。要素および属性へのプログラム・アクセスを可能にします。DOMオブジェクトおよびそのインタフェースは、W3C勧告です。プログラム・アクセス用のAPIなど、XML文書のDOMを指定します。DOMは、解析対象ドキュメントをオブジェクトのツリーとして表示します。

- PL/SQL XML Parser API for XMLType(パッケージDBMS_XMLPARSER): XML文書のコンテンツおよび構造にアクセスするために使用します。

- PL/SQL XSLT Processor for XMLType(パッケージDBMS_XSLPROCESSOR): XSLTを使用してXML文書を他のフォーマットに変換するために使用します。

APIの機能

PL/SQL API for XMLTypeを使用すると、次のタスクを実行できます。

- XMLType表、列およびビューの作成

- 別のキャラクタ・セットでエンコードされたデータからのXMLTypeインスタンスの作成

- XMLTypeデータへのアクセス

- XMLTypeデータの操作

関連項目:

- Oracle XML DBアーキテクチャおよび新機能の概要については、「Oracle XML DBの機能」を参照してください。

- 第4章「XMLTypeの操作」

- 『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

XMLの遅延ロード(実体化の遅延)

XMLTypeでは動的メモリーまたは仮想ドキュメント・オブジェクト・モデル(DOM)が提供されるため、XMLの遅延ロード(実体化の遅延と言われることもあります)というメモリー節約プロセスを使用できます。このプロセスは、データ行が要求されたときに、データ行のみをロードすることによって、メモリー使用量を最適化します。メモリーの使用量が大きくなりすぎた場合に、文書内の参照済の部分を廃棄します。XMLの遅延ロードは、多くの同時ユーザーが大規模なXML文書にアクセスする必要がある高度にスケーラブルなアプリケーションをサポートします。

XMLTypeデータ型でのXML Schemaのサポート

XMLTypeデータ型では、XML Schemaもサポートされています。XML Schemaを作成し、XMLを使用してオブジェクト・リレーショナル記憶域からのマッピングに注釈を付けることができます。PL/SQL DOM APIを使用するには、まずXML Schemaを作成して登録します。その後、作成するXMLType表および列が、登録したXML Schemaに準拠するように指定できます。

XMLTypeによる異なるキャラクタ・セットのデータのサポート

PL/SQLのXMLTypeコンストラクタまたはcreateXML() XMLTypeメソッドを使用することにより、Oracleでサポートされているキャラクタ・セットのいずれかでエンコードされたデータから、XMLTypeインスタンスを作成できます。ソースのXMLデータは、BFILEまたはBLOBデータ型を使用して指定する必要があります。データのエンコーディングは、csid引数で指定されます。この引数が0(ゼロ)の場合、ソース・データのエンコーディングは、「XML 1.0 Reference」の付録Fで指定されているとおりに、XMLのプロローグから判断されます。

注意:
AL32UTF8は、XMLTypeデータに適したOracle Databaseキャラクタ・セットです。これはIANAの登録済標準であるUTF-8エンコーディングと同等であり、すべての有効なXML文字をサポートします。
Oracle Databaseのデータベース・キャラクタ・セットUTF8(ハイフンなし)とデータベース・キャラクタ・セットAL32UTF8またはキャラクタ・エンコーディングUTF-8を混同しないでください。データベース・キャラクタ・セットUTF8はAL32UTF8で置き換えられています。XMLデータにはUTF8を使用しないでください。キャラクタ・セットUTF8でサポートされるのはUnicodeバージョン3.1以下のみです。すべての有効なXML文字がサポートされるわけではありません。AL32UTF8には、このような制限はありません。

XMLデータにデータベース・キャラクタ・セットUTF8を使用すると、システムが停止したりセキュリティに悪影響を及ぼす可能性があります。入力した文書要素の名前にデータベース・キャラクタ・セットでサポートされない文字が含まれている場合、その文字は置換文字(通常は「?」)で置き換えられます。このため、解析が終了して例外が発生します。リカバリ不能なエラーが発生する可能性があります。

PL/SQL DOM API for XMLType(DBMS_XMLDOM)

この項では、PL/SQL DOM API for XMLTypeであるDBMS_XMLDOMについて説明します。

関連項目:
各DBMS_XMLDOMメソッドの説明は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

W3Cのドキュメント・オブジェクト・モデル(DOM)勧告の概要

World Wide Web Consortium(W3C)によって勧告された一般的なDOM仕様を十分に理解している場合は、この項をスキップしてください。

W3Cによって勧告されたドキュメント・オブジェクト・モデル(DOM)は、XML文書の構造にアクセスするための汎用APIです。動的HTMLを使用すると、Webページのアニメーション、対話および動的更新が可能になります。DOMは、WebページおよびXML文書に、言語およびプラットフォームに依存しないオブジェクト・モデルを提供します。DOMは、XMLのコンポーネントおよび要素にアクセスおよび操作するための、言語およびプラットフォームに依存しないインタフェースを記述します。XML文書の構造を、コンテンツに依存しない汎用的な方法で表現します。XML文書のコンテンツ、属性およびスタイルを動的に削除、追加および編集するアプリケーションを作成できます。DOMによって、すべてのブラウザ、サーバーおよびプラットフォームで適切に動作するアプリケーションを作成できます。

W3C DOM標準へのOracle XML Developer's Kit拡張

Oracle XML Developer's Kit (XDK)は、様々な方法でW3C DOM APIを拡張します。これらの拡張は、データベースに適用されないクライアント側の操作と関連するもの以外、すべてOracle XML DBでサポートされています。この種類の手続き型処理は、Oracle XML Developer's KitのJavaおよびCコンポーネントで、Simple API for XML(SAX)インタフェースを介して実行できます。

関連項目:
『Oracle XML Developer's Kitプログラマーズ・ガイド』

W3CのDOM勧告のサポート

XMLにアクセスして操作するためのすべてのOracle XML DB APIは、W3Cで承認された標準のXML処理要件に準拠しています。PL/SQL DOMは、W3CのDOM仕様のレベル1.0およびレベル2.0をサポートします。

- Oracle9iリリース1(9.0.1)では、Oracle XML Developer's Kit for PL/SQLにDOMレベル1.0およびレベル2.0の一部が実装されていました。

- Oracle9i リリース2(9.2)およびOracle Database 10g リリース1(10.1)では、PL/SQL API for XMLTypeにDOMレベル1.0およびレベル2.0コアが実装され、XMLType APIの拡張機能を介してデータベースに完全に統合されています。

次に、それぞれのレベルを簡単に説明します。

- DOMレベル1.0: 1998年10月に勧告された、DOM仕様の最初の形式レベルです。レベル1.0では、XML 1.0およびHTMLへのサポートが定義されています。

- DOMレベル2.0: 2000年11月に勧告され、レベル2.0では、名前空間を含むXML 1.0をサポートすることによって、レベル1.0が拡張されています。また、カスケーディング・スタイルシート(CSS)およびイベント(ユーザー・インタフェース・イベントおよびツリー操作イベント)のサポートが追加され、ツリー操作(ツリーの範囲および検索メカニズム)が拡張されています。CSSは、スタイル(フォント、カラー、間隔など)をWebドキュメントに追加するための単純なメカニズムです。

DOMとSAXの違い

XML用の一般的なAPIは、主に2つのカテゴリに分類できます。

- ツリーベース。DOMは、XML用の主要な汎用ツリーベースAPIです。

- イベントベース。SAX (Simple API for XML)は、XML ParserとXMLアプリケーション間の、主要な汎用イベントベース・プログラム・インタフェースです。

DOMは、オブジェクトを作成することによって機能します。これらのオブジェクトは子オブジェクトおよびプロパティを持ち、子オブジェクトはさらにその子オブジェクトおよびプロパティを持ち、というように続きます。オブジェクトは、オブジェクト階層を下って検索するか、HTML要素にID属性を明示的に指定することによって参照されます。次に例を示します。

<img src="employee_jdoe.gif" ID="0123jdoe">

次に、構造的な操作の例を示します。

- 要素の再順序付け

- 要素の追加または削除

- 属性の追加または削除

- 要素名の変更

関連項目:

- DOMの詳細は、http://www.w3.org/DOM/を参照してください。

- SAXの詳細は、http://www.saxproject.org/を参照してください。

PL/SQL DOM API for XMLType(DBMS_XMLDOM): 機能

Oracle XML DBは、XMLデータの格納と取出しのSQLサポート以外にも、Oracle Database XML開発プラットフォームを拡張しています。PL/SQL、JavaおよびCでDOMを使用して、XMLTypeインスタンスを操作できます。

PL/SQL DOM API for XMLType (DBMS_XMLDOM)のデフォルトの動作は、次のとおりです。

- DOM APIによってアクセス可能な解析ツリーを生成します。

- DTDが検出された場合に検証を行います。検出されない場合は検証を行いません。

- 解析が正常に実行されない場合、アプリケーション・エラーが発生します。

対象のドキュメントが指示された時点でDTD検証が実行されます。実体化の遅延を使用する場合は、使用時にドキュメントの検証が行われます。

PL/SQL DOM APIは、サーバーでCベース表現のXMLを使用し、XML Schemaに基づくXMLインスタンスを操作します。PL/SQL DOM API for XMLTypeおよびJava DOM API for XMLTypeは、W3CのDOM勧告に準拠して、リレーショナル列またはオブジェクト・リレーショナル列にXMLTypeの動的メモリー・インスタンスとして、XMLデータの構造化記憶域を定義および実装します。W3CのDOM勧告の詳細は、「PL/SQL DOM API for XMLTypeを使用するためのXMLデータの準備」を参照してください。

XML Schemaのサポート

PL/SQL DOM API for XMLTypeは、XML Schemaをサポートしています。Oracle XML DBは、XML Schema内で注釈をメタデータとして使用し、XML文書およびその文書のデータベース・スキーマへのマッピングの両方を決定します。

注意:
下位互換性および柔軟性を得るために、PL/SQL DOMは、XML Schemaに基づく文書とXML Schemaに基づかない文書の両方をサポートします。

Oracle XML DBにXML Schemaが登録されると、PL/SQL DOM API for XMLTypeは、ノード・オブジェクトの階層として関連XML文書の動的メモリー内ツリー表現を構築します。各ツリー表現は、独自の特別なインタフェースを持ちます。多くのノード・オブジェクト型は子ノード型を持つことができ、これによって、さらに特別な追加のインタフェースを実装できます。ノード型には、様々な型の子ノードを持つことができるものと、子ノードを持つことができないリーフ・ノードがあります。

パフォーマンスの向上

Oracle XML DBは、DOMを使用して、複数のバックエンド・データ・ソースとXML間でデータを変換する標準的な方法を提供します。これによって、環境内の様々なデータ・ソースに個別のXML変換方法を使用する必要がなくなります。XMLデータを交換する必要があるアプリケーションでは、単一のネイティブなXMLデータベースを使用して、XML文書をキャッシュできます。そのため、XML DBは、Webアプリケーションとバックエンド・データ・ソース間の中間キャッシュとして機能することによって、リレーショナル・データベース内かファイル・システム内かにかかわらず、アプリケーションのパフォーマンスを向上させることができます。

関連項目:
第15章「Java DOM API for XMLType」

Oracle XML Developer's KitおよびOracle XML DBを使用したエンドツーエンド・アプリケーションの設計

Oracle XML DBに基づくアプリケーションを構築する場合、Oracle XML Developer's Kitに追加のコンポーネントは必要ありません。ただし、エンドツーエンドで実行するXML対応アプリケーションの統合スイートをデプロイするために、Oracle XML Developer's KitのコンポーネントとともにOracle XML DBを使用することはできます。Oracle XML Developer's Kitの機能を次の処理に使用できます。

- Simple API for XML(SAX)インタフェース処理。SAXは、XML Parserによって提供され、手続き型およびイベント・ベース・アプリケーションによって使用されるXML標準インタフェースです。

- DOMインタフェース処理。再帰的な構造型オブジェクト・ベース処理に使用します。

Oracle XML Developer's Kitには、クライアント、ブラウザまたはプラグインで実行するアプリケーションを作成するための基本的な構成ブロックが含まれています。通常、これらのアプリケーションでは、XML文書の読取り、操作、変換、表示などを行います。様々なデプロイメント・オプションを提供するために、Oracle XML Developer's KitはJava、C、およびC++で使用できます。Oracle XML Developer's Kitは、フル・サポートされており、商用再配布ライセンスを受けています。

Oracle XML Developer's Kit for Javaは、次のコンポーネントで構成されています。

- XML Parsers: 業界標準のDOMインタフェースおよびSAXインタフェースを使用して、XMLを作成および解析します。Java、C、C++、Java API for XML Processing(JAXP)をサポートします。

- XSLプロセッサ: XMLを、HTMLなどの他のテキストベース形式に変換またはレンダリングします。Java、CおよびC++をサポートします。

- XML Schemaプロセッサ: XMLの単純および複合なデータ型を使用します。Java、CおよびC++をサポートします。

- XML Class Generator、Oracle JAXB Class Generator: DTDおよびXML Schemaから自動的にJavaクラスおよびC++クラスを生成し、WebフォームまたはアプリケーションからXMLデータを送信します。Class Generatorは、入力ファイルを受け入れ、対応する機能を持つ一連の出力クラスを作成するユーティリティです。XML Class Generatorの場合、入力ファイルはDTDであり、出力は、そのDTDに準拠するXML文書を作成するために使用できる一連のクラスです。

- XML SQL Utility: SQL問合せから、XML文書、DTDおよびXML Schemaを生成します。Javaをサポートします。

- TransX Utility: XMLにカプセル化されたデータをデータベースにロードします。インストールに有効な追加機能が含まれています。

- XMLパイプライン・プロセッサ: XML制御ファイルを使用してJavaプロセッサを起動します。

- XSLT VMおよびコンパイラ: コンパイルされたスタイルシートを使用する、高パフォーマンスなCベースのXSLT変換エンジンを提供します。

- XML JavaBeans: Javaコンポーネントを使用して、XML文書を解析、変換、比較、取得および圧縮します。

関連項目:
『Oracle XML Developer's Kitプログラマーズ・ガイド』

PL/SQL DOM API for XMLTypeを使用するためのXMLデータの準備

Oracle XML DBでPL/SQL DOM APIを使用するためにデータを準備するには、次の操作を実行します。

1. 標準のXML Schemaを作成します。

2. 使用するSQLオブジェクトの定義をXML Schemaの注釈として付けます。

3. XML Schemaを登録して、必要なデータベース・マッピングを生成します。

これによって、次のいずれかの操作を実行できます。

- XMLTypeビューを使用して、既存のリレーショナルまたはオブジェクト・リレーショナル・データをXML形式にラップして、XML形式のアプリケーションで使用できるようにします。「XMLTypeビューを使用したXMLへの既存データのラッピング」を参照してください。

- XMLデータをXMLType列に挿入します。

- Oracle XML DBのPL/SQL DOM APIおよびJava DOM APIを使用して、XMLType列および表に格納されたXMLデータを操作します。

SQLオブジェクト型へのXML Schemaのマッピングの定義

XML SchemaをXML文書で参照できるようにするには、まず、登録する必要があります。XML Schemaを登録すると、その中で宣言される要素および属性が、データベース内の対応するSQLオブジェクト型の属性にマップされます。

XML Schemaの登録完了後、このXML Schemaに準拠、および参照するXML文書をOracle XML DBで管理できます。準拠する文書を格納するための表および列を、このXML Schemaによって定義されたルート要素に対して作成できます。

関連項目:
第7章「XML Schemaの格納と問合せ: 基本」

XML Schemaを登録するには、PL/SQLパッケージのDBMS_XMLSCHEMAを使用し、スキーマ・ドキュメントとそのスキーマの場所のURLを指定します。このURLは、データベース内に登録されたスキーマを一意に識別する名前です。実際の場所に対応する必要はなく、また、特に、スキーマ・ドキュメントの場所を示す必要はありません。

スキーマのターゲット名前空間は、XML Schemaで使用される別のURLです。XML Schemaの要素および型の名前空間を指定します。XML文書は、ルート要素の名前空間と、この要素を定義するスキーマの場所のURLの両方を指定する必要があります。

HTTP(S)やFTPなど、パスベースのプロトコルを使用してOracle XML DBに文書が挿入されると、指定されたXML Schemaの名前および場所が事前に登録されていない場合は、その文書が準拠するXML Schemaが暗黙的に登録されます。

関連項目:
各DBMS_XMLSCHEMAメソッドの説明は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

XML SchemaのマッピングのためのDOM再現性

XML Schema内で宣言された要素および属性は、対応するSQLオブジェクト型の個別の属性にマップされます。コメント、処理命令、名前空間、宣言および接頭辞など、XML文書内のエンコードされた他の情報は、直接表現されません。

このような追加情報を格納するため、SYS_XDBPD$というバイナリ属性が、生成されたすべてのSQLオブジェクト型に存在します。この属性では、元のXML文書内で、他のデータベース属性を使用して格納されないすべての情報が格納されます。このような補足情報を保持することで、Oracle XML DB内に格納されるXML文書のDOM再現性が保証されます。つまり、データベースから取得されるXML文書は、格納された元の文書と同じものです。

注意:
このマニュアルの多くの例では、簡略化のためSYS_XDBPD$属性を省略しています。ただし、この属性は、スキーマの登録によって生成されたSQLオブジェクト型に常に存在します。

XMLTypeビューを使用したXMLへの既存データのラッピング

既存のリレーショナル・データおよびオブジェクト・リレーショナル・データをXMLアプリケーションで使用できるようにするには、データをXML形式にラップして、XMLTypeビューを作成します。これにより、PL/SQL DOM APIを使用してこのXMLデータにアクセスできます。

XMLとSQLオブジェクト型間のマッピングを表す注釈を含むXML Schemaを登録した後、このXML Schemaに準拠するXMLTypeを作成できます。

関連項目:
第19章「XMLTypeビュー」

サポートされているDBMS_XMLDOMのメソッド

次の例外を除き、Oracle XML DBでは、すべてのDBMS_XMLDOMメソッドがサポートされています。

- writeExternalDTDToFile()

- writeExternalDTDToBuffer()

- writeExternalDTDToClob()

関連項目:
各DBMS_XMLDOMメソッドの説明は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

PL/SQL DOM API for XMLType: ノード型

DOM仕様では、「ドキュメント」という用語は、DOMの対象となる様々な情報またはデータのコンテナを示すために使用されます。DOMは、XML文書コンテナ内の要素を使用して、オブジェクト・ベースのツリー構造を作成し、XML文書に格納されたオブジェクトを管理および使用するためのインタフェースを定義および公開する方法を指定します。また、DOMは様々なシステムの文書の格納をサポートします。

getNodeType(myNode)などの要求が指定されると、親ノードによってサポートされるノード型myNodeTypeが戻されます。次の定数は、ノードが使用可能な様々な型を表します。

- ELEMENT_NODE

- ATTRIBUTE_NODE

- TEXT_NODE

- CDATA_SECTION_NODE

- ENTITY_REFERENCE_NODE

- ENTITY_NODE

- PROCESSING_INSTRUCTION_NODE

- COMMENT_NODE

- DOCUMENT_NODE

- DOCUMENT_TYPE_NODE

- DOCUMENT_FRAGMENT_NODE

- NOTATION_NODE

表13-1に、XMLおよびHTMLのノード型と、それに対応する使用可能な子ノード型を示します。

表13-1 XMLおよびHTMLのDOMノード型およびその子ノード型

ノード型

子ノード型

Document

Element(1つ以下)、ProcessingInstruction、Comment、DocumentType(1つ以下)

DocumentFragment

Element、ProcessingInstruction、Comment、Text、CDATASection、EntityReference

DocumentType

子を持ちません。

EntityReference

Element、ProcessingInstruction、Comment、Text、CDATASection、EntityReference

Element

Element、Text、Comment、ProcessingInstruction、CDATASection、EntityReference

Attr

Text、EntityReference

ProcessingInstruction

子を持ちません。

Comment

子を持ちません。

Text

子を持ちません。

CDATASection

子を持ちません。

Entity

Element、ProcessingInstruction、Comment、Text、CDATASection、EntityReference

Notation

子を持ちません。

Oracle XML DB DOM API for XMLTypeは、次のインタフェースも指定します。

- A NodeListインタフェース: 次のような、順序付けられたノードのリストを処理します。

- ノードの子

- 要素インタフェースのgetElementsByTagName()メソッドによって戻された要素

- A NamedNodeMapインタフェース: 要素の属性など、名前属性によって参照される、順序付けられていない一連のノードを処理します。

XML Schemaに基づくデータの操作

Oracle Databaseには、キャラクタ・セット変換およびファイル・システムへの入出力用に、いくつかの拡張機能があります。PL/SQL API for XMLTypeは、XML Schemaに基づくXMLインスタンスを操作するために最適化されています。関数newDOMDocumentは、指定されたXMLType値でDOM文書ハンドルを構成します。

PL/SQLアプリケーションの一般的な使用例は次のとおりです。

1. XMLTypeインスタンスのフェッチまたは構成

2. XMLTypeインスタンス上でのDOMDocumentノードの構成

3. DOM APIを使用したXMLデータへのアクセスおよび操作

注意:
DOMDocumentでは、ノード型はXMLフラグメントのデータ自体ではなく、XMLフラグメントへのハンドルを表します。
たとえば、ノード値をコピーすると、DOMDocumentによって、基礎となる同じデータへのハンドルもコピーされます。一方のハンドルによって変更されたデータは、もう一方のハンドルでアクセスしても参照できます。DOMDocumentハンドルが構成されたXMLType値はデータであり、このハンドルに対して行われたすべてのDOM操作の結果が反映されます。

DOM NodeListオブジェクトおよびNamedNodeMapオブジェクト

基礎となるドキュメント構造への変更は、すべての適切なNodeListオブジェクトおよびNamedNodeMapオブジェクトに反映されます。

たとえば、DOMユーザーが要素の子を含むNodeListオブジェクトを取得し、その要素に子を追加(または削除や変更)した場合、これらの変更は自動的にNodeListに伝播されます。同様に、ツリー内のノードへの変更は、NodeListオブジェクトおよびNamedNodeMapオブジェクトのノードへのすべての参照に伝播されます。

Text、CommentおよびCDATASectionインタフェースは、CharacterDataインタフェースを継承します。

PL/SQL DOM API for XMLType(DBMS_XMLDOM)の使用

図13-1に、PL/SQL DOM API for XMLType(DBMS_XMLDOM)の使用方法を示します。

DOM文書(DOMDocument)は、既存のXMLTypeから作成するか、または空の文書として作成できます。

1. newDOMDocumentプロシージャが、XMLTypeまたは空の文書を処理します。これによって、DOMDocumentインスタンスが作成されます。

2. DOM API PL/SQLメソッド(createElement()、createText()、createAttribute()、createComment()など)を使用して、DOMツリーを検索および拡張します。

3. DOMElement()およびDOMText()などのPL/SQLメソッドの結果をPL/SQL関数makeNodeに渡して、DOMNodeインタフェースを取得することもできます。

図13-1 PL/SQL DOM API for XMLTypeの使用

PL/SQL DOM API for XMLTypeの例

この項に、PL/SQL DOM API for XMLTypeの使用例を示します。

このインタフェースを使用する際、DOMDocumentインスタンスごとにfreeDocumentプロシージャを必ずコールするようにしてください。このプロシージャにより、文書とそのノードがすべて解放されます。DOMDocumentインスタンスが解放された後でも、DOMDocumentインスタンスが構築されたXMLTypeインスタンスにアクセスできます。

例13-1では、動的メモリー内のXML文書の階層的な表現であるDOM文書を作成します。

例13-1 DOM文書の作成および操作

CREATE TABLE person OF XMLType;

DECLARE
var       XMLType;
doc       DBMS_XMLDOM.DOMDocument;
ndoc      DBMS_XMLDOM.DOMNode;
docelem   DBMS_XMLDOM.DOMElement;
node      DBMS_XMLDOM.DOMNode;
childnode DBMS_XMLDOM.DOMNode;
nodelist  DBMS_XMLDOM.DOMNodelist;
buf       VARCHAR2(2000);
BEGIN
var := XMLType('<PERSON><NAME>ramesh</NAME></PERSON>');

-- Create DOMDocument handle
doc     := DBMS_XMLDOM.newDOMDocument(var);
ndoc    := DBMS_XMLDOM.makeNode(doc);

DBMS_XMLDOM.writeToBuffer(ndoc, buf);
DBMS_OUTPUT.put_line('Before:'||buf);

docelem := DBMS_XMLDOM.getDocumentElement(doc);

-- Access element
nodelist := DBMS_XMLDOM.getElementsByTagName(docelem, 'NAME');
node := DBMS_XMLDOM.item(nodelist, 0);
childnode := DBMS_XMLDOM.getFirstChild(node);

-- Manipulate element
DBMS_XMLDOM.setNodeValue(childnode, 'raj');
DBMS_XMLDOM.writeToBuffer(ndoc, buf);
DBMS_OUTPUT.put_line('After:'||buf);
DBMS_XMLDOM.freeDocument(doc);
INSERT INTO person VALUES (var);
END;
/

これによって、次の出力が生成されます。

Before:<PERSON>
<NAME>ramesh</NAME>
</PERSON>

After:<PERSON>
<NAME>raj</NAME>
</PERSON>

この問合せでは、データが変更されたことを確認します。

SELECT * FROM person;
SYS_NC_ROWINFO$
---------------
<PERSON>
<NAME>raj</NAME>
</PERSON>

1 row selected.

例13-1では、DOM文書へのハンドルを使用して、操作、出力、一部の変更、および変更後の出力を行います。ハンドルによりDOM文書を操作すると、この文書で表現されるXMLデータにも間接的に影響するため、変更後にそのデータを問い合せると、変更した結果が示されます。

DOM文書は、PL/SQL関数newDOMDocumentを使用してXMLType変数から作成されます。この文書へのハンドルは、makeNode関数を使用して作成されます。また、この文書は、writeToBuffer関数を使用してVARCHAR2バッファに書き込まれ、さらに、このバッファは、DBMS_OUTPUT.put_lineを使用して出力されます。

様々なDBMS_XMLDOMプロシージャを使用してこの文書を操作した後、XMLType変数内の(変更された)データは表内に挿入され、問い合せることで変更を確認できます。データがデータベース表内に挿入されると、永続的になります。それまではメモリー内にのみ存在します。この永続性は、動的メモリー内の文書(DOMDocumentインスタンス)が解放されてからデータベース問合せが作成されるという事実からわかります。

例13-2では、空のDOM文書を作成し、要素ノード(<ELEM>)をこの文書に追加します。DBMS_XMLDOM APIノード・プロシージャを使用して、要素ノードの名前(<ELEM>)、値(NULL)および型(1 =要素ノード)を取得します。

例13-2 要素ノードの作成および関連情報の取得

DECLARE
doc   DBMS_XMLDOM.DOMDocument;
elem  DBMS_XMLDOM.DOMElement;
nelem DBMS_XMLDOM.DOMNode;
BEGIN
doc := DBMS_XMLDOM.newDOMDocument;
elem := DBMS_XMLDOM.createElement(doc, 'ELEM');
nelem := DBMS_XMLDOM.makeNode(elem);
DBMS_OUTPUT.put_line('Node name = ' || DBMS_XMLDOM.getNodeName(nelem));
DBMS_OUTPUT.put_line('Node value = '|| DBMS_XMLDOM.getNodeValue(nelem));
DBMS_OUTPUT.put_line('Node type = ' || DBMS_XMLDOM.getNodeType(nelem));
DBMS_XMLDOM.freeDocument(doc);
END;
/

これによって、次の出力が生成されます。

Node name = ELEM
Node value =
Node type = 1

DBMS_XMLDOMを使用した大規模ノード処理

Oracle Database 11gリリース(11.1)以前は、Oracle XML DBにより処理されるテキスト・ノードまたは属性値のサイズはそれぞれ64KBに制限されていました。リリース11.1以降、この制限はなくなりました。

このサイズ制限を克服し、ノードにグラフィック・ファイル、PDFファイル、およびマルチバイト文字エンコーディングを含めるには、次の抽象ストリームが使用できます。これらの抽象PL/SQLストリームは、対応するJavaストリームに類似しています。各入力ストリームには関連ライターまたはデータ・プロデューサがあり、各出力ストリームには関連リーダーまたはデータ・コンシューマがあります。

1. バイナリ入力ストリーム: バイトの連続した(配列ではない)線形空間として、データ・コンシューマにはソース・データへの読取り専用アクセスが与えられます。コンシューマは、(表現内容を問わず)基礎となるバイナリ形式のソース・データに反復して読取りアクセスできます。つまり、変換されていないRAW形式のソース・データへ読取りアクセスします。コンシューマは、このバイト・シーケンスがノードに存在しているとみなします。ソース・データの形式や表現の指定はありません。特に、関連付けられたキャラクタ・セットはありません。

2. バイナリ出力ストリーム: バイトの連続した(配列ではない)線形空間として、データ・プロデューサにはターゲット・データへの書込み専用アクセスが与えられます。プロデューサはバイナリ形式のターゲット・データに反復して書込みアクセスできます。つまり、データ・セマンティクスのない純粋なバイナリ形式でのターゲット・データへ書込みアクセスします。プロデューサはバイト・シーケンスを渡し、ターゲット・データはこれらのバイトと置換されます。データ変換は行われません。

3. 文字入力ストリーム: 文字の連続した(配列ではない)線形空間として、データ・コンシューマには、ソース・データの表現や形式とは関係なくソース・データへの読取り専用アクセスが与えられます。ソース・データの変換は行われる場合も、行われない場合もあります。

4. 文字出力ストリーム: 文字の連続した(配列ではない)線形空間として、データ・プロデューサはターゲット・データに反復して書込み専用アクセスができます。プロデューサは文字シーケンスを渡し、ターゲット・データはこの文字シーケンスと置換されます。渡されたデータの変換は行われる場合も、行われない場合もあります。

入力ストリームにはそれぞれ、open、read、closeという抽象メソッドがあります。出力ストリームにはそれぞれ、open、write、flush、closeという抽象メソッドがあります。出力ストリームについては、ノードが物理的に書き込まれる前にストリームを閉じる必要があります。

読取りおよび書込みには、4つの一般ノード・アクセス・モデルがあります。各アクセス・モデルには、バイナリ・バージョンとキャラクタ・バージョンの両方があります。データ型DOMNodeで定義されているバイナリ・ストリーム・メソッドおよび文字ストリーム・メソッドは、これらのアクセス・モデルを認識します。アクセス・モデルはそれぞれ別の項で説明しており、パッケージDBMS_XMLDOMの大規模ノードで動作するPL/SQLのファンクションおよびプロシージャについても説明しています。

- Get-Pushモデル

- Get-Pullモデル

- Set-Pullモデル

- Set-Pushモデル

get-pushおよびset-pullを除くすべてのアクセス・モデル(バイナリまたは文字)について、使用できる具体的なストリームが(暗黙的に)提供されています。get-pushおよびset-pullについては、提供される抽象ストリーム・タイプのサブタイプを定義し、さらにそのアクセス・メソッド(open、closeなど)を実装する必要があります。get-pushおよびset-pullについては、ストリーム・タイプをインスタンス化し、ストリームをアクセス・メソッドへの引数として提供します。たとえば、get-pushにはmy_node.getNodeValueAsCharacterStream(my-stream)、get-pullにはmy_node.getNodeValueAsCharacterStream()を使用します。Oracleが提供する具体的なストリームを使用するため、get-pullには明示的なストリーム引数は必要ありません。

注意:
文字データ・ストリームにアクセスすると、使用するアクセス・メソッドにより、アクセスされるノードのキャラクタ・セットが決まります。ストリームへのアクセスにJavaを使用する場合、Javaプログラムから見えるキャラクタ・セットはUCS2(またはアプリケーション固有のキャラクタ・セット)です。ストリームへのアクセスにPL/SQLを使用する場合、PL/SQLプログラムから見えるキャラクタ・セットはデータベース・セッションのキャラクタ・セット(またはアプリケーション固有のキャラクタ・セット)です。しかし、いずれの場合も、XMLデータはデータベース・キャラクタ・セットのデータベースに格納されます。
次の説明では、C1はデータベースに格納されているノードのキャラクタ・セットを、C2はプログラムから見えるノードのキャラクタ・セットを示しています。

関連項目:

- 大規模ノードでJavaを使用する場合の詳細は、「Javaを使用した大規模ノードの処理」を参照してください。

- 『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

- 大規模ノード処理のためのJava関数の詳細は、『Oracle Database XML Java API Reference』を参照してください。

- 大規模ノード処理のためのC関数の詳細は、『Oracle Database XML C APIリファレンス』を参照してください。

Get-Pushモデル

このモデルでノード値を読み取るため、バイナリ出力ストリームまたは文字出力ストリームが作成され、Oracle XML DBに渡されます。この場合、ソース・データはノード値です。Oracle XML DBは、ノード・データをストリームにプッシュすることで出力ストリームを移入します。ストリームが文字出力ストリームの場合、キャラクタ・セットC2がセッションのキャラクタ・セットになり、必要に応じてC1からC2にノード・データが変換されます。また、ノードのデータ型はOracle XML DBでサポートでき、ノード・データ型が文字データでない場合、ノード・データはまずC2の文字データに変換されます。バイナリ出力ストリームの場合は、ノードのデータ型はRAWまたはBLOBである必要があります。

この場合に使用するDBMS_XMLDOMパッケージのプロシージャは次のとおりです。

PROCEDURE getNodeValueAsBinaryStream (n     IN DBMS_XMLDOM.domnode,
value IN SYS.utl_BinaryOutputStream);

Oracle XML DBによるノードのコンテンツの書込み先となるSYS.utl_BinaryOutputStreamの実装が渡されます。ノードのデータ型は、RAWまたはCLOBである必要があります。それ以外の場合は、例外が発生します。

PROCEDURE getNodeValueAsCharacterStream (n     IN DBMS_XMLDOM.domnode,
value IN SYS.utl_CharacterOutputStream);

ノード・データは必要に応じてセッションのキャラクタ・セットに変換され、SYS.utl_CharacterOutputStreamにプッシュされます。

次の例は、ノード値をバイナリ・データとして読み取り、writeメソッドをMyBinaryOutputStreamと呼ばれるユーザー定義サブタイプSYS.utl_BinaryOutPutStreamで実行しているところを示しています。

例13-3 ユーザー定義サブタイプSYS.util_BinaryOutputStream()の作成

CREATE TYPE MyBinaryOutputStream UNDER SYS.utl_BinaryOutputStream (
CONSTRUCTOR FUNCTION MyBinaryOutputStream ()
RETURN SELF AS RESULT,
MEMBER FUNCTION  write (bytes IN RAW) RETURN INTEGER,
MEMBER PROCEDURE write (bytes IN RAW, offset IN INTEGER, length IN OUT
INTEGER),
MEMBER FUNCTION flush () RETURN BOOLEAN,
MEMBER FUNCTION close () RETURN BOOLEAN);
);

-- Put code here that implements these methods
...

例13-4 ユーザー定義ストリームによるノード値の取得

DECLARE
ostream     MyBinaryOutputStream = MyBinaryOutputStream ();
node        DBMS_XMLDOM.domnode;
...
BEGIN
...
-- This drives the write methods in MyBinaryOutputStream,
-- flushes the data, and closes the stream after the value has been
-- completely written.
DBMS_XMLDOM.getNodeValueAsBinaryStream (node, ostream);
...
END;

Get-Pullモデル

このモデルでノード値を読み取るため、Oracle XML DBはバイナリ入力ストリームまたは文字入力ストリームを作成し、この値をコール元に戻します。文字入力ストリームのキャラクタ・セットC2は、現在のセッションのキャラクタ・セットです。Oracle XML DBは、コール元がノード・データをストリームから抽出するに従って入力ストリームを移入するため、Oracle XML DBは再度データ・プロデューサになります。ストリームが文字入力ストリームの場合は、ノード・データ型はOracle XML DBでサポートされる型になることができ、文字の場合は必要に応じてノード・データはC1からC2に変換されます。ノード・データが文字以外の場合は、C2の文字に変換されます。バイナリ入力ストリームの場合、ノードのデータ型はRAWまたはBLOBである必要があります。

この場合に使用するDBMS_XMLDOMパッケージのファンクションは、getNodeValueAsBinaryStreamおよびgetNodeValueAsCharacterStreamです。

FUNCTION getNodeValueAsBinaryStream(n IN DBMS_XMLDOM.domnode)
RETURN SYS.utl_BinaryInputStream;

このファンクションは、"Set-Pull Model"の項で説明している定義済メソッドで読み取ることができる新しいPL/SQL SYS.utl_BinaryInputStreamのインスタンスを戻します。ノードのデータ型は、RAWまたはBLOBである必要があります。それ以外の場合は、例外が発生します。

FUNCTION getNodeValueAsCharacterStream (n IN DBMS_XMLDOM.domnode)
RETURN SYS.utl_CharacterInputStream;

このファンクションは、定義済メソッドで読み取ることができる新しいPL/SQL SYS.utl_CharacterInputStreamのインスタンスを戻します。ノード・データが文字の場合は、現在のセッションのキャラクタ・セットに変換されます。ノード・データが文字以外の場合は、まず文字データに変換されます。

例13-5では、ノード値をバイナリ・データとして50バイトずつ読み取っています。

例13-5 バイナリ・データのGet-Pull

DECLARE
istream      SYS.utl_BinaryInputStream;
node         DBMS_XMLDOM.domnode;
buffer       raw(50);
numBytes     pls_integer;
...
BEGIN
...
istream := DBMS_XMLDOM.getNodeValueAsBinaryStream (node);
-- Read stream in 50-byte chunks
LOOP
numBytes := 50;
istream.read ( buffer, numBytes);
if numBytes <= 0 then
exit;
end if;
-- Process next 50 bytes of node value in buffer
END LOOP
...
END;

例13-6では、ノード値を文字データとして50文字ずつ読み取っています。

例13-6 文字データのGet-Pull

DECLARE
istream      SYS.utl_CharacterInputStream;
node         DBMS_XMLDOM.domnode;
buffer       varchar2(50);
numChars     pls_integer;
...
BEGIN
...
istream := DBMS_XMLDOM.getNodeValueAsCharacterStream (node);
-- Read stream in 50-character chunks
LOOP
numChars := 50;
istream.read ( buffer, numChars);
IF numChars <= 0 then
exit;
END IF;
-- Process next 50 characters of node value in buffer
END LOOP
...
END;

Set-Pullモデル

このモードでノード値を書き込むため、バイナリ入力ストリームまたは文字入力ストリームが作成され、Oracle XML DBに渡されます。文字入力ストリームのキャラクタ・セットC2は、セッションのキャラクタ・セットです。Oracle XML DBは、データを入力ストリームから抽出し、ノードに移入します。ストリームが文字入力ストリームの場合、ノードのデータ型はOracle XML DBでサポートされる型になることができます。ノードのデータ型が文字以外の場合、まずストリーム・データはノード・データ型に変換されます。ノード・データ型が文字の場合は変換されないため、ノード・データはキャラクタ・セットC2に残ります。ストリームがバイナリ入力ストリームの場合、ノードのデータ型はRAWまたはBLOBである必要があり、変換は行われません。

この場合に使用するDBMS_XMLDOMパッケージのプロシージャは、setNodeValueAsBinaryStreamおよびsetNodeValueAsCharacterStreamです。

PROCEDURE setNodeValueAsBinaryStream(n IN DBMS_XMLDOM.domnode,
value IN SYS.utl_BinaryInputStream);

Oracle XML DBがノードに移入するためデータの読取り元となるSYS.utl_BinaryInputStreamの実装が渡されます。ノードのデータ型は、RAWまたはBLOBである必要があります。それ以外の場合は、例外が発生します。

PROCEDURE setNodeValueAsCharacterStream (n IN DBMS_XMLDOM.domnode,
value IN SYS.utl_CharacterInputStream);

Oracle XML DBがノードに移入するため読取り元となるSYS.utl_CharacterInputStreamの実装が渡されます。ノードのデータ型は、Oracle XML DBでサポートされる任意の有効な型になることができます。文字以外のデータ型の場合、ストリームから読み取られた文字データはノードのデータ型に変換されます。ノードのデータ型が文字またはCLOBのいずれかの場合、変換は行われず、ノードのキャラクタ・セットはPL/SQLセッションのキャラクタ・セットになります。

例13-7は、ノード値をMyBinaryInputStreamと呼ばれるユーザー定義サブタイプSYS.utl_BinaryInputStreamで定義されたreadメソッドで作成したバイナリ・データに設定しているところを示しています。

例13-7 バイナリ・データのSet-Pull

CREATE TYPE MyBinaryInputStream UNDER SYS.utl_BinaryInputStream (
CONSTRUCTOR FUNCTION MyBinaryInputStream ()
RETURN SELF AS RESULT,
MEMBER FUNCTION read () RETURN RAW,
MEMBER PROCEDURE read (bytes IN OUT RAW, numbytes IN OUT INTEGER),
MEMBER PROCEDURE read (bytes IN OUT RAW,
offset IN INTEGER,
length IN OUT INTEGER),
MEMBER FUNCTION close () RETURN BOOLEAN);

MyBinaryInputStream型のオブジェクトを使用して、ノード値を次のように設定できます。

DECLARE
istream     MyBinaryInputStream = MyBinaryInputStream ();
node        DBMS_XMLDOM.domnode;
...
BEGIN
...
-- This drives the read methods in MyBinaryInputStream
DBMS_XMLDOM.setNodeValueAsBinaryStream (node, istream);
...
END;

Set-Pushモデル

このモードでノード値を新たに書き込むため、Oracle XML DBはバイナリ出力ストリームまたは文字出力ストリームを作成し、この値をコール元に戻します。文字出力ストリームのキャラクタ・セットC2は、現在のセッションのキャラクタ・セットです。コール元はデータを出力ストリームにプッシュし、Oracle XML DBはこれをOracle XML DBノードに書き込みます。ストリームが文字出力ストリームの場合、ノードのデータ型はOracle XML DBでサポートされる型になることができます。この場合、文字データはノード・データ型に変換されます。ノード・データ型が文字の場合、キャラクタ・セットC1はC2に変換されます。データ変換は行われません。バイナリ入力ストリームの場合、ノードのデータ型はRAWまたはBLOBである必要があります。この場合、ストリームはデータ変換されず読み取られます。

この場合に使用するDBMS_XMLDOMパッケージのプロシージャは、setNodeValueAsBinaryStreamおよびsetNodeValueAsCharacterStreamです。

FUNCTION setNodeValueAsBinaryStream(n IN DBMS_XMLDOM.domnode)
RETURN SYS.utl_BinaryOutputStream;

このファンクションは、コール元によるノード値の書込み先となるSYS.utl_BinaryOutputStreamのインスタンスを戻します。ノードのデータ型は、RAWまたはBLOBである必要があります。それ以外の場合は、例外が発生します。

FUNCTION setNodeValueAsCharacterStream (n IN DBMS_XMLDOM.domnode)
RETURN SYS.utl_CharacterOutputStream;

このファンクションは、コール元によるノード値の書込み先となるPL/SQLのSYS.utl_CharacterOutputStream型のインスタンスを戻します。ノードのデータ型は、任意の有効なOracle XML DBデータ型になることができます。型が文字以外またはCLOBの場合、ストリームに書き込まれる文字データはノードのデータ型に変換されます。ノードのデータ型が文字またはCLOBの場合、ストリームに書き込まれる文字データはPL/SQLセッションのキャラクタ・セットからノードのキャラクタ・セットに変換されます。

例13-8では、50バイトのセグメントをSYS.utl_BinaryOutputStreamに書き込むことで、ノード値をバイナリ・データに設定しています。

例13-8 バイナリ・データのSet-Push

DECLARE
ostream      SYS.utl_BinaryOutputStream;
node         DBMS_XMLDOM.domnode;
buffer       raw(500);
segment      raw(50);
numBytes     pls_integer;
offset       pls_integer;
...
BEGIN
...
ostream := DBMS_XMLDOM.setNodeValueAsBinaryStream (node);
offset := 0;
length := 500;
-- Write to stream in 50-byte chunks
LOOP
numBytes := 50;
-- Get next 50 bytes of buffer
ostream.write ( segment, offset, numBytes);
length := length - numBytes;
IF length  <= 0 then
exit;
END IF;
END LOOP
ostream.close();
...
END;

バイナリ・ストリームか文字ストリームかの判断

ノード値にアクセスする場合に文字ストリームを使用するか、バイナリ・ストリームを使用するかを判断するには、DBMS_XMLDOMパッケージに記載されている次の方法を使用します。

FUNCTION useBinaryStream (n IN DBMS_XMLDOM.domnode) RETURN BOOLEAN;

このファンクションは、ノードのデータ型がRAWまたはBLOBの場合はSYS.utl_BinaryInputStreamまたはSYS.utl_BinaryOutputStreamのいずれかを使用してノード値の読取りまたは書込みができるようTRUEを戻します。値FALSEが戻されると、ノード値はSYS.utl_CharacterInputStreamまたはSYS.utl_CharacterOutputStreamを使用してのみアクセスできます。

PL/SQL Parser API for XMLType(DBMS_XMLPARSER)

XML文書は、エンティティというデータの格納単位で構成され、各エンティティには解析対象または解析対象外のデータが含まれます。解析対象データは文字で構成され、中には文書内の文字データを形成したり、タグを形成するものもあります。タグ付けは、文書のデータ格納レイアウトおよび論理構造の記述をエンコーディングします。XMLは、データ格納レイアウトおよび論理構造を制約するメカニズムを提供します。

XMLパーサーまたはプロセッサというソフトウェア・モジュールは、XML文書を読み取り、その文書のコンテンツおよび構造にアクセスします。XMLパーサーは、他のモジュール(通常はアプリケーション)のかわりに作業を行います。

PL/SQL Parser API for XMLTypeの機能

PL/SQL Parser API for XMLType(DBMS_XMLPARSER)は、PL/SQL APIによってアクセス可能な結果ツリーを構築します。解析が正常に実行されない場合、エラーが発生します。

メソッドDBMS_XMLPARSER.setErrorLog()はサポートされません。

関連項目:
各DBMS_XMLPARSERメソッドの説明は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

PL/SQL Parser API for XMLType(DBMS_XMLPARSER)の使用

図13-2に、PL/SQL Parser for XMLType(DBMS_XMLPARSER)の使用方法を示します。次の手順を実行します。

1. PL/SQLメソッドnewParser()を使用してパーサーのインスタンスを構成します。

2. parseBuffer()、parseClob()、parse(URI)などのPL/SQLメソッドを使用してXML文書を解析します。入力された文書が妥当なXML文書ではない場合、エラーを戻されます。

3. パーサーでPL/SQL関数getDocumentをコールし、DOMDocumentインタフェースを取得します。

図13-2 PL/SQL Parser API for XMLTypeの使用

例13-9では、単純なXML文書を解析します。XMLパーサー(DBMS_XMLPARSER.parserのインスタンス)を作成し、これを使用して、indoc変数のXML文書(テキスト)を解析します。解析によって、DBMS_XMLPARSER.getDocumentを使用してパーサーから取り出されるDOM文書が作成されます。文書全体を含んだDOMノードが作成され、そして、このノードが出力されます。DOM文書を解放(破棄)した後、DBMS_XMLPARSER.freeParserを使用して、パーサーのインスタンスが解放されます。

例13-9 XML文書の解析

DECLARE
indoc    VARCHAR2(2000);
indomdoc DBMS_XMLDOM.DOMDocument;
innode   DBMS_XMLDOM.DOMNode;
myparser DBMS_XMLPARSER.parser;
buf      VARCHAR2(2000);
BEGIN
indoc := '<emp><name>De Selby</name></emp>';
myParser := DBMS_XMLPARSER.newParser;
DBMS_XMLPARSER.parseBuffer(myParser, indoc);
indomdoc := DBMS_XMLPARSER.getDocument(myParser);
innode := DBMS_XMLDOM.makeNode(indomdoc);
DBMS_XMLDOM.writeToBuffer(innode, buf);
DBMS_OUTPUT.put_line(buf);
DBMS_XMLDOM.freeDocument(indomdoc);
DBMS_XMLPARSER.freeParser(myParser);
END;
/

これによって、次の出力が生成されます。

<emp><name>De Selby</name></emp>

PL/SQL XSLT Processor for XMLType(DBMS_XSLPROCESSOR)

W3CのXSL勧告では、ソース・ツリーから結果ツリーへ変換する規則が記載されています。Extensible Stylesheet Language Transformation(XSLT)言語で表現される変換を、XSLスタイルシートと呼びます。指定された変換は、XSLTスタイルシートに定義したテンプレートとパターンを対応付けることによって実行されます。結果ツリーの一部を作成するために、テンプレートはインスタンス化されます。

XSLTを使用した変換

Oracle XML DB PL/SQL DOM API for XMLTypeは、XSLTもサポートします。これによって、あるXML文書を別のXML、またはHTMLやPDFなどのその他の形式に変換できます。XSLTは、XMLをブラウザで表示するために、HTMLに変換するためにも広く使用されます。

埋込みXSLTプロセッサは、Extensible Stylesheet Language(XSL)文に従い、DOMツリー構造内のXMLTypeに存在するXMLデータを検索します。Oracle XML DBアプリケーションでは、以前のリリースで必要であったXML Parser for PL/SQLのような個別のパーサーは必要ありません。ただし、外部処理を必要とするアプリケーションでは、最初にXML Parser for PL/SQLを使用して文書構造を公開できます。

注意:
Oracle XML Developer's KitのXML Parser for PL/SQLは、XML文書(または単独のDTD)を解析して、通常はクライアントで実行しているアプリケーションでこのXML文書を処理できるようにします。PL/SQL API for XMLTypeは、サーバーで実行され、データベースにネイティブに統合されたアプリケーションに使用されます。これによるメリットには、パフォーマンスの向上、アクセスや操作のオプションの拡張などが含まれます。

関連項目:
第11章「XMLTypeデータの変換および検証」

PL/SQL XSLT Processor for XMLType: 機能

PL/SQL XSLT Processor for XMLType (DBMS_XSLPROCESSOR)は、Oracle XML DBによるXSLプロセッサの実装です。これは、W3CのXSLT最終勧告(REC-xslt-19991116)に準拠しています。この最終勧告には、XSLTスタイルシートの読取り方法および変換方法に関して、XSLプロセッサに必要な動作が記載されています。これは単一のスタイルシートを複数の文書に適用する便利で効率的な方法を提供します。

PL/SQL XSLT Processor APIの型およびメソッドは、PL/SQLパッケージDBMS_XSLPROCESSORに付属しています。このパッケージ内のメソッドでは、XSLプロセッサの実装に固有のPL/SQLデータ型である、PROCESSORおよびSTYLESHEETが使用されます。

setErrorLog()メソッドの例外を除き、Oracle XML DBでは、すべてのDBMS_XSLPROCESSORメソッドがサポートされています。

関連項目:
各DBMS_XSLPROCESSORメソッドの説明は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

PL/SQL XSLT Processor API for XMLType(DBMS_XSLPROCESSOR)の使用

図13-3に、XSLT Processor for XMLType(DBMS_XSLPROCESSOR)の使用方法を示します。次の手順を実行します。

1. newProcessorを使用して、XSLTプロセッサを構成します。

2. newStylesheetを使用して、DOM文書からSTYLESHEETオブジェクトを構築します。

3. オプションとして、setParamsを使用してSTYLESHEETオブジェクトにパラメータを設定できます。

4. processXSLを使用して、このプロセッサおよびSTYLESHEETオブジェクトを使用しDOM文書を変換します。

5. PL/SQL DOM API for XMLTypeを使用して、XSLT処理の結果を操作します。

図13-3 PL/SQL XSLT Processor for XMLTypeの使用

例13-10では、processXSLプロシージャを使用してXML文書を変換します。これは、同じパーサー・インスタンスを使用して、変換するXMLテキストとXSLTスタイルシートの2つの異なるDOM文書を作成します。XSLプロセッサ・インスタンスが作成され、このスタイルシートをソースのXMLに適用して、新しいDOMフラグメントを生成します。DOMノード(outnode)が、このフラグメントから作成され、このノードのコンテンツが出力されます。freeDocFrag、freeParserおよびfreeProcessorプロシージャをそれぞれ使用して、出力されたDOMフラグメント、パーサーおよびXSLTプロセッサ・インスタンスが解放されます。

例13-10 XSLスタイルシートを使用したXML文書の変換

DECLARE
indoc      VARCHAR2(2000);
xsldoc     VARCHAR2(2000);
myParser   DBMS_XMLPARSER.parser;
indomdoc   DBMS_XMLDOM.DOMDocument;
xsltdomdoc DBMS_XMLDOM.DOMDocument;
xsl        DBMS_XSLPROCESSOR.stylesheet;
outdomdocf DBMS_XMLDOM.DOMDocumentFragment;
outnode    DBMS_XMLDOM.DOMNode;
proc       DBMS_XSLPROCESSOR.processor;
buf        VARCHAR2(2000);
BEGIN
indoc := '<emp><empno>1</empno>
<fname>robert</fname>
<lname>smith</lname>
<sal>1000</sal>
<job>engineer</job>
</emp>';
xsldoc := '<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="utf-8"/>
<!-- alphabetizes an xml tree -->
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="*|text()">
<xsl:sort select="name(.)" data-type="text"
order="ascending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="normalize-space(.)"/>
</xsl:template>
</xsl:stylesheet>';
myParser := DBMS_XMLPARSER.newParser;
DBMS_XMLPARSER.parseBuffer(myParser, indoc);
indomdoc   := DBMS_XMLPARSER.getDocument(myParser);
DBMS_XMLPARSER.parseBuffer(myParser, xsldoc);
xsltdomdoc := DBMS_XMLPARSER.getDocument(myParser);
xsl        := DBMS_XSLPROCESSOR.newStyleSheet(xsltdomdoc, '');
proc       := DBMS_XSLPROCESSOR.newProcessor;
--apply stylesheet to DOM document
outdomdocf := DBMS_XSLPROCESSOR.processXSL(proc, xsl, indomdoc);
outnode    := DBMS_XMLDOM.makeNode(outdomdocf);
-- PL/SQL DOM API for XMLType can be used here
DBMS_XMLDOM.writeToBuffer(outnode, buf);
DBMS_OUTPUT.put_line(buf);
DBMS_XMLDOM.freeDocument(indomdoc);
DBMS_XMLDOM.freeDocument(xsltdomdoc);
DBMS_XMLDOM.freeDocFrag(outdomdocf);
DBMS_XMLPARSER.freeParser(myParser);
DBMS_XSLPROCESSOR.freeProcessor(proc);
END;
/

これによって、次の出力が生成されます。

<emp>
<empno>1</empno>
<fname>robert</fname>
<job>engineer</job>
<lname>smith</lname>
<sal>1000</sal>
</emp>

PL/SQL Translation API for XMLType(DBMS_XMLTRANSLATIONS)

セキュリティ・オブジェクトがOracle XML DBリポジトリに格納される場合、XMLTypeインスタンスとして格納されます。セキュリティ・オブジェクトには、様々な言語で検索または表示できるように、変換が必要な文字列も含まれています。これらの文字列を変換したものは、元のドキュメントと関連付ける必要があるため、Oracle XML DBリポジトリに元の文字列とともに格納されています。ユーザーの言語設定に応じて、これらの文字列を取得および操作できます。

Oracle XML DBでは、DBMS_XMLTRANSLATIONSパッケージを使用して変換サポートが提供されています。このパッケージは変換を実行するインタフェースを提供し、様々な言語での検索や表示を可能にしています。

関連項目:
XML変換の概要については第7章「XML Schemaの格納と問合せ: 基本」を参照してください。

DBMS_XMLTRANSLATIONSメソッド

PL/SQLパッケージDBMS_XMLTRANSLATIONSでは次のメソッドが提供されています。

- updateTranslation(): 指定されたXPATHにある、特定の言語での変換を更新します。その言語での変換が存在しない場合は、それが挿入されます。

- setSourceLang(): ソース言語をXPATHにある、特定の言語に設定します。

- translateXML(): 特定の言語で文書を戻します。

- getBaseDocument(): 主ドキュメントをすべての変換とともに戻します。

- extractXLiff(): XMLTYPEインスタンスまたはOracle XML DBリポジトリのリソースから変換をXLIFF形式で抽出します。

- mergeXLiff(): XMLTYPEインスタンスまたはOracle XML DBリポジトリのリソースに、変換をXLIFF形式でマージします。

- disableTranslation(): 現在のセッションで変換を無効にして、問合せまたは取出しが、セッションの言語値を無視して主ドキュメント上で行われるようにします。

- enableTranslation(): 現在のセッションで変換を有効にします。

関連項目:
各DBMS_XMLTRANSLATIONSメソッドの説明は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

14 PL/SQLパッケージDBMS_XMLSTORE

この章では、PL/SQLパッケージDBMS_XMLSTOREについて説明します。このパッケージは、オブジェクト・リレーショナル表のXML文書に対するデータの挿入、更新および削除に使用されます。

この章の内容は次のとおりです。

- PL/SQLパッケージDBMS_XMLSTOREの概要

- DBMS_XMLSTOREパッケージの使用

- DBMS_XMLSTOREを使用した挿入

- DBMS_XMLSTOREを使用した更新

- DBMS_XMLSTOREを使用した削除

PL/SQLパッケージDBMS_XMLSTOREの概要

PL/SQLパッケージDBMS_XMLSTOREを使用すると、XMLを使用して、リレーショナル表でDML操作を実行できます。パッケージDBMS_XMLGENで生成されるマッピングと同様に正規XMLマッピングを使用し、それをオブジェクト・リレーショナルの構成に変換し、リレーショナル表に対して対応する値を挿入、更新または削除します。

パッケージDBMS_XMLSTOREの機能は、Oracle XML SQL Utility(XSU)の一部であるDBMS_XMLSAVEパッケージと類似しています。ただし、いくつか重要な違いがあります。

- DBMS_XMLSTOREはCで作成されてカーネルにコンパイルされるため、優れたパフォーマンスが得られます。

- DBMS_XMLSTOREは、Simple API for XML(SAX)を使用して入力XML文書を解析するため、拡張性が高く、メモリー要件が低減します。DBMS_XMLSTOREでは、CLOBおよびVARCHARに加え、XMLTypeデータを入力できます。

- DBMS_XMLSAVEにも存在するPL/SQL関数のinsertXML、updateXMLおよびdeleteXMLが、DBMS_XMLSTOREでは、CLOB値と文字列の他にXMLTypeインスタンスを取るように拡張されています。この結果、Oracle XML DB機能との緊密な統合が実現します。

DBMS_XMLSTOREパッケージの使用

PL/SQLパッケージDBMS_XMLSTOREを使用するには、次の手順を実行します。

1. DBMS_XMLSTORE.newContext()関数をコールし、DML操作に使用する表名を指定してコンテキスト・ハンドルを作成します。大/小文字を区別する場合は、関数に渡す文字列を二重引用符(")で囲みます。
デフォルトでは、XML文書は<ROW>タグで行を識別します。これは、XMLデータの生成時にDBMS_XMLGENパッケージで使用されるデフォルトと同じです。この動作は、setRowTag関数を使用してオーバーライドできます。

2. 挿入の場合、パフォーマンスを向上させるには、列ごとにDBMS_XMLSTORE.setUpdateColumnプロシージャをコールして、挿入する列リストを設定できます。デフォルト動作では(列のリストを指定しない場合)、対応する要素がXML文書内に存在しているすべての列に値が挿入されます。

3. 更新の場合、関数DBMS_XMLSTORE.setKeyColumnを使用して(擬似)キー列を1つ以上指定します。これらは、更新する行を指定するために使用されます。SQLのUPDATE文のWHERE句でこれを行います。指定する列は、表のキーである必要はありませんが、更新する行を一意に指定する必要があります。

たとえば、employees表のemployee_id列は、行を一意に識別します(表のキーです)。表の更新に使用するXML文書に、<EMPLOYEE_ID>2176</EMPLOYEE_ID>要素が含まれている場合、employee_idが2176と等しい行が更新されます。

パフォーマンスを向上させるために、DBMS_XMLSTORE.setUpdateColumnを使用して、update列のリストを指定することもできます。デフォルト動作では、対応する要素がXML文書に存在するsetKeyColumnによって識別される行内のすべての列が更新されます。

4. 削除の場合、削除する行を識別するために、(擬似)キー列を指定します。これは更新する行の指定と同じ方法で行います。手順3を参照してください。

5. PL/SQL関数のinsertXML、updateXMLまたはdeleteXMLに文書を指定します。この手順を複数のXML文書に対して繰り返すことができます。

6. DBMS_XMLSTORE.closeContext関数をコールしてコンテキストをクローズします。

DBMS_XMLSTOREを使用した挿入

表またはビューにXML文書を挿入するには、表名またはビュー名、および文書を指定します。DBMS_XMLSTOREによって文書が解析され、すべての値がバインドされるINSERT文が作成されます。デフォルトでは、DBMS_XMLSTOREによって、XML文書内の要素で表されるすべての列に値が挿入されます。

例14-1では、DBM_XMLSTOREを使用して、2人の新入社員に関する情報をemployees表に挿入します。この情報は、XMLデータ形式で提供されます。

例14-1 指定した列でのデータの挿入

SELECT employee_id AS EMP_ID, salary, hire_date, job_id, email, last_name
FROM employees WHERE department_id = 30;

EMP_ID     SALARY HIRE_DATE JOB_ID     EMAIL       LAST_NAME
------ ---------- --------- ---------- ---------- ----------
114      11000 07-DEC-94 PU_MAN     DRAPHEAL     Raphaely
115       3100 18-MAY-95 PU_CLERK   AKHOO            Khoo
116       2900 24-DEC-97 PU_CLERK   SBAIDA          Baida
117       2800 24-JUL-97 PU_CLERK   STOBIAS        Tobias
118       2600 15-NOV-98 PU_CLERK   GHIMURO        Himuro
119       2500 10-AUG-99 PU_CLERK   KCOLMENA   Colmenares

6 rows selected.

DECLARE
insCtx DBMS_XMLSTORE.ctxType;
rows NUMBER;
xmlDoc CLOB :=
'<ROWSET>
<ROW num="1">
<EMPLOYEE_ID>920</EMPLOYEE_ID>
<SALARY>1800</SALARY>
<DEPARTMENT_ID>30</DEPARTMENT_ID>
<HIRE_DATE>17-DEC-2002</HIRE_DATE>
<LAST_NAME>Strauss</LAST_NAME>
<EMAIL>JSTRAUSS</EMAIL>
<JOB_ID>ST_CLERK</JOB_ID>
</ROW>
<ROW>
<EMPLOYEE_ID>921</EMPLOYEE_ID>
<SALARY>2000</SALARY>
<DEPARTMENT_ID>30</DEPARTMENT_ID>
<HIRE_DATE>31-DEC-2004</HIRE_DATE>
<LAST_NAME>Jones</LAST_NAME>
<EMAIL>EJONES</EMAIL>
<JOB_ID>ST_CLERK</JOB_ID>
</ROW>
</ROWSET>';
BEGIN
insCtx := DBMS_XMLSTORE.newContext('HR.EMPLOYEES'); -- Get saved context
DBMS_XMLSTORE.clearUpdateColumnList(insCtx); -- Clear the update settings

-- Set the columns to be updated as a list of values
DBMS_XMLSTORE.setUpdateColumn(insCtx, 'EMPLOYEE_ID');
DBMS_XMLSTORE.setUpdateColumn(insCtx, 'SALARY');
DBMS_XMLSTORE.setUpdateColumn(insCtx, 'HIRE_DATE');
DBMS_XMLSTORE.setUpdateColumn(insCtx, 'DEPARTMENT_ID');
DBMS_XMLSTORE.setUpdateColumn(insCtx, 'JOB_ID');
DBMS_XMLSTORE.setUpdateColumn(insCtx, 'EMAIL');
DBMS_XMLSTORE.setUpdateColumn(insCtx, 'LAST_NAME');

-- Insert the doc.
rows := DBMS_XMLSTORE.insertXML(insCtx, xmlDoc);
DBMS_OUTPUT.put_line(rows || ' rows inserted.');

-- Close the context
DBMS_XMLSTORE.closeContext(insCtx);
END;
/

2 rows inserted.

PL/SQL procedure successfully completed.

SELECT employee_id AS EMP_ID, salary, hire_date, job_id, email, last_name
FROM employees WHERE department_id = 30;

EMP_ID     SALARY HIRE_DATE JOB_ID     EMAIL       LAST_NAME
------ ---------- --------- ---------- ---------- ----------
114      11000 07-DEC-94 PU_MAN     DRAPHEAL     Raphaely
115       3100 18-MAY-95 PU_CLERK   AKHOO            Khoo
116       2900 24-DEC-97 PU_CLERK   SBAIDA          Baida
117       2800 24-JUL-97 PU_CLERK   STOBIAS        Tobias
118       2600 15-NOV-98 PU_CLERK   GHIMURO        Himuro
119       2500 10-AUG-99 PU_CLERK   KCOLMENA   Colmenares
920       1800 17-DEC-02 ST_CLERK   STRAUSS       Strauss
921       2000 31-DEC-04 ST_CLERK   EJONES          Jones

8 rows selected.

DBMS_XMLSTOREを使用した更新

DBMS_XMLSTOREパッケージを使用して既存のデータを更新(変更)するには、更新する行を指定する必要があります。SQLでは、UPDATE文のWHEREを使用してこの操作を実行します。DBMS_XMLSTOREでは、行を識別するのにまとめて使用される列ごとにsetKeyColumnプロシージャを1回ずつコールして実行します。

この列のセットは、キー列と同様に機能し、組み合せて使用することにより、更新する一意の行を指定します。ただし、(setKeyColumnとともに)使用する列は、表内のキーである必要はありません。行を一意に指定するかぎり、setKeyColumnへのコールとともに使用できます。

例14-2では、DBM_XMLSTOREを使用して情報を更新します。この例では、従業員番号188の名前が誤って「Kelly」として記録されていると仮定し、この名前を「Pat」に訂正します。employee_id列が、employees表の主キーであるため、更新用に一意の行を識別するには、employee_id列を指定するsetKeyColumnへの1回のコールで十分です。

例14-2 キー列を使用したデータの更新

SELECT employee_id, first_name FROM employees WHERE employee_id = 188;

EMPLOYEE_ID FIRST_NAME
----------- ----------
188 Kelly

1 row selected.

DECLARE
updCtx DBMS_XMLSTORE.ctxType;
rows NUMBER;
xmlDoc CLOB :=
'<ROWSET>
<ROW>
<EMPLOYEE_ID>188</EMPLOYEE_ID>
<FIRST_NAME>Pat</FIRST_NAME>
</ROW>
</ROWSET>';
BEGIN
updCtx := DBMS_XMLSTORE.newContext('HR.EMPLOYEES'); -- get the context
DBMS_XMLSTORE.clearUpdateColumnList(updCtx);        -- clear update settings

-- Specify that column employee_id is a "key" to identify the row to update.
DBMS_XMLSTORE.setKeyColumn(updCtx, 'EMPLOYEE_ID');
rows := DBMS_XMLSTORE.updateXML(updCtx, xmlDoc);    -- update the table
DBMS_XMLSTORE.closeContext(updCtx);                 -- close the context
END;
/

SELECT employee_id, first_name FROM employees WHERE employee_id = 188;

EMPLOYEE_ID FIRST_NAME
----------- ----------
188 Pat

1 row selected.

次のUPDATE文は、例14-2で使用されているDBM_XMLSTOREと同等です。

UPDATE hr.employees SET first_name = 'Pat' WHERE employee_id = 188;

DBMS_XMLSTOREを使用した削除

削除の場合は、更新の場合と同様、削除する行を識別するキー、または疑似キー列を指定します。

例14-3 DBMS_XMLSTORE.DELETEXMLの例

SELECT employee_id FROM employees WHERE employee_id = 188;

EMPLOYEE_ID
-----------
188

1 row selected.

DECLARE
delCtx DBMS_XMLSTORE.ctxType;
rows NUMBER;
xmlDoc CLOB :=
'<ROWSET>
<ROW>
<EMPLOYEE_ID>188</EMPLOYEE_ID>
<DEPARTMENT_ID>50</DEPARTMENT_ID>
</ROW>
</ROWSET>';
BEGIN
delCtx  := DBMS_XMLSTORE.newContext('HR.EMPLOYEES');
DBMS_XMLSTORE.setKeyColumn(delCtx, 'EMPLOYEE_ID');
rows := DBMS_XMLSTORE.deleteXML(delCtx, xmlDoc);
DBMS_XMLSTORE.closeContext(delCtx);
END;
/

SELECT employee_id FROM employees WHERE employee_id = 188;

no rows selected.

15 Java DOM API for XMLType

この章では、Java Database Connectivity(JDBC)を介したXMLTypeデータのフェッチなど、JavaでXMLTypeを使用する方法を説明します。

この章の内容は次のとおりです。

- Java DOM API for XMLTypeの概要

- Java DOM API for XMLType

- JDBCを使用した、データベースへの大規模なXML文書のロード

- Java DOM API for XMLTypeの機能

- Java DOM API for XMLTypeのクラス

- Javaを使用した大規模ノードの処理

- バイナリXMLでのJava DOM APIおよびJDBCの使用

Java DOM API for XMLTypeの概要

Oracle XML DBはJava Document Object Model (DOM) Application Program Interface (API) for XMLTypeをサポートします。これはXML Schemaに基づく文書とXML Schemaに基づかない文書に対する、クライアントおよびサーバー用の汎用APIです。このAPIは、Javaパッケージoracle.xml.parser.v2を使用して実装されます。DOMは、XML文書のメモリー内ツリーベースのオブジェクト表現で、要素および属性へのプログラム・アクセスを可能にします。DOMオブジェクトおよびインタフェースは、W3C勧告の一部です。DOMは、解析対象ドキュメントをオブジェクトのツリーとして表示します。

JDBCを使用してXMLTypeデータにアクセスするには、クラスoracle.xdb.XMLTypeを使用します。

どのXML Schemaにも準拠しないXML文書には、すべての妥当なXML文書を処理可能なJava DOM API for XMLTypeを使用できます。

関連項目:
『Oracle Database XML Java API Reference』

Java DOM API for XMLType

Java DOM API for XMLTypeは、Oracle XML DBへの格納方法にかかわらず、すべての種類の妥当なXML文書を処理します。XML文書は、XML Schemaに基づくか、XML Schemaに基づかないか(基礎となる記憶域モデルの形式が何であるか)にかかわらず、アプリケーションで同様に表示されます。Java DOM APIは、クライアントおよびサーバーの両方で動作します。

第13章「PL/SQL API for XMLType」で説明したとおり、Oracle XML DB DOM APIは、W3CのDOMレベル1.0およびレベル2.0のコア勧告に準拠しています。

Java DOM API for XMLTypeを使用すると、別のキャラクタ・セットでエンコードされたデータからXMLTypeインスタンスを作成できます。

Java DOM API for XMLTypeを使用して、JavaアプリケーションからOracle XML DBリポジトリに格納されたXML文書にアクセスできます。ネーミングは、W3CのDOM勧告で指定されている、DOMへのJavaバインディングに準拠しています。リポジトリには、XML Schemaに基づくドキュメントおよび基づかないドキュメントの両方を含めることができます。

JDBCを使用したXMLTypeデータへのアクセス

JDBCは、Oracle XML DB内のXML文書など、Oracle Database内のすべてのデータにアクセスするための、Javaアプリケーション用のSQLベースの方法です。XMLデータを作成するには、oracle.xdb.XMLType JavaクラスのcreateXML()メソッドを使用します。

注意:
入力としてストリームを引き渡す場合は、メソッドXMLType.createXML()とThickドライバを使用してください。この場合、Thinドライバは使用できません。

JDBCとのXMLTypeデータの使用

XMLデータのJDBC 4.0標準データ型はjava.sql.SQLXMLです。getObject()メソッドでは、oracle.xdb.XMLType型のオブジェクトが戻されます。Oracle Databaseリリース2 (11.2.0.3)から、oracle.xdb.XMLTypeがインタフェースjava.sql.SQLXMLを実装しています。

JDBCを使用してJavaアプリケーションでOracle XML DB内のXML文書にアクセスする方法

JDBCユーザーは、XMLType表を問い合せて、SQL XMLTypeデータ型でサポートされるすべてのSQL/XML関数をサポートするJDBC XMLTypeインタフェースを取得できます。Java(JDBC)API for XMLTypeインタフェースは、DOMDocumentインタフェースを実装できます。

例15-1に、JDBCを使用してXMLType表を問い合せる方法を示します。

例15-1 JDBCを使用したXMLType表の問合せ

import oracle.xdb.XMLType;
...
OraclePreparedStatement stmt = (OraclePreparedStatement)
conn.prepareStatement("SELECT e.poDoc FROM po_xml_tab e");
ResultSet rset = stmt.executeQuery();
OracleResultSet orset = (OracleResultSet) rset;
while(orset.next())
{
// get the XMLType
XMLType poxml = (XMLType)orset.getObject(1);
// get the XMLDocument as a string...
Document podoc = (Document)poxml.getDOM();
}

次のいずれかの方法で、JDBCを使用してXMLTypeデータを選択できます。

- SQLでSQL/XML関数XMLSerializeを使用し、Javaでoracle.sql.CLOB、java.lang.Stringまたはoracle.sql.BLOBとして結果を取得します。例15-2のJavaスニペットに、これを示します。

- PreparedStatementでメソッドgetObject()をコールして、XMLTypeインスタンス全体を取得します。このメソッドの戻り値は、oracle.xdb.XMLType型です。これによって、XMLTypeクラスでJava関数を使用して、データにアクセスできます。この方法を例15-3に示します。

例15-2 getStringVal()およびgetCLOB()を使用したXMLTypeデータの選択

DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn =
DriverManager.getConnection("jdbc:oracle:oci8:@", "QUINE", "CURRY");
OraclePreparedStatement stmt =
(OraclePreparedStatement) conn.prepareStatement(
"SELECT XMLSerialize(DOCUMENT e.poDoc AS CLOB) poDoc, " +
"XMLSerialize(DOCUMENT e.poDoc AS VARCHAR2(2000)) poString " +
" FROM po_xml_tab e");
ResultSet rset = stmt.executeQuery();
OracleResultSet orset = (OracleResultSet) rset;
while(orset.next())
{
// the first argument is a CLOB
oracle.sql.CLOB clb = orset.getCLOB(1);
// the second argument is a string..
String poString = orset.getString(2);
// now use the CLOB inside the program
}

例15-3では、getObject()メソッドを使用してResultSetからXMLTypeインスタンスを直接取得します。

例15-3 getObject()を使用してXMLTypeデータを戻す方法

import oracle.xdb.XMLType;
...
PreparedStatement stmt =  conn.prepareStatement(
"SELECT e.poDoc FROM po_xml_tab e");
ResultSet rset = stmt.executeQuery();
while(rset.next())
{
// get the XMLType
XMLType poxml = (XMLType)rset.getObject(1);
// get the XML as a string...
String poString = poxml.getStringVal();
}

例15-4では、XMLType型の出力パラメータをSQL文にバインドします。この出力パラメータは、XMLTypeデータ型として登録されます。

例15-4 出力パラメータを使用してXMLTypeデータを戻す方法

public void doCall (String[] args)
throws Exception
{
//  CREATE OR REPLACE FUNCTION getPurchaseOrder(reference VARCHAR2)
//  RETURN XMLTYPE
//  AS
//    xml XMLTYPE;
//  BEGIN
//    SELECT OBJECT_VALUE INTO xml
//      FROM purchaseorder
//      WHERE XMLCast(XMLQuery('$p/PurchaseOrder/Reference'
//                             PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
//                    AS VARCHAR2(30))
//            = reference;
//      RETURN xml;
//  END;
String SQLTEXT = "{? = call getPurchaseOrder('BLAKE-2002100912333601PDT')}";
CallableStatement sqlStatement = null;
XMLType xml = null;
super.doSomething(args);
createConnection();
try
{
System.out.println("SQL := " + SQLTEXT);
sqlStatement = getConnection().prepareCall(SQLTEXT);
sqlStatement.registerOutParameter (1, OracleTypes.OPAQUE,"SYS.XMLTYPE");
sqlStatement.execute();
xml = (XMLType) sqlStatement.getObject(1);
System.out.println(xml.getStringVal());
}
catch (SQLException SQLe)
{
if (sqlStatement != null)
{
sqlStatement.close();
throw SQLe;
}
}

JDBCを使用したXMLデータベース文書の操作

Java Database Connectivity(JDBC)を使用して、XMLTypeデータを更新、挿入および削除することもできます。

注意:
XMLTypeメソッドのextract()、transform()およびexistsNode()は、OCIドライバでのみ機能します。
Thin JDBCドライバでは、すべてのoracle.xdb.XMLType関数がサポートされているわけではありません。oracle.xdb.XMLTypeクラスとOCIドライバを使用しない場合、XMLのインテリジェント処理に関連したパフォーマンスのメリットを失う可能性があります。

XMLTypeデータを次のいずれかの方法で、更新、挿入または削除できます。

- CLOBまたは文字列をINSERT、UPDATEまたはDELETE文にバインドし、SQL内でXMLTypeコンストラクタを使用してXMLインスタンスを作成します。例15-5に、これを示します。

- PreparedStatementでsetObject()を使用して、XMLTypeインスタンス全体を設定します。例15-6に、これを示します。

例15-5 SQL UPDATEとコンストラクタXMLTypeを使用したXMLTypeデータの更新

OraclePreparedStatement stmt =
(OraclePreparedStatement) conn.prepareStatement(
"UPDATE po_xml_tab SET poDoc = XMLType(?)");

// the second argument is a string..
String poString = "<PO><PONO>200</PONO><PNAME>PO_2</PNAME></PO>";

// now bind the string..
stmt.setString(1,poString);
stmt.execute();

例15-6 SQL UPDATEとsetObject()を使用したXMLTypeデータの更新

import oracle.xdb.XMLType;
...
OraclePreparedStatement stmt =
(OraclePreparedStatement) conn.prepareStatement(
"UPDATE po_xml_tab SET poDoc = ?");

// the second argument is a string
String poString = "<PO><PONO>200</PONO><PNAME>PO_2</PNAME></PO>";
XMLType poXML = XMLType.createXML(conn, poString);

// now bind the string..
stmt.setObject(1,poXML);
stmt.execute();

XMLType値を選択すると、JDBCによって、列が不透明型として記述されます。列型の名前を選択し、それをXMLTYPEと比較すると、XMLTypeインスタンスを処理しているかどうかを確認できます。例15-7に、これを示します。

例15-7 JDBCを使用したXMLTypeデータに関するメタデータの取得

import oracle.sql.*;
import oracle.jdbc.*;
...
OraclePreparedStatement stmt =
(OraclePreparedStatement) conn.prepareStatement(
"SELECT poDoc FROM po_xml_tab");

OracleResultSet rset = (OracleResultSet)stmt.executeQuery();

// Get the resultset metadata
OracleResultSetMetaData mdata =
(OracleResultSetMetaData)rset.getMetaData();

// Describe the column = the column type comes out as OPAQUE
// and column type name comes out as XMLTYPE
if (mdata.getColumnType(1) == OracleTypes.OPAQUE &&
mdata.getColumnTypeName(1).compareTo("SYS.XMLTYPE") == 0)
{
// It is an XMLtype
}

例15-8では、XMLType列に格納されているPurchaseOrder要素内のdiscount要素を更新します。ここではJDBCおよびoracle.xdb.XMLTypeクラスを使用します。XMLパーサーを使用してDOMツリーを更新し、更新されたXML値をXMLType列に書き込みます。

例15-8 JDBCを使用したXMLType列の要素の更新

-- Create po_xml_hist table to store old PurchaseOrders
CREATE TABLE po_xml_hist (xpo XMLType);
/* NOTE: You must have xmlparserv2.jar and xdb.jar in CLASSPATH */
import java.sql.*;
import java.io.*;
import oracle.xml.parser.v2.*;
import org.xml.sax.*;
import org.w3c.dom.*;
import oracle.jdbc.driver.*;
import oracle.sql.*;
import oracle.xdb.XMLType;
public class tkxmtpje
{
static String conStr = "jdbc:oracle:oci8:@";
static String user = "QUINE";
static String pass = "CURRY";
static String qryStr =
"SELECT x.poDoc from po_xml_tab x " +
"WHERE XMLCast(XMLQuery('/PO/PONO/text()'" +
" PASSING x.poDoc RETURNING CONTENT)" +
" AS NUMBER)" +
" = 200";
static String updateXML(String xmlTypeStr)
Java DOM API for XMLType
Beta Draft Java DOM API for XMLType 15-7
{
System.out.println("\n===============================");
System.out.println("xmlType.getStringVal():");
System.out.println(xmlTypeStr);
System.out.println("===============================");
String outXML = null;
try {
DOMParser parser = new DOMParser();
parser.setValidationMode(false);
parser.setPreserveWhitespace (true);
parser.parse(new StringReader(xmlTypeStr));
System.out.println("xmlType.getStringVal(): xml String is well-formed");
XMLDocument doc = parser.getDocument();
NodeList nl = doc.getElementsByTagName("DISCOUNT");
for(int i=0;i<nl.getLength();i++)
{
XMLElement discount = (XMLElement)nl.item(i);
XMLNode textNode = (XMLNode)discount.getFirstChild();
textNode.setNodeValue("10");
}
StringWriter sw = new StringWriter();
doc.print(new PrintWriter(sw));
outXML = sw.toString();
//print modified xml
System.out.println("\n===============================");
System.out.println("Updated PurchaseOrder:");
System.out.println(outXML);
System.out.println("===============================");
}
catch (Exception e)
{
e.printStackTrace(System.out);
}
return outXML;
}
}

public static void main(String args[]) throws Exception
{
try {
System.out.println("qryStr=" + qryStr);
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn =
DriverManager.getConnection("jdbc:oracle:oci8:@", user, pass);
Statement s = conn.createStatement();
OraclePreparedStatement stmt;
ResultSet rset = s.executeQuery(qryStr);
OracleResultSet orset = (OracleResultSet) rset;
while(orset.next())
{
//retrieve PurchaseOrder xml document from database
XMLType xt = (XMLType)orset.getObject(1);
//store this PurchaseOrder in po_xml_hist table
stmt = (OraclePreparedStatement)conn.prepareStatement(
"INSERT INTO po_xml_hist VALUES(?)");
stmt.setObject(1,xt); // bind the XMLType instance
stmt.execute();
//update "DISCOUNT" element
String newXML = updateXML(xt.getStringVal());
// create a new instance of an XMLtype from the updated value
xt = XMLType.createXML(conn, newXML);
// update PurchaseOrder xml document in database
stmt = (OraclePreparedStatement)conn.prepareStatement(
"UPDATE po_xml_tab x SET x.poDoc =? WHERE " +
"XMLCast(XMLQuery('/PO/PONO/text()'" +
" PASSING value(xmltab) RETURNING CONTENT)" +
" AS NUMBER)" +
"= 200");
stmt.setObject(1,xt); // bind the XMLType instance
stmt.execute();
conn.commit();
System.out.println("PurchaseOrder 200 Updated!");
}
//delete PurchaseOrder 1001
s.execute("DELETE FROM po_xml x WHERE" +
"XMLCast(XMLQuery('/PurchaseOrder/PONO/text()'" +
" PASSING value(xmltab) RETURNING CONTENT)" +
" AS NUMBER)" +
"= 1001");
System.out.println("PurchaseOrder 1001 deleted!");
}
catch(Exception e)
{
e.printStackTrace(System.out);
}
}

SELECT x.xpo.getCLOBVal() FROM po_xml x;

例15-9は、例15-8から得られる更新済の発注書を示します。

例15-9 更新済の発注書

<?xml version = "1.0"?>
<PurchaseOrder>
<PONO>200</PONO>
<CUSTOMER>
<CUSTNO>2</CUSTNO>
<CUSTNAME>John Nike</CUSTNAME>
<ADDRESS>
<STREET>323 College Drive</STREET>
<CITY>Edison</CITY>
<STATE>NJ</STATE>
<ZIP>08820</ZIP>
</ADDRESS>
<PHONELIST>
<VARCHAR2>609-555-1212</VARCHAR2>
<VARCHAR2>201-555-1212</VARCHAR2>
</PHONELIST>
</CUSTOMER>
<ORDERDATE>20-APR-97</ORDERDATE>
<SHIPDATE>20-MAY-97 12.00.00.000000 AM</SHIPDATE>
<LINEITEMS>
<LINEITEM_TYP LineItemNo="1">
<ITEM StockNo="1004">
<PRICE>6750</PRICE>
<TAXRATE>2</TAXRATE>
</ITEM>
<QUANTITY>1</QUANTITY>
<DISCOUNT>10</DISCOUNT>
</LINEITEM_TYP>
<LINEITEM_TYP LineItemNo="2">
<ITEM StockNo="1011">
<PRICE>4500.23</PRICE>
<TAXRATE>2</TAXRATE>
</ITEM>
<QUANTITY>2</QUANTITY>
<DISCOUNT>10</DISCOUNT>
</LINEITEM_TYP>
</LINEITEMS>
<SHIPTOADDR>
<STREET>55 Madison Ave</STREET>
<CITY>Madison</CITY>
<STATE>WI</STATE>
<ZIP>53715</ZIP>
</SHIPTOADDR>
</PurchaseOrder>

例15-10では、次のものがすべて処理されます。

- XMLType表からのXMLTypeインスタンスの選択

- XPath式に基づくXMLTypeインスタンスの一部の抽出

- 要素の有無の確認

- XSLに基づく別のXML形式へのXMLTypeインスタンスの変換

- XML Schemaに対するXMLType文書の妥当性の確認

例15-10 JDBCを使用したXMLType列の操作

import java.sql.*;
import java.io.*;
import java.net.*;
import java.util.*;
import oracle.xml.parser.v2.*;
import oracle.xml.parser.schema.*;
import org.xml.sax.*;
import org.w3c.dom.*;
import oracle.xml.sql.dataset.*;
import oracle.xml.sql.query.*;
import oracle.xml.sql.docgen.*;
import oracle.xml.sql.*;
import oracle.jdbc.driver.*;
import oracle.sql.*;
import oracle.xdb.XMLType;
public class tkxmtpk1
{
static String conStr = "jdbc:oracle:oci8:@";
static String user = "tpjc";
static String pass = "tpjc";
static String qryStr = "select x.resume from t1 x where id<3";
static String xslStr =
"<?xml version='1.0'?> " +
"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1" +
"999/XSL/Transform'> " +
"<xsl:template match='ROOT'> " +
"<xsl:apply-templates/> " +
"</xsl:template> " +
"<xsl:template match='NAME'> " +
"<html> " +
" <body> " +
" This is Test " +
" </body> " +
"</html> " +
"</xsl:template> " +
"</xsl:stylesheet>";
static void parseArg(String args[])
{
conStr = (args.length >= 1 ? args[0]:conStr);
user = (args.length >= 2 ? args[1].substring(0, args[1].indexOf("/")):user);
pass = (args.length >= 2 ? args[1].substring(args[1].indexOf("/")+1):pass);
qryStr = (args.length >= 3 ? args[2]:qryStr);
}
/**
* Print the byte array contents
*/
static void showValue(byte[] bytes) throws SQLException
{
if (bytes == null)
System.out.println("null");
else if (bytes.length == 0)
System.out.println("empty");
else
{
for(int i=0; i<bytes.length; i++)
System.out.print((bytes[i]&0xff)+" ");
System.out.println();
}
}
public static void main(String args[]) throws Exception
{
tkxmjnd1 util = new tkxmjnd1();
try{
if(args != null)
parseArg(args);
// System.out.println("conStr=" + conStr);
System.out.println("user/pass=" + user + "/" +pass );
System.out.println("qryStr=" + qryStr);
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection(conStr, user, pass);
Statement s = conn.createStatement();
ResultSet rset = s.executeQuery(qryStr);
OracleResultSet orset = (OracleResultSet) rset;
OPAQUE xml;
while(orset.next()){
oracle.xdb.XMLType xt = (oracle.xdb.XMLType)(orset.getObject(1));
System.out.println("Testing getDOM() ...");
Document doc = xt.getDOM();
util.printDocument(doc);
System.out.println("Testing getBytesValue() ...");
showValue(xt.getBytesValue());
System.out.println("Testing existsNode() ...");
try {
System.out.println("existsNode(/)" + xt.existsNode("/", null));
}
Java DOM API for XMLType
Beta Draft Java DOM API for XMLType 15-11
catch (SQLException e) {
System.out.println("Thin driver Expected exception: " + e);
}
System.out.println("Testing extract() ...");
try {
XMLType xt1 = xt.extract("/RESUME", null);
System.out.println("extract RESUME: " + xt1.getStringVal());
System.out.println("should be Fragment: " + xt1.isFragment());
}
catch (SQLException e) {
System.out.println("Thin driver Expected exception: " + e);
}
System.out.println("Testing isFragment() ...");
try {
System.out.println("isFragment = " + xt.isFragment()); }
catch (SQLException e)
{
System.out.println("Thin driver Expected exception: " + e);
}
System.out.println("Testing isSchemaValid() ...");
try {
System.out.println("isSchemaValid(): " + xt.isSchemaValid(null,"RES UME"));
}
catch (SQLException e) {
System.out.println("Thin driver Expected exception: " + e);
}
System.out.println("Testing transform() ...");
System.out.println("XSLDOC: \n" + xslStr + "\n");
try {
/* XMLType xslDoc = XMLType.createXML(conn, xslStr);
System.out.println("XSLDOC Generated");
System.out.println("After transformation:\n" + (xt.transform(xslDoc,
null)).getStringVal()); */
System.out.println("After transformation:\n" + (xt.transform(null,
null)).getStringVal());
}
catch (SQLException e) {
System.out.println("Thin driver Expected exception: " + e);
}
System.out.println("Testing createXML(conn, doc) ...");
try {
XMLType xt1 = XMLType.createXML(conn, doc);
System.out.println(xt1.getStringVal());
}
catch (SQLException e) {
System.out.println("Got exception: " + e);
}
}
}
catch(Exception e)
{
e.printStackTrace(System.out);
}
}
}

JDBCを使用した、データベースへの大規模なXML文書のロード

大規模なXML文書(通常4000文字を超える場合)がJDBCのStringオブジェクトを使用してXMLTypeの表または列に挿入されると、次のランタイム・エラーが発生します。

"java.sql.SQLException: Data size bigger than max size for this type"

このエラーは、JavaのCLOBオブジェクトを使用して大規模なXML文書を保持することで回避できます。例15-11に、このテクニックを使用するコードを示します。これはXMLTypeメソッドのinsertXML()を定義します。これを使用して、大規模なXML文書が表poTableのXMLTypeの列purchaseOrderに挿入されます。XMLType表の場合も同じ方法を使用できます。

メソッドinsertXML()はXML文書を含むCLOBオブジェクトを使用します。CLOBオブジェクトは、クライアント側でクラスoracle.sql.CLOBを使用して作成されます。このクラスは、Oracle JDBC Driverによる標準JDBCインタフェースjava.sql.Clobの実装です。メソッドinsertXML()はCLOBオブジェクトをJDBCのプリコンパイルされたSQL文にバインドします。これによりデータがXMLType列に挿入されます。

insertXML()を使用するための前提条件は、次のとおりです。

- Oracle Databaseがリリース9.2.0.1以上であること。

- ターゲット・データベース表が存在すること。例を実行する前に、次のSQLを実行してください。
CREATE TABLE poTable (purchaseOrder XMLType);

XMLTypeメソッドのinsertXML()の仮パラメータは、次のとおりです。

- xmlData: XMLType列に挿入するXMLデータ

- conn: データベース接続オブジェクト(Oracle Connection Object)

例15-11 JavaメソッドinsertXML()

...
import oracle.sql.CLOB;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.PreparedStatement;
...

private void insertXML(String xmlData, Connection conn) {
CLOB clob = null;
String query;
// Initialize statement Object
PreparedStatement pstmt = null;
try{
query = "INSERT INTO potable (purchaseOrder) VALUES (XMLType(?)) ";
// Get the statement Object
pstmt = conn.prepareStatement(query);
// xmlData is the string that contains the XML Data.
// Get the CLOB object.
clob = getCLOB(xmlData, conn);
// Bind this CLOB with the prepared Statement
pstmt.setObject(1, clob);
// Execute the Prepared Statement
if (pstmt.executeUpdate () == 1) {
System.out.println ("Successfully inserted a Purchase Order");
}
} catch(SQLException sqlexp){
sqlexp.printStackTrace();
} catch(Exception exp){
exp.printStackTrace();
}
}

JavaメソッドinsertXML()は、メソッドgetCLOB()をコールして、XMLデータを格納するCLOBオブジェクトを作成して戻します。getCLOB()メソッドの仮パラメータは例15-12で定義され、次のとおりです。

- xmlData: XMLType列に挿入するXMLデータ

- conn: データベース接続オブジェクト(Oracle Connection Object)

例15-12 JavaメソッドgetCLOB()

...
import oracle.sql.CLOB;
import java.sql.Connection;
import java.sql.SQLException;
import java.io.Writer;
...

private CLOB getCLOB(String xmlData, Connection conn) throws SQLException{
CLOB tempClob = null;
try{
// If the temporary CLOB has not yet been created, create one
tempClob = CLOB.createTemporary(conn, true, CLOB.DURATION_SESSION);

// Open the temporary CLOB in readwrite mode, to enable writing
tempClob.open(CLOB.MODE_READWRITE);
// Get the output stream to write
Writer tempClobWriter = tempClob.getCharacterOutputStream();
// Write the data into the temporary CLOB
tempClobWriter.write(xmlData);

// Flush and close the stream
tempClobWriter.flush();
tempClobWriter.close();

// Close the temporary CLOB
tempClob.close();
} catch(SQLException sqlexp){
tempClob.freeTemporary();
sqlexp.printStackTrace();
} catch(Exception exp){
tempClob.freeTemporary();
exp.printStackTrace();
}
return tempClob;
}

関連項目:
『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』

Java DOM API for XMLTypeの機能

Java DOM APIを使用してOracle XML DBからXMLデータを取得する場合:

- 接続がThinの場合は、XMLDocumentインスタンスを取得します。

- 接続がThickまたはkprbの場合は、getDOM()メソッドでXDBDocumentインスタンスを、getDocument()メソッドでXMLDocumentインスタンスを取得します。getDOM()メソッドとXDBDocumentクラスは非推奨になりました。

XMLDocumentおよびXDBDocument(非推奨)は、どちらもW3Cドキュメント・オブジェクト・モデル(DOM)・インタフェースのインスタンスです。このドキュメント・インタフェースからドキュメントの要素にアクセスすると、W3CのDOM勧告に指定されたすべての操作を実行できます。DOMは、次のものに対して機能します。

- XML Schemaに基づく、基づかないに関係なく、あらゆる種類のXML文書

- 文書で使用されるすべての形式の基礎となる記憶域

- キャラクタ・ラージ・オブジェクト(Character Large Object: CLOB)

- バイナリ・ラージ・オブジェクト(Binary Large Object: BLOB)

- オブジェクト・リレーショナル

Java DOM API for XMLTypeは、XMLオブジェクトの子およびプロパティ(名前、名前空間など)を取得するために、文書内でのディープ検索およびシャロウ検索をサポートします。Java DOM API for XMLTypeはDOM 2.0勧告に準拠し、名前空間を認識します。

Java API for XMLTypeを使用すると、アプリケーションではプログラムによって、その場で(動的に)XML文書を作成できます。そのような文書は、登録されたXML Schemaに準拠することもあれば、しないこともあります。

XML Schemaに基づく文書の作成

XML Schemaに基づく文書を作成するには、Java DOM API for XMLTypeの拡張機能を使用して、使用するXML Schema URLを指定します。XML Schemaに基づく文書では、作成中のDOMが指定されたXML Schemaに準拠するかどうか(適切な子が適切な文書に挿入されているか)を検証します。

注意:
Java DOM API for XMLTypeは型および制約のチェックは実行しません。

DOMオブジェクトの作成後は、Oracle XML DB Resource API for Javaを使用して、DOMオブジェクトをOracle XML DBリポジトリに保存できます。XML文書は次の適切な形式で格納されます。

- BLOBインスタンス(スキーマに基づかない文書の場合)

- XML Schemaで指定された形式(XML Schemaに基づく文書の場合)

例15-13では、Java DOM API for XMLTypeを使用してDOMオブジェクトを作成し、関連するXML Schemaで指定された形式で格納します。この例では、XML Schemaに対する検証は示されていません。

例15-13 Java DOM APIを使用したDOMオブジェクトの作成

import oracle.xdb.XMLType;
...
OraclePreparedStatement stmt =
(OraclePreparedStatement) conn.prepareStatement(
"update po_xml_XMLTypetab set poDoc = ? ");

// the second argument is a string
String poString = "<PO><PONO>200</PONO><PNAME>PO_2</PNAME></PO>";
XMLType poXML = XMLType.createXML(conn, poString);
Document poDOM = (Document)poXML.getDOM();

Element rootElem = poDOM.createElement("PO");
poDOM.insertBefore(poDOM, rootElem, null);

// now bind the string..
stmt.setObject(1,poXML);
stmt.execute();

JDBCまたはSQLJ

XMLTypeインスタンスは、oracle.xdb.XMLTypeによってJavaで表現されます。XMLTypeインスタンスがJDBCを使用してフェッチされると、このインスタンスは提供されたXMLTypeクラスのオブジェクトとして自動的に明示されます。同様に、このクラスのオブジェクトは、データ操作言語(DML)文の値としてバウンドできます。通常、この値はXMLTypeです。SQLJクライアントでも同じ動作がサポートされます。

Java DOM API for XMLTypeのクラス

Oracle XML DBは、W3CのDOMレベル2勧告をサポートします。W3C勧告に加えて、Oracle XML DB DOM APIは、アプリケーションとOracle XML Developer's Kit for Javaの相互作用を円滑にするOracle固有の拡張機能も提供します。Oracleの拡張機能のリストは、次のURLを参照してください。

http://www.oracle.com/technetwork/database-features/xmldb/overview/index.html

XMLDocumentは、インスタンス化されたXML文書用のDOMを表すクラスです。XMLTypeの値は、Documentの引数を取るXMLTypeコンストラクタを使用してXML文書から取得できます。

XMLType createXML(Connection conn, Document domdoc)

表15-1に、Java DOM API for XMLTypeのクラスおよび実装されるW3CのDOMインタフェースを示します。Java DOM APIクラスはすべて、oracle.xml.parser.v2パッケージに入っています。

表15-1 Java DOM API for XMLType: クラス

Java DOM API for XMLTypeのクラス

W3CのDOMインタフェース勧告のクラス

XMLDocument

org.w3c.dom.Document

XMLCDATA

org.w3c.dom.CDataSection

XMLComment

org.w3c.dom.Comment

XMLPI

org.w3c.dom.ProcessingInstruction

XMLText

org.w3c.dom.Text

XMLEntity

org.w3c.dom.Entity

DTD

org.w3c.dom.DocumentType

XMLNotation

org.w3c.dom.Notation

XMLAttr

org.w3c.dom.Attribute

XMLDomImplementation

org.w3c.dom.DOMImplementation

XMLElement

org.w3c.dom.Element

XMLAttrList

org.w3c.dom.NamedNodeMap

XMLNode

org.w3c.dom.Node

推奨またはサポートされていないJavaメソッド

リリース2(9.2.0.1)のマニュアルには次のメソッドに関する説明が含まれていますが、サポートされなくなりました。

- XDBDocument.getElementByID

- XDBDocument.importNode

- XDBNode.normalize

- XDBNode.isSupported

- XDBDomImplementation.hasFeature

また、Oracle Database 11gリリース1以前は、oracle.xdb.domパッケージの異なるAPIがJava DOMに使用されていました。非推奨になったAPIの詳細は、該当リリースのドキュメントを参照してください。oracle.xdb.domの次のクラスは、非推奨です。かわりにoracle.xml.parser.v2クラスを使用してください。

- XDBAttribute: XMLAttrを使用

- XDBBinaryDocument

- XDBCData: XMLCDATAを使用

- XDBComment: XMLCommentを使用

- XDBDocFragment: XMLDocumentFragmentを使用

- XDBDocument: XMLDocumentを使用

- XDBDocumentType: DTDを使用

- XDBDOMException: XMLDomExceptionを使用

- XDBDomImplementation: XMLDomImplementationを使用

- XDBElement: XMLElementを使用

- XDBEntity: XMLEntityを使用

- XDBEntityReference: XMLEntityReferenceを使用

- XDBNamedNodeMap: XMLAttrListを使用

- XDBNode: XMLNodeを使用

- XDBNodeList: NodeListを使用

- XDBNotation: XMLNotationを使用

- XDBProcInst: XMLPIを使用

- XDBText: XMLTextを使用

Java DOM API for XMLTypeの使用

図15-1に、Java DOM API for XMLTypeを示します脚注1 。次の手順を実行します。

1. XMLType表または表のXMLType列からXMLデータを取り出します。XMLデータをフェッチすると、OracleによってXMLTypeのインスタンスが作成されます。これによって、getDocument()メソッドを使用して文書のインスタンスを取得できます。その後、Java DOM API for XMLTypeを使用してDOMツリーの要素を操作できます。

2. Java DOM API for XMLTypeを使用してDOMツリーの要素を操作します。変更されたデータはXMLTypeインスタンスに格納されますが、データはJDBC更新を使用して戻されます。

XMLTypeおよびXMLDocumentインスタンスは、各クラスでclose()メソッドを使用してクローズする必要があります。クローズすると、保持されていた基礎となるメモリーがすべて解放されます。

図15-1 Java DOM API for XMLTypeの使用

Javaを使用した大規模ノードの処理

Oracle Database 11gリリース1 (11.1)以前は、ノードのサイズが64KB未満に制限されていました。ノード値を設定および取得するJavaメソッドはjava.lang.String型の引数のみでサポートされているためです。文字列の最大サイズはJava VMの実装により依存していますが、限定されています。リリース11.1以前は、oracle.xdb.dom.XDBNode.javaクラス内に含まれているノード値を管理するJava DOM APIは次のようになっていました。

public String getNodeValue ();
public void setNodeValue (String value);

以前は、oracle.xdb.dom.XDBAttribute.javaクラス内に含まれている属性を管理するJava DOM APIは次のようになっていました。

public String getValue ();
public void setValue (String value);

Oracle Database 11gリリース1 (11.1)から、パッケージoracle.xdb.domは非推奨になっています。このパッケージ内のJavaクラスXDBNodeおよびXDBAttributeは、パッケージoracle.xml.parser.v2内でそれぞれクラスXMLNodeおよびXMLAttrに置き換えられています。また、これらのDOM APIはリリース11.1では拡張され、任意のサイズのテキスト・ノード値およびバイナリ・ノード値をサポートしています。

注意:
大規模ノード機能は、Thickまたはkprb接続でのみ動作します。Thin接続では動作しません。

関連項目:

- 大規模ノードにおけるPL/SQLの使用については、「DBMS_XMLDOMを使用した大規模ノードの処理」を参照してください。

- 非推奨のXDBNodeクラスおよびXDBAttributeクラスの詳細は、「推奨またはサポートされていないJavaメソッド」を参照してください。

Java DOMへのストリーム拡張

Java String、Reader、およびWriterデータはすべてUCS2で表現されます。これは、データベース・キャラクタ・セットと同じではない場合があります。また、ノード文字データはキャラクタ・セットIDでタグ付けされており、ノード値が移入するときに設定されます。

次に示すoracle.xml.parser.v2.XMLNode.javaのメソッドにより、サイズが64KBを超えるノードにアクセスできます。リーフ・ノード(属性、PI、CDATAなど)ではないノードを取得または設定しようとすると、これらのAPIにより例外が発生します。また、その値を実際に書き込み、ノードへのストリーム・アクセス状態を維持する場合に使用するリソースを解放するclose()を使用してください。

Get-Pullモデル

バイナリ入力ストリームの場合:

public java.io.InputStream getNodeValueAsBinaryStream ()
throws java.io.IOException, DOMException;

メソッドgetNodeValueAsBinaryStream()は、このクラスの定義メソッドを使用して読み取ることができるjava.io.InputStreamのインスタンスを戻します。ノードのデータ型はRAWまたはBLOBである必要があります。それ以外の場合は、IOExceptionが発生します。次の例では、バイナリ50バイトのセグメントのノード値を読み取っています。

...
oracle.xml.parser.v2.XMLNode node = null;
...

java.io.InputStream value = node.getNodeValueAsBinaryStream ();
// now read InputStream...
byte buffer [] = new byte [50];
int returnValue = 0;
while ((returnValue = value.read (buffer)) != -1)
{
// process next 50 bytes of node
}
...

文字入力ストリームの場合:

public java.io.Reader getNodeValueAsCharacterStream()
throws java.io.IOException, DOMException;

メソッドgetNodeValueAsCharacterStream()は、このクラスの定義メソッドを使用して読み取ることができるjava.io.Readerのインスタンスを戻します。ノードのデータ型が文字でもCLOBでもない場合、まずノード・データは文字に変換されます。すべてのノード・データは最終的には文字形式になり、必要に応じてUCS2に変換されます。次の例では、50文字のセグメントのノード値を読み取っています。

...
oracle.xml.parser.v2.XMLNode node = null;
...

java.io.Reader value = node.getNodeValueAsCharacterStream ();
// now read InputStream
char buffer [] = new char [50];
int returnValue = 0;
while ((returnValue = value.read (buffer)) != -1)
{
// process next 50 characters of node
}
...

Get-Pushモデル

バイナリ出力ストリームの場合:

public void getNodeValueAsBinaryStream (java.io.OutputStream pushValue)
throws java.io.IOException,  DOMException;

pushValueで指定されるjava.io.OutputStreamの状態はopenである必要があります。ノードのデータ型はRAWまたはBLOBである必要があります。それ以外の場合は、IOExceptionが発生します。ノード・バイナリ・データはOutputStreamのwrite()メソッドを使用してpushValueに書き込まれ、ノード値が完全にストリームに書き込まれるとclose()メソッドがコールされます。

文字出力ストリームの場合:

public void getNodeValueAsCharacterStream (java.io.Writer pushValue)
throws java.io.IOException, DOMException;

pushValueで指定されるjava.io.Writerの状態はopenである必要があります。ノードのデータ型が文字でもCLOBでもない場合、まずデータは文字に変換されます。常に文字形式のノード・データは必要に応じてUCS2に変換され、java.io.Writerにプッシュされます。

Set-Pullモデル

バイナリ入力ストリームの場合:

public void setNodeValueAsBinaryStream (java.io.InputStream pullValue)
throws java.io.IOException, DOMException;

pullValueで指定されるjava.io.InputStreamの状態はopenである必要があります。ノードのデータ型はRAWまたはBLOBである必要があります。それ以外の場合は、IOExceptionが発生します。pullValueのバイナリ・データ全体がInputStreamのread()メソッドを使用して読み取られ、ノード値を置換します。

import java.io.InputStream;
import oracle.xml.parser.*;
...
oracle.xml.parser.v2.XMLNode node = null;
...
byte [] buffer = new byte [500];
java.io.InputStream  istream; //user-defined input stream
node.setNodeValueAsBinaryStream (istream);

文字入力ストリームの場合:

public void setNodeValueAsCharacterStream (java.io.Reader pullValue)
throws java.io.IOException, DOMException;

pullValueで指定されるjava.io.Readerの状態はopenである必要があります。ノードのデータ型が文字でもCLOBでもない場合、文字データはUCS2からノード・データ型に変換されます。ノードのデータ型が文字またはCLOBの場合、pullValueから読み取られた文字データは、UCS2からノードのキャラクタ・セットに変換されます。

Set-Pushモデル

バイナリ出力ストリームの場合:

public java.io.OutputStream setNodeValueAsBinaryStream ()
throws java.io.IOException, DOMException;

メソッドsetNodeValueAsBinaryStream()は、コール元によるノード値の書込み先となるjava.io.OutputStreamのインスタンスを戻します。ノードのデータ型はRAWまたはBLOBである必要があります。それ以外の場合は、IOExceptionが発生します。次の例では、Oracle XML DBまたはOracle XML Developer's Kitが提供するjava.io.OutputStreamの実装に書き込むことで、ノード値をバイナリ・データに設定しています。

文字出力ストリームの場合:

public java.io.Writer setNodeValueAsCharacterStream ()
throws java.io.IOException, DOMException;

メソッドsetNodeValueAsCharacterStream()は、コール元によるノード値の書込み先となるjava.io.Writerのインスタンスを戻します。書き込まれた文字データはまず、必要に応じてUCS2からノードのキャラクタ・セットに変換されます。ノードのデータ型が文字でもCLOBでもない場合、文字データはノード・データ型に変換されます。同様に、次の例では、Oracle XML DBまたはOracle XML Developer's Kitが提供するjava.io.Writerの実装に書き込むことで、ノード値を文字データに設定しています。

import java.io.Writer;
import oracle.xml.parser.*;
...
oracle.xml.parser.v2.XMLNode node = null;
...
char [] buffer = new char [500];
java.io.Writer  writer = node.setNodeValueAsCharacterStream ();
for (int k = 0; k < 10; k++)
{
byte segment [] = new byte [50];
// copy next subset of buffer into segment
writer.write (segment);
}
writer.flush ();
writer.close();

関連項目:

- 『Oracle Database XML Java API Reference』

- 大規模ノードのためのC関数の詳細は、『Oracle Database XML C APIリファレンス』を参照してください。

Oracle XML DBはwriterまたはOutputStreamを作成し、それをノード値が完全に書き込まれるまで繰り返しwrite()メソッドをコールするユーザーに渡します。新規ノード値は、ユーザーがclose()メソッドをコールするときのみ反映されます。

バイナリXMLでのJava DOM APIおよびJDBCの使用

XMLデータはXMLTypeを使用してOracle XML DBに格納でき、この抽象データ型の記憶域モデルの1つはバイナリXMLです。バイナリXMLはXMLデータの簡潔な、XML Schema対応のエンコーディングです。データベース内のXMLTypeの記憶域モデルとして使用することができますが、データベース外にあるXMLデータに対しても使用することができます。XMLデータのクライアント側処理には、Oracle XML DB内に格納されているデータや、データベース外に存在する一時データが関わることがあります。

Java DOM APIを使用して、Oracle XML DBに対して、バイナリXML形式でエンコードされたXMLデータを読書きすることができます。この処理には通常の読書きプロシージャが関与します。

バイナリXMLはXML Schemaに対応しており、必要性とデータに応じて、各種のコード体系を使用することができます。このため、バイナリXMLデータを操作するためには、関連するXML Schemaとエンコーディングについて、データとこのメタデータの両方が必要です。

データベースに格納されているXMLTypeデータの場合、このメタデータもデータベースに格納されます。ただし、データベースとデータのセットアップに応じて、メタデータが適用されるデータと同一のサーバーにメタデータが格納されない場合があります。この場合、データベースに対してバイナリXMLデータを読書きするためには、次の手順を実行する必要があります。

1. メタデータのコンテキスト・インスタンスを作成します。

2. このコンテキストを、データベース内のバイナリXMLデータにアクセスするために使用するデータ接続に関連付けます。データ接続は、専用接続でも接続プールでもかまいません。クラスjava.sql.ConnectionのメソッドgetDedicatedConn()およびgetConnPool()を使用して、それらの接続の型に応じて、これら2つの接続型へのハンドルを取得します。

すると、アプリケーションがデータ接続上でバイナリXMLデータをエンコードまたはデコードする必要がある場合、それに必要なメタデータが自動的にフェッチされます。一連の動作の全体は次のとおりです。

1. クラスjava.sql.ConnectionにXMLデータ接続オブジェクトを作成します。

2. パッケージoracle.xml.binxml内のメソッドBinXMLMetadataProviderFactory.createDBMetadataProvider()を使用して、必要に応じて1つ以上のメタデータ・コンテキストを作成します。メタデータ・コンテキストは、メタデータ・リポジトリと呼ばれることもあります。メタデータ・コンテキストは、専用接続または接続プールから作成することができます。

3. メタデータ・コンテキストをバイナリXMLデータ接続に関連付けます。これには、パッケージoracle.xml.binxml内のメソッドDBBinXMLMetadataProvider.associateDataConnection()を使用します。

4. (オプション) XMLデータがデータベース外に由来するものの場合は、メソッドoracle.xdb.XMLType.setFormatPref()を使用して、データベースに送信されるXMLデータがバイナリXML形式でエンコードされるように指定します。これは、DOM文書(クラスoracle.xdb.XMLType)に適用されます。バイナリXMLを指定しない場合、データはテキストとしてデータベースに送信されます。

5. 通常のJavaメソッドを使用して、データベースに対してXMLデータを読書きします。バイナリXML文書のエンコードやデコードに必要なときは常に、メタデータ・コンテキストを使用して、必要なメタデータが自動的にフェッチされます。
Java DOM API for XMLを使用して、クライアント・レベルのXMLデータに対して操作します。

例15-14に、これを示します。

例15-14 バイナリXMLでのJava DOM APIの使用

import java.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;
import oracle.xdb.XMLType;
import oracle.xml.binxml.*;

class tdadxdbxdb11jav001 {
public static void printBinXML() throws SQLException, BinXMLException
{
// Create datasource to connect to local database
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:kprb");
System.out.println("Starting Binary XML Java Example");
// Create data connection
Connection conn = ods.getConnection();
// Create binary XML metadata context, using connection pool
DBBinXMLMetadataProvider repos =
BinXMLMetadataProviderFactory.createDBMetadataProvider();
repos.setConnectionPool(ods);
// Associate metadata context with data connection
repos.associateDataConnection(conn);
// Query XML data stored in XMLType column as binary XML
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery("SELECT doc FROM po_binxmltab");
// Get the XMLType object
while (rset.next())
{
XMLType xmlobj = (XMLType) rset.getObject(1);
// Perform XMLType operation
String xmlvalue = xmlobj.getStringVal();
System.out.println(xmlvalue);
}
// Close result set, statement, and connection
rset.close();
stmt.close();
conn.close();
System.out.println("Completed Binary XML Java Example");
}
}

関連項目:

- 「XMLType記憶域モデル」

- 『Oracle XML Developer's Kitプログラマーズ・ガイド』

脚注の凡例

脚注1: ここでは、XMLデータがXML Schemaに登録済であり、XMLTypeの列に格納されていると想定しています。

16 C API for XMLの使用

この章では、Oracle XML DBでC API for XMLを使用するためのガイドラインを示します。内容は次のとおりです。

- C API for XMLの概要(Oracle XDKおよびOracle XML DB)

- Oracle XML DBでのOCIおよびC API for XMLの使用

- C DOM API関数のXMLコンテキスト・パラメータ

- XMLコンテキストの初期化および終了

- バイナリXMLでのC API for XMLの使用

- Oracle XML DBでのOracle XML Developer's Kit Pull Parserの使用

- Cでの一般的なXMLType操作

C API for XMLの概要(Oracle XDKおよびOracle XML DB)

C API for XMLは、Oracle XML Developer's Kit (XDK)およびOracle XML DBの両方で使用されます。これはCベースのDOM脚注 1  API for XMLです。データベース内外のXMLデータに対して使用できます。このAPIには、XDKでXMLデータの従来のXML記憶域に、またはOracle XML DBで表のXMLType列として記憶域に使用できるパフォーマンス向上拡張機能もあります。

注意:
Oracle Database 10gリリース1以前のリリースのC DOM関数は、下位互換性のみの目的でサポートされています。

C API for XMLは、Oracle XML DBのXMLType上に実装されます。W3CのDOM勧告において、ドキュメントという用語は広い意味(URI、ファイル・システム、メモリー・バッファ、標準入出力)で使用されます。C API for XMLは、Oracle XML Developer's KitおよびOracle XML DBアプリケーションに必要なすべての機能を含んだ結合プログラム・インタフェースです。これは、XSLTおよびXML Schemaの実装用に提供されています。DOM 2.0勧告に厳密に従っていましたが、オブジェクト指向のDOM 2.0勧告からフラットCの名前空間へのマッピングにはいくつかのネーミング変更が必要でした。たとえば、getName()()メソッドは、getAttrName()メソッドに名前が変更されました

C API for XMLは以前のOracle APIに置き換わります。特に、oraxmlインタフェース(最上位、DOM、SAXおよびXSLT)およびoraxsd.h(Schema)インタフェースは、将来のリリースで非推奨になる予定です。

Oracle XML DBでのOCIおよびC API for XMLの使用

OCIアプリケーションは、通常はサーバーに格納されているXMLデータまたはクライアントで作成されたXMLデータで動作します。この項では、この2つのアクセス方法について詳しく説明します。

データベースに格納されているXMLTypeデータへのアクセス

Oracle XML DBでは、抽象データ型XMLTypeを使用したXMLインスタンスの格納および操作がサポートされています。これらのXMLインスタンスは、C DOM API for XMLとともにOracle Call Interface(OCI)を使用して、クライアント側でアクセスおよび操作できます。C DOM構造xmldocnodeを使用してXMLTypeをバインドおよび定義できます。この構造は、OCI文でXML値のバインド、定義および操作に使用できます。OCI文を使用してサーバーからXMLデータを選択し、C DOM API関数で使用できます。同様に、値はSQL文に直接バインドしなおすことができます。

アプリケーション・プログラムのメイン・フローには、サーバー・ハンドルや文ハンドルなど、通常のOCIハンドルの初期化の後に、XMLコンテキスト・パラメータの初期化が続きます。その後で、データベースでXMLインスタンスを操作するか、またはクライアント側で新規インスタンスを作成できます。初期化されたXMLコンテキストは、すべてのC DOM関数で使用できます。

関連項目:
「C DOM API関数のXMLコンテキスト・パラメータ」

クライアントでのXMLTypeインスタンスの作成

次のように、XmlLoadDom()を使用して、クライアント上で新しいXMLTypeインスタンスを構成できます。

1. 例16-1に示すように、xmlctxを初期化します。

2. ユーザー・バッファ、ローカル・ファイルまたはURIからXMLデータを構成します。これらの戻り値は(xmldocnode *)で、他の一般的なC APIで使用できます。

3. 必要に応じて、(xmldocnode *)を(void*)にキャストし、バインド値として直接提供できます。

XMLCreateDocument()を使用して、空のXMLTypeインスタンスを構成できます。これは、他の型に対してOCIObjectNew()を使用するのに類似しています。

C DOM API関数のXMLコンテキスト・パラメータ

XMLコンテキストは、すべてのC DOM API関数に必須のパラメータです。このOPAQUE型のコンテキストは、データ・エンコーディング、エラー・メッセージの言語などに関係する情報をカプセル化します。コンテキストの内容は、Oracle XML Developer's KitアプリケーションおよびOracle XML DBに対して異なります。Oracle XML DBには、XMLコンテキストを初期化(OCIXmlDbInitXmlCtx())、および終了(OCIXmlDbFreeXmlCtx())するための2つのOCI関数が用意されています。

OCIXmlDbInitXmlCtx()構文

OCIXmlDbInitXmlCtx()関数の構文は次のとおりです。

xmlctx *OCIXmlDbInitXMlCtx (OCIEnv        *envhp,
OCISvcHp      *svchp,
OCIError      *errhp,
ocixmldbparam *params,
ub4           num_params);

表16-1で、各パラメータについて説明します。

表16-1 OCIXmlDbInitXMlCtx()パラメータ

パラメータ

説明

envhp (IN)

OCI環境ハンドル。

svchp (IN)

OCIサービス・ハンドル。

errhp (IN)

OCIエラー・ハンドル。

params (IN)

オプション値の配列:

- OCI継続時間。デフォルト値はOCI_DURATION_SESSIONです。

- 次のユーザー登録コールバックであるエラー・ハンドラ。

void (*err_handler) (sword errcode,
(CONST OraText *) errmsg);

num_params (IN)

paramsから読み取るパラメータ数。

OCIXmlDbFreeXmlCtx()構文

xctx (IN)パラメータが終了対象のXMLコンテキストである場合のOCIXmlDbFreeXmlCtx() 関数の構文は次のとおりです。

void OCIXmlDbFreeXmlCtx (xmlctx *xctx);

XMLコンテキストの初期化および終了

例16-1に、C DOM APIを使用してXML文書を構成し、Oracle Databaseのmy_table表に保存するCプログラムを示します。OCI関数のOCIXmlDbInitXmlCtx()とOCIXmlDbFreeXmlCtx()をコールし、XMLコンテキストを初期化および終了します。これらのOCI関数は、ヘッダー・ファイルocixmldb.hで定義されます。

例16-1のCコードでは、データベース・スキーマcapiuserでmy_table表を作成するため、次のSQLコードを最初に実行したことを前提としています。

CONNECT CAPIUSER
Enter password: password

Connected.

CREATE TABLE my_table OF XMLType;

例16-1では、OCI関数のOCIXmlDbInitXmlCtx()およびOCIXmlDbFreeXmlCtx()を使用して、XMLコンテキストを初期化および終了する方法を示します。

例16-1 OCIXMLDBINITXMLCTX()およびOCIXMLDBFREEXMLCTX()の使用

#ifndef S_ORACLE
#include <s.h>
#endif
#ifndef ORATYPES_ORACLE
#include <oratypes.h>
#endif
#ifndef XML_ORACLE
#include <xml.h>
#endif
#ifndef OCIXML_ORACLE
#include <ocixml.h>
#endif
#ifndef OCI_ORACLE
#include <oci.h>
#endif
#include <string.h>

typedef struct test_ctx {
OCIEnv *envhp;
OCIError *errhp;
OCISvcCtx *svchp;
OCIStmt *stmthp;
OCIServer *srvhp;
OCIDuration dur;
OCISession *sesshp;
oratext *username;
oratext *password;
} test_ctx;

/* Helper function 1: execute a sql statement which binds xml data */
STATICF sword exec_bind_xml(OCISvcCtx *svchp,
OCIError *errhp,
OCIStmt *stmthp,
void *xml,
OCIType *xmltdo,
OraText *sqlstmt);

/* Helper function 2: Initialize OCI handles and connect */
STATICF sword init_oci_handles(test_ctx *ctx);

/* Helper function 3: Free OCI handles and disconnect */
STATICF sword free_oci_handles(test_ctx *ctx);

void main()
{
test_ctx temp_ctx;
test_ctx *ctx = &temp_ctx;
OCIType *xmltdo = (OCIType *) 0;
xmldocnode *doc = (xmldocnode *)0;
ocixmldbparam params[1];
xmlnode *quux, *foo, *foo_data, *top;
xmlerr err;
sword status = 0;
xmlctx *xctx;

oratext ins_stmt[] = "insert into my_table values (:1)";
oratext tlpxml_test_sch[] = "<TOP/>";
ctx->username = (oratext *)"capiuser";
ctx->password = (oratext *)"***********"; /* Replace with real password */

/* Initialize envhp, svchp, errhp, dur, stmthp */
init_oci_handles(ctx);

/* Get an xml context */
params[0].name_ocixmldbparam = XCTXINIT_OCIDUR;
params[0].value_ocixmldbparam = &ctx->dur;
xctx = OCIXmlDbInitXmlCtx(ctx->envhp, ctx->svchp, ctx->errhp, params, 1);

/* Start processing - first, check that this DOM supports XML 1.0 */
printf("\n\nSupports XML 1.0? : %s\n",
XmlHasFeature(xctx, (oratext *) "xml", (oratext *) "1.0") ?
"YES" : "NO");

/* Parse a document */
if (!(doc = XmlLoadDom(xctx, &err, "buffer", tlpxml_test_sch,
"buffer_length", sizeof(tlpxml_test_sch)-1,
"validate", TRUE, NULL)))
{
printf("Parse failed, code %d\n", err);
}
else
{
/* Get the document element */
top = (xmlnode *)XmlDomGetDocElem(xctx, doc);

/* Print out the top element */
printf("\n\nOriginal top element is :\n");
XmlSaveDom(xctx, &err, top, "stdio", stdout, NULL);

/* Print out the document-note that the changes are reflected here */
printf("\n\nOriginal document is :\n");
XmlSaveDom(xctx, &err, (xmlnode *)doc, "stdio", stdout, NULL);

/* Create some elements and add them to the document */
quux = (xmlnode *) XmlDomCreateElem(xctx ,doc, (oratext *) "QUUX");
foo = (xmlnode *) XmlDomCreateElem(xctx, doc, (oratext *) "FOO");
foo_data = (xmlnode *) XmlDomCreateText(xctx, doc, (oratext *) "data");
foo_data = XmlDomAppendChild(xctx, (xmlnode *) foo, (xmlnode *) foo_data);
foo = XmlDomAppendChild(xctx, quux, foo);
quux = XmlDomAppendChild(xctx, top, quux);

/* Print out the top element */
printf("\n\nNow the top element is :\n");
XmlSaveDom(xctx, &err, top, "stdio", stdout, NULL);

/* Print out the document. Note that the changes are reflected here */
printf("\n\nNow the document is :\n");
XmlSaveDom(xctx, &err, (xmlnode *)doc, "stdio", stdout, NULL);

/* Insert the document into my_table */
status = OCITypeByName(ctx->envhp, ctx->errhp, ctx->svchp,
(const text *) "SYS", (ub4) strlen((char *)"SYS"),
(const text *) "XMLTYPE",
(ub4) strlen((char *)"XMLTYPE"), (CONST text *) 0,
(ub4) 0, OCI_DURATION_SESSION, OCI_TYPEGET_HEADER,
(OCIType **) &xmltdo);
if (status == OCI_SUCCESS)
{
exec_bind_xml(ctx->svchp, ctx->errhp, ctx->stmthp, (void *)doc, xmltdo,
ins_stmt);
}
}
/* Free xml ctx */
OCIXmlDbFreeXmlCtx(xctx);

/* Free envhp, svchp, errhp, stmthp */
free_oci_handles(ctx);
}

このCプログラムのコンパイルおよび実行からの出力は、次のとおりです。

Supports XML 1.0? : YES

Original top element is :
<TOP/>

Original document is :
<TOP/>

Now the top element is :
<TOP>
<QUUX>
<FOO>data</FOO>
</QUUX>
</TOP>

Now the document is :
<TOP>
<QUUX>
<FOO>data</FOO>
</QUUX>
</TOP>

これは、my_tableで構成された文書を問い合せた結果です。

SELECT * FROM my_table;

SYS_NC_ROWINFO$
---------------
<TOP>
<QUUX>
<FOO>data</FOO>
</QUUX>
</TOP>

1 row selected.

例16-1では、C DOM APIを使用してXML文書を構成し、データベース内に保存します。コードでは、ここには示されていない、ヘルパー関数のexec_bind_xml、init_oci_handlesおよびfree_oci_handlesが使用されます。ヘルパー関数を含む、この例の詳細は、付録A「Oracleが提供するXML Schemaおよび例」の「XMLコンテキスト(OCI)の初期化および終了」を参照してください。

例16-4では、my_table表を問い合せ、例16-1で挿入されたデータを表示します。

バイナリXMLでのC API for XMLの使用

XMLデータはXMLTypeを使用してOracle XML DBに格納でき、この抽象データ型の記憶域モデルの1つはバイナリXMLです。バイナリXMLはXMLデータの簡潔な、XML Schema対応のエンコーディングです。データベース内のXMLTypeの記憶域モデルとして使用することができますが、データベース外にあるXMLデータに対しても使用することができます。「Oracle XML DBでのOCIおよびC API for XMLの使用」で説明したように、XMLデータのクライアント側処理には、Oracle XML DBに格納されているデータ、またはデータベース外にある一時データが関与します。

C APIを使用して、Oracle XML DBに対して、バイナリXML形式でエンコードされたXMLデータを読み書きすることができます。この処理には通常の読書きプロシージャが関与します。

バイナリXMLはXML Schemaに対応しており、必要性とデータに応じて、各種のコード体系を使用することができます。このため、バイナリXMLデータを操作するためには、関連するXML Schemaとエンコーディングについて、データとこのメタデータの両方が必要です。

データベースに格納されているXMLTypeデータの場合、このメタデータもデータベースに格納されます。ただし、データベースとデータのセットアップに応じて、メタデータが適用されるデータと同一のサーバーにメタデータが格納されない場合があります。この場合、データベースに対してバイナリXMLデータを読書きするためには、次の手順を実行する必要があります。

1. メタデータのコンテキスト・インスタンスを作成します。

2. このコンテキストを、データベース内のバイナリXMLデータにアクセスするために使用するデータ接続に関連付けます。データ接続は、専用接続(OCISvcCtx)でも接続プール(OCICPool)でもかまいません。

すると、アプリケーションがデータ接続上でバイナリXMLデータをエンコードまたはデコードする必要がある場合、それに必要なメタデータが自動的にフェッチされます。一連の動作の全体は次のとおりです。

1. 環境(OCIEnv)、接続(OCISvcCtx)、エラー・コンテキスト(OCIError)に応じて、通常のOCIハンドルを作成します。

2. 必要に応じて1つ以上のメタデータ・コンテキストを作成します。メタデータ・コンテキストはメタデータ・リポジトリと呼ばれることもあり、OCIBinXMLReposCtxはOCIコンテキスト・データ構造です。
専用接続からはOCIBinXMLCreateReposCtxFromConnを使用して、接続プールからはOCIBinXMLCreateReposCtxFromCPoolを使用してメタデータ・コンテキストを作成します。

3. メタデータ・コンテキストをバイナリXMLデータ接続に関連付けます。これにはOCIBinXmlSetReposCtxForConnを使用します。

4. (オプション)XMLデータがデータベース外に由来するものの場合は、setPicklePreferenceを使用して、それ以降データベースに送信されるXMLデータがバイナリXML形式になるよう指定します。これは、DOM文書(xmldomdoc)に適用されます。バイナリXMLを指定しない場合、データはテキスト(CLOB)として格納されます。

5. OCIライブラリを使用して、データベースに対してXMLデータを読書きします。バイナリXML文書のエンコードやデコードに必要なときは常に、メタデータ・コンテキストを使用して、必要なメタデータが自動的にフェッチされます。
C DOM API for XMLを使用して、クライアント・レベルのXMLデータに対して操作します。

例16-2に、これを示します。

例16-2 バイナリXMLでのC API for XMLの使用

. . .
/* Private types and constants */
#define SCHEMA        (OraText *)"SYS"
#define TYPE          (OraText *)"XMLTYPE"
#define USER          (OraText *)"oe"
#define USER_LEN      (ub2)(strlen((char *)USER))
#define PWD           (OraText *)"oe"
#define PWD_LEN       (ub2)(strlen((char *)PWD))
#define NUM_PARAMS    1
STATICF void checkerr(OCIError *errhp, sword status);
STATICF sword create_env(OraText *user, ub2 user_len, OraText *pwd, ub2 pwd_len,
OCIEnv **envhp, OCISvcCtx **svchp, OCIError **errhp);
STATICF sword run_example(OCIEnv *envhp, OCISvcCtx *svchp, OCIError *errhp,
OCIDuration dur);
STATICF void cleanup(OCIEnv *envhp, OCISvcCtx *svchp, OCIError *errhp);

int main (int argc, char *argv[])
{
OCIEnv     *envhp;
OCISvcCtx  *svchp;
OCIError   *errhp;
printf("*** Starting Binary XML Example program\n");
if (create_env(USER, USER_LEN, PWD, PWD_LEN, &envhp, &svchp, &errhp))
{
printf("FAILED: create_env()\n");
cleanup(envhp, svchp, errhp);
return OCI_ERROR;
}
if (run_example(envhp, svchp, errhp, OCI_DURATION_SESSION))
{
printf("FAILED: run_example()\n");
cleanup(envhp, svchp, errhp);
return OCI_ERROR;
}
cleanup(envhp, svchp, errhp);
printf ("*** Completed Binary XML example\n");
return OCI_SUCCESS;
}

STATICF sword create_env(OraText *user, ub2 user_len,
OraText *pwd,  ub2 pwd_len,
OCIEnv **envhp, OCISvcCtx **svchp, OCIError **errhp)
{
sword       status;
OCIServer  *srvhp;
OCISession *usrp;
OCICPool   *poolhp;
OraText    *poolname;
ub4         poolnamelen;
OraText    *database =(OraText *)"";
OCIBinXmlReposCtx *rctx;
/* Create and initialize environment. Allocate error handle. */
. . .
if ((status = OCIConnectionPoolCreate((dvoid *)*envhp, (dvoid*)*errhp,
(dvoid *)poolhp, &poolname,
(sb4 *)&poolnamelen,
(OraText *)0,
(sb4) 0, 1, 10, 1,
(OraText *)USER,
(sb4) USER_LEN,
(OraText *)PWD,
(sb4) PWD_LEN,
OCI_DEFAULT)) != OCI_SUCCESS)
{
printf ("OCIConnectionPoolCreate - Fail %d\n", status);
return OCI_ERROR;
}
status = OCILogon2((OCIEnv *)*envhp, *errhp, svchp, (OraText *)USER,
(ub4)USER_LEN, (const oratext *)PWD, (ub4)PWD_LEN,
(const oratext *)poolname, poolnamelen, OCI_CPOOL);
if (status)
{
printf ("OCILogon2 - Fail %d\n", status);
return OCI_ERROR;
}
OCIBinXmlCreateReposCtxFromCPool(*envhp, poolhp, *errhp, &rctx);
OCIBinXmlSetReposCtxForConn(*svchp, rctx);
return OCI_SUCCESS;
}

STATICF sword run_example(OCIEnv *envhp, OCISvcCtx *svchp, OCIError *errhp,
OCIDuration dur)
{
OCIType   *xmltdo = (OCIType *)0;
OCIStmt   *stmthp;
OCIDefine *defnp;
xmldocnode *xmldoc = (xmldocnode *)0;
ub4        xmlsize = 0;
text      *selstmt = (text *)"SELECT doc FROM po_binxmltab";
sword      status;
struct xmlctx *xctx = (xmlctx *) 0;
ocixmldbparam params[NUM_PARAMS];
xmlerr xerr = (xmlerr) 0;
/* Obtain type definition for XMLType. Allocate statement handle.
Prepare SELECT statement. Define variable for XMLType. Execute statement. */
. . .
/* Construct xmlctx for using XML C API */
params[0].name_ocixmldbparam = XCTXINIT_OCIDUR;
params[0].value_ocixmldbparam = &dur;
xctx = OCIXmlDbInitXmlCtx(envhp, svchp, errhp, params, NUM_PARAMS);
/* Print result to local string */
XmlSaveDom(xctx, &xerr, (xmlnode *)xmldoc, "stdio", stdout, NULL);
/* Free instances */
. . .
}

関連項目:

- 「XMLType記憶域モデル」

- 『Oracle XML Developer's Kitプログラマーズ・ガイド』

Oracle XML DBでのOracle XML Developer's Kit Pull Parserの使用

Oracle XML DBで、XMLTypeインスタンスによりOracleX XML Developer's Kit Pull Parserを使用できます。このパーサーを使用する場合、解析はオン・デマンドで行われ、アプリケーションが解析処理を起動します。アプリケーションは、Simple API for XML(SAX)解析同様、開始タグ、終了タグ、およびコメントにより一連のイベントを介してXML文書にアクセスします。ただし、解析イベントがコールバックで処理されるSAX解析とは異なり、プル解析では、必要な場合のみ(pull)イベントを要求するメソッドがコールされます。これにより、アプリケーションはXML処理の制御をより容易にできます。特に、PullパーサーではSAXパーサーよりフィルタリングに柔軟性があります。

Oracle XML Developer's Kit Pull Parserを使用して、ストリームに基づくXML Schemaの検証もできます。

例16-3は、XMLTypeインスタンスによるOracle XML DB Pull Parserの使用方法を示しています。Pullパーサーを使用するには、UNIXシステムおよびLinuxシステムではlibxml10.a静的ライブラリ、Microsoft Windowsシステムではoraxml10.dllが必要です。また、xmlev.hヘッダー・ファイルも必要です。

関連項目:

- Oracle XML Developer's Kit Pull Parserの詳細は、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。

- ストリームに基づく検証のPullパーサーの使用方法の詳細は、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。

例16-3 Oracle XML DB Pull Parserの使用

#define MAXBUFLEN 64*1024
void main()
{
test_ctx temp_ctx;
test_ctx *ctx = &temp_ctx;
OCIType *xmltdo = (OCIType *) 0;
ocixmldbparam params[1];
sword status = 0;
xmlctx *xctx;
OCIDefine *defnp = (OCIDefine *) 0;
oratext sel_stmt[] =
"SELECT XMLSerialize(DOCUMENT x.OBJECT_VALUE AS CLOB) FROM PURCHASEORDER x where rownum = 1";
OCILobLocator *cob;
ub4 amtp, nbytes;
ub1 bufp[MAXBUFLEN];
ctx->username = (oratext *)"oe";
ctx->password = (oratext *)"*************";    /* Replace with real password */

/* Initialize envhp, svchp, errhp, dur, stmthp */
init_oci_handles(ctx);

/* Get an xml context */
params[0].name_ocixmldbparam = XCTXINIT_OCIDUR;
params[0].value_ocixmldbparam = &ctx->dur;
xctx = OCIXmlDbInitXmlCtx(ctx->envhp, ctx->svchp, ctx->errhp, params, 1);

/* Start processing */
printf("\n\nSupports XML 1.0? : %s\n",
XmlHasFeature(xctx, (oratext *) "xml", (oratext *) "1.0") ?
"YES" : "NO");

/* Allocate the lob descriptor */
status = OCIDescriptorAlloc((dvoid *) ctx->envhp, (dvoid **) &clob,
(ub4)OCI_DTYPE_LOB, (size_t) 0, (dvoid **) 0);
if (status)
{
printf("OCIDescriptorAlloc Failed\n");
goto error;
}
status = OCIStmtPrepare(ctx->stmthp, ctx->errhp,
(CONST OraText *)sel_stmt, (ub4) strlen((char *)sel_stmt),
(ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT);
if (status)
{
printf("OCIStmtPrepare Failed\n");
goto error;
}
status = OCIDefineByPos(ctx->stmthp, &defnp, ctx->errhp, (ub4) 1,
(dvoid *) &clob, (sb4) -1, (ub2 ) SQLT_CLOB,
(dvoid *) 0, (ub2 *)0,
(ub2 *)0, (ub4) OCI_DEFAULT);
if (status)
{
printf("OCIDefineByPos Failed\n");
goto error;
}
status = OCIStmtExecute(ctx->svchp, ctx->stmthp, ctx->errhp, (ub4) 1,
(ub4) 0, (CONST OCISnapshot*) 0, (OCISnapshot*) 0,
(ub4) OCI_DEFAULT);
if (status)
{
printf("OCIStmtExecute Failed\n");
goto error;
}
/* read the fetched value into a buffer */
amtp = nbytes = MAXBUFLEN-1;
status = OCILobRead(ctx->svchp, ctx->errhp, clob, &amtp,
(ub4) 1, (dvoid *) bufp, (ub4) nbytes, (dvoid *)0,
(sb4 (*)(dvoid *, CONST dvoid *, ub4, ub1)) 0,
(ub2) 0, (ub1) SQLCS_IMPLICIT);
if (status)
{
printf("OCILobRead Failed\n");
goto error;
}
bufp[amtp] = '\0';
if (amtp > 0)
{
printf("\n=> Query result of %s: \n%s\n", sel_stmt, bufp);
/********** PULL PARSING ******************/
status = pp_parse(xctx, bufp, amtp);
if (status)
printf("Pull Parsing failed\n");
}
error:
/* Free XML Ctx */
OCIXmlDbFreeXmlCtx(xctx);

/* Free envhp, svchp, errhp, stmthp */
free_oci_handles(ctx);
}
#define ERRBUFLEN 256
sb4 pp_parse(xctx, buf, amt)
xmlctx  *xctx;
oratext *buf;
ub4     amt;
{
xmlevctx *evctx;
xmlerr   xerr = XMLERR_OK;
oratext  message[ERRBUFLEN];
oratext  *emsg = message;
xmlerr   ecode;
boolean  done, inattr = FALSE;
xmlevtype event;

/* Create an XML event context - Pull Parser Context */
evctx = XmlEvCreatePPCtx(xctx, &xerr,
"expand_entities", FALSE,
"validate", TRUE,
"attr_events", TRUE,
"raw_buffer_len", 1024,
NULL);
if (!evctx)
{
printf("FAILED: XmlEvCreatePPCtx: %d\n", xerr);
return OCI_ERROR;
}
/* Load the document from input buffer */
xerr = XmlEvLoadPPDoc(xctx, evctx, "buffer", buf, amt, "utf-8");
if (xerr)
{
printf("FAILED: XmlEvLoadPPDoc: %d\n", xerr);
return OCI_ERROR;
}
/* Process the events until END_DOCUMENT event or error */
done = FALSE;
while(!done)
{
event = XmlEvNext(evctx);
switch(event)
{
case XML_EVENT_START_ELEMENT:
printf("START ELEMENT: %s\n", XmlEvGetName0(evctx));
break;
case XML_EVENT_END_ELEMENT:
printf("END ELEMENT: %s\n", XmlEvGetName0(evctx));
break;
case XML_EVENT_START_DOCUMENT:
printf("START DOCUMENT\n");
break;
case XML_EVENT_END_DOCUMENT:
printf("END DOCUMENT\n");
done = TRUE;
break;
case XML_EVENT_START_ATTR:
printf("START ATTRIBUTE: %s\n", XmlEvGetAttrName0(evctx, 0));
inattr = TRUE;
break;
case XML_EVENT_END_ATTR:
printf("END ATTRIBUTE: %s\n", XmlEvGetAttrName0(evctx, 0));
inattr = FALSE;
break;
case XML_EVENT_CHARACTERS:
if (inattr)
printf("ATTR VALUE: %s\n", XmlEvGetText0(evctx));
else
printf("TEXT: %s\n", XmlEvGetText0(evctx));
break;
case XML_EVENT_ERROR:
case XML_EVENT_FATAL_ERROR:
done = TRUE;
ecode = XmlEvGetError(evctx, &emsg);
printf("ERROR: %d: %s\n", ecode, emsg);
break;
}
}
/* Destroy the event context */
XmlEvDestroyPPCtx(xctx, evctx);
return OCI_SUCCESS;
}

このCプログラムのコンパイルおよび実行からの出力は、次のとおりです。

=> Query result of XMLSerialize(DOCUMENT x.OBJECT_VALUE AS CLOB) FROM PURCHASEORDER x where rownum = 1:
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd">
<Reference>AMCEWEN-20021009123336171PDT</Reference>
<Actions>
<Action>
<User>KPARTNER</User>
</Action>
</Actions>
<Reject/>
<Requestor>Allan D. McEwen</Requestor>
<User>AMCEWEN</User>
<CostCenter>S30</CostCenter>
<ShippingInstructions>
<name>Allan D. McEwen</name>
<address>Oracle Plaza
Twin Dolphin Drive
Redwood Shores
CA
94065
USA</address>
<telephone>650 506 7700</telephone>
</ShippingInstructions>
<SpecialInstructions>Ground</SpecialInstructions>
<LineItems>
<LineItem ItemNumber="1">
<Description>Salesman</Description>
<Part Id="37429158920" UnitPrice="39.95" Quantity="2"/>
</LineItem>
. . .
</LineItems>
</PurchaseOrder>

START DOCUMENT
START ELEMENT: PurchaseOrder
START ATTRIBUTE: xmlns:xsi
ATTR VALUE: http://www.w3.org/2001/XMLSchema-instance
END ATTRIBUTE: xmlns:xsi
START ATTRIBUTE: xsi:noNamespaceSchemaLocation
ATTR VALUE: http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd
END ATTRIBUTE: xsi:noNamespaceSchemaLocation
START ELEMENT: Reference
TEXT: AMCEWEN-20021009123336171PDT
END ELEMENT: Reference
START ELEMENT: Actions
START ELEMENT: Action
START ELEMENT: User
TEXT: KPARTNER
END ELEMENT: User
END ELEMENT: Action
END ELEMENT: Actions
START ELEMENT: Reject
END ELEMENT: Reject
START ELEMENT: Requestor
TEXT: Allan D. McEwen
END ELEMENT: Requestor
START ELEMENT: User
TEXT: AMCEWEN
END ELEMENT: User
START ELEMENT: CostCenter
TEXT: S30
END ELEMENT: CostCenter
START ELEMENT: ShippingInstructions
START ELEMENT: name
TEXT: Allan D. McEwen
END ELEMENT: name
START ELEMENT: address
TEXT: Oracle Plaza
Twin Dolphin Drive
Redwood Shores
CA
94065
USA
END ELEMENT: address
START ELEMENT: telephone
TEXT: 650 506 7700
END ELEMENT: telephone
END ELEMENT: ShippingInstructions
START ELEMENT: SpecialInstructions
TEXT: Ground
END ELEMENT: SpecialInstructions
START ELEMENT: LineItems
START ELEMENT: LineItem
START ATTRIBUTE: ItemNumber
ATTR VALUE: 1
END ATTRIBUTE: ItemNumber
START ELEMENT: Description
TEXT: Salesman
END ELEMENT: Description
START ELEMENT: Part
START ATTRIBUTE: Id
ATTR VALUE: 37429158920
END ATTRIBUTE: Id
START ATTRIBUTE: UnitPrice
ATTR VALUE: 39.95
END ATTRIBUTE: UnitPrice
START ATTRIBUTE: Quantity
ATTR VALUE: 2
END ATTRIBUTE: Quantity
END ELEMENT: Part
END ELEMENT: LineItem
. . .
END ELEMENT: LineItems
END ELEMENT: PurchaseOrder
END DOCUMENT

Cでの一般的なXMLType操作

表16-2に、一般的なXML操作のXMLType関数を示します。

表16-2 Cでの一般的なXMLType操作

説明

C API XMLType関数

空のXMLTypeインスタンスの作成

XmlCreateDocument()

ソース・バッファからの作成

XmlLoadDom()

XPath式の抽出

XmlXPathEvalexpr()とそのグループ関数

XSLTスタイルシートを使用した変換

XmlXslProcess()とそのグループ関数

XPathの存在チェック

XmlXPathEvalexpr()とそのグループ関数

XML Schemaに基づく文書かどうかのチェック

XmlDomIsSchemaBased()

スキーマ情報の取得

XmlDomGetSchema()

文書名前空間の取得

XmlDomGetNodeURI()

使用スキーマの検証

XmlSchemaValidate()

XMLTypeからのDOMの取得

(void *)の(xmldocnode *)へのキャスト

DOMからのXMLTypeの取得

(xmldocnode *)の(void *)へのキャスト

関連項目:
『Oracle XML Developer's Kitプログラマーズ・ガイド』のXML Parser for Cに関する項を参照してください。

例16-4では、DOMを使用して、発注された特定部品のインスタンスの数を判別する方法を示します。対象となる部品は、Id 37429158722です。ヘルパー関数exec_bind_xml、free_oci_handlesおよびinit_oci_handlesの定義は、付録A「Oracleが提供するXML Schemaおよび例」の例A-5を参照してください。

例16-4 DOMを使用した発注部品のカウント

#ifndef S_ORACLE
#include <s.h>
#endif
#ifndef ORATYPES_ORACLE
#include <oratypes.h>
#endif
#ifndef XML_ORACLE
#include <xml.h>
#endif
#ifndef OCIXML_ORACLE
#include <ocixml.h>
#endif
#ifndef OCI_ORACLE
#include <oci.h>
#endif
#include <string.h>

typedef struct test_ctx {
OCIEnv *envhp;
OCIError *errhp;
OCISvcCtx *svchp;
OCIStmt *stmthp;
OCIServer *srvhp;
OCIDuration dur;
OCISession *sesshp;
oratext *username;
oratext *password;
} test_ctx;

/* Helper function 1: execute a sql statement which binds xml data */
STATICF sword exec_bind_xml(OCISvcCtx *svchp,
OCIError *errhp,
OCIStmt *stmthp,
void *xml,
OCIType *xmltdo,
OraText *sqlstmt);

/* Helper function 2: Initialize OCI handles and connect */
STATICF sword init_oci_handles(test_ctx *ctx);

/* Helper function 3: Free OCI handles and disconnect */
STATICF sword free_oci_handles(test_ctx *ctx);

void main()
{
test_ctx temp_ctx;
test_ctx *ctx = &temp_ctx;
OCIType *xmltdo = (OCIType *) 0;
xmldocnode *doc = (xmldocnode *)0;
ocixmldbparam params[1];
xmlnode *quux, *foo, *foo_data, *top;
xmlerr err;
sword status = 0;
xmlctx *xctx;
ub4 xmlsize = 0;
OCIDefine *defnp = (OCIDefine *) 0;
oratext sel_stmt[] = "SELECT SYS_NC_ROWINFO$ FROM PURCHASEORDER";
xmlnodelist *litems = (xmlnodelist *)0;
xmlnode *item = (xmlnode *)item;
xmlnode *part;
xmlnamedmap *attrs;
xmlnode *id;
xmlnode *qty;
oratext *idval;
oratext *qtyval;
ub4 total_qty;
int i;
int numdocs;

ctx->username = (oratext *)"oe";
ctx->password = (oratext *)"***********";   /* Replace with real password */

/* Initialize envhp, svchp, errhp, dur, stmthp */
init_oci_handles(ctx);

/* Get an xml context */
params[0].name_ocixmldbparam = XCTXINIT_OCIDUR;
params[0].value_ocixmldbparam = &ctx->dur;
xctx = OCIXmlDbInitXmlCtx(ctx->envhp, ctx->svchp, ctx->errhp, params, 1);

/* Start processing */
printf("\n\nSupports XML 1.0? : %s\n",
XmlHasFeature(xctx, (oratext *) "xml", (oratext *) "1.0") ?
"YES" : "NO");

/* Get the documents from the database using a select statement */
status = OCITypeByName(ctx->envhp, ctx->errhp, ctx->svchp, (const text *) "SYS",
(ub4) strlen((char *)"SYS"), (const text *) "XMLTYPE",
(ub4) strlen((char *)"XMLTYPE"), (CONST text *) 0,
(ub4) 0, OCI_DURATION_SESSION, OCI_TYPEGET_HEADER,
(OCIType **) &xmltdo);
status = OCIStmtPrepare(ctx->stmthp, ctx->errhp,
(CONST OraText *)sel_stmt, (ub4) strlen((char *)sel_stmt),
(ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT);
status = OCIDefineByPos(ctx->stmthp, &defnp, ctx->errhp, (ub4) 1, (dvoid *) 0,
(sb4) 0, SQLT_NTY, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, (ub4) OCI_DEFAULT);
status = OCIDefineObject(defnp, ctx->errhp, (OCIType *) xmltdo,
(dvoid **) &doc,
&xmlsize, (dvoid **) 0, (ub4 *) 0);
status = OCIStmtExecute(ctx->svchp, ctx->stmthp, ctx->errhp, (ub4) 0, (ub4) 0,
(CONST OCISnapshot*) 0, (OCISnapshot*) 0, (ub4) OCI_DEFAULT);

/* Initialize variables */
total_qty = 0;
numdocs = 0;

/* Loop through all the documents */
while ((status = OCIStmtFetch2(ctx->stmthp, ctx->errhp, (ub4) 1, (ub4) OCI_FETCH_NEXT,
(ub4)1, (ub4) OCI_DEFAULT)) == 0)
{
numdocs++;

/* Get all the LineItem elements */
litems = XmlDomGetDocElemsByTag(xctx, doc, (oratext *)"LineItem");
i = 0;

/* Loop through all LineItems */
while (item = XmlDomGetNodeListItem(xctx, litems, i))
{
/* Get the part */
part = XmlDomGetLastChild(xctx, item);

/* Get the attributes */
attrs = XmlDomGetAttrs(xctx, (xmlelemnode *)part);

/* Get the id attribute and its value */
id = XmlDomGetNamedItem(xctx, attrs, (oratext *)"Id");
idval = XmlDomGetNodeValue(xctx, id);

/* Keep only parts with id 37429158722 */
if (idval && (strlen((char *)idval) == 11 )
&& !strncmp((char *)idval, (char *)"37429158722", 11))
{
/* Get the quantity attribute and its value.*/
qty = XmlDomGetNamedItem(xctx, attrs, (oratext *)"Quantity");
qtyval = XmlDomGetNodeValue(xctx, qty);

/* Add the quantity to total_qty */
total_qty += atoi((char *)qtyval);
}
i++;
}
XmlFreeDocument(xctx, doc);
doc = (xmldocnode *)0;
}
printf("Total quantity needed for part 37429158722 = %d\n", total_qty);
printf("Number of documents in table PURCHASEORDER = %d\n", numdocs);

/* Free Xml Ctx */
OCIXmlDbFreeXmlCtx(xctx);

/* Free envhp, svchp, errhp, stmthp */
free_oci_handles(ctx);
}

このCプログラムのコンパイルおよび実行からの出力は、次のとおりです。

Supports XML 1.0? : YES
Total quantity needed for part 37429158722 = 42
Number of documents in table PURCHASEORDER = 132

脚注の凡例

脚注1: この場合のDOMは、World Wide Web Consortium(W3C)のDOM 2.0勧告に準拠していることを示しています。

17 Oracle XML DBでのOracle Data Provider for .NETの使用

Oracle Data Provider for Microsoft .NET (ODP.NET)は、Oracle Databaseに対するデータ・プロバイダの実装です。ODP.NETは、Oracle固有のAPIを使用して、すべての.NETアプリケーションからOracleのデータおよび機能への迅速で信頼性の高いアクセスを提供します。また、ODP.NETは、Microsoft .NET Framework Class Libraryで入手可能なクラスおよびインタフェースを使用し、継承します。ODP.NETでは、.NETのネイティブLOBデータ型として、BLOB、CLOB、NCLOBおよびBFILEがサポートされます。

この章では、Oracle XML DBでODP.NETを使用する方法について説明します。内容は次のとおりです。

- ODP.NETのXMLサポートおよびOracle XML DB

- ODP.NETのサンプル・コード

ODP.NETのXMLサポートおよびOracle XML DB

ODP.NETでは、Oracle XML DBを介して、データベースでXMLがネイティブにサポートされます。ODP.NETのXMLサポートには次の機能があります。

- XMLデータをXMLTypeとしてOracle Databaseにネイティブに格納します。

- Oracle DatabaseからMicrosoftの.NET環境まで、リレーショナル・データおよびオブジェクト・リレーショナル・データにXMLデータとしてアクセスし、Microsoftの.NET Frameworkを使用してXMLを処理します。

- XMLデータを使用して、変更内容をデータベース・サーバーに保存します。

これらの機能には、.NETアプリケーション開発者用に次の拡張機能が含まれています。

- OracleCommand、OracleConnectionおよびOracleDataReaderクラスの拡張。次のXML固有のクラスが提供されます。

- OracleXmlType

- OracleXmlStream

- OracleXmlQueryProperties

- OracleXmlSaveProperties

ODP.NETのサンプル・コード

例17-1では、データベースから.NETにXMLTypeデータが取り出され、結果が出力されます。

例17-1 .NETへのXMLTypeデータの取出し

//Create OracleCommand and query XMLType
OracleCommand xmlCmd = new OracleCommand();
poCmd.CommandText = "SELECT po FROM po_tab";
poCmd.Connection = conn;
// Execute OracleCommand and output XML results to an OracleDataReader
OracleDataReader poReader = poCmd.ExecuteReader();
// ODP.NET native XML data type object from Oracle XML DB
OracleXmlType poXml;
string str = ""; //read XML results
while (poReader.Read())
{
// Return OracleXmlType object of the specified XmlType column
poXml = poReader.GetOracleXmlType(0);
// Concatenate output for all the records
str = str + poXml.Value;
} //Output XML results to the screen
Console.WriteLine(str);

関連項目:
Oracle XML DBに対するOracle .NETサポートの詳細は、『Oracle Data Provider for .NET開発者ガイド』を参照してください。

第IV部

既存データのXML表示

第IV部では、既存のデータをXMLとして表示する方法を説明します。次の章で構成されます。

- 第18章「データベースからのXMLデータの生成」

- 第19章「XMLTypeビュー」

- 第20章「URIを介したデータのアクセス」

18 データベースからのXMLデータの生成

この章では、データベースのリレーショナル・データからXMLデータを生成(構成)するためのOracle XML DB機能を説明します。また、リレーショナル・コンテンツからXMLデータを生成するためのSQL/XML標準関数およびOracle Databaseが提供する関数とパッケージについて説明します。

この章の内容は次のとおりです。

- Oracle DatabaseからのXMLデータ生成の概要

- SQL関数を使用したXMLの生成

- DBMS_XMLGENを使用したXMLの生成

- SYS_XMLGEN Oracle SQL関数

- SYS_XMLAGG Oracle SQL関数

- Oracle XML DBを使用してXMLを生成する場合のガイドライン

関連項目:
SQL/XML関数XMLQueryおよびXMLTableを使用するXMLデータの構成の詳細は、第5章「Oracle XML DBでのXQueryの使用」を参照してください。

Oracle DatabaseからのXMLデータ生成の概要

次に示す方法でOracle DatabaseによりXMLデータを生成できます。

- 標準SQL/XML関数を使用します。「SQL関数を使用したXMLの生成」を参照してください。

- Oracle SQL関数を使用します。次の項を参照してください。

- XMLROOT Oracle SQL関数

- XMLCOLATTVAL Oracle SQL関数

- XMLCDATA Oracle SQL関数

- SYS_XMLGEN Oracle SQL関数この関数は、行を操作し、XML文書を生成します。

- SYS_XMLAGG Oracle SQL関数この関数は、行のグループを操作し、複数のXML文書を1つに集約します。

- PL/SQLパッケージDBMS_XMLGENの使用。「DBMS_XMLGENを使用したXMLの生成」を参照してください。

- DBURITypeインスタンスを使用してデータベース・データからXML文書を構成します。第20章「URIを介したデータのアクセス」を参照してください。

関連項目:

- 第3章「Oracle XML DBの使用」

- 第11章「XMLTypeデータの変換および検証」

- 第13章「PL/SQL APIs for XMLType」

- 第15章「Java DOM API for XMLType」

SQL関数を使用したXMLの生成

この項では、XMLデータの構成に使用するSQL関数について説明します。この関数の多くは、SQL/XML標準に属しています。

- XMLELEMENTおよびXMLATTRIBUTES SQL/XML関数

- XMLFOREST SQL/XML関数

- XMLCONCAT SQL/XML関数

- XMLAGG SQL/XML関数

- XMLPI SQL/XML関数

- XMLCOMMENT SQL/XML関数

- XMLSERIALIZE SQL/XML関数

- XMLPARSE SQL/XML関数

標準XML生成関数はSQL/XMLパブリッシング関数とも呼ばれます。

SQL/XML関数XMLQueryを使用してXMLデータを構成することもできます。XMLQueryの用途は、XMLデータのパブリッシュにかぎりません。非常に汎用性が高く、このマニュアルではSQL/XML問合せおよびアクセス関数と呼んでいます。

この標準化プロセスは進行中です。XMLQueryやXMLTableを含むSQL/XML関数の最新情報については、http://www.sqlx.orgを参照してください。

この項で説明する、XMLを生成する他のSQL関数は、(SQL/XML標準の一部ではなく)Oracle専用です。

- XMLROOT Oracle SQL関数

- XMLCOLATTVAL Oracle SQL関数

- XMLCDATA Oracle SQL関数

- SYS_XMLGEN Oracle SQL関数この関数は、リレーショナル行を操作し、XML文書を生成します。

- SYS_XMLAGG Oracle SQL関数この関数は、リレーショナル行のグループを操作し、複数のXML文書を1つに集約します。

すべてのXML生成SQL関数では、スカラーおよびユーザーのデータ型インスタンスが正規のXML形式に変換されます。この正規マッピングでは、ユーザー定義のデータ型の属性はXML要素にマップされます。

関連項目:

- SQL/XML関数XMLQueryを使用したXMLデータの構成の詳細は、第5章「Oracle XML DBでのXQueryの使用」を参照してください。

- OracleによるSQL/XML標準のサポートの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

XMLELEMENTおよびXMLATTRIBUTES SQL/XML関数

SQL/XML標準関数XMLElementを使用して、リレーショナル・データからXML要素を構成します。この関数は、要素名、その要素の属性のコレクション(オプション)、およびその要素のコンテンツを構成する0(ゼロ)個以上の引数を取ります。戻り値はXMLTypeインスタンスです。

図18-1 XMLELEMENTの構文

キーワードENTITYESCAPINGおよびNOENTITYESCAPINGの説明は、「生成されたXMLデータにおける文字のエスケープ」を参照してください。これらのキーワードは、標準SQL/XML関数XMLElementおよびXMLAttributesに対応するためのOracleの拡張です。

関数XMLElementの最初の引数は、作成されるrootXML要素名に名前を付ける識別子を定義します。ルート要素識別子の引数は、リテラル識別子(図18-1のidentifier)を使用することで、またはEVALNAMEに識別子を評価する式(value_expr)を続けることで定義できます。ただし、識別子は、定義されてもNULLにできません。NULLの場合、エラーが発生します。EVALNAMEの使用の可能性は、標準SQL/XML関数XMLElementに対応するためのOracleの拡張です。

関数XMLElementのオプションのXML-attributes-clause引数は、生成されるルート要素の属性を指定します。この関数の構文を図18-2に示します。

オプションのXML-attributes-clause引数の他に、関数XMLElementは、ルート要素のコンテンツ(子要素とテキスト・コンテンツ)を構成する0 (ゼロ)個以上のvalue_expr引数を取ります。XML-attributes-clause引数も存在する場合、XML-attributes-clause引数の後にこれらのコンテンツ引数が続く必要があります。個々のコンテンツ引数式が評価され、結果がXMLフォーマットに変換されます。値引数の評価結果がNULLだった場合、その引数にはコンテンツが作成されません。

オプションのXML-attributes-clause引数は、SQL/XML標準関数XMLAttributesを使用してルート要素の属性を指定します。関数XMLAttributesは、関数XMLElementのコールでのみ使用できます。単独では使用できません。

図18-2 XMLAttributes句の構文(XMLATTRIBUTES)

キーワードENTITYESCAPINGおよびNOENTITYESCAPINGの説明は、「生成されたXMLデータにおける文字のエスケープ」を参照してください。これらのキーワードは、標準SQL/XML関数XMLElementおよびXMLAttributesに対応するためのOracleの拡張です。

キーワードSCHEMACHECKおよびNOSCHEMACHECKは、生成された属性のいずれかがOracle XML DBで登録されているXML Schemaに対応するスキーマの場所を指定するか確認し、指定している場合は、それに対応するXML Schemaに基づくXMLデータを生成するか確認するため、それら属性で実行時チェックが行われるかどうか判断します。NOSCHEMACHECKで提供されているデフォルト動作では、チェックは行いません。11gリリース2(11.2)以前のリリースでは、デフォルト動作ではチェックを行います。SCHEMACHECKキーワードを使用して、下位互換性を得ることができます。

NOSCHEMACHECKの有無にかかわらず、同様のチェックをコンパイル時に必ず行います。つまり、特にXML Schemaの場所属性値の指定に文字列リテラルを使用している場合、(コンパイル時)チェックが行われ、適切な場合、XML Schemaに基づくデータがそれに伴って生成されます。

キーワードSCHEMACHECKおよびNOSCHEMACHECKは、標準SQL/XML関数XMLAttributesに対応するためのOracleの拡張です。

注意:
XMLデータの生成にビューが作成されると、XMLAttributes関数を使用してXML Schemaの場所参照が追加されます。ターゲットXML SchemaはOracle XML DBに登録されないため、生成されたXMLデータはXML Schemaに基づきません。XML Schemaが引き続き登録されると、それ以降生成されたXMLデータもXML Schemaに基づきません。XML Schemaに基づくデータを作成するには、ビューを再コンパイルする必要があります。

引数XML-attributes-clause自身には、関数XMLAttributesへの引数として、1つ以上のvalue_expr式が含まれます。それらはルート要素の属性の値を取得するために評価されます。(関数XMLAttributesへのこれらのvalue_expr引数を、ルート要素のコンテンツを指定する、関数XMLElementへのvalue_expr引数と混同しないでください)。各value_exprのオプションのAS c_alias句は、属性名がc_aliasであることを指定しています。この属性名は文字列リテラルまたはEVALNAMEに文字列リテラルを評価する式が続く名前になります。(EVALNAMEの使用の可能性は、標準SQL/XML関数XMLElementに対応するためのOracleの拡張です)。

属性値式がNULLであると評価された場合、その式に対応する属性は作成されません。属性値式のデータ型は、オブジェクト型またはコレクションにできません。

生成されたXMLデータにおける文字のエスケープ

SQL/XML標準で規定されているとおり、明示された識別子に含まれる文字はいかなる場合もエスケープされません。必ず、有効なXML名を使用してください。これはすべてのSQL/XML関数に当てはまります。特に、XMLElementのルート要素識別子(図18-1のidentifier)やXMLAttributesのAS句で名前を指定された属性識別子エイリアスに当てはまります(図18-2を参照)。

ただし、生成される他のXMLデータはデフォルトではエスケープされるため、有効なNameChar文字のみが生成されます。SQL識別子から有効なXML要素や属性名を生成する際、XML名として許容されない文字は、元の文字の16進数Unicode表現の前後にアンダースコア(_)を付けたものに置換されます。たとえば、コロン(:)は_003A_に置換されてエスケープされます。003Aは16進数Unicode表現です。

エスケープは、XMLElementやXMLAttributesなど、すべてのSQL/XML関数に対する、評価されたvalue_expr引数に含まれる文字に適用されます。また、AS句の前でないXMLAttributes属性値式で暗黙的に定義されている属性識別子の文字にも適用されます。SQL列名のエスケープされた形が属性の名前として使用されます。

文字のエスケープが不要な場合もあります。たとえば、生成中のXMLデータが整形式であることがわかっている場合、エスケープをしないことで処理時間を節約できます。SQL/XML関数XMLElementおよびXMLAttributesにNOENTITYESCAPINGキーワードを指定して処理時間を節約できます。ENTITYESCAPINGキーワードでエスケープを制限します。これはデフォルトの動作ではありません。キーワードNOENTITYESCAPINGおよびENTITYESCAPINGは、標準SQL/XML関数XMLElementおよびXMLAttributesに対応するためのOracleの拡張です。

XMLの日付とタイムスタンプのフォーマット

XMLデータの日付とタイムスタンプは標準フォーマットで表記するようにXMLスキーマ標準で規定されています。Oracle XML DBにおけるXML生成関数では、この標準に従ってXMLの日付とタイムスタンプが生成されます。

Oracle Database 10gリリース2より前のリリースでは、XML Schemaの標準フォーマットでなく、日付やタイムスタンプのフォーマットに関するデータベース設定がXMLに対して使用されていました。データベース・イベント19119、レベル0x8を次のように設定すると、こうした以前の動作を再現できます。

ALTER SESSION SET EVENTS '19119 TRACE NAME CONTEXT FOREVER, LEVEL 0x8';

標準以外のXMLの日付とタイムスタンプを生成する必要がある場合は、SQL関数to_charを使用します(例18-1を参照)。

関連項目:
http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#isoformats にある、XMLの日付およびタイムスタンプのフォーマットに関するXMLスキーマの仕様

XMLElementの例

この項では、SQL/XML関数XMLElementを使用する例を示します。

例18-1では、XMLElementを使用して、XML Schemaの標準フォーマットと異なるフォーマットを持つXMLの日付を生成します。

例18-1 XMLELEMENT: 日付のフォーマット

-- With standard XML date format:
SELECT XMLElement("Date", hire_date)
FROM hr.employees
WHERE employee_id = 203;

XMLELEMENT("DATE",HIRE_DATE)
----------------------------
<Date>2002-06-07</Date>

1 row selected.

-- With an alternative date format:
SELECT XMLElement("Date", to_char(hire_date))
FROM hr.employees
WHERE employee_id = 203;

XMLELEMENT("DATE",TO_CHAR(HIRE_DATE))
-------------------------------------
<Date>07-JUN-02</Date>

1 row selected.

例18-2では、XMLElementを使用して、従業員の名前をコンテンツとして持つEmp要素を各従業員に1つずつ生成します。

例18-2 XMLELEMENT: 各従業員の要素の生成

SELECT e.employee_id,
XMLELEMENT ("Emp", e.first_name ||' '|| e.last_name) AS "RESULT"
FROM hr.employees e
WHERE employee_id > 200;

この問合せにより生成される典型的な結果は次のとおりです。

EMPLOYEE_ID RESULT
----------- -----------------------------------
201 <Emp>Michael Hartstein</Emp>
202 <Emp>Pat Fay</Emp>
203 <Emp>Susan Mavris</Emp>
204 <Emp>Hermann Baer</Emp>
205 <Emp>Shelley Higgins</Emp>
206 <Emp>William Gietz</Emp>

6 rows selected.

SQL/XMLL関数XMLElementは、ネストすることにより、ネスト構造を持つXMLデータを生成することもできます。

例18-3では、XMLElementを使用して、従業員名と雇用日を提供する子要素を持つEmp要素を各従業員に1つずつ生成します。

例18-3 XMLELEMENT: ネストされたXMLの生成

SELECT XMLElement("Emp",
XMLElement("name", e.first_name ||' '|| e.last_name),
XMLElement("hiredate", e.hire_date)) AS "RESULT"
FROM hr.employees e
WHERE employee_id > 200;

この問合せによって、次の典型的なXMLが結果として戻されます。

RESULT
-----------------------------------------------------------------------
<Emp><name>Michael Hartstein</name><hiredate>2004-02-17</hiredate></Emp>
<Emp><name>Pat Fay</name><hiredate>2005-08-17</hiredate></Emp>
<Emp><name>Susan Mavris</name><hiredate>2002-06-07</hiredate></Emp>
<Emp><name>Hermann Baer</name><hiredate>2002-06-07</hiredate></Emp>
<Emp><name>Shelley Higgins</name><hiredate>2002-06-07</hiredate></Emp>
<Emp><name>William Gietz</name><hiredate>2002-06-07</hiredate></Emp>

6 rows selected.

例18-4では、XMLElementを使用して、属性idおよびnameを持つEmp要素を各従業員に1つずつ生成します。

例18-4 XMLELEMENT: IDおよびname属性を持つ従業員要素の生成

SELECT XMLElement("Emp", XMLAttributes(
e.employee_id as "ID",
e.first_name ||' ' || e.last_name AS "name"))
AS "RESULT"
FROM hr.employees e
WHERE employee_id > 200;

この問合せによって、次の典型的なXMLフラグメントが結果として戻されます。

RESULT
-----------------------------------------------
<Emp ID="201" name="Michael Hartstein"></Emp>
<Emp ID="202" name="Pat Fay"></Emp>
<Emp ID="203" name="Susan Mavris"></Emp>
<Emp ID="204" name="Hermann Baer"></Emp>
<Emp ID="205" name="Shelley Higgins"></Emp>
<Emp ID="206" name="William Gietz"></Emp>

6 rows selected.

「生成されたXMLデータにおける文字のエスケープ」で前述のとおり、ルート要素名、およびAS句により定義される属性の名前に含まれる文字はエスケープされません。識別指名に含まれる文字は、その名前が、評価された式から作成される場合にのみエスケープされます(列の参照と同様)。

例18-5は、XMLElementを使用して構成されたXNLデータによって、ルート要素名と属性名がエスケープされないことを示します。大なり記号(>)とカンマ(,)はXML要素や属性名では許容されないため、無効なXMLが作成されます。

例18-5 XMLELEMENT: 生成されたXMLにおける文字がエスケープされない

SELECT XMLElement("Emp->Special",
XMLAttributes(e.last_name || ', ' || e.first_name
AS "Last,First"))
AS "RESULT"
FROM hr.employees e
WHERE employee_id = 201;

この問合せにより作成される結果は次のとおりで、整形式のXMLではありません。

RESULT
--------------------------------------------------------------------
<Emp->Special Last,First="Hartstein, Michael"></Emp->Special>

1 row selected.

文字のエスケープに関する詳細説明は、SQL/XML標準に含まれています。

例18-6では、名前空間を使用してXML Schemaに基づく文書を作成する方法を示します。XML Schema http://www.oracle.com/Employee.xsdが存在し、ターゲットの名前空間が存在しない場合、例18-6の問合せによって、そのスキーマに準拠したXMLTypeインスタンスが作成されます。

例18-6 XMLELEMENTと名前空間を使用したXML Schemaに基づく文書の作成

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 Schema Employee.xsdに準拠している、次のXML文書が作成されます。(ここではわかりやすいように、この結果をフォーマット出力しています。)

RESULT
-----------------------------------------------------------------------------
<Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema"
xsi:nonamespaceSchemaLocation="http://www.oracle.com/Employee.xsd">
<EMPLOYEE_ID>200</EMPLOYEE_ID>
<LAST_NAME>Whalen</LAST_NAME>
<SALARY>4400</SALARY>
</Employee>

1 row selected.

例18-7では、XMLElementを使用して、従業員と部門情報を含むXML文書を生成します。ここでは、サンプルのデータベース・スキーマ表hr.departmentsを使用します。

例18-7 XMLELEMENT: ユーザー定義のデータ型インスタンスからの要素の生成

CREATE OR REPLACE TYPE emp_t AS OBJECT ("@EMPNO" NUMBER(4),
ENAME VARCHAR2(10));

CREATE OR REPLACE TYPE emplist_t AS TABLE OF emp_t;

CREATE OR REPLACE TYPE dept_t AS OBJECT ("@DEPTNO" NUMBER(2),
DNAME VARCHAR2(14),
EMP_LIST emplist_t);

SELECT XMLElement("Department",
dept_t(department_id,
department_name,
cast(MULTISET
(SELECT employee_id, last_name
FROM hr.employees e
WHERE e.department_id = d.department_id)
AS emplist_t)))
AS deptxml
FROM hr.departments d
WHERE d.department_id = 10;

これによって、Department要素およびdept_t型の正規マッピングを含むXML文書が生成されます。

DEPTXML
-------------
<Department>
<DEPT_T DEPTNO="10">
<DNAME>ACCOUNTING</DNAME>
<EMPLIST>
<EMP_T EMPNO="7782">
<ENAME>CLARK</ENAME>
</EMP_T>
<EMP_T EMPNO="7839">
<ENAME>KING</ENAME>
</EMP_T>
<EMP_T EMPNO="7934">
<ENAME>MILLER</ENAME>
</EMP_T>
</EMPLIST>
</DEPT_T>
</Department>

1 row selected.

XMLFOREST SQL/XML関数

SQL/XML標準関数XMLForestを使用して、XML要素のフォレストを構成します。その引数は評価する式で、オプションで別名も付けられます。図18-3 は、XMLForestの構文を説明するものです。

図18-3 XMLFORESTの構文

値の式(図18-3のvalue_expr)がXMLフォーマットに変換され、識別子c_aliasが属性識別子として使用されます(c_aliasは文字列リテラルまたはEVALNAMEに文字列リテラルを評価する式が続く名前になります)。EVALNAMEの使用の可能性は、標準SQL/XML関数XMLForestに対応するためのOracleの拡張です。

オブジェクト型またはコレクションの場合、AS句は必須です。それ以外の方の場合、AS句はオプションです。指定された式でAS句が省略されている場合は、評価された値の式に含まれる文字はエスケープされ、要素の囲みタグ名を形成します。エスケープの方式は「生成されたXMLデータにおける文字のエスケープ」での定義によります。値の式の評価結果がNULLだった場合、その式には要素が作成されません。

例18-8では、XMLElementとXMLForestを使用して、name属性を含み、雇用日および部門をコンテンツとして含む子要素を持つEmp要素を各従業員に1つずつ生成します。

例18-7 XMLFOREST: 属性と子要素を持つ要素の生成

SELECT XMLElement("Emp",
XMLAttributes(e.first_name ||' '|| e.last_name AS "name"),
XMLForest(e.hire_date, e.department AS "department"))
AS "RESULT"
FROM employees e WHERE e.department_id = 20;

(ここでWHERE句は、例を簡潔にするために使用されています。)この問合せにより生成されるXMLは次のとおりです。

RESULT
-------------------------------------
<Emp name="Michael Hartstein">
<HIRE_DATE>2004-02-17</HIRE_DATE>
<department>20</department>
</Emp>
<Emp name="Pat Fay">
<HIRE_DATE>2005-08-17</HIRE_DATE>
<department>20</department>
</Emp>

2 rows selected.

関連項目:
例18-20「XMLCOLATTVAL: 属性と子要素を持つ要素の生成」

例18-9では、XMLForestを使用して、ユーザー定義のデータ型インスタンスから階層XMLデータを生成します。

例18-9 XMLFOREST: ユーザー定義のデータ型インスタンスからの要素の生成

SELECT XMLForest(
dept_t(department_id,
department_name,
cast(MULTISET
(SELECT employee_id, last_name
FROM hr.employees e WHERE e.department_id = d.department_id)
AS emplist_t))
AS "Department")
AS deptxml
FROM hr.departments d
WHERE department_id=10;

これにより、属性DEPTNOおよび子要素DNAMEを含む要素Departmentを持つXMLドキュメントが作成されます。

DEPTXML
---------------------------------
<Department DEPTNO="10">
<DNAME>Administration</DNAME>
<EMP_LIST>
<EMP_T EMPNO="200">
<ENAME>Whalen</ENAME>
</EMP_T>
</EMP_LIST>
</Department>

1 row selected.

この例を例18-7および例18-25と比較してください。

XMLCONCAT SQL/XML関数

SQL/XML標準関数XMLConcatを使用して、複数のXMLTypeインスタンスを連結することにより、XMLフラグメントを構成します。図18-4はXMLConcatの構文を説明するものです。関数XMLConcatには次の2つの形式があります。

- 1つ目の形式では、XMLTypeインスタンスのVARRAYであるXMLSequenceType値を引数として取り、VARRAYのすべての要素を連結して単一のXMLTypeインスタンスを戻します。この形式は、XMLTypeインスタンスのリストを単一のインスタンスに縮小する場合に有効です。

- 2つ目の形式では、任意の数のXMLTypeインスタンスを取り、それらの値を連結します。値の1つがNULLである場合、その値は結果に出力されません。すべての値がNULLである場合、結果はNULLになります。この形式は、任意の数のXMLTypeインスタンスを同じ行に連結するために使用できます。関数XMLAggを使用すると、複数行にわたってXMLTypeインスタンスを連結できます。

図18-4 XMLCONCATの構文

例18-10では、SQL/XML関数XMLConcatを使用して、XMLSequenceType値(XMLTypeインスタンスのVALLAY)のXMLTypeインスタンスを連結して戻します。

例18-10 XMLCONCAT: 順序で使用されるXMLTypeインスタンスの連結

SELECT XMLSerialize(
CONTENT
XMLConcat(XMLSequenceType(
XMLType('<PartNo>1236</PartNo>'),
XMLType('<PartName>Widget</PartName>'),
XMLType('<PartPrice>29.99</PartPrice>')))
AS CLOB)
AS "RESULT"
FROM DUAL;

この問合せによりXMLフラグメントが戻されます。(ここではわかりやすいように、この結果をフォーマット出力しています。)

RESULT
---------------
<PartNo>1236</PartNo>
<PartName>Widget</PartName>
<PartPrice>29.99</PartPrice>

1 row selected.

例18-11では、XMLConcatを使用して、従業員の姓と名のXML要素を作成して連結します。

例18-11 XMLCONCAT: XML要素の連結

SELECT XMLConcat(XMLElement("first", e.first_name),
XMLElement("last", e.last_name))
AS "RESULT"
FROM employees e;

この問合せにより生成されるXMLフラグメントは次のとおりです。

RESULT
--------------------------------------------
<first>Den</first><last>Raphaely</last>
<first>Alexander</first><last>Khoo</last>
<first>Shelli</first><last>Baida</last>
<first>Sigal</first><last>Tobias</last>
<first>Guy</first><last>Himuro</last>
<first>Karen</first><last>Colmenares</last>

6 rows selected.

XMLAGG SQL/XML関数

SQL/XML標準関数XMLAggを使用して、XML要素のコレクションからXML要素のフォレストを構成します。これは集計関数です。

図18-5 XMLAGGの構文

図18-5はXMLAggの構文を示しています。この構文でorder_by_clauseは次のとおりです。

ORDER BY [list of: expr [ASC|DESC] [NULLS {FIRST|LAST}]]

数値リテラルは、列の位置として解釈されません。たとえば、ORDER BY 1は、最初の列での順序付けを意味しません。数値リテラルは他のリテラルと同様に解釈されます。

SQL/XML関数XMLConcatと同様に、値がNULLである引数は結果から削除されます。SQL/XML関数XMLAggはOracle SQL関数sys_XMLAggに類似していますが、XMLAggはノードのフォレストを戻し、XMLFormatパラメータを取らない点で異なります。

SQL/XML関数XMLAggを使用すると、複数行にわたってXMLTypeインスタンスを連結できます。また、オプションのORDER BY句を使用して、集計するXML値を順序付けできます。関数XMLAggは各グループについて1つの集計XMLを生成します。問合せでGROUP BYが指定されていない場合、問合せのすべての行に対する結果が集計され、1つのXMLが戻されます。

例18-12では、SQL/XML関数XMLAggおよびXMLElementを使用して、従業員のジョブIDおよび姓を要素のコンテンツとして持つEmployee要素を含むDepartment要素を作成します。また、その部門に属するEmployee要素を従業員の姓で順序付けします。また、その部門に属する Employee 要素を従業員の姓で順序付けします (わかりやすいように、この結果をフォーマット出力しています)。

例18-12 XMLAGG: 子の従業員要素を含む部門要素の生成

SELECT XMLElement("Department", XMLAgg(XMLElement("Employee",
e.job_id||' '||e.last_name)
ORDER BY e.last_name))
AS "Dept_list"
FROM hr.employees e
WHERE e.department_id = 30 OR e.department_id = 40;

Dept_list
------------------
<Department>
<Employee>PU_CLERK Baida</Employee>
<Employee>PU_CLERK Colmenares</Employee>
<Employee>PU_CLERK Himuro</Employee>
<Employee>PU_CLERK Khoo</Employee>
<Employee>HR_REP Mavris</Employee>
<Employee>PU_MAN Raphaely</Employee>
<Employee>PU_CLERK Tobias</Employee>
</Department>

1 row selected.

XMLAggによって行が集計されるため、単一の従業員行が戻されます。

例18-13は、GROUP BY句を使用して、戻された一連の行を複数のグループにグループ化し、Department要素を構成する方法を示しています。(ここではわかりやすいように、この結果をフォーマット出力しています。)

例18-13 XMLAGG: GROUP BYを使用した複数の部門要素の生成

SELECT XMLElement("Department", XMLAttributes(department_id AS "deptno"),
XMLAgg(XMLElement("Employee", e.job_id||' '||e.last_name)))
AS "Dept_list"
FROM hr.employees e
GROUP BY e.department_id;

Dept_list
------------------
<Department deptno="30">
<Employee>PU_MAN Raphaely</Employee>
<Employee>PU_CLERK Colmenares</Employee>
<Employee>PU_CLERK Himuro</Employee>
<Employee>PU_CLERK Tobias</Employee>
<Employee>PU_CLERK Baida</Employee>
<Employee>PU_CLERK Khoo</Employee></Department>

<Department deptno="40">
<Employee>HR_REP Mavris</Employee>
</Department>

2 rows selected.

XMLAgg式でORDER BY句を使用すると、各部門内で従業員を順序付けできます。

注意:
ORDER BY句にかぎり、他のOracle Databaseでの使用方法とは異なり、数値リテラルは列の位置として解釈されません。

関数XMLAggを使用すると、表に存在するいくつかの階層関係を反映できます。例18-14では、部門30の部門要素を生成します。この要素内に、部門の各従業員に対応する子要素empがあります。各従業員要素内に、その従業員の各依存に対応するdependent要素があります。

例18-14 XMLAGG: ネストされた要素の生成

SELECT last_name, employee_id FROM employees WHERE department_id = 30;

LAST_NAME                 EMPLOYEE_ID
------------------------- -----------
Raphaely                          114
Khoo                              115
Baida                             116
Tobias                            117
Himuro                            118
Colmenares                        119

6 rows selected.

dependents表で、各従業員の依存を保持します。

CREATE TABLE hr.dependents (id NUMBER(4) PRIMARY KEY,
employee_id NUMBER(4),
name VARCHAR2(10));
Table created.
INSERT INTO dependents VALUES (1, 114, 'MARK');
1 row created.
INSERT INTO dependents VALUES (2, 114, 'JACK');
1 row created.
INSERT INTO dependents VALUES (3, 115, 'JANE');
1 row created.
INSERT INTO dependents VALUES (4, 116, 'HELEN');
1 row created.
INSERT INTO dependents VALUES (5, 116, 'FRANK');
1 row created.
COMMIT;
Commit complete.

次の問合せは、依存についての情報を含む部門のXMLデータを生成します。(ここではわかりやすいように、この結果をフォーマット出力しています。)

SELECT
XMLElement(
"Department",
XMLAttributes(d.department_name AS "name"),
(SELECT
XMLAgg(XMLElement("emp",
XMLAttributes(e.last_name AS name),
(SELECT XMLAgg(XMLElement("dependent",
XMLAttributes(de.name AS "name")))
FROM dependents de
WHERE de.employee_id = e.employee_id)))
FROM employees e
WHERE e.department_id = d.department_id)) AS "dept_list"
FROM departments d
WHERE department_id = 30;

dept_list
--------------------------------------------------------------------------------
<Department name="Purchasing">
<emp NAME="Raphaely">
<dependent name="MARK"></dependent>
<dependent name="JACK"></dependent>
</emp><emp NAME="Khoo">
<dependent name="JANE"></dependent>
</emp>
<emp NAME="Baida">
<dependent name="HELEN"></dependent>
<dependent name="FRANK"></dependent>
</emp><emp NAME="Tobias"></emp>
<emp NAME="Himuro"></emp>
<emp NAME="Colmenares"></emp>
</Department>

1 row selected.

XMLPI SQL/XML関数

SQL/XML標準関数XMLPIを使用して、XML処理命令(PI)を構成します。図18-6に構文を示します。

図18-6 XMLPIの構文

引数value_exprが評価され、文字列の結果が、空白で区切られてオプションの識別子(identifier)に追加されます。この連結は、次に「<?」と「?>」で囲まれて処理命令になります。つまり、string-resultがvalue_exprの評価結果だとすると、生成された処理命令は<?identifier string-result?>となります。string-resultが空の文字列''の場合、関数は<?identifier?>を戻します。

キーワードNAMEにリテラル文字列identifierを続ける方法の他に、キーワードEVALNAMEに、評価結果が識別子として使用される文字列になる式を続ける方法もあります。EVALNAMEの使用の可能性は、標準SQL/XML関数XMLPIに対応するためのOracleの拡張です。

構成されたXMLが有効なXML処理命令でない場合はエラーが発生します。特に、次の点に注意してください。

- identifierには「xml」という語は使用できません(大文字、小文字、混合のいずれも)。

- string-resultには「?>」という文字の並びを含めることはできません。

関数XMLPIはXMLTypeのインスタンスを戻します。string-resultがNULLの場合はNULLが戻されます。

例18-15では、XMLPIを使用して簡単な処理の指示を生成します。

例18-15 SQL/XML関数XMLPIの使用

SELECT XMLPI(NAME "OrderAnalysisComp", 'imported, reconfigured, disassembled')
AS pi FROM DUAL;

これによって、次の出力が生成されます。

PI
----------------------------------------------------------
<?OrderAnalysisComp imported, reconfigured, disassembled?>

1 row selected.

XMLCOMMENT SQL/XML関数

SQL/XML標準関数XMLCommentを使用して、XMLコメントを構成します。図18-7に構文を示します。

図18-7 XMLCommentの構文

引数value_exprの評価結果は文字列で、生成されるXMLコメントの本文として使用されます。つまり、結果は<!--string-result-->で、ここでstring-resultがvalue_exprの文字列評価結果です。string-resultが空の文字列の場合、次のようにコメントは空になります。<!---->

構成されたXMLが有効なXMLコメントでない場合はエラーが発生します。特に、string-resultに、ハイフン(-)が連続して2つ含まれてはいけないことに注意してください(--)。

関数XMLCommentはXMLTypeのインスタンスを戻します。string-resultがNULLの場合、関数はNULLを戻します。

例18-16では、XMLCommentを使用して簡単なXMLコメントを生成します。

例18-16 SQL/XML関数XMLCOMMENTの使用

SELECT XMLComment('This is a comment') AS cmnt FROM DUAL;

この問合せによって、次の出力が生成されます。

CMNT
--------------------------
<!--This is a comment-->

XMLSERIALIZE SQL/XML関数

SQL/XML標準関数XMLSerializeは、文字列またはXMLデータのLOB表現を取得するために使用します。

図18-8にXMLSerializeの構文を示します。

図18-8 XMLSerializeの構文

引数value_expr/が評価され、結果のXMLTypeインスタンスがシリアライズされて、作成された文字列またはLOBのコンテンツを生成します。存在する場合は脚注1、指定されたdatatypeは、次のいずれかであることが必要です(デフォルトのデータ型はCLOB)。

- VARCHAR2(N)。Nはバイト・サイズ(上限limit 4000)を示します。

- CLOB

- BLOB

DOCUMENTを指定した場合、value_exprの評価の結果は整形式の文書である必要があります。特に、ルートは単独にしてください。結果が整形式の文書でない場合、エラーが発生します。ただし、CONTENTを指定した場合は、value_exprの結果は整形であるかどうかがチェックされません。

value_expr の評価結果がNULLまたは空の文字列('')の場合、関数 XMLSerializeはNULLを戻します。

ENCODING句は、BLOBインスタンスとしてシリアライズされたXMLデータの文字エンコーディングを指定します。xml_encoding_specは、XMLエンコーディング宣言(encoding="...")です。datatypeがBLOBの場合、ENCODING句を指定すると、指定したとおりに出力がエンコードされ、BLOBエンコーディングを示すためにxml_encoding_specがプロローグに追加されます。ENCODING句をBLOB以外のdatatypeとともに指定した場合、エラーが発生します。

VERSIONを指定した場合、XML宣言(<?xml version="..." ...?>)でそのバージョンが使用されます。

NO INDENTを指定した場合、無意味な空白は出力に表示されないようにすべて削除されます。INDENT SIZE = N (Nは整数)を指定した場合、出力はN個の空白の相対インデントを使用してフォーマット出力されます。Nが0の場合、フォーマット出力で各要素の後に改行文字が挿入されます。行の各要素はそれ自身で置き換えられますが、出力に他の無意味な空白は含まれません。SIZEを指定せずにINDENTを指定した場合、2個の空白を使用したインデントが使用されます。NO INDENTもINDENTも指定しない場合、動作(フォーマット出力かどうか)は不確定です。

HIDE DEFAULTSおよびSHOW DEFAULTSは、XML Schemaに基づくデータにのみ適用されます。SHOW DEFAULTSを指定した場合、XML Shemaでデフォルト値が定義されているオプションの要素や属性が入力データに存在しないと、それらの要素や属性はそのデフォルト値とともに出力に含められます。HIDE DEFAULTSを指定した場合、このような要素や属性は出力に含められません。HIDE DEFAULTSがデフォルトの動作です。

例18-17では、XMLSerializeを使用して、シリアライズされたXMLデータを含むCLOBインスタンスを生成します。

例18-17 SQL/XML関数XMLSERIALIZEの使用

SELECT XMLSerialize(DOCUMENT XMLType('<poid>143598</poid>') AS CLOB)
AS xmlserialize_doc FROM DUAL;

これによって、次の出力が生成されます。

XMLSERIALIZE_DOC
-------------------
<poid>143598</poid>

XMLPARSE SQL/XML関数

SQL/XML標準関数XMLParseは、XMLデータを含む文字列を解析してXMLTypeインスタンスの対応する値を構成するために使用します。図18-9に構文を示します。

図18-9 XMLParseの構文

引数value_exprが評価され、解析された文字列が生成されます。DOCUMENTを指定した場合、value_exprは、整形式のXML文書に対応していて、ルートが単独である必要があります。CONTENTを指定した場合、value_exprは整形式のXMLフラグメントに対応していれば問題ありません(ルートが単独である必要はありません)。

キーワードWELLFORMEDは、SQL/XML標準に向けたOracle XML DBの拡張です。WELLFORMEDを指定する場合、パーサーに対して、引数value_exprが整形式であると通知することになるため、Oracle XML DBで、本当に整形式かどうかを確認する必要がありません。

関数XMLParseはXMLTypeのインスタンスを戻します。value_expr の評価結果がNULLの場合、関数はNULLを戻します。

例18-18では、XMLParseを使用してXMLコードの文字列を解析し、XMLTypeインスタンスを生成します。

例18-18 SQL/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>

関連項目:
http://www.w3.org/TR/REC-xml/「Extensible Markup Language (XML) 1.0」にある、整形式のXML文書およびフラグメントに関する説明

XMLROOT Oracle SQL関数

SQL関数XMLRootはSQL/XML標準関数である時期がありましたが、SQL/XML 2005時点で標準関数として非推奨になりました。Oracle SQL関数としてOracle XML DBでは使用できます。

XMLRootは、XML値のルート情報項目へのVERSIONプロパティの追加や、オプションのSTANDALONEプロパティの追加に使用します。通常、これはデータモデル準拠の確認に使用します。図18-10にXMLRootの構文を示します。

図18-10 XMLRootの構文

最初の引数xml-expressionが評価され、示されたプロパティ(VERSION、STANDALONE)およびその値が、結果のXMLTypeインスタンスの新しいプロローグに追加されます。評価されたxml-expressionがすでにプロローグに含まれている場合、エラーが発生します。

2番目の引数string-valued-expression(キーワードVERSIONの次)が評価され、結果の文字列がプロローグのversionプロパティの値として使用されます。プロローグのstandaloneプロパティ(小文字)がオプションの3番目の引数STANDALONEのYESまたはNOの値から取得されます。VERSIONでNOVALUEが使用されている場合、結果のプロローグでは「version=1.0」が使用されます。STANDALONEでNOVALUEが使用されている場合、結果のプロローグではstandaloneプロパティが省略されます。

関数XMLRootはXMLTypeのインスタンスを戻します。最初の引数xml-expressionの評価結果がNULLの場合、関数はNULLを戻します。

例18-19では、XMLRootを使用して、version属性およびstandalone属性を持つXML宣言を追加します。

例18-19 Oracle SQL関数XMLRootの使用

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.

XMLCOLATTVAL Oracle SQL関数

Oracle SQL関数XMLColAttValは、渡された引数の値を含むXMLのcolumn要素のフォレストを生成します。この関数は、SQL/XML ANSI-ISO標準関数に対応するためのOracleの拡張です。図18-11はXMLColAttValの構文を説明するものです。

図18-11 XMLCOLATTVALの構文

引数はcolumn要素のname属性の値として使用されます。c_alias値は属性識別子として使用されます。

キーワードASにリテラル文字列c_aliasを続ける方法の他に、AS EVALNAMEに、評価結果が属性識別子として使用される文字列になる式を続ける方法もあります。

引数値value_exprは属性valuesとしてのみ使用されているため、いずれにしてもエスケープする必要はありません。XMLForestとは対照的です。つまり、XMLColAttValを使用すると、SQL列と値をエスケープせずに転送できます。

例18-20では、XMLColAttValを使用して、name属性を含み、雇用日および部門をコンテンツとして含むcolumn要素を持つEmp要素を各従業員に1つずつ生成します。

例18-20 XMLCOLATTVAL: 属性と子要素を持つ要素の生成

SELECT XMLElement("Emp",
XMLAttributes(e.first_name ||' '||e.last_name AS "fullname" ),
XMLColAttVal(e.hire_date, e.department_id AS "department"))
AS "RESULT"
FROM hr.employees e
WHERE e.department_id = 30;

この問合せにより生成されるXMLは次のとおりです。(ここではわかりやすいように、この結果をフォーマット出力しています。)

RESULT
-----------------------------------------------------------
<Emp fullname="Den Raphaely">
<column name = "HIRE_DATE">2002-12-07</column>
<column name = "department">30</column>
</Emp>
<Emp fullname="Alexander Khoo">
<column name = "HIRE_DATE">2003-05-18</column>
<column name = "department">30</column>
</Emp>
<Emp fullname="Shelli Baida">
<column name = "HIRE_DATE">2005-12-24</column>
<column name = "department">30</column>
</Emp>
<Emp fullname="Sigal Tobias">
<column name = "HIRE_DATE">2005-07-24</column>
<column name = "department">30</column>
</Emp>
<Emp fullname="Guy Himuro">
<column name = "HIRE_DATE">2006-11-15</column>
<column name = "department">30</column>
</Emp>
<Emp fullname="Karen Colmenares">
<column name = "HIRE_DATE">2007-08-10</column>
<column name = "department">30</column>
</Emp>

6 rows selected.

関連項目:
例18-8「XMLFOREST: 属性と子要素を持つ要素の生成」

XMLCDATA Oracle SQL関数

Oracle SQL関数XMLCDATAを使用して、XML CDATAセクションを生成します。図18-12に構文を示します。

図18-12 XMLCDATAの構文

引数value_exprの評価結果は文字列で、生成されるXML CDATAセクション<![CDATA[string-result]]>の本文として使用されます。ここで、string-resultは、value_exprを評価した結果です。string-resultが空の文字列の場合、CDATAセクションは空(<![CDATA[]]>)です。

構成されたXMLが有効なXMLのCDATAセクションと異なる場合はエラーが発生します。特に、string-resultに、左開き大カッコ(])が連続して2つ含まれてはいけないことに注意してください(]])。

関数XMLCDATAはXMLTypeのインスタンスを戻します。string-resultがNULLの場合、関数はNULLを戻します。

例18-21では、XMLCDATAを使用して、XML CDATAセクションを生成します。

例18-21 Oracle SQL関数XMLCDATAの使用

SELECT XMLElement("PurchaseOrder",
XMLElement("Address",
XMLCDATA('100 Pennsylvania Ave.'),
XMLElement("City", 'Washington, D.C.')))
AS RESULT FROM DUAL;

これによって、次の出力が生成されます。(ここではわかりやすいように、この結果をフォーマット出力しています。)

RESULT
--------------------------
<PurchaseOrder>
<Address>
<![CDATA[100 Pennsylvania Ave.]]>
<City>Washington, D.C.</City>
</Address>
</PurchaseOrder>

XML DBMS_XMLGENを使用したXMLの生成

PL/SQLパッケージDBMS_XMLGENは、SQL問合せの結果からXML文書を作成します。XML文書はCLOBまたはXMLType値として取得されます。

fetchインタフェースが用意されるので、それを使用して、取得する行の最大数とスキップする行数を指定できます。たとえば、最初のフェッチで最大10行を取り出し、最初の4行をスキップできます。これは特にWebアプリケーションでのページ区切り要件を満たすために有効です。

DBMS_XMLGENには、ROW、ROWSETなどのタグ名を変更するオプションもあります。DBMS_XMLGENパッケージのパラメータは、取り出す行の数を制限し、タグ名を囲みます。

関連項目:

- 『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

- 『Oracle XML Developer's Kitプログラマーズ・ガイド』(OracleXMLQueryとDBMS_XMLGENを比較)

PL/SQLパッケージDBMS_XMLGENの使用

図18-13は、パッケージDBMS_XMLGENの使用方法を示しています。手順は次のとおりです。

1. SQL問合せを実行し、PL/SQL関数newContextをコールすることによって、パッケージからコンテキストを取得します。

2. そのコンテキストをパッケージ内のすべてのプロシージャまたは関数に渡して、様々なオプションを設定します。たとえば、ROW要素の名前を設定するには、setRowTag(ctx)を使用します。このctxは、前のnewContextコールから取得したコンテキストです。

3. PL/SQL関数getXMLまたはgetXMLTypeを使用してXML結果を取得します。PL/SQLプロシージャsetMaxRowsを使用してフェッチごとに取り出す行の最大数を設定すると、この関数を繰り返しコールして、コールごとに最大数までの行を取得できます。この関数はXMLデータを(それぞれCLOB値およびXMLTypeのインスタンスとして)戻します。取得された行がない場合、NULLを戻します。取得する行数を決めるには、PL/SQL関数getNumRowsProcessedを使用します。

4. 問合せをリセットして再度開始し、手順3を繰り返すことができます。

5. PL/SQLプロシージャcloseContextをコールして、すでに割り当てられているリソースを解放します。

図18-13 PL/SQLパッケージDBMS_XMLGENの使用

SQL問合せと組み合せることにより、PL/SQLメソッドDBMS_XMLGEN.getXMLは通常、次のような結果をCLOB値として戻します。

<?xml version="1.0"?>
<ROWSET>
<ROW>
<EMPLOYEE_ID>100</EMPLOYEE_ID>
<FIRST_NAME>Steven</FIRST_NAME>
<LAST_NAME>King</LAST_NAME>
<EMAIL>SKING</EMAIL>
<PHONE_NUMBER>515.123.4567</PHONE_NUMBER>
<HIRE_DATE>17-JUN-87</HIRE_DATE>
<JOB_ID>AD_PRES</JOB_ID>
<SALARY>24000</SALARY>
<DEPARTMENT_ID>90</DEPARTMENT_ID>
</ROW>
<ROW>
<EMPLOYEE_ID>101</EMPLOYEE_ID>
<FIRST_NAME>Neena</FIRST_NAME>
<LAST_NAME>Kochhar</LAST_NAME>
<EMAIL>NKOCHHAR</EMAIL>
<PHONE_NUMBER>515.123.4568</PHONE_NUMBER>
<HIRE_DATE>21-SEP-89</HIRE_DATE>
<JOB_ID>AD_VP</JOB_ID>
<SALARY>17000</SALARY>
<MANAGER_ID>100</MANAGER_ID>
<DEPARTMENT_ID>90</DEPARTMENT_ID>
</ROW>
</ROWSET>

リレーショナル・データとXMLデータの間のデフォルト・マッピングは次のとおりです。

- SQL問合せによって戻される各行は、デフォルトの要素名ROWを使用してXML要素にマップします。

- SQL問合せによって戻される各列は、ROW要素の子要素にマップします。

- 結果全体は、ROWSET要素で囲まれます。

- バイナリ・データは、16進数表現に変換されます。

要素名ROWおよびROWSETは、それぞれDBMS_XMLGENプロシージャsetRowTagNameおよびsetRowSetTagNameを使用して選択した名前に置換できます。

getXMLにより戻されたCLOB値は、データベースのキャラクタ・セットと同じエンコーディングを持ちます。データベースのキャラクタ・セットがSHIFTJISの場合、戻されるXML文書もSHIFTJISです。

パッケージDBMS_XMLGENのファンクションおよびプロシージャ

表18-1に、DBMS_XMLGENのファンクションおよびプロシージャの概要を示します。

表18-1 DBMS_XMLGENのファンクションおよびプロシージャ

ファンクションまたはプロシージャ

説明

SUBTYPE ctxHandle IS NUMBER

すべてのファンクションで使用されるコンテキスト・ハンドルです。

Document Type Definition(DTD)またはSchemaの指定は次のとおりです。

NONE CONSTANT NUMBER:= 0;

DTD CONSTANT NUMBER:= 1;

SCHEMA CONSTANT NUMBER:= 2;

これらの指定をgetXMLファンクションで使用して、DTDを生成するか、XML Schemaを生成するか、または何も生成しないか(NONE)を指定できます。NONE指定のみがサポートされています。

newContext()

任意の問合せ文字列に対して、後続のファンクションで使用される新しいコンテキスト・ハンドルを生成します。

newContext(
queryString IN VARCHAR2)

新しいコンテキストを戻します。

パラメータ: queryString (IN) - XMLに変換する必要がある結果の問合せ文字列。

戻り値: コンテキスト・ハンドル。最初にこのファンクションをコールして、結果からXMLを戻すためのgetXMLおよびその他のファンクションで使用できるハンドルを取得します。

newContext(
queryString IN SYS_REFCURSOR)
RETURN ctxHandle;

PL/SQLカーソル変数からコンテキスト・ハンドルを作成します。コンテキスト・ハンドルは、他のファンクションにも使用できます。

newContextFromHierarchy(
queryString IN VARCHAR2)
RETURN ctxHandle;

パラメータ: queryString (IN) - XMLに変換する必要がある結果の問合せ文字列。この問合せは、通常、CONNECT BY句を使用して構成された階層問合せであり、CONNECT BY問合せによって生成された結果セットと同じプロパティを持つ必要があります。結果セットの列は、レベル数およびXML値の2つのみである必要があります。レベル数は、結果のXML文書内でのXML値の階層位置を判断するために使用されます。

戻り値: コンテキスト・ハンドル。最初にこのファンクションをコールして、結果から再帰要素付きの階層XMLを戻すためのgetXMLおよびその他のファンクションで使用できるハンドルを取得します。

setRowTag()

すべての行を区切る要素の名前を設定します。デフォルト名はROWです。

setRowTag(ctx IN ctxHandle,
rowTag IN VARCHAR2);

パラメータ:

ctx(IN): newContextをコールして取得されるコンテキスト・ハンドル。

rowTag(IN) - ROW要素の名前。rowTagのNULL値は、ROW要素が必要ないことを示しています。

このファンクションをコールして、ROW要素の名前を設定すると、デフォルト名のROWは表示されません。rowTagをNULLに設定すると、ROW要素が出力されません。

ただし、getXMLはXMLフラグメントでなく完全なXML文書を戻すため、単独のルート要素が存在する必要があります。このため、rowTag値とrowSetTag値(次のsetRowSetTagを参照)の両方が NULLで、出力に複数の列または行が存在する場合はエラーが発生します。

setRowSetTag()

文書のルート要素の名前を設定します。デフォルト名はROWSETです。

setRowSetTag(ctx IN ctxHandle,
rowSetTag IN VARCHAR2);

パラメータ:

ctx(IN): newContextをコールして取得されるコンテキスト・ハンドル。

rowSetTag(IN): 出力で使用される、文書のルート要素の名前。rowSetTagのNULL値は、ROWSET要素が必要ないことを示しています。

このファンクションをコールして、文書のルート要素の名前を設定すると、デフォルト名のROWSETは使用されません。rowSetTagをNULLに設定すると、文書のルート要素は出力されません。

ただし、getXMLはXMLフラグメントでなく完全なXML文書を戻すため、単独のルート要素が存在する必要があります。このため、rowTag値とrowSetTag値(前のsetRowTagを参照)の両方がNULLで、出力に複数の列または行が存在する場合、またはrowSetTag値がNULLで、出力に複数の行が存在する場合はエラーが発生します。

getXML()

指定されている最大数の行をフェッチすることによってXML文書を取得します。また、そのXML文書を渡されたCLOBに追加します。

getXML(ctx IN ctxHandle,
clobval IN OUT NCOPY clob,
dtdOrSchema IN number:= NONE);

パラメータ:

ctx(IN): newContextをコールして取得されるコンテキスト・ハンドル。

clobval(IN/OUT) - XML文書を追加するCLOB。

dtdOrSchema(IN) - DTDまたはSchemaのどちらを生成するか。このパラメータはサポートされていません。

このバージョンのgetXMLファンクションを使用して、余分なCLOBコピーの生成を回避したり、後続のコールで同じCLOBを再利用します。このgetXMLコールは、LOBロケータの作成を必要としますが、次のファンクションよりも効率的です。XMLを生成するときは、setSkipRowsコールに指定された数の行がスキップされ、setMaxRowsコールに指定された最大数の行(または指定がない場合は結果全体)がフェッチされ、XMLに変換されます。getNumRowsProcessedファンクションを使用して、行が取り出されたかどうかを確認します。

getXML()

XML文書を生成し、それをCLOBとして戻します。

getXML(ctx IN ctxHandle,
dtdOrSchema IN number:= NONE)
RETURN clob;

パラメータ:

ctx(IN): newContextをコールして取得されるコンテキスト・ハンドル。

dtdOrSchema(IN) - DTDまたはXMLスキーマのどちらを生成するか。このパラメータはサポートされていません。

戻り値: 文書を含む一時CLOB。DBMS_LOB.freeTemporaryコールを使用して、このファンクションから取得した一時CLOBを解放します。

getXMLType(
ctx IN ctxHandle,
dtdOrSchema IN number:= NONE)
RETURN XMLType;

パラメータ:

ctx(IN): newContextをコールして取得されるコンテキスト・ハンドル。

dtdOrSchema(IN) - DTDまたはXMLスキーマのどちらを生成するか。このパラメータはサポートされていません。

戻り値: 文書を含むXMLTypeインスタンス。

getXML(
sqlQuery IN VARCHAR2,
dtdOrSchema IN NUMBER := NONE)
RETURN CLOB;

渡されたSQL問合せ文字列からの問合せ結果をXML形式に変換し、XMLをCLOBとして戻します。

getXMLType(
sqlQuery IN VARCHAR2,
dtdOrSchema IN NUMBER := NONE)
RETURN XMLType;

渡されたSQL問合せ文字列からの問合せ結果をXML形式に変換し、XMLをCLOBとして戻します。

getNumRowsProcessed()

ファンクションgetXMLを使用してXMLを生成するときに処理される、SQLの行数を取得します。この行数には、XMLデータの生成前にスキップされる行数は含まれません。

getNumRowsProcessed(ctx IN ctxHandle)
RETURN number;

パラメータ: queryString (IN) - XMLに変換する必要がある結果の問合せ文字列。

戻り値: getXMLを最後にコールしたときに処理されたSQL行の数を取得します。

このファンクションをコールして、結果セットの最後に達したかどうかを確認できます。これには、XMLデータの生成前にスキップされる行数は含まれません。ループでgetXMLをコールする場合、このファンクションを使用して終了条件を決定します。getXMLは、行がない場合でも常にXML文書を生成することに注意してください。

setMaxRows()

getXMLのコールごとに、SQL問合せ結果からフェッチする行の最大数を設定します。newContextFromHierarchyファンクションで作成されたコンテキスト・ハンドルでこのファンクションをコールすると、エラーになります。

setMaxRows(ctx IN ctxHandle,
maxRows IN NUMBER);

パラメータ:

ctx(IN) - 実行されている問合せに対応するコンテキスト・ハンドル。

maxRows(IN) - getXMLをコールするたびに取得する最大行数。

maxRowsパラメータは、このユーティリティを使用して結果のページ区切りを生成するときに使用できます。たとえば、XMLまたはHTMLデータのページを生成する場合、XMLに変換する行数を制限し、後続のコールにおいて、次の一連の行を次々に取得できます。これによって応答時間が短縮できます。newContextFromHierarchy関数で作成されたコンテキスト・ハンドルでこのプロシージャをコールすると、エラーになります。

setSkipRows()

getXMLをコールするたびに、XML出力の生成前に指定の行数をスキップします。newContextFromHierarchyファンクションで作成されたコンテキスト・ハンドルでこのファンクションをコールすると、エラーになります。

setSkipRows(ctx IN ctxHandle,
skipRows IN NUMBER);

パラメータ:

ctx(IN) - 実行されている問合せに対応するコンテキスト・ハンドル。

skipRows(IN) - getXMLをコールするたびにスキップする最大行数。

skipRowsパラメータは、このユーティリティを使用して、ステートレスなWebページの結果の区切りを生成するときに使用できます。たとえば、XMLまたはHTMLデータの最初のページを生成するときに、skipRowsを0(ゼロ)に設定できます。次の設定では、skipRowsを最初に指定した行数に設定できます。newContextFromHierarchyファンクションで作成されたコンテキスト・ハンドルでこのファンクションをコールすると、エラーになります。

setConvertSpecialChars()

XMLデータの特殊文字を、XMLの等価のエスケープ文字に変換する必要があるかどうかを指定します。たとえば、<符号は&lt;に変換されます。デフォルトでは、エスケープ変換が実行されます。

setConvertSpecialChars(
ctx IN ctxHandle,
conv IN BOOLEAN);

パラメータ:

ctx(IN) - 使用するコンテキスト・ハンドル。

conv(IN) - 変換が必要かどうか。

エスケープ文字で置換する必要がある特殊文字(<、>、"、'など)が、入力データに含まれていないことがわかっている場合は、このファンクションを使用してXML処理を高速化できます。実際に文字データをスキャンして特殊文字を置換するには、特に大量のデータを処理する場合、大きいコストがかかります。したがって、データがXMLで問題ない場合、この関数をコールしてパフォーマンスを向上できます。

useItemTagsForColl()

コレクション要素名を設定します。コレクション要素のデフォルト名は、型名自体です。このファンクションを使用して、列名を、列名に_ITEMタグを追加した名前にオーバーライドできます。

useItemTagsForColl(ctx IN ctxHandle);

パラメータ: ctx(IN) - コンテキスト・ハンドル。

たとえば、NUMBERというコレクションがある場合、コレクション要素のデフォルトのタグ名はNUMBERになります。このプロシージャをコールすると、このデフォルト動作を変更して、デフォルト名に_ITEMタグを追加したコレクション列名を生成できます。

restartQuery()

問合せを再度開始し、最初の行からXMLを生成します。

restartQuery(ctx IN ctxHandle);

パラメータ: ctx(IN) - 現行の問合せに対応するコンテキスト・ハンドル。このプロシージャをコールすると、新しいコンテキストを作成することなく、問合せの実行を再度開始できます。

closeContext()

任意のコンテキストをクローズし、SQLカーソル、バインドや定義バッファなど、そのコンテキストに対応付けられているすべてのリソースを解放します。

closeContext(ctx IN ctxHandle);

パラメータ: ctx(IN) - クローズするコンテキスト・ハンドル。このハンドルに対応付けられているすべてのリソースをクローズします。クローズした後は、他のすべてのDBMS_XMLGENファンクションをコールするときに、このハンドルを使用できなくなります。

変換ファンクション

convert(
xmlData IN varchar2,
flag IN NUMBER := ENTITY_ENCODE)
RETURN VARCHAR2;

XMLデータ文字列引数をエンコードまたはデコードします。

- エンコーディングとは、<などの実体参照を&lt;などのエスケープされた同等のものに置き換えることです。

- デコーディングとは、逆方向の変換です。

convert(
xmlData IN CLOB,
flag IN NUMBER := ENTITY_ENCODE)
RETURN CLOB;

渡されたXMLのCLOBデータをエンコードまたはデコードします。

- エンコーディングとは、<などの実体参照を&lt;などのエスケープされた同等のものに置き換えることです。

- デコーディングとは、逆方向の変換です。

NULL処理

setNullHandling(ctx IN ctxHandle,
flag IN NUMBER);

setNullHandlingのフラグ値は、次のとおりです。

- DROP_NULLS CONSTANT NUMBER := 0;
これがデフォルト設定で、NULL要素の場合もタグはそのまま残されます。

- NULL_ATTR CONSTANT NUMBER := 1;
この場合は、xsi:nil = "true"に設定されます。

- EMPTY_TAG CONSTANT NUMBER := 2;
この場合は、たとえば<foo/>に設定されます。

useNullAttributeIndicator(
ctx IN ctxHandle,
attrind IN BOOLEAN := TRUE);

useNullAttributeIndicatorはsetNullHandling(ctx, NULL_ATTR)のショートカットです。

setBindValue(
ctx IN ctxHandle,
bindVariableName IN VARCHAR2,
bindValue IN VARCHAR2);

コンテキスト・ハンドルに関連付けられた問合せ文字列内で使用されているバインド変数に、バインド値を設定します。バインド変数が含まれる問合せ文字列は、setBindValueコールを使用してすべてのバインド変数に値が設定されるまで実行できません。

clearBindValue(ctx IN ctxHandle);

コンテキスト・ハンドルに関連付けられた問合せ文字列内で使用されているすべてのバインド変数のバインド値をすべて消去します。後で、setBindValueを使用してすべてのバインド変数に新しい値をリバインドする必要があります。

DBMS_XMLGENの例

例18-22では、DBMS_XMLGENを使用して、オブジェクト・リレーショナル表から従業員データを選択してXML文書を作成し、結果のCLOB値を表に挿入します。

例18-22 DBMS_XMLGEN: 単純なXMLの生成

CREATE TABLE temp_clob_tab (result CLOB);

DECLARE
qryCtx DBMS_XMLGEN.ctxHandle;
result CLOB;
BEGIN
qryCtx := DBMS_XMLGEN.newContext(
'SELECT * FROM hr.employees WHERE employee_id = 101');
-- Set the row header to be EMPLOYEE
DBMS_XMLGEN.setRowTag(qryCtx, 'EMPLOYEE');
-- Get the result
result := DBMS_XMLGEN.getXML(qryCtx);
INSERT INTO temp_clob_tab VALUES(result);
--Close context
DBMS_XMLGEN.closeContext(qryCtx);
END;
/

これにより、次のXML文書が生成されます。

SELECT * FROM temp_clob_tab;

RESULT
-------------------------------------------------------
<?xml version="1.0"?>
<ROWSET>
<EMPLOYEE>
<EMPLOYEE_ID>101</EMPLOYEE_ID>
<FIRST_NAME>Neena</FIRST_NAME>
<LAST_NAME>Kochhar</LAST_NAME>
<EMAIL>NKOCHHAR</EMAIL>
<PHONE_NUMBER>515.123.4568</PHONE_NUMBER>
<HIRE_DATE>21-SEP-05</HIRE_DATE>
<JOB_ID>AD_VP</JOB_ID>
<SALARY>17000</SALARY>
<MANAGER_ID>100</MANAGER_ID>
<DEPARTMENT_ID>90</DEPARTMENT_ID>
</EMPLOYEE>
</ROWSET>

1 row selected.

すべての行に対してXMLデータ全体を生成するかわりに、パッケージDBMS_XMLGENのフェッチ・インタフェースを使用して、1回に固定の行数を取り出すことができます。これによって特に行数が多い場合に、応答時間が短縮され、また結果のXMLにドキュメント・オブジェクト・モデル(DOM)Application Program Interface(API)を使用する必要があるアプリケーションのスケーリングに有効です。

例18-23では、DBMS_XMLGENを使用してHR.employees表から結果を取り出します。

例18-23 DBMS_XMLGEN: ページ区切りを使用した単純なXMLの生成(フェッチ)

-- Create a table to hold the results
CREATE TABLE temp_clob_tab (result clob);
DECLARE
qryCtx DBMS_XMLGEN.ctxHandle;
result CLOB;
BEGIN
-- Get the query context;
qryCtx := DBMS_XMLGEN.newContext('SELECT * FROM hr.employees');
-- Set the maximum number of rows to be 2
DBMS_XMLGEN.setMaxRows(qryCtx, 2);
LOOP
-- Get the result
result := DBMS_XMLGEN.getXML(qryCtx);
-- If no rows were processed, then quit
EXIT WHEN DBMS_XMLGEN.getNumRowsProcessed(qryCtx) = 0;

-- Do some processing with the lob data
--   Insert the results into a table.
--   You can print the lob out, output it to a stream,
--   put it in a queue, or do any other processing.
INSERT INTO temp_clob_tab VALUES(result);
END LOOP;
--close context
DBMS_XMLGEN.closeContext(qryCtx);
END;
/

SELECT * FROM temp_clob_tab WHERE rownum < 3;

RESULT
----------------------------------------------------------
<?xml version="1.0"?>
<ROWSET>
<ROW>
<EMPLOYEE_ID>100</EMPLOYEE_ID>
<FIRST_NAME>Steven</FIRST_NAME>
<LAST_NAME>King</LAST_NAME>
<EMAIL>SKING</EMAIL>
<PHONE_NUMBER>515.123.4567</PHONE_NUMBER>
<HIRE_DATE>17-JUN-03</HIRE_DATE>
<JOB_ID>AD_PRES</JOB_ID>
<SALARY>24000</SALARY>
<DEPARTMENT_ID>90</DEPARTMENT_ID>
</ROW>
<ROW>
<EMPLOYEE_ID>101</EMPLOYEE_ID>
<FIRST_NAME>Neena</FIRST_NAME>
<LAST_NAME>Kochhar</LAST_NAME>
<EMAIL>NKOCHHAR</EMAIL>
<PHONE_NUMBER>515.123.4568</PHONE_NUMBER>
<HIRE_DATE>21-SEP-05</HIRE_DATE>
<JOB_ID>AD_VP</JOB_ID>
<SALARY>17000</SALARY>
<MANAGER_ID>100</MANAGER_ID>
<DEPARTMENT_ID>90</DEPARTMENT_ID>
</ROW>
</ROWSET>

<?xml version="1.0"?>
<ROWSET>
<ROW>
<EMPLOYEE_ID>102</EMPLOYEE_ID>
<FIRST_NAME>Lex</FIRST_NAME>
<LAST_NAME>De Haan</LAST_NAME>
<EMAIL>LDEHAAN</EMAIL>
<PHONE_NUMBER>515.123.4569</PHONE_NUMBER>
<HIRE_DATE>13-JAN-01</HIRE_DATE>
<JOB_ID>AD_VP</JOB_ID>
<SALARY>17000</SALARY>
<MANAGER_ID>100</MANAGER_ID>
<DEPARTMENT_ID>90</DEPARTMENT_ID>
</ROW>
<ROW>
<EMPLOYEE_ID>103</EMPLOYEE_ID>
<FIRST_NAME>Alexander</FIRST_NAME>
<LAST_NAME>Hunold</LAST_NAME>
<EMAIL>AHUNOLD</EMAIL>
<PHONE_NUMBER>590.423.4567</PHONE_NUMBER>
<HIRE_DATE>03-JAN-06</HIRE_DATE>
<JOB_ID>IT_PROG</JOB_ID>
<SALARY>9000</SALARY>
<MANAGER_ID>102</MANAGER_ID>
<DEPARTMENT_ID>60</DEPARTMENT_ID>
</ROW>
</ROWSET>

2 rows selected.

例18-24では、DBMS_XMLGENとオブジェクト型を使用してネスト構造を表現しています。

例18-24 DBMS_XMLGEN: オブジェクト型を使用したXMLの生成

CREATE TABLE new_departments (department_id   NUMBER PRIMARY KEY,
department_name VARCHAR2(20));
CREATE TABLE new_employees (employee_id       NUMBER PRIMARY KEY,
last_name         VARCHAR2(20),
department_id     NUMBER REFERENCES new_departments);
CREATE TYPE emp_t AS OBJECT ("@employee_id"   NUMBER,
last_name        VARCHAR2(20));
/
INSERT INTO new_departments VALUES (10, 'SALES');
INSERT INTO new_departments VALUES (20, 'ACCOUNTING');
INSERT INTO new_employees   VALUES (30, 'Scott', 10);
INSERT INTO new_employees   VALUES (31, 'Mary',  10);
INSERT INTO new_employees   VALUES (40, 'John',  20);
INSERT INTO new_employees   VALUES (41, 'Jerry', 20);
COMMIT;
CREATE TYPE emplist_t AS TABLE OF emp_t;
/
CREATE TYPE dept_t AS OBJECT ("@department_id" NUMBER,
department_name  VARCHAR2(20),
emplist          emplist_t);
/
CREATE TABLE temp_clob_tab (result CLOB);
DECLARE
qryCtx DBMS_XMLGEN.ctxHandle;
result CLOB;
BEGIN
DBMS_XMLGEN.setRowTag(qryCtx, NULL);
qryCtx := DBMS_XMLGEN.newContext
('SELECT dept_t(department_id,
department_name,
cast(MULTISET
(SELECT e.employee_id, e.last_name
FROM new_employees e
WHERE e.department_id = d.department_id)
AS emplist_t))
AS deptxml
FROM new_departments d');
-- 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;

結果として戻されるXMLは、次のとおりです。

RESULT
--------------------------------------------
<?xml version="1.0"?>
<ROWSET>
<ROW>
<DEPTXML department_id="10">
<DEPARTMENT_NAME>SALES</DEPARTMENT_NAME>
<EMPLIST>
<EMP_T employee_id="30">
<LAST_NAME>Scott</LAST_NAME>
</EMP_T>
<EMP_T employee_id="31">
<LAST_NAME>Mary</LAST_NAME>
</EMP_T>
</EMPLIST>
</DEPTXML>
</ROW>
<ROW>
<DEPTXML department_id="20">
<DEPARTMENT_NAME>ACCOUNTING</DEPARTMENT_NAME>
<EMPLIST>
<EMP_T employee_id="40">
<LAST_NAME>John</LAST_NAME>
</EMP_T>
<EMP_T employee_id="41">
<LAST_NAME>Jerry</LAST_NAME>
</EMP_T>
</EMPLIST>
</DEPTXML>
</ROW>
</ROWSET>

1 row selected.

リレーショナル・データの場合、結果はネストされた要素がないXML文書になります。ネストしたXML構造にするには、オブジェクト・リレーショナル・データを使用します。この場合のマッピングは次のとおりです。

- オブジェクト型はXML要素をマップします。第7章「XML Schemaの格納と問合せ: 基本」を参照してください。

- 型の属性は、親要素のサブ要素にマップされます。

注意:
複雑な構造にするには、オブジェクト型を使用し、オブジェクト・ビューまたはオブジェクト表を作成します。正規マッピングを使用して、オブジェクト・インスタンスをXMLにマップしてください。
アットマーク(@)を列名または属性名で使用すると、マッピングでXMLの囲み要素の属性に変換されます。

ユーザー定義のデータ型インスタンスをDBMS_XMLGENファンクションに入力すると、ユーザー定義データ型インスタンスは正規マッピングを使用してXML文書にマップされます。ユーザー定義のデータ型の属性はXML要素にマップされます。アットマーク「@」で始まる名前の属性は、その前にある要素の属性にマップされます。

ユーザー定義のデータ型インスタンスを使用して、結果のXML文書内でネストできます。

たとえば、例18-25で定義されたempおよびdeptという2つの表を考えてみます。部門とその従業員のデータの階層ビューを生成するために、例18-25では、適切なオブジェクト型を定義してデータベース内に構造を作成します。

例18-25 DBMS_XMLGEN: ユーザー定義のデータ型インスタンスを使用したXMLの生成

CREATE TABLE dept (deptno NUMBER PRIMARY KEY, dname VARCHAR2(20));
CREATE TABLE emp (empno   NUMBER PRIMARY KEY, ename VARCHAR2(20),
deptno  NUMBER REFERENCES dept);

-- empno is preceded by an at-sign (@) to indicate that it must
-- be mapped as an attribute of the enclosing Employee element.
CREATE TYPE emp_t AS OBJECT ("@empno" NUMBER,  -- empno defined as attribute
ename   VARCHAR2(20));
/
INSERT INTO DEPT VALUES (10, 'Sports');
INSERT INTO DEPT VALUES(20, 'Accounting');
INSERT INTO EMP VALUES(200, 'John',  10);
INSERT INTO EMP VALUES(300, 'Jack',  10);
INSERT INTO EMP VALUES(400, 'Mary',  20);
INSERT INTO EMP VALUES(500, 'Jerry', 20);
COMMIT;
CREATE TYPE emplist_t AS TABLE OF emp_t;
/
CREATE TYPE dept_t AS OBJECT("@deptno" NUMBER,
dname     VARCHAR2(20),
emplist   emplist_t);
/
-- Department type dept_t contains a list of employees.
-- You can now query the employee and department tables and get
-- the result as an XML document, as follows:
CREATE TABLE temp_clob_tab (result CLOB);
DECLARE
qryCtx DBMS_XMLGEN.ctxHandle;
RESULT CLOB;
BEGIN
-- get query context
qryCtx := DBMS_XMLGEN.newContext(
'SELECT dept_t(deptno,
dname,
cast(MULTISET
(SELECT empno, ename FROM emp e WHERE e.deptno = d.deptno)
AS emplist_t))
AS deptxml
FROM dept d');
-- set maximum number of rows to 5
DBMS_XMLGEN.setMaxRows(qryCtx, 5);
-- set no row tag for this result, since there is a single ADT column
DBMS_XMLGEN.setRowTag(qryCtx, NULL);
LOOP
-- get result
result := DBMS_XMLGEN.getXML(qryCtx);
-- if there were no rows processed, then quit
EXIT WHEN DBMS_XMLGEN.getNumRowsProcessed(qryCtx) = 0;
-- do something with the result
INSERT INTO temp_clob_tab VALUES (result);
END LOOP;
END;
/

Oracle SQL関数castのMULTISETキーワードでは、その部門に勤務する従業員をリストとして扱い、castがリストを適切なコレクション型に割り当てます。部門インスタンスは、コンストラクタdept_tを使用して作成され、DBMS_XMLGENルーチンがオブジェクト・インスタンスのXMLデータを作成します。

SELECT * FROM temp_clob_tab;

RESULT
---------------------------------
<?xml version="1.0"?>
<ROWSET>
<DEPTXML deptno="10">
<DNAME>Sports</DNAME>
<EMPLIST>
<EMP_T empno="200">
<ENAME>John</ENAME>
</EMP_T>
<EMP_T empno="300">
<ENAME>Jack</ENAME>
</EMP_T>
</EMPLIST>
</DEPTXML>
<DEPTXML deptno="20">
<DNAME>Accounting</DNAME>
<EMPLIST>
<EMP_T empno="400">
<ENAME>Mary</ENAME>
</EMP_T>
<EMP_T empno="500">
<ENAME>Jerry</ENAME>
</EMP_T>
</EMPLIST>
</DEPTXML>
</ROWSET>

1 row selected.

デフォルト名ROWは、NULLに設定しているため存在しません。deptnoおよびempnoは囲み要素の属性になっています。

例18-26では、DBMS_XMLGEN.getXMLTypeを使用して、オブジェクト・ビューによって発注書をXML形式で生成します。

例18-26 DBMS_XMLGEN: XML発注書の生成

-- Create relational schema and define object views
-- DBMS_XMLGEN maps user-defined data-type attribute names that start
--    with an at-sign (@) to XML attributes

-- Purchase Order Object View Model

-- PhoneList varray object type
CREATE TYPE phonelist_vartyp AS VARRAY(10) OF VARCHAR2(20)
/
-- Address object type
CREATE TYPE address_typ AS OBJECT(Street VARCHAR2(200),
City   VARCHAR2(200),
State  CHAR(2),
Zip    VARCHAR2(20))
/
-- Customer object type
CREATE TYPE customer_typ AS OBJECT(CustNo    NUMBER,
CustName  VARCHAR2(200),
Address   address_typ,
PhoneList phonelist_vartyp)
/
-- StockItem object type
CREATE TYPE stockitem_typ AS OBJECT("@StockNo" NUMBER,
Price      NUMBER,
TaxRate    NUMBER)
/
-- LineItems object type
CREATE TYPE lineitem_typ AS OBJECT("@LineItemNo" NUMBER,
Item          stockitem_typ,
Quantity      NUMBER,
Discount      NUMBER)
/
-- LineItems ordered collection table
CREATE TYPE lineitems_ntabtyp AS TABLE OF lineitem_typ
/
-- Purchase Order object type
CREATE TYPE po_typ AUTHID CURRENT_USER
AS OBJECT(PONO            NUMBER,
Cust_ref        REF customer_typ,
OrderDate       DATE,
ShipDate        TIMESTAMP,
LineItems_ntab  lineitems_ntabtyp,
ShipToAddr      address_typ)
/
-- Create Purchase Order relational model tables
-- Customer table
CREATE TABLE customer_tab (CustNo     NUMBER NOT NULL,
CustName   VARCHAR2(200),
Street     VARCHAR2(200),
City       VARCHAR2(200),
State      CHAR(2),
Zip        VARCHAR2(20),
Phone1     VARCHAR2(20),
Phone2     VARCHAR2(20),
Phone3     VARCHAR2(20),
CONSTRAINT cust_pk PRIMARY KEY (CustNo));
-- Purchase Order table
CREATE TABLE po_tab (PONo       NUMBER,        /* purchase order number */
Custno     NUMBER     /*  foreign KEY referencing customer */
CONSTRAINT po_cust_fk REFERENCES customer_tab,
OrderDate  DATE,          /*  date of order */
ShipDate   TIMESTAMP,     /* date to be shipped */
ToStreet   VARCHAR2(200), /* shipto address */
ToCity     VARCHAR2(200),
ToState    CHAR(2),
ToZip      VARCHAR2(20),
CONSTRAINT po_pk PRIMARY KEY(PONo));
--Stock Table
CREATE TABLE stock_tab (StockNo NUMBER CONSTRAINT stock_uk UNIQUE,
Price   NUMBER,
TaxRate NUMBER);
--Line Items table
CREATE TABLE lineitems_tab (LineItemNo NUMBER,
PONo       NUMBER
CONSTRAINT li_po_fk REFERENCES po_tab,
StockNo    NUMBER,
Quantity   NUMBER,
Discount   NUMBER,
CONSTRAINT li_pk PRIMARY KEY (PONo, LineItemNo));
-- Create Object views
-- Customer Object View
CREATE OR REPLACE VIEW customer OF customer_typ
WITH OBJECT IDENTIFIER(CustNo)
AS SELECT c.custno, c.custname,
address_typ(c.street, c.city, c.state, c.zip),
phonelist_vartyp(phone1, phone2, phone3)
FROM customer_tab c;
--Purchase order view
CREATE OR REPLACE VIEW po OF po_typ
WITH OBJECT IDENTIFIER (PONo)
AS SELECT p.pono, make_ref(Customer, P.Custno), p.orderdate, p.shipdate,
cast(MULTISET
(SELECT lineitem_typ(l.lineitemno,
stockitem_typ(l.stockno, s.price,
s.taxrate),
l.quantity, l.discount)
FROM lineitems_tab l, stock_tab s
WHERE l.pono = p.pono AND s.stockno=l.stockno)
AS lineitems_ntabtyp),
address_typ(p.tostreet,p.tocity, p.tostate, p.tozip)
FROM po_tab p;
-- Create table with XMLType column to store purchase order in XML format
CREATE TABLE po_xml_tab (poid  NUMBER, podoc XMLType)
/
-- Populate data
-------------------
-- Establish Inventory
INSERT INTO stock_tab VALUES(1004, 6750.00, 2);
INSERT INTO stock_tab VALUES(1011, 4500.23, 2);
INSERT INTO stock_tab VALUES(1534, 2234.00, 2);
INSERT INTO stock_tab VALUES(1535, 3456.23, 2);
-- Register Customers
INSERT INTO customer_tab
VALUES (1, 'Jean Nance', '2 Avocet Drive',
'Redwood Shores', 'CA', '95054',
'415-555-1212', NULL, NULL);
INSERT INTO customer_tab
VALUES (2, 'John Nike', '323 College Drive',
'Edison', 'NJ', '08820',
'609-555-1212', '201-555-1212', NULL);
-- Place orders
INSERT INTO po_tab
VALUES (1001, 1, '10-APR-1997', '10-MAY-1997',
NULL, NULL, NULL, NULL);
INSERT INTO po_tab
VALUES (2001, 2, '20-APR-1997', '20-MAY-1997',
'55 Madison Ave', 'Madison', 'WI', '53715');
-- Detail line items
INSERT INTO lineitems_tab VALUES(01, 1001, 1534, 12,  0);
INSERT INTO lineitems_tab VALUES(02, 1001, 1535, 10, 10);
INSERT INTO lineitems_tab VALUES(01, 2001, 1004,  1,  0);
INSERT INTO lineitems_tab VALUES(02, 2001, 1011,  2,  1);

-- Use package DBMS_XMLGEN to generate purchase order in XML format
--   and store XMLType in table po_xml
DECLARE
qryCtx DBMS_XMLGEN.ctxHandle;
pxml XMLType;
cxml CLOB;
BEGIN
-- get query context;
qryCtx := DBMS_XMLGEN.newContext('SELECT pono,deref(cust_ref) customer,
p.orderdate,
p.shipdate,
lineitems_ntab lineitems,
shiptoaddr
FROM po p');
-- set maximum number of rows to be 1,
DBMS_XMLGEN.setMaxRows(qryCtx, 1);
-- set ROWSET tag to NULL and ROW tag to PurchaseOrder
DBMS_XMLGEN.setRowSetTag(qryCtx, NULL);
DBMS_XMLGEN.setRowTag(qryCtx, 'PurchaseOrder');
LOOP
-- get purchase order in XML format
pxml := DBMS_XMLGEN.getXMLType(qryCtx);
-- if there were no rows processed, then quit
EXIT WHEN DBMS_XMLGEN.getNumRowsProcessed(qryCtx) = 0;
-- Store XMLType po in po_xml table (get the pono out)
INSERT INTO po_xml_tab(poid, poDoc)
VALUES(XMLCast(XMLQuery('//PONO/text()' PASSING pxml RETURNING CONTENT)
AS NUMBER),
pxml);
END LOOP;
END;
/

この問合せによって、2件のXML発注書が生成されます。

SELECT XMLSerialize(DOCUMENT x.podoc AS CLOB) xpo FROM po_xml_tab x;

XPO
---------------------------------------------------
<PurchaseOrder>
<PONO>1001</PONO>
<CUSTOMER>
<CUSTNO>1</CUSTNO>
<CUSTNAME>Jean Nance</CUSTNAME>
<ADDRESS>
<STREET>2 Avocet Drive</STREET>
<CITY>Redwood Shores</CITY>
<STATE>CA</STATE>
<ZIP>95054</ZIP>
</ADDRESS>
<PHONELIST>
<VARCHAR2>415-555-1212</VARCHAR2>
</PHONELIST>
</CUSTOMER>
<ORDERDATE>10-APR-97</ORDERDATE>
<SHIPDATE>10-MAY-97 12.00.00.000000 AM</SHIPDATE>
<LINEITEMS>
<LINEITEM_TYP LineItemNo="1">
<ITEM StockNo="1534">
<PRICE>2234</PRICE>
<TAXRATE>2</TAXRATE>
</ITEM>
<QUANTITY>12</QUANTITY>
<DISCOUNT>0</DISCOUNT>
</LINEITEM_TYP>
<LINEITEM_TYP LineItemNo="2">
<ITEM StockNo="1535">
<PRICE>3456.23</PRICE>
<TAXRATE>2</TAXRATE>
</ITEM>
<QUANTITY>10</QUANTITY>
<DISCOUNT>10</DISCOUNT>
</LINEITEM_TYP>
</LINEITEMS>
<SHIPTOADDR/>
</PurchaseOrder>

<PurchaseOrder>
<PONO>2001</PONO>
<CUSTOMER>
<CUSTNO>2</CUSTNO>
<CUSTNAME>John Nike</CUSTNAME>
<ADDRESS>
<STREET>323 College Drive</STREET>
<CITY>Edison</CITY>
<STATE>NJ</STATE>
<ZIP>08820</ZIP>
</ADDRESS>
<PHONELIST>
<VARCHAR2>609-555-1212</VARCHAR2>
<VARCHAR2>201-555-1212</VARCHAR2>
</PHONELIST>
</CUSTOMER>
<ORDERDATE>20-APR-97</ORDERDATE>
<SHIPDATE>20-MAY-97 12.00.00.000000 AM</SHIPDATE>
<LINEITEMS>
<LINEITEM_TYP LineItemNo="1">
<ITEM StockNo="1004">
<PRICE>6750</PRICE>
<TAXRATE>2</TAXRATE>
</ITEM>
<QUANTITY>1</QUANTITY>
<DISCOUNT>0</DISCOUNT>
</LINEITEM_TYP>
<LINEITEM_TYP LineItemNo="2">
<ITEM StockNo="1011">
<PRICE>4500.23</PRICE>
<TAXRATE>2</TAXRATE>
</ITEM>
<QUANTITY>2</QUANTITY>
<DISCOUNT>1</DISCOUNT>
</LINEITEM_TYP>
</LINEITEMS>
<SHIPTOADDR>
<STREET>55 Madison Ave</STREET>
<CITY>Madison</CITY>
<STATE>WI</STATE>
<ZIP>53715</ZIP>
</SHIPTOADDR>
</PurchaseOrder>

2 rows selected.

例18-27では、問合せのカーソル変数の開き方、およびカーソル変数を使用してDBMS_XMLGENの新しいコンテキスト・ハンドルを作成する方法を説明します。

例18-27 DBMS_XMLGEN: REFカーソルからの新規コンテキスト・ハンドルの生成

CREATE TABLE emp_tab (emp_id       NUMBER PRIMARY KEY,
name         VARCHAR2(20),
dept_id      NUMBER);
Table created.
INSERT INTO emp_tab VALUES (122, 'Scott',  301);
1 row created.
INSERT INTO emp_tab VALUES (123, 'Mary',   472);
1 row created.
INSERT INTO emp_tab VALUES (124, 'John',   93);
1 row created.
INSERT INTO emp_tab VALUES (125, 'Howard', 488);
1 row created.
INSERT INTO emp_tab VALUES (126, 'Sue',    16);
1 row created.
COMMIT;

DECLARE
ctx     NUMBER;
maxrow  NUMBER;
xmldoc  CLOB;
refcur  SYS_REFCURSOR;
BEGIN
DBMS_LOB.createtemporary(xmldoc, TRUE);
maxrow := 3;
OPEN refcur FOR 'SELECT * FROM emp_tab WHERE ROWNUM <= :1' USING maxrow;
ctx := DBMS_XMLGEN.newContext(refcur);
-- xmldoc will have 3 rows
DBMS_XMLGEN.getXML(ctx, xmldoc, DBMS_XMLGEN.NONE);
DBMS_OUTPUT.put_line(xmldoc);
DBMS_LOB.freetemporary(xmldoc);
CLOSE refcur;
DBMS_XMLGEN.closeContext(ctx);
END;
/
<?xml version="1.0"?>
<ROWSET>
<ROW>
<EMP_ID>122</EMP_ID>
<NAME>Scott</NAME>
<DEPT_ID>301</DEPT_ID>
</ROW>
<ROW>
<EMP_ID>123</EMP_ID>
<NAME>Mary</NAME>
<DEPT_ID>472</DEPT_ID>
</ROW>
<ROW>
<EMP_ID>124</EMP_ID>
<NAME>John</NAME>
<DEPT_ID>93</DEPT_ID>
</ROW>
</ROWSET>

PL/SQL procedure successfully completed.

関連項目:
カーソル変数(REF CURSOR)の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

例18-28に、DBMS_XMLGENを使用する場合のNULL処理の指定方法を示します。

例18-28 DBMS_XMLGEN: NULL処理の指定

CREATE TABLE emp_tab (emp_id       NUMBER PRIMARY KEY,
name         VARCHAR2(20),
dept_id      NUMBER);
Table created.
INSERT INTO emp_tab VALUES (30, 'Scott', NULL);
1 row created.
INSERT INTO emp_tab VALUES (31, 'Mary', NULL);
1 row created.
INSERT INTO emp_tab VALUES (40, 'John', NULL);
1 row created.
COMMIT;
CREATE TABLE temp_clob_tab (result CLOB);
Table created.

DECLARE
qryCtx DBMS_XMLGEN.ctxHandle;
result CLOB;
BEGIN
qryCtx := DBMS_XMLGEN.newContext('SELECT * FROM emp_tab where name = :NAME');
-- Set the row header to be EMPLOYEE
DBMS_XMLGEN.setRowTag(qryCtx, 'EMPLOYEE');
-- Drop nulls
DBMS_XMLGEN.setBindValue(qryCtx, 'NAME', 'Scott');
DBMS_XMLGEN.setNullHandling(qryCtx, DBMS_XMLGEN.DROP_NULLS);
result := DBMS_XMLGEN.getXML(qryCtx);
INSERT INTO temp_clob_tab VALUES(result);
-- Null attribute
DBMS_XMLGEN.setBindValue(qryCtx, 'NAME', 'Mary');
DBMS_XMLGEN.setNullHandling(qryCtx, DBMS_XMLGEN.NULL_ATTR);
result := DBMS_XMLGEN.getXML(qryCtx);
INSERT INTO temp_clob_tab VALUES(result);
-- Empty tag
DBMS_XMLGEN.setBindValue(qryCtx, 'NAME', 'John');
DBMS_XMLGEN.setNullHandling(qryCtx, DBMS_XMLGEN.EMPTY_TAG);
result := DBMS_XMLGEN.getXML(qryCtx);
INSERT INTO temp_clob_tab VALUES(result);
--Close context
DBMS_XMLGEN.closeContext(qryCtx);
END;
/

PL/SQL procedure successfully completed.

SELECT * FROM temp_clob_tab;

RESULT
-------------------------------------------
<?xml version="1.0"?>
<ROWSET>
<EMPLOYEE>
<EMP_ID>30</EMP_ID>
<NAME>Scott</NAME>
</EMPLOYEE>
</ROWSET>

<?xml version="1.0"?>
<ROWSET xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance">
<EMPLOYEE>
<EMP_ID>31</EMP_ID>
<NAME>Mary</NAME>
<DEPT_ID xsi:nil = "true"/>
</EMPLOYEE>
</ROWSET>

<?xml version="1.0"?>
<ROWSET>
<EMPLOYEE>
<EMP_ID>40</EMP_ID>
<NAME>John</NAME>
<DEPT_ID/>
</EMPLOYEE>
</ROWSET>

3 rows selected.

関数DBMS_XMLGEN.newContextFromHierarchyは通常CONNECT BY句を使用して形成される階層問合せ文字列を引数として取ります。再帰要素が含まれる階層XML文書の生成に使用されるコンテキストを戻します。

階層問合せでは、レベル番号(CONNECT BY問合せを使用して生成される疑似列)とXMLTypeの2つの列が戻されます。レベルは、結果XML文書の階層内のXMLType値の位置を判断するために使用されます。

newContextFromHierarchyから作成されたコンテキストに対して、スキップ行数または最大行数を設定するとエラーになります。

例18-29では、DBMS_ XMLGEN.newContextFromHierarchyを使用して、管理者(従業員階層)を生成します。

例18-29 DBMS_XMLGEN: 階層問合せを使用した再帰XMLの生成

CREATE TABLE sqlx_display (id NUMBER, xmldoc XMLType);
Table created.

DECLARE
qryctx DBMS_XMLGEN.ctxhandle;
result XMLType;
BEGIN
qryctx :=
DBMS_XMLGEN.newContextFromHierarchy(
'SELECT level,
XMLElement("employees",
XMLElement("enumber", employee_id),
XMLElement("name", last_name),
XMLElement("Salary", salary),
XMLElement("Hiredate", hire_date))
FROM hr.employees
START WITH last_name=''De Haan'' CONNECT BY PRIOR employee_id=manager_id
ORDER SIBLINGS BY hire_date');
result := DBMS_XMLGEN.getxmltype(qryctx);
DBMS_OUTPUT.put_line('<result num rows>');
DBMS_OUTPUT.put_line(to_char(DBMS_XMLGEN.getNumRowsProcessed(qryctx)));
DBMS_OUTPUT.put_line('</result num rows>');
INSERT INTO sqlx_display VALUES (2, result);
COMMIT;
DBMS_XMLGEN.closecontext(qryctx);
END;
/
<result num rows>
6
</result num rows>
PL/SQL procedure successfully completed.

SELECT xmldoc FROM sqlx_display WHERE id = 2;

XMLDOC
-----------------------------------------------------
<?xml version="1.0"?>
<employees>
<enumber>102</enumber>
<name>De Haan</name>
<Salary>17000</Salary>
<Hiredate>2001-01-13</Hiredate>
<employees>
<enumber>103</enumber>
<name>Hunold</name>
<Salary>9000</Salary>
<Hiredate>2006-01-03</Hiredate>
<employees>
<enumber>105</enumber>
<name>Austin</name>
<Salary>4800</Salary>
<Hiredate>2005-06-25</Hiredate>
</employees>
<employees>
<enumber>106</enumber>
<name>Pataballa</name>
<Salary>4800</Salary>
<Hiredate>2006-02-05</Hiredate>
</employees>
<employees>
<enumber>107</enumber>
<name>Lorentz</name>
<Salary>4200</Salary>
<Hiredate>2007-02-07</Hiredate>
</employees>
<employees>
<enumber>104</enumber>
<name>Ernst</name>
<Salary>6000</Salary>
<Hiredate>2007-05-21</Hiredate>
</employees>
</employees>
</employees>

1 row selected.

デフォルトでは、ROWSETタグはNULLです。つまり、XML結果を囲むために使用されるデフォルトのROWSETタグはありません。ただし、次のように、setRowSetTagプロシージャを使用するとROWSETタグを明示的に設定できます。

CREATE TABLE gg (x XMLType);
Table created.

DECLARE
qryctx DBMS_XMLGEN.ctxhandle;
result CLOB;
BEGIN
qryctx := DBMS_XMLGEN.newContextFromHierarchy(
'SELECT level,
XMLElement("NAME", last_name) AS myname FROM hr.employees
CONNECT BY PRIOR employee_id=manager_id
START WITH employee_id = 102');
DBMS_XMLGEN.setRowSetTag(qryctx, 'mynum_hierarchy');
result:=DBMS_XMLGEN.getxml(qryctx);
DBMS_OUTPUT.put_line('<result num rows>');
DBMS_OUTPUT.put_line(to_char(DBMS_XMLGEN.getNumRowsProcessed(qryctx)));
DBMS_OUTPUT.put_line('</result num rows>');
INSERT INTO gg VALUES(XMLType(result));
COMMIT;
DBMS_XMLGEN.closecontext(qryctx);
END;
/
<result num rows>
6
</result num rows>
PL/SQL procedure successfully completed.

SELECT * FROM gg;

X
----------------------------------------------------------
<?xml version="1.0"?>
<mynum_hierarchy>
<NAME>De Haan
<NAME>Hunold
<NAME>Ernst</NAME>
<NAME>Austin</NAME>
<NAME>Pataballa</NAME>
<NAME>Lorentz</NAME>
</NAME>
</NAME>
</mynum_hierarchy>

1 row selected.

コンテキストの作成に使用する問合せ文字列にホスト変数が含まれている場合、問合せの実行前にPL/SQLメソッドsetBindValueを使用して、変数値を指定できます。例18-30に、これを示します。

例18-30 DBMS_XMLGEN: SETBINDVALUE()を使用した問合せ変数のバインド

-- Bind one variable
DECLARE
ctx NUMBER;
xmldoc CLOB;
BEGIN
ctx := DBMS_XMLGEN.newContext(
'SELECT * FROM employees WHERE employee_id = :NO');
DBMS_XMLGEN.setBindValue(ctx, 'NO', '145');
xmldoc := DBMS_XMLGEN.getXML(ctx);
DBMS_OUTPUT.put_line(xmldoc);
DBMS_XMLGEN.closeContext(ctx);
EXCEPTION
WHEN OTHERS THEN DBMS_XMLGEN.closeContext(ctx);
RAISE;
END;
/
<?xml version="1.0"?>
<ROWSET>
<ROW>
<EMPLOYEE_ID>145</EMPLOYEE_ID>
<FIRST_NAME>John</FIRST_NAME>
<LAST_NAME>Russell</LAST_NAME>
<EMAIL>JRUSSEL</EMAIL>
<PHONE_NUMBER>011.44.1344.429268</PHONE_NUMBER>
<HIRE_DATE>01-OCT-04</HIRE_DATE>
<JOB_ID>SA_MAN</JOB_ID>
<SALARY>14000</SALARY>
<COMMISSION_PCT>.4</COMMISSION_PCT>
<MANAGER_ID>100</MANAGER_ID>
<DEPARTMENT_ID>80</DEPARTMENT_ID>
</ROW>
</ROWSET>

PL/SQL procedure successfully completed.

-- Bind one variable twice with different values
DECLARE
ctx NUMBER;
xmldoc CLOB;
BEGIN
ctx := DBMS_XMLGEN.newContext('SELECT * FROM employees
WHERE hire_date = :MDATE');
DBMS_XMLGEN.setBindValue(ctx, 'MDATE', '01-OCT-04');
xmldoc := DBMS_XMLGEN.getXML(ctx);
DBMS_OUTPUT.put_line(xmldoc);
DBMS_XMLGEN.setBindValue(ctx, 'MDATE', '10-MAR-05');
xmldoc := DBMS_XMLGEN.getXML(ctx);
DBMS_OUTPUT.put_line(xmldoc);
DBMS_XMLGEN.closeContext(ctx);
EXCEPTION
WHEN OTHERS THEN DBMS_XMLGEN.closeContext(ctx);
RAISE;
END;
/
<?xml version="1.0"?>
<ROWSET>
<ROW>
<EMPLOYEE_ID>145</EMPLOYEE_ID>
<FIRST_NAME>John</FIRST_NAME>
<LAST_NAME>Russell</LAST_NAME>
<EMAIL>JRUSSEL</EMAIL>
<PHONE_NUMBER>011.44.1344.429268</PHONE_NUMBER>
<HIRE_DATE>01-OCT-04</HIRE_DATE>
<JOB_ID>SA_MAN</JOB_ID>
<SALARY>14000</SALARY>
<COMMISSION_PCT>.4</COMMISSION_PCT>
<MANAGER_ID>100</MANAGER_ID>
<DEPARTMENT_ID>80</DEPARTMENT_ID>
</ROW>
</ROWSET>

<?xml version="1.0"?>
<ROWSET>
<ROW>
<EMPLOYEE_ID>147</EMPLOYEE_ID>
<FIRST_NAME>Alberto</FIRST_NAME>
<LAST_NAME>Errazuriz</LAST_NAME>
<EMAIL>AERRAZUR</EMAIL>
<PHONE_NUMBER>011.44.1344.429278</PHONE_NUMBER>
<HIRE_DATE>10-MAR-05</HIRE_DATE>
<JOB_ID>SA_MAN</JOB_ID>
<SALARY>12000</SALARY>
<COMMISSION_PCT>.3</COMMISSION_PCT>
<MANAGER_ID>100</MANAGER_ID>
<DEPARTMENT_ID>80</DEPARTMENT_ID>
</ROW>
<ROW>
<EMPLOYEE_ID>159</EMPLOYEE_ID>
<FIRST_NAME>Lindsey</FIRST_NAME>
<LAST_NAME>Smith</LAST_NAME>
<EMAIL>LSMITH</EMAIL>
<PHONE_NUMBER>011.44.1345.729268</PHONE_NUMBER>
<HIRE_DATE>10-MAR-97</HIRE_DATE>
<JOB_ID>SA_REP</JOB_ID>
<SALARY>8000</SALARY>
<COMMISSION_PCT>.3</COMMISSION_PCT>
<MANAGER_ID>146</MANAGER_ID>
<DEPARTMENT_ID>80</DEPARTMENT_ID>
</ROW>
</ROWSET>
PL/SQL procedure successfully completed.
-- Bind two variables
DECLARE
ctx NUMBER;
xmldoc CLOB;
BEGIN
ctx := DBMS_XMLGEN.newContext('SELECT * FROM employees
WHERE employee_id = :NO
AND hire_date = :MDATE');
DBMS_XMLGEN.setBindValue(ctx, 'NO', '145');
DBMS_XMLGEN.setBindValue(ctx, 'MDATE', '01-OCT-04');
xmldoc := DBMS_XMLGEN.getXML(ctx);
DBMS_OUTPUT.put_line(xmldoc);
DBMS_XMLGEN.closeContext(ctx);
EXCEPTION
WHEN OTHERS THEN DBMS_XMLGEN.closeContext(ctx);
RAISE;
END;
/
<?xml version="1.0"?>
<ROWSET>
<ROW>
<EMPLOYEE_ID>145</EMPLOYEE_ID>
<FIRST_NAME>John</FIRST_NAME>
<LAST_NAME>Russell</LAST_NAME>
<EMAIL>JRUSSEL</EMAIL>
<PHONE_NUMBER>011.44.1344.429268</PHONE_NUMBER>
<HIRE_DATE>01-OCT-04</HIRE_DATE>
<JOB_ID>SA_MAN</JOB_ID>
<SALARY>14000</SALARY>
<COMMISSION_PCT>.4</COMMISSION_PCT>
<MANAGER_ID>100</MANAGER_ID>
<DEPARTMENT_ID>80</DEPARTMENT_ID>
</ROW>
</ROWSET>
PL/SQL procedure successfully completed.

SYS_XMLGEN Oracle SQL関数

Oracle SQL関数sys_XMLGenは、SQL/XML標準関数XMLElementに類似していますが、単一の引数を取り、結果をXMLTypeインスタンスに変換します。他のXML生成関数とは異なり、sys_XMLGenは常に整形式のXML文書を戻します。また、問合せレベルで機能するDBMS_XMLGENとは異なり、ssys_XMLGenは行レベルで機能し、各行に対してXML文書を戻します。

例18-31では、sys_XMLGenを使用してXMLインスタンスを問い合せ、リレーショナル・データの各行にXML文書を戻します。

例18-31 SYS_XMLGENを使用したXMLデータの作成

SELECT sys_XMLGen(employee_id) AS "result"
FROM employees WHERE first_name LIKE 'John%';

結果のXML文書は次のようになります。

result
---------------
<?xml version="1.0"?>
<EMPLOYEE_ID>110</EMPLOYEE_ID>

<?xml version="1.0"?>
<EMPLOYEE_ID>139</EMPLOYEE_ID>

<?xml version="1.0"?>
<EMPLOYEE_ID>145</EMPLOYEE_ID>

3 rows selected.

SYS_XMLGENの構文

Oracle SQL関数sys_XMLGenは、XML文書に変換するスカラー値の引数、オブジェクト型またはXMLTypeインスタンスを取ります。また、結果のXML文書のフォーマット・オプションを指定するオプションのXMLFormatオブジェクト(以前のXMLGenFormatType)も取ります(オプション)。この構文を図18-14に示します。

図18-14 SYS_XMLGENの構文

式exprの評価結果はデータベースの特定の行と列です。これは、スカラー値、ユーザー定義のデータ型インスタンス、またはXMLTypeインスタンスのいずれかです。

- exprの評価結果がスカラー値の場合、この関数は、スカラー値を含むXML要素を戻します。

- exprの評価結果がユーザー定義のデータ型インスタンスの場合、ユーザー定義の型属性をXML要素にマップします。

- exprの評価結果がXMLTypeインスタンスの場合、この関数は、デフォルトのタグ名がROWであるXML要素で文書を囲みます。

デフォルトでは、XML文書の要素はexprと一致します。たとえば、exprが列名に変換される場合、XMLの囲み要素の名前は列名と同じになります。XML文書を別の方法でフォーマットする場合は、XMLFormatオブジェクトのインスタンスであるfmtを指定します。

問合せ内でWHEREをsys_XMLGenとともに使用して<ROW/>タグを出力しないようにすると、NULL値が表示されません。

SELECT sys_XMLGen(x) FROM table_name WHERE x IS NOT NULL;

例18-32では、表HR.employeesから、従業員(employee_id値が110)の名前を取得し、FIRST_NAME要素を持つXML文書を含むXMLTypeインスタンスを生成します。

例18-32 SYS_XMLGEN: データベース列からのXML要素の生成

SELECT XMLSerialize(DOCUMENT SYS_XMLGEN(first_name))
FROM employees WHERE employee_id = 110;

XMLSERIALIZE(DOCUMENTSYS_XMLGEN(FIRST_NAME))
--------------------------------------------
<?xml version="1.0"?>
<FIRST_NAME>John</FIRST_NAME>

1 row selected.

Oracle SQL関数SYS_XMLGENを使用する利点

Oracle SQL関数sys_XMLGenには次の利点があります。

- SQL問合せ内でXMLインスタンスを作成し、問い合せることができます。

- オブジェクト・リレーショナル・インフラストラクチャを使用して、簡単なリレーショナル表から複雑なネストしたXMLインスタンスを作成できます。たとえば、オブジェクト型でsys_XMLGenを使用した場合のXMLTypeビューを使用すると、Oracle XML DBでは、可能なかぎりこれらの問合せがリライトされます。第8章「構造化記憶域のXPathリライト」も参照してください。

sys_XMLGenは、ユーザー定義のデータ型インスタンス、スカラー値、またはXMLTypeインスタンスからXML文書を作成します。戻り値はXMLTypeインスタンスです。

sys_XMLGenは、結果をカスタマイズするのに使用するオプションのXMLFormatオブジェクトも引数として受け入れます。書式設定オブジェクトがNULLの場合は、デフォルトのマッピング動作が使用されます。

XMLFormatオブジェクト型の使用

XMLFormatを使用して、Oracle SQL関数sys_XMLGenおよびsys_XMLAggに対してフォーマット引数を指定できます。

関数sys_XMLGenはXML文書を含むXMLTypeインスタンスを戻します。Oracle Databaseには、sys_XMLGenの出力をフォーマットするXMLFormatオブジェクトが用意されています。

表18-2に、オブジェクトXMLFormatの属性をリストします。

表18-2 XMLFormatオブジェクトの属性

属性

データ型

用途

enclTag

VARCHAR2(100)

sys_XMLGen関数の結果の囲みタグ名です。関数の入力が列名の場合、その列名がデフォルト値として使用されます。それ以外の場合、デフォルト値はROWSETです。schemaTypeがUSE_GIVEN_SCHEMAに設定されている場合、この属性によってXMLスキーマ要素の名前も指定されます。

schemaType

VARCHAR2(100)

出力ドキュメントに対するスキーマ生成の型です。有効な値は、NO_SCHEMAおよびUSE_GIVEN_SCHEMAです。デフォルト値は、NO_SCHEMAです。

schemaName

VARCHAR2(4000)

schemaTypeがUSE_GIVEN_SCHEMAである場合のターゲット・スキーマの名前です。schemaNameを指定した場合、囲みタグが要素名として使用されます。

targetNameSpace

VARCHAR2(4000)

スキーマ(schemaTypeがGEN_SCHEMA_*またはUSE_GIVEN_SCHEMA)を指定した場合のターゲットの名前空間です。

dburl

VARCHAR2(2000)

WITH_SCHEMAを指定した場合に使用するデータベースのURLです。この属性を指定しない場合、型のURLが相対参照URLとして宣言されます。

processingIns

VARCHAR2(4000)

ユーザー指定の処理命令です。関数出力の先頭の要素の前に追加されるユーザーの処理命令です。

PL/SQLメソッドcreateFormatを使用すると、XMLFormatオブジェクトを実装できます。オブジェクトXMLFormat()のメソッドcreateFormatは、囲み要素名、XML Schema型、およびXML Schema名を引数に取ります。他のXMLFormat属性にはデフォルト値が用意されています。

関連項目:

- 例18-35は、createFormatを使用してsys_XMLGenによる出力であるルート要素に名前を付ける例を示しています。

- sys_XMLGenおよびXMLFormatオブジェクトの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

SQL関数sys_XMLGenは、スカラー値を、そのスカラー値を含む要素に変換します。例18-33の問合せに、これを示します。employee_id値を要素EMPLOYEE_IDのコンテンツとして含むXML文書を戻します。

例18-33 SYS_XMLGEN: スカラー値のXML要素コンテンツへの変換

SELECT sys_XMLGen(employee_id) FROM hr.employees WHERE ROWNUM < 2;

SYS_XMLGEN(EMPLOYEE_ID)
---------------------------
<?xml version="1.0"?>
<EMPLOYEE_ID>100</EMPLOYEE_ID>

1 row selected.

囲み要素名(この例ではEMPLOYEE_ID)はsys_XMLGenに渡された列名から導出されます。問合せ結果は、完全なXML文書に対応するXMLTypeインスタンスを含む単独の行です。

例18-33で、列名EMPLOYEE_IDはXML要素名のデフォルトとして使用されています。列名を直接導出できない場合は、例18-34に示すように、デフォルト名ROWがかわりに使用されます。

例18-34 SYS_XMLGEN: デフォルトの要素名ROW

SELECT sys_XMLGen(employee_id*2) FROM hr.employees WHERE ROWNUM < 2;

SYS_XMLGEN(EMPLOYEE_ID*2)
-------------------------
<?xml version="1.0"?>
<ROW>200</ROW>

1 row selected.

例18-34では、sys_XMLGenの引数が単純な列名ではないため、出力要素タグの名前をそのまま列名にできません。このためデフォルトの要素名ROWが使用されます。

デフォルトのROWタグは、XMLFormatオブジェクトを2番目のsys_XMLGen引数に指定することによって変更できます。例18-35にこれを示します。問合せがフォーマット引数をsys_XMLGenに渡し、要素の名前を明示的に指定します。

例18-35 SYS_XMLGENとXMLFormatを使用したデフォルトの要素名のオーバーライド

SELECT XMLSerialize(DOCUMENT
SYS_XMLGEN(employee_id*2,
XMLFormat.createformat('DOUBLE_ID'))
AS CLOB)
FROM hr.employees WHERE ROWNUM < 2;

XMLSERIALIZE(DOCUMENTSYS_XMLGEN(EMPLOYEE_ID*2,XMLFORMAT.CREATEFORMAT('DOUBLE_ID'
--------------------------------------------------------------------------------
<?xml version="1.0"?>
<DOUBLE_ID>200</DOUBLE_ID>

1 row selected.

ユーザー定義のデータ型インスタンスをsys_XMLGenに引数として指定すると、インスタンスはXML文書に正規マッピングされます。このマッピングでは、ユーザー定義のデータ型の属性はXML要素にマップされます。

アットマーク「@」で始まる名前のデータ型属性は、その前にあるXML要素の属性にマップされます。ユーザー定義のデータ型インスタンスを使用して、結果のXML文書内でネストを取得できます。

例18-36に、「DBMS_XMLGENを使用したXMLの生成」の項の従業員と部門の例の階層XMLを生成する方法を示します。

例18-36 SYS_XMLGEN: ユーザー定義のデータ型インスタンスのXMLへの変換

CREATE OR REPLACE TYPE hr.emp_t AS OBJECT(empno    NUMBER(6),
ename    VARCHAR2(25),
job      VARCHAR2(10),
mgr      NUMBER(6),
hiredate DATE,
sal      NUMBER(8,2),
comm     NUMBER(2,2));
/
Type created.
CREATE OR REPLACE TYPE hr.emplist_t AS TABLE OF emp_t;
/
Type created.
CREATE OR REPLACE TYPE hr.dept_t AS OBJECT(deptno  NUMBER(4),
dname   VARCHAR2(30),
loc     VARCHAR2(4),
emplist emplist_t);
/
Type created.

SELECT XMLSerialize(
DOCUMENT
SYS_XMLGEN(
dept_t(department_id,
department_name,
d.location_id,
cast(MULTISET
(SELECT emp_t(e.employee_id, e.last_name,
e.job_id, e.manager_id, e.hire_date,
e.salary, e.commission_pct)
FROM hr.employees e
WHERE e.department_id = d.department_id)
AS emplist_t)))
AS CLOB)
AS deptxml
FROM hr.departments d WHERE department_id = 10 OR department_id = 20;

Oracle SQL関数castのMULTISETキーワードでは、その部門に勤務する従業員をリストとして扱い、castによって適切なコレクション型に割り当てられます。sys_XMLGenは、オブジェクト・インスタンスのXMLデータを作成します。

結果は次のようになります。関数が入力オペランドの名前を直接推論できないため、デフォルト名ROWが存在します。

DEPTXML
-------------------------------------
<?xml version="1.0"?>
<ROW>
<DEPTNO>10</DEPTNO>
<DNAME>Administration</DNAME>
<LOC>1700</LOC>
<EMPLIST>
<EMP_T>
<EMPNO>200</EMPNO>
<ENAME>Whalen</ENAME>
<JOB>AD_ASST</JOB>
<MGR>101</MGR>
<HIREDATE>17-SEP-03</HIREDATE>
<SAL>4400</SAL>
</EMP_T>
</EMPLIST>
</ROW>

<?xml version="1.0"?>
<ROW>
<DEPTNO>20</DEPTNO>
<DNAME>Marketing</DNAME>
<LOC>1800</LOC>
<EMPLIST>
<EMP_T>
<EMPNO>201</EMPNO>
<ENAME>Hartstein</ENAME>
<JOB>MK_MAN</JOB>
<MGR>100</MGR>
<HIREDATE>17-FEB-04</HIREDATE>
<SAL>13000</SAL>
</EMP_T>
<EMP_T>
<EMPNO>202</EMPNO>
<ENAME>Fay</ENAME>
<JOB>MK_REP</JOB>
<MGR>201</MGR>
<HIREDATE>17-AUG-05</HIREDATE>
<SAL>6000</SAL>
</EMP_T>
</EMPLIST>
</ROW>

2 rows selected.

注意:
前の例から、SQL関数sys_XMLGenとPL/SQLパッケージDBMS_XMLGENの違いは明確です。関数sys_XMLGen はSQL問合せの内部で動作し、行内の式および列を操作します。パッケージDBMS_XMLGENは、結果セット全体で動作します。

XML文書をsys_XMLGenに渡す場合、この関数は、タグ名がデフォルトのROWである要素、またはXMLFormat書式設定オブジェクトを介して渡される名前で、その文書(またはフラグメント)を囲みます。この機能を使用して、XMLフラグメントを整形式の文書に変換できます。例18-37に、これを示します。

例18-37 SYS_XMLGEN: XMLTypeインスタンスの変換

CREATE TABLE po_xml_tab (podoc XMLType);
Table created.

INSERT INTO po_xml_tab VALUES (XMLType('<DOCUMENT>
<EMPLOYEE>
<ENAME>John</ENAME>
<EMPNO>200</EMPNO>
</EMPLOYEE>
<EMPLOYEE>
<ENAME>Jack</ENAME>
<EMPNO>400</EMPNO>
</EMPLOYEE>
<EMPLOYEE>
<ENAME>Joseph</ENAME>
<EMPNO>300</EMPNO>
</EMPLOYEE>
</DOCUMENT>'));
1 row created.
COMMIT;

この問合せはENAME要素を抽出します。

SELECT XMLQuery('/DOCUMENT/EMPLOYEE/ENAME' PASSING e.podoc RETURNING CONTENT)
FROM po_xml_tab e;

問合せの結果はXML文書フラグメントです(ここではわかりやすくするためフォーマット出力しています)。

<ENAME>John</ENAME>
<ENAME>Jack</ENAME>
<ENAME>Joseph</ENAME>

このフラグメントを有効なXML文書にするには、次のように、sys_XMLGenをコールして、フラグメントをルート要素で囲みます。

SELECT XMLSerialize(DOCUMENT
sys_XMLGen(XMLQuery('/DOCUMENT/EMPLOYEE/ENAME'
PASSING e.podoc RETURNING CONTENT))
AS CLOB)
FROM po_xml_tab e;

これによって、次のように、フラグメントの前後に要素ROWが置かれます(ここではわかりやすくするためフォーマット出力しています)。

<?xml version="1.0"?>
<ROW>
<ENAME>John</ENAME>
<ENAME>Jack</ENAME>
<ENAME>Joseph</ENAME>
</ROW>

注意:
sys_XMLGenへの入力が列の場合、その列名がデフォルトの要素名として使用されます。要素名は、XMLFormat書式設定オブジェクトを2番目の引数としてsys_XMLGenに渡すことで変更できます。「XMLFormatオブジェクト型の使用」を参照してください。

例18-38では、オブジェクト・ビューでsys_XMLGenを使用する方法を示します(ここで定義されていないエンティティは、例18-26のコードを参照してください)。

例18-38 オブジェクト・ビューでのSYS_XMLGENの使用

-- Create purchase order object type
CREATE OR REPLACE TYPE po_typ AUTHID CURRENT_USER
AS OBJECT(pono            NUMBER,
customer        customer_typ,
orderdate       DATE,
shipdate        TIMESTAMP,
lineitems_ntab  lineitems_ntabtyp,
shiptoaddr      address_typ)
/
--Purchase order view
CREATE OR REPLACE VIEW po OF po_typ
WITH OBJECT IDENTIFIER (PONO)
AS SELECT p.pono, customer_typ(p.custno, c.custname, c.address, c.phonelist),
p.orderdate, p.shipdate,
cast(MULTISET
(SELECT lineitem_typ(l.lineitemno,
stockitem_typ(l.stockno, s.price,
s.taxrate),
l.quantity, l.discount)
FROM lineitems_tab l, stock_tab s
WHERE l.pono = p.pono AND s.stockno=l.stockno)
AS lineitems_ntabtyp),
address_typ(p.tostreet, p.tocity, p.tostate, p.tozip)
FROM po_tab p, customer c
WHERE p.custno=c.custno;

-- Use sys_XMLGen to generate PO in XML format
SELECT XMLSerialize(DOCUMENT
SYS_XMLGEN(OBJECT_VALUE,
XMLFormat.createFormat('PurchaseOrder'))
AS CLOB) PO
FROM po p WHERE p.pono=1001;

この問合せは発注書をXML形式で戻します。

PO
----------------------------------------------
<?xml version="1.0"?>
<PurchaseOrder>
<PONO>1001</PONO>
<CUSTOMER>
<CUSTNO>1</CUSTNO>
<CUSTNAME>Jean Nance</CUSTNAME>
<ADDRESS>
<STREET>2 Avocet Drive</STREET>
<CITY>Redwood Shores</CITY>
<STATE>CA</STATE>
<ZIP>95054</ZIP>
</ADDRESS>
<PHONELIST>
<VARCHAR2>415-555-1212</VARCHAR2>
</PHONELIST>
</CUSTOMER>
<ORDERDATE>10-APR-97</ORDERDATE>
<SHIPDATE>10-MAY-97 12.00.00.000000 AM</SHIPDATE>
<LINEITEMS_NTAB>
<LINEITEM_TYP LineItemNo="1">
<ITEM StockNo="1534">
<PRICE>2234</PRICE>
<TAXRATE>2</TAXRATE>
</ITEM>
<QUANTITY>12</QUANTITY>
<DISCOUNT>0</DISCOUNT>
</LINEITEM_TYP>
<LINEITEM_TYP LineItemNo="2">
<ITEM StockNo="1535">
<PRICE>3456.23</PRICE>
<TAXRATE>2</TAXRATE>
</ITEM>
<QUANTITY>10</QUANTITY>
<DISCOUNT>10</DISCOUNT>
</LINEITEM_TYP>
</LINEITEMS_NTAB>
<SHIPTOADDR/>
</PurchaseOrder>

1 row selected.

SYS_XMLAGG Oracle SQL関数

Oracle SQL関数sys_XMLAggは、式により表されるすべてのXML文書またはフラグメントを集計し、単一のXML文書を生成します。この関数は、デフォルト名ROWSETの新しい要素の式の結果を囲みます。

Oracle関数sys_XMLAggはSQL/XML標準関数sys_XMLAggに類似していますが、XMLAggは単一のノードを戻し、XMLFormatパラメータを取ります。そのパラメータを使用して結果のXML文書を様々な方法でフォーマットできます。

図18-15 SYS_XMLAGGの構文

関連項目:
『Oracle Database SQL言語リファレンス』

Oracle XML DBを使用してXMLを生成する場合のガイドライン

この項では、Oracle XML DBを使用してXMLを生成する場合の追加のガイドラインを示します。

XMLAGG ORDER BY句を使用して、問合せ結果を集計前に順序付けする方法

集計前にXMLAgg ORDER BY句を使用するには、最初のXMLAGG引数の後にORDER BY句を指定します。これを例18-39に示します。

例18-39 XMLAGG ORDER BY句の使用

CREATE TABLE dev_tab (dev         NUMBER,
dev_total   NUMBER,
devname     VARCHAR2(20));
Table created.
INSERT INTO dev_tab VALUES (16, 5,  'Alexis');
1 row created.
INSERT INTO dev_tab VALUES (2,  14, 'Han');
1 row created.
INSERT INTO dev_tab VALUES (1,  2,  'Jess');
1 row created.
INSERT INTO dev_tab VALUES (9,  88, 'Kurt');
1 row created.
COMMIT;

次の問合せの結果は、dev列の順に従って集計されます。(ここではわかりやすいように、この結果をフォーマット出力しています。)

SELECT XMLAgg(XMLElement("Dev",
XMLAttributes(dev AS "id", dev_total AS "total"),
devname)
ORDER BY dev)
FROM tab1 dev_total;

XMLAGG(XMLELEMENT("DEV",XMLATTRIBUTES(DEVAS"ID",DEV_TOTALAS"TOTAL"),DEVNAME)ORDE
--------------------------------------------------------------------------------
<Dev id="1" total="2">Jess</Dev>
<Dev id="2" total="14">Han</Dev>
<Dev id="9" total="88">Kurt</Dev>
<Dev id="16" total="5">Alexis</Dev>

1 row selected.

XMLTABLEを使用して行セットを戻す方法

標準SQL/XML関数XMLTableを使用し、例18-40のように、複数の行として抽出された文書の関連する部分の行セットを戻します。

例18-40 XMLTABLEを使用して行セットを戻す方法

CONNECT oe
Enter password: password

Connected.

SELECT item.descr, item.partid
FROM purchaseorder,
XMLTable('$p/PurchaseOrder/LineItems/LineItem' PASSING OBJECT_VALUE
COLUMNS descr  VARCHAR2(256) PATH 'Description',
partid VARCHAR2(14)  PATH 'Part/@Id') item
WHERE item.partid = '715515012027'
OR item.partid = '715515011921'
ORDER BY partid;

この例では、説明とPart IDのみを含む行セットが、Part IDの順序で戻されます。

DESCR
--------------
PARTID
--------------
My Man Godfrey
715515011921

My Man Godfrey
715515011921

My Man Godfrey
715515011921

My Man Godfrey
715515011921

My Man Godfrey
715515011921

My Man Godfrey
715515011921

My Man Godfrey
715515011921

Mona Lisa
715515012027

Mona Lisa
715515012027

Mona Lisa
715515012027

Mona Lisa
715515012027

Mona Lisa
715515012027

Mona Lisa
715515012027

Mona Lisa
715515012027

Mona Lisa
715515012027

Mona Lisa
715515012027

16 rows selected.

脚注の凡例

脚注 1: SQL/XML標準では、引数data-typeが存在することが必須ですが、Oracle XML DBでのこの標準の実装では、便宜性を考慮してオプションとなっています。

19 XMLTypeビュー

この章では、XMLTypeビューを作成および使用する方法を説明します。内容は次のとおりです。

- XMLTypeビューの概要

- XML Schemaに基づかないXMLTypeビューの作成

- XML Schemaに基づくXMLTypeビューの作成

- XMLType表からのXMLTypeビューの作成

- SQL関数REFを使用したXMLTypeビュー・オブジェクトの参照

- XMLTypeビューでのデータ操作言語(DML)

XMLTypeビューの概要

XMLTypeビューは、既存のリレーショナル・データおよびオブジェクト・リレーショナル・データをXML形式でラップします。XMLTypeビューを使用する主なメリットは次のとおりです。

- 基本のレガシー・データを移行せずに、XML Schema機能を使用するOracle XML DBのXML機能を使用できます。

- XMLTypeビューでは、XMLType表で使用可能なオブジェクト・リレーショナル記憶域、CLOB記憶域、バイナリXML記憶域の他に、様々な形式の記憶域を使用できます。

XMLTypeビューは、オブジェクト・ビューに類似しています。XMLTypeビューの各行は、XMLTypeインスタンスに対応しています。ビュー内の各行を一意に識別するためのオブジェクト識別子は、SQL/XML関数XMLCastおよびXMLQuery()を使用して作成できます。

この章では、XML Schemaとは、W3CのXML Schema 1.0勧告(http://www.w3.org/XML/Schema)のことを指します。

XMLTypeビューには2つのタイプがあります。

- XML Schemaに基づかないXMLTypeビュー。これらのビューは特定のXML Schemaに準拠しません。

- XML Schemaに基づくXMLTypeビュー。XMLType表に関して、特定のXML Schemaに準拠するXMLTypeビューは、XML Schemaに基づくXMLTypeビューと呼びます。これらのビューでは、XML Schemaに基づかないXMLTypeビューより厳密な型指定ができます。

XMLTypeビューに対する問合せのXPathリライトは、XML Schemaに基づくXMLTypeビューとXML Schemaに基づかないXMLTypeビューの両方で可能です。XPathリライトの詳細は、第8章「構造化記憶域のXPathリライト」で説明しています。

XML Schemaに基づくXMLTypeビューを作成するには、最初にXML Schemaを登録します。ビューがオブジェクト・ビューである場合、つまりオブジェクト型を使用して構成されている場合、XML Schemaには、XMLとSQLオブジェクト型の間の双方向マッピングを表す注釈が必要です。その後、適切なSQLオブジェクト型のインスタンスを構築する基礎となる問合せを指定することによって、登録されたXML Schemaに準拠するXMLTypeビューを作成できます。

関連項目:

- 「リレーショナル・ビューを使用したOracle XML DB内のXMLデータへのアクセス」

- 第7章「XML Schemaの格納と問合せ: 基本」

XMLTypeビューは、次のいずれかの方法で作成できます。

- XMLElement、XMLForest、XMLConcat、XMLAggなどのSQL/XMLパブリッシング関数に基づいて構成する方法。SQL/XMLパブリッシング関数を使用すると、XML Schemaに基づかないXMLTypeビューとXML Schemaに基づくXMLTypeビューの両方を構成できます。これによって、リレーショナル・レガシー・データをXMLに物理的に移行せずに、基礎となるリレーショナル表から直接XMLTypeビューを構成できます。ただし、XML Schemaに基づくXMLTypeビューを構成するには、XML Schemaを登録する必要があり、SQL/XMLパブリッシング関数によって生成されたXML値はXML Schemaに制限される必要があります。

- オブジェクト型、オブジェクト・ビューおよびOracle SQL関数sys_XMLGenに基づいて構成する方法。XML Schemaに基づかないXMLTypeビューは、オブジェクト型、オブジェクト・ビューおよび関数sys_XMLGenを使用して構成できます。XML Schemaに基づくXMLTypeビューは、オブジェクト型およびオブジェクト・ビューを使用して構成できます。これによって、リレーショナルまたはオブジェクト・リレーショナルのレガシー・データをXMLに物理的に移行せずに、基礎となるリレーショナル表またはオブジェクト・リレーショナル表から直接XMLTypeビューを構成できます。XML Schemaに基づかないXMLTypeビューの作成では、既存のオブジェクト型またはオブジェクト・ビューに対してsys_XMLGenを使用する必要があります。XML Schemaに基づくXMLTypeビューでは、既存のオブジェクト型へのマッピングをXML Schemaに注釈として付けるか、または既存のオブジェクト型からXML Schemaを生成する必要があります。

- XMLType表から直接構成する方法。

XMLTypeビューの作成: 構文

図19-1に、XMLTypeビューを作成するためのCREATE VIEW句を示します。CREATE VIEWの構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

図19-1 XMLTypeビューの作成の句: 構文

XML Schemaに基づかないXMLTypeビューの作成

XML Schemaに基づかないXMLTypeビューは、結果として戻されるXML値が、登録されたXML Schema内の特定の要素に制限されないXMLTypeビューです。XML Schemaに基づかないXMLTypeビューは、次のいずれかの方法で作成できます。

- SQL/XMLパブリッシング関数を使用する方法。

関連項目:
SQL/XMLパブリッシング関数の詳細は、第18章「データベースからのXMLデータの生成」を参照してください。

- Oracle SQL関数sys_XMLGenと、オブジェクト型またはオブジェクト・ビューを使用する方法。この方法は、XMLデータにマップするオブジェクト型、ビューおよび表がすでにある場合に便利です。

- 関連項目:
「オブジェクト型またはオブジェクト・ビューを使用した、XML Schemaに基づくXMLTypeビューの作成」

SQL/XMLパブリッシング関数を使用した、XML Schemaに基づかないXMLTypeビューの作成
例19-1に、SQL/XML関数XMLELementを使用してXMLTypeビューを作成する方法を示します。

例19-1 XMLELEMENTを使用したXMLTypeビューの作成

CREATE OR REPLACE VIEW emp_view OF XMLType
WITH OBJECT ID (XMLCast(XMLQuery('/Emp/@empno'
PASSING OBJECT_VALUE RETURNING CONTENT)
AS BINARY_DOUBLE)) AS
SELECT XMLElement("Emp",
XMLAttributes(employee_id AS "empno"),
XMLForest(e.first_name ||' '|| e.last_name AS "name",
e.hire_date AS "hiredate"))
AS "result" FROM employees e WHERE salary > 15000;

SELECT * FROM emp_view;

SYS_NC_ROWINFO$
-------------------------------------------------------------------------------------
<Emp empno="100"><name>Steven King</name><hiredate>2003-06-17</hiredate></Emp>
<Emp empno="101"><name>Neena Kochhar</name><hiredate>2005-09-21</hiredate></Emp>
<Emp empno="102"><name>Lex De Haan</name><hiredate>2001-01-13</hiredate></Emp>

リレーショナル表またはリレーショナル・ビュー内の既存のデータは、この方法を使用してXMLとして公開できます。ビューがSQL/XMLパブリッシング関数によって生成されると、XPath式を使用してそのビューにアクセスする問合せは、多くの場合リライトされます。最適化された問合せは、基礎となるリレーショナル列に直接アクセスできます。詳細は、第8章「構造化記憶域のXPathリライト」を参照してください。

これらのXMLTypeビューに対してDML操作を行うことができますが、通常、DML操作を処理するためにINSTEAD OFトリガーを作成する必要があります。

オブジェクト型またはSYS_XMLGENを使用した、XML Schemaに基づかないXMLTypeビューの作成

オブジェクト型とOracle SQL関数sys_XMLGenを使用して、XMLTypeビューを作成することもできます。関数sys_XMLGenは、引数としてオブジェクト型のインスタンスを受け入れ、対応するXMLTypeのインスタンスを生成します。例19-2の問合せでは、sys_XMLGenを使用し、例19-1の問合せと同じ結果を生成します。

例19-2 オブジェクト型およびSYS_XMLGENを使用したXMLTypeビューの作成

CREATE TYPE emp_t AS OBJECT ("@empno"  NUMBER(6),
fname     VARCHAR2(20),
lname     VARCHAR2(25),
hiredate  DATE);
/

CREATE OR REPLACE VIEW employee_view OF XMLType
WITH OBJECT ID (XMLCast(XMLQuery('/Emp/@empno'
PASSING OBJECT_VALUE RETURNING CONTENT)
AS BINARY_DOUBLE)) AS
SELECT sys_XMLGen(emp_t(e.employee_id, e.first_name, e.last_name, e.hire_date),
XMLFormat('EMP'))
FROM employees e WHERE salary > 15000;

SELECT * FROM employee_view;

SYS_NC_ROWINFO$
--------------------------------------------------------
<?xml version="1.0"?
<EMP empno="100">
<FNAME>Steven</FNAME>
<LNAME>King</LNAME>
<HIREDATE>17-JUN-03</HIREDATE>
</EMP>

<?xml version="1.0"?>
<EMP empno="101">
<FNAME>Neena</FNAME>
<LNAME>Kochhar</LNAME>
<HIREDATE>21-SEP-05</HIREDATE>
</EMP>

<?xml version="1.0"?>
<EMP empno="102">
<FNAME>Lex</FNAME>
<LNAME>De Haan</LNAME>
<HIREDATE>13-JAN-01</HIREDATE>
</EMP>

既存のリレーショナル・データまたはオブジェクト・リレーショナル・データは、このメカニズムを使用してXMLデータとして公開できます。

XML Schemaに基づくXMLTypeビューの作成

XML Schemaに基づくXMLTypeビューは、データがXML Schemaに準拠するように制約されるビューです。XML Schemaに基づくXMLTypeビューは、次のいずれかの方法で作成できます。

- SQL/XMLパブリッシング関数を使用する方法。

関連項目:
「SQL/XMLパブリッシング関数を使用した、XML Schemaに基づくXMLTypeビューの作成」

- オブジェクト型またはオブジェクト・ビューを使用する方法。この方法は、XMLデータにマップするオブジェクト型、ビューおよび表がすでにある場合に便利です。

関連項目:
「オブジェクト型またはオブジェクト・ビューを使用した、XML Schemaに基づくXMLTypeビューの作成」

SQL/XMLパブリッシング関数を使用した、XML Schemaに基づくXMLTypeビューの作成

SQL/XMLパブリッシング関数を使用すると、「XML Schemaに基づかないXMLTypeビューの作成」の項で説明したXML Schemaに基づかない場合と同様の方法で、XML Schemaに基づくXMLTypeビューを作成できます。

1. 必要なXML構造を含むXML Schema文書を作成および登録します。XML型とSQLオブジェクト型の間のマッピングを定義する注釈をXML Schemaに付ける必要はありません。

2. XML Schemaに準拠するXMLTypeビューを作成するには、SQL/XMLパブリッシング関数を使用します。

この2つの手順を、それぞれ例19-3および例19-4に示します。

例19-3 XML Schema emp_simple.xsdの登録

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.oracle.com/emp_simple.xsd',
SCHEMADOC => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.oracle.com/emp_simple.xsd"
version="1.0"
xmlns:xdb="http://xmlns.oracle.com/xdb"
elementFormDefault="qualified">
<element name = "Employee">
<complexType>
<sequence>
<element name = "EmployeeId"
type = "positiveInteger" minOccurs = "0"/>
<element name = "Name"
type = "string" minOccurs = "0"/>
<element name = "Job"
type = "string" minOccurs = "0"/>
<element name = "Manager"
type = "positiveInteger" minOccurs = "0"/>
<element name = "HireDate"
type = "date" minOccurs = "0"/>
<element name = "Salary"
type = "positiveInteger" minOccurs = "0"/>
<element name = "Commission"
type = "positiveInteger" minOccurs = "0"/>
<element name = "Dept">
<complexType>
<sequence>
<element name = "DeptNo"
type = "positiveInteger" minOccurs = "0"/>
<element name = "DeptName"
type = "string" minOccurs = "0"/>
<element name = "Location"
type = "positiveInteger" minOccurs = "0"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>',
LOCAL     => TRUE,
GENTYPES  => TRUE);
END;

例19-3では、従業員を定義するXML構造を含むemp_simple.xsdというXML Schemaがあると想定します。この例では、目的の場所http://www.oracle.com/emp_simple.xsdを使用してXML Schemaを登録します。

SQL/XMLパブリッシング関数を使用してXML Schemaに基づくコンテンツを生成する場合、すべての要素に適切な名前空間情報を指定し、xsi:schemaLocation属性を使用してスキーマの場所を指定する必要があります。これらは、XMLAttributes句を使用して指定できます。例19-4に、これを示します。

例19-4 SQL/XMLパブリッシング関数を使用したXMLTypeビューの作成

CREATE OR REPLACE VIEW emp_simple_xml OF XMLType
XMLSCHEMA "http://www.oracle.com/emp_simple.xsd" ELEMENT "Employee"
WITH OBJECT ID (XMLCast(XMLQuery('/Employee/EmployeeId/text()'
PASSING OBJECT_VALUE
RETURNING CONTENT)
AS BINARY_DOUBLE)) AS
SELECT
XMLElement("Employee",
XMLAttributes(
'http://www.oracle.com/emp_simple.xsd' AS "xmlns" ,
'http://www.w3.org/2001/XMLSchema-instance' AS "xmlns:xsi",
'http://www.oracle.com/emp_simple.xsd
http://www.oracle.com/emp_simple.xsd'
AS "xsi:schemaLocation"),
XMLForest(e.employee_id    AS "EmployeeId",
e.last_name      AS "Name",
e.job_id         AS "Job",
e.manager_id     AS "Manager",
e.hire_date      AS "HireDate",
e.salary         AS "Salary",
e.commission_pct AS "Commission",
XMLForest(
d.department_id   AS "DeptNo",
d.department_name AS "DeptName",
d.location_id     AS "Location") AS "Dept"))
FROM employees e, departments d
WHERE e.department_id = d.department_id;

例19-4では、関数XMLElementでXML要素Employeeが作成されます。関数XMLForestは、要素Employeeの子を作成します。XMLElement内のXMLAttributes句によって、生成されたXMLがビューのXML Schemaに準拠するように、必須のXML namespaceおよびスキーマのlocation属性が作成されます。最も内側にあるXMLForest関数のコールによって、Employee要素の子である、department要素の子が作成されます。

XML生成関数は、デフォルトではXML Schemaに基づかないXMLインスタンスを生成します。ただし、スキーマ位置が属性xsi:schemaLocationまたはxsi:noNamespaceSchemaLocationを使用して指定されている場合は、Oracle XML DBによってXML Schemaに基づくXMLデータが生成されます。XMLTypeビューの場合は、要素と属性の名前がXML Schema内の要素と属性の名前に一致しているかぎり、このXMLデータが有効なXML Schemaに基づく文書に暗黙的に変換されます。生成されたXMLデータで発生したエラーは、XMLインスタンス上で検証や抽出などの操作が実行されたときに、後で検出されます。

例19-5では、XMLTypeビューを問い合せて、employeesおよび departments表からXMLの結果が戻されています。問合せの結果は、わかりやすくするためフォーマット出力しています。

例19-5 XMLTypeビューの問合せ

SELECT OBJECT_VALUE AS RESULT FROM emp_simple_xml WHERE ROWNUM < 2;

RESULT
---------------------------------------------------------------------
<Employee xmlns="http://www.oracle.com/emp_simple.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.oracle.com/emp_simple.xsd
http://www.oracle.com/emp_simple.xsd">
<EmployeeId>200</EmployeeId>
<Name>Whalen</Name>
<Job>AD_ASST</Job>
<Manager>101</Manager>
<HireDate>2003-09-17</HireDate>
<Salary>4400</Salary>
<Dept>
<DeptNo>10</Deptno>
<DeptName>Administration</DeptName>
<Location>1700</Location>
</Dept>
</Employee>

SQL/XMLパブリッシング関数での名前空間の使用

複数の名前空間を含む複合XML Schemaが存在する場合は、SQL/XMLパブリッシング関数で提供される部分的にエスケープされたマッピングを使用して、適切な名前空間と接頭辞を持つ要素を作成する必要があります。

例19-6の問合せでは、正しい名前空間、接頭辞およびターゲット・スキーマの場所を持つXMLインスタンスが作成されます。これをemp_simple_xmlビューの定義で問合せとして使用できます。

例19-6 SQL/XMLパブリッシング関数での名前空間接頭辞の使用

SELECT XMLElement("ipo:Employee",
XMLAttributes('http://www.oracle.com/emp_simple.xsd' AS "xmlns:ipo",
'http://www.oracle.com/emp_simple.xsd
http://www.oracle.com/emp_simple.xsd' AS "xmlns:xsi"),
XMLForest(e.employee_id                     AS "ipo:EmployeeId",
e.last_name                       AS "ipo:Name",
e.job_id                          AS "ipo:Job",
e.manager_id                      AS "ipo:Manager",
TO_CHAR(e.hire_date,'YYYY-MM-DD') AS "ipo:HireDate",
e.salary                          AS "ipo:Salary",
e.commission_pct                  AS "ipo:Commission",
XMLForest(d.department_id   AS "ipo:DeptNo",
d.department_name AS "ipo:DeptName", d.location_id
AS "ipo:Location") AS "ipo:Dept"))
FROM employees e, departments d
WHERE e.department_id = d.department_id AND d.department_id = 20;
BEGIN
-- Delete schema if it already exists (else error)
DBMS_XMLSCHEMA.deleteSchema('emp-noname.xsd', 4);
END;

XMLELEMENT("IPO:EMPLOYEE",XMLATTRIBUTES('HTTP://WWW.ORACLE.COM/EMP_SIMPLE.XSD'AS
--------------------------------------------------------------------------------
<ipo:Employee
xmlns:ipo="http://www.oracle.com/emp_simple.xsd"
xmlns:xsi="http://www.oracle.com/emp_simple.xsd
http://www.oracle.com/emp_simple.xsd">
<ipo:EmployeeId>201</ipo:EmployeeId><ipo:Name>Hartstein</ipo:Name>
<ipo:Job>MK_MAN</ipo:Job><ipo:Manager>100</ipo:Manager>
<ipo:HireDate>2004-02-17</ipo:HireDate><ipo:Salary>13000</ipo:Salary>
<ipo:Dept><ipo:DeptNo>20</ipo:DeptNo><ipo:DeptName>Marketing</ipo:DeptName>
<ipo:Location>1800</ipo:Location></ipo:Dept></ipo:Employee>
<ipo:Employee xmlns:ipo="http://www.oracle.com/emp_simple.xsd"
xmlns:xsi="http://www.oracle.com/emp_simple.xsd
http://www.oracle.com/emp_simple.xsd"><ipo:EmployeeId>202</ipo:EmployeeId>
<ipo:Name>Fay</ipo:Name><ipo:Job>MK_REP</ipo:Job><ipo:Manager>201</ipo:Manager>
<ipo:HireDate>2005-08-17</ipo:HireDate><ipo:Salary>6000</ipo:Salary>
<ipo:Dept><ipo:DeptNo>20</ipo:Dept
No><ipo:DeptName>Marketing</ipo:DeptName><ipo:Location>1800</ipo:Location>
</ipo:Dept>
</ipo:Employee>

XML Schemaにターゲットの名前空間が存在しない場合は、xsi:noNamespaceSchemaLocation属性を使用してターゲットの名前空間を示すことができます。例19-7に、このようなXML Schemaを示します。

例19-7 ターゲットの名前空間が存在しないXML Schema

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'emp-noname.xsd',
SCHEMADOC => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<element name = "Employee">
<complexType>
<sequence>
<element name = "EmployeeId" type = "positiveInteger"/>
<element name = "Name" type = "string"/>
<element name = "Job" type = "string"/>
<element name = "Manager" type = "positiveInteger"/>
<element name = "HireDate" type = "date"/>
<element name = "Salary" type = "positiveInteger"/>
<element name = "Commission" type = "positiveInteger"/>
<element name = "Dept">
<complexType>
<sequence>
<element name = "DeptNo" type = "positiveInteger" />
<element name = "DeptName" type = "string"/>
<element name = "Location" type = "positiveInteger"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>',
LOCAL     => TRUE,
GENTYPES  => TRUE);
END;

例19-8では、例19-7のXML Schemaに準拠するビューが作成されます。XMLAttributes句によって、noNamespaceスキーマの場所属性を含むXML要素が作成されます。

例19-8 ターゲットの名前空間が存在しないXML Schemaのビューの作成

CREATE OR REPLACE VIEW emp_xml OF XMLType
XMLSCHEMA "emp-noname.xsd" ELEMENT "Employee"
WITH OBJECT ID (XMLCast(XMLQuery('/Employee/EmployeeId/text()'
PASSING OBJECT_VALUE
RETURNING CONTENT)
AS BINARY_DOUBLE)) AS
SELECT XMLElement(
"Employee",
XMLAttributes('http://www.w3.org/2001/XMLSchema-instance' AS "xmlns:xsi",
'emp-noname.xsd' AS "xsi:noNamespaceSchemaLocation"),
XMLForest(e.employee_id    AS "EmployeeId",
e.last_name      AS "Name",
e.job_id         AS "Job",
e.manager_id     AS "Manager",
e.hire_date      AS "HireDate",
e.salary         AS "Salary",
e.commission_pct AS "Commission",
XMLForest(d.department_id   AS "DeptNo",
d.department_name AS "DeptName",
d.location_id     AS "Location") AS "Dept"))
FROM employees e, departments d
WHERE e.department_id = d.department_id;

例19-9では、ビューdept_xmlが作成されます。このビューは、XML Schema dept.xsdに準拠します。

例19-9 XML Schemaに基づくXMLTypeビューでのSQL/XML関数の使用

BEGIN
-- Delete schema if it already exists (else error)
DBMS_XMLSCHEMA.deleteSchema('http://www.oracle.com/dept.xsd', 4);
END;
/

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.oracle.com/dept.xsd',
SCHEMADOC => '<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.oracle.com/dept.xsd"
version="1.0"
xmlns:xdb="http://xmlns.oracle.com/xdb"
elementFormDefault="qualified">
<element name = "Department">
<complexType>
<sequence>
<element name = "DeptNo" type = "positiveInteger"/>
<element name = "DeptName" type = "string"/>
<element name = "Location" type = "positiveInteger"/>
<element name = "Employee" maxOccurs = "unbounded">
<complexType>
<sequence>
<element name = "EmployeeId" type = "positiveInteger"/>
<element name = "Name" type = "string"/>
<element name = "Job" type = "string"/>
<element name = "Manager" type = "positiveInteger"/>
<element name = "HireDate" type = "date"/>
<element name = "Salary" type = "positiveInteger"/>
<element name = "Commission" type = "positiveInteger"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>',
LOCAL     => TRUE,
GENTYPES  => FALSE);
END;
/

CREATE OR REPLACE VIEW dept_xml OF XMLType
XMLSCHEMA "http://www.oracle.com/dept.xsd" ELEMENT "Department"
WITH OBJECT ID (XMLCast(XMLQuery('/Department/DeptNo'
PASSING OBJECT_VALUE RETURNING CONTENT)
AS BINARY_DOUBLE)) AS
SELECT XMLElement(
"Department",
XMLAttributes(
'http://www.oracle.com/emp.xsd' AS "xmlns" ,
'http://www.w3.org/2001/XMLSchema-instance' AS "xmlns:xsi",
'http://www.oracle.com/dept.xsd
http://www.oracle.com/dept.xsd' AS "xsi:schemaLocation"),
XMLForest(d.department_id "DeptNo",
d.department_name "DeptName",
d.location_id "Location"),
(SELECT XMLagg(
XMLElement("Employee",
XMLForest(
e.employee_id  "EmployeeId",
e.last_name "Name",
e.job_id "Job",
e.manager_id "Manager",
to_char(e.hire_date,'YYYY-MM-DD') "Hiredate",
e.salary "Salary",
e.commission_pct "Commission")))
FROM employees e
WHERE e.department_id = d.department_id))
FROM departments d;

これは、結果のXMLTypeインスタンスです。

SELECT OBJECT_VALUE AS result FROM dept_xml WHERE ROWNUM < 2;

RESULT
----------------------------------------------------------------
<Department
xmlns="http://www.oracle.com/emp.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.oracle.com/dept.xsd
http://www.oracle.com/dept.xsd">
<DeptNo>10</DeptNo>
<DeptName>Administration</DeptName>
<Location>1700</Location>
<Employee>
<EmployeeId>200</EmployeeId>
<Name>Whalen</Name>
<Job>AD_ASST</Job>
<Manager>101</Manager>
<Hiredate>2003-09-17</Hiredate>
<Salary>4400</Salary>
</Employee>
</Department>

オブジェクト型またはオブジェクト・ビューを使用した、XML Schemaに基づくXMLTypeビューの作成

XML Schemaに基づくXMLTypeビューをオブジェクト型またはオブジェクト・ビューから作成するには、次の手順を実行します。

1. オブジェクト型が存在しない場合は、作成します。

2. XML Schemaを作成してから登録し、XML型とSQLオブジェクト型および属性間のマッピングを定義する注釈を付けます。
XML Schemaを登録する前に、XML Schemaに注釈を付けることができます。通常は、既存のデータをラップしてXMLTypeビューを作成する前に行います。

関連項目:
第7章「XML Schemaの格納と問合せ: 基本」

PL/SQL関数DBMS_XMLSchema.generateSchemaおよびDBMS_XMLSchema.generateSchemasを使用して、指定したオブジェクト型に対するデフォルトのXMLマッピングを生成できます。生成されたXML Schemaには、必要な注釈のSQLTypeやSQLSchemaなどがあります。このようなXML Schema文書が登録されると、次の検証が実行される場合があります。

- simpleTypeに基づく属性または要素に対するSQLType。SQL型は、対応するXMLTypeデータのXML型と互換性がある必要があります。たとえば、XML stringのデータ型は、VARCHAR2またはラージ・オブジェクト(LOB)データ型にのみマップできます。

- complexTypeに基づく要素に対して指定されたSQLType。これは、LOBまたはcomplexTypeの宣言と互換性がある構造を持つオブジェクト型のいずれかです。オブジェクト型には、正しいデータ型を持つ正しい数の属性が含まれます。

3. XMLTypeビューを作成し、XML SchemaのURLおよびルート要素名を指定します。ビューを定義する問合せによって、まずオブジェクト・インスタンスが作成され、これらのインスタンスがXMLに変換されます。

1. オブジェクト・ビューを作成します。

2. そのオブジェクト・ビューのXMLTypeビューを作成します。

次の各項では、オブジェクト型またはオブジェクト・ビューを使用して、XML Schemaに基づくXMLTypeビューを作成する例について説明します。これらは、従業員データおよび部門データを含むリレーショナル表に基づきます。

- 「ネストした部門情報を使用したXMLType従業員ビューの作成」

- 「ネストした従業員情報を使用したXMLType部門ビューの作成」

2つのXMLTypeビューをそれぞれ作成するために、同じリレーショナル・データが使用されます。従業員ビューemp_xmlでは、XML文書で従業員を記述し、ネストした情報として従業員の部門が含まれます。部門ビューdept_xmlでは、XMLデータで部門を記述し、ネストした情報として部門の従業員が含まれます。

ネストした部門情報を使用したXMLType従業員ビューの作成

この項では、オブジェクト・ビューに基づいたXMLTypeビューemp_xmlの作成方法について説明します。最後の手順には、2つの代替方法があります。

- 手順3a: オブジェクト型emp_tを使用したXMLTypeビューemp_xmlの作成: オブジェクト型emp_tを使用してXMLTypeビューemp_xmlを作成します。

- 手順3b: オブジェクト・ビューemp_vを使用したXMLTypeビューemp_xmlの作成: オブジェクト型emp_vを使用してXMLTypeビューemp_xmlを作成します。

手順1: オブジェクト型の作成

例19-10は、その他の手順で使用されるオブジェクト型を作成しています。

例19-10 XML Schemaに基づくXMLTypeビューに対応するオブジェクト型の作成

CREATE TYPE dept_t AS OBJECT
(deptno NUMBER(4),
dname  VARCHAR2(30),
loc    NUMBER(4));
/

CREATE TYPE emp_t AS OBJECT
(empno     NUMBER(6),
ename     VARCHAR2(25),
job       VARCHAR2(10),
mgr       NUMBER(6),
hiredate  DATE,
sal       NUMBER(8,2),
comm      NUMBER(2,2),
dept      dept_t);
/

手順2.XML Schema emp_complex.xsdの作成および登録

XML Schemaは、手動で作成するか、またはパッケージDBMS_XMLSCHEMAを使用して既存のオブジェクト型から自動的に作成できます。例19-11を参照してください。

例19-11 DBMS_XMLSCHEMA.GENERATESCHEMAによるXML Schemaの生成

SELECT DBMS_XMLSCHEMA.generateSchema('HR','EMP_T') AS result FROM DUAL;

例19-11では、emp_t型のXML Schemaが生成されます。PL/SQL関数DBMS_XMLSCHEMA.generateSchemasには、名前空間を追加するためなどの、様々な引数を指定できます。このXML Schemaを編集して、生成されたデフォルトのマッピングを変更することもできます。関数generateSchemasは、オブジェクト型とその属性が参照するSQLデータベース・スキーマごとに、1つのXML Schemaのリストを生成します。

例19-12は、XML Schema emp_complex.xsdを登録する方法を示しています。このXML Schemaでは、オブジェクト型の対応するオブジェクト属性に、XML要素および属性がどのようにマップされるかを指定します(xdb:SQLType注釈)。

例19-12 XML Schema emp_complex.xsdの登録

BEGIN
-- Delete schema if it already exists (else error)
DBMS_XMLSCHEMA.deleteSchema('http://www.oracle.com/emp_complex.xsd', 4);
END;
/

COMMIT;

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.oracle.com/emp_complex.xsd',
SCHEMADOC => '<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xdb="http://xmlns.oracle.com/xdb"
xsi:schemaLocation="http://xmlns.oracle.com/xdb
http://xmlns.oracle.com/xdb/XDBSchema.xsd">
<xsd:element name="Employee" type="EMP_TType" xdb:SQLType="EMP_T"
xdb:SQLSchema="HR"/>
<xsd:complexType name="EMP_TType" xdb:SQLType="EMP_T" xdb:SQLSchema="HR"
xdb:maintainDOM="false">
<xsd:sequence>
<xsd:element name="EMPNO" type="xsd:double" xdb:SQLName="EMPNO"
xdb:SQLType="NUMBER"/>
<xsd:element name="ENAME" xdb:SQLName="ENAME" xdb:SQLType="VARCHAR2">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="25"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="JOB" xdb:SQLName="JOB" xdb:SQLType="VARCHAR2">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="10"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="MGR" type="xsd:double" xdb:SQLName="MGR"
xdb:SQLType="NUMBER"/>
<xsd:element name="HIREDATE" type="xsd:date" xdb:SQLName="HIREDATE"
xdb:SQLType="DATE"/>
<xsd:element name="SAL" type="xsd:double" xdb:SQLName="SAL"
xdb:SQLType="NUMBER"/>
<xsd:element name="COMM" type="xsd:double" xdb:SQLName="COMM"
xdb:SQLType="NUMBER"/>
<xsd:element name="DEPT" type="DEPT_TType" xdb:SQLName="DEPT"
xdb:SQLSchema="HR" xdb:SQLType="DEPT_T"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="DEPT_TType" xdb:SQLType="DEPT_T" xdb:SQLSchema="HR"
xdb:maintainDOM="false">
<xsd:sequence>
<xsd:element name="DEPTNO" type="xsd:double" xdb:SQLName="DEPTNO"
xdb:SQLType="NUMBER"/>
<xsd:element name="DNAME" xdb:SQLName="DNAME" xdb:SQLType="VARCHAR2">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="30"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="LOC" type="xsd:double" xdb:SQLName="LOC"
xdb:SQLType="NUMBER"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>',
LOCAL     => TRUE,
GENTYPES  => FALSE);
END;
/

例19-12では、目的の場所http://www.oracle.com/emp_complex.xsdを使用してXML Schemaを登録します。

手順3a: オブジェクト型emp_tを使用したXMLTypeビューemp_xmlの作成

例19-13では、オブジェクト型emp_tを使用してXMLTypeビューを作成します。

例19-13 XMLTypeビューemp_xmlの作成

CREATE OR REPLACE VIEW emp_xml OF XMLType
XMLSCHEMA "http://www.oracle.com/emp_complex.xsd"
ELEMENT "Employee"
WITH OBJECT ID (XMLCast(XMLQuery('/Employee/EMPNO'
PASSING OBJECT_VALUE RETURNING CONTENT)
AS BINARY_DOUBLE)) AS
SELECT emp_t(e.employee_id, e.last_name, e.job_id, e.manager_id, e.hire_date,
e.salary, e.commission_pct,
dept_t(d.department_id, d.department_name, d.location_id))
FROM employees e, departments d
WHERE e.department_id = d.department_id;

例19-13では、OBJECT ID句でSQL/XML関数XMLCastを使用して、XML従業員番号をSQLデータ型BINARY_DOUBLEに変換します。

手順3b: オブジェクト・ビューemp_vを使用したXMLTypeビューemp_xmlの作成

例19-14では、オブジェクト・ビューに基づいてXMLTypeビューを作成します。

例19-14 オブジェクト・ビューの作成と、そのオブジェクト・ビューへのXMLTypeビューの作成

CREATE OR REPLACE VIEW emp_v OF emp_t WITH OBJECT ID (empno) AS
SELECT emp_t(e.employee_id, e.last_name, e.job_id, e.manager_id, e.hire_date,
e.salary, e.commission_pct,
dept_t(d.department_id, d.department_name, d.location_id))
FROM employees e, departments d
WHERE e.department_id = d.department_id;

CREATE OR REPLACE VIEW emp_xml OF XMLType
XMLSCHEMA "http://www.oracle.com/emp_complex.xsd" ELEMENT "Employee"
WITH OBJECT ID DEFAULT AS
SELECT VALUE(p) FROM emp_v p;

ネストした従業員情報を使用したXMLType部門ビューの作成

この項では、XMLTypeビューdept_xmlの作成方法について説明します。このビューの各部門には、ネストされた従業員情報が含まれます。最後の手順には、2つの代替方法があります。

- 手順3a: オブジェクト型dept_を使用したXMLTypeビューdept_xmlの作成: 部門用のオブジェクト型dept_tを使用してXMLTypeビューdept_xmlを作成します。

- 手順3b: リレーショナル・データを直接使用したXMLTypeビューdept_xmlの作成: リレーショナル・データを直接使用してXMLTypeビューdept_xmlを作成します。

手順1: オブジェクト型の作成

例19-15は、その他の手順で使用されるオブジェクト型を作成しています。

例19-15 オブジェクト型の作成

CREATE TYPE emp_t AS OBJECT (empno    NUMBER(6),
ename    VARCHAR2(25),
job      VARCHAR2(10),
mgr      NUMBER(6),
hiredate DATE,
sal      NUMBER(8,2),
comm     NUMBER(2,2)); /

CREATE OR REPLACE TYPE emplist_t AS TABLE OF emp_t;
/

CREATE TYPE dept_t AS OBJECT (deptno NUMBER(4),
dname  VARCHAR2(30),
loc    NUMBER(4),
emps   emplist_t);
/

手順2.XML Schema dept_complex.xsdの登録

既存のXML Schemaを使用するか、または関数DBMS_XMLSCHEMA.generateSchemaまたはDBMS_XMLSCHEMA.generateSchemasを使用してオブジェクト型からXML Schemaを生成します(例19-11を参照)。例19-16では、XML Schema dept_complex.xsdを登録します。

例19-16 XML Schema dept_complex.xsdの登録

BEGIN
-- Delete schema if it already exists (else error)
DBMS_XMLSCHEMA.deleteSchema('http://www.oracle.com/dept_complex.xsd', 4);
END;
/

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.oracle.com/dept_complex.xsd',
SCHEMADOC => '<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xdb="http://xmlns.oracle.com/xdb"
xsi:schemaLocation="http://xmlns.oracle.com/xdb
http://xmlns.oracle.com/xdb/XDBSchema.xsd">
<xsd:element name="Department" type="DEPT_TType" xdb:SQLType="DEPT_T"
xdb:SQLSchema="HR"/>
<xsd:complexType name="DEPT_TType" xdb:SQLType="DEPT_T" xdb:SQLSchema="HR"
xdb:maintainDOM="false">
<xsd:sequence>
<xsd:element name="DEPTNO" type="xsd:double" xdb:SQLName="DEPTNO"
xdb:SQLType="NUMBER"/>
<xsd:element name="DNAME" xdb:SQLName="DNAME" xdb:SQLType="VARCHAR2">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="30"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="LOC" type="xsd:double" xdb:SQLName="LOC"
xdb:SQLType="NUMBER"/>
<xsd:element name="EMPS" type="EMP_TType" maxOccurs="unbounded"
minOccurs="0" xdb:SQLName="EMPS"
xdb:SQLCollType="EMPLIST_T" xdb:SQLType="EMP_T"
xdb:SQLSchema="HR" xdb:SQLCollSchema="HR"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="EMP_TType" xdb:SQLType="EMP_T" xdb:SQLSchema="HR"
xdb:maintainDOM="false">
<xsd:sequence>
<xsd:element name="EMPNO" type="xsd:double" xdb:SQLName="EMPNO"
xdb:SQLType="NUMBER"/>
<xsd:element name="ENAME" xdb:SQLName="ENAME" xdb:SQLType="VARCHAR2">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="25"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="JOB" xdb:SQLName="JOB" xdb:SQLType="VARCHAR2">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="10"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="MGR" type="xsd:double" xdb:SQLName="MGR"
xdb:SQLType="NUMBER"/>
<xsd:element name="HIREDATE" type="xsd:date" xdb:SQLName="HIREDATE"
xdb:SQLType="DATE"/>
<xsd:element name="SAL" type="xsd:double" xdb:SQLName="SAL"
xdb:SQLType="NUMBER"/>
<xsd:element name="COMM" type="xsd:double" xdb:SQLName="COMM"
xdb:SQLType="NUMBER"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>',
LOCAL     => TRUE,
GENTYPES  => FALSE);
END;
/

手順3a: オブジェクト型dept_tを使用したXMLTypeビューdept_xmlの作成

例19-17では、オブジェクト型dept_tを使用してXMLTypeビューdept_xmlを作成します。

例19-17 オブジェクト型dept_tを使用したXMLTypeビューdept_xmlの作成

CREATE OR REPLACE VIEW dept_xml OF XMLType
XMLSCHEMA "http://www.oracle.com/dept_complex.xsd" ELEMENT "Department"
WITH OBJECT ID (XMLCast(XMLQuery('/Department/DEPTNO'
PASSING OBJECT_VALUE RETURNING CONTENT)
AS BINARY_DOUBLE)) AS
SELECT dept_t(d.department_id, d.department_name, d.location_id,
cast(MULTISET
(SELECT emp_t(e.employee_id, e.last_name, e.job_id,
e.manager_id, e.hire_date,
e.salary, e.commission_pct)
FROM employees e WHERE e.department_id = d.department_id)
AS emplist_t))
FROM departments d;

手順3b: リレーショナル・データを直接使用したXMLTypeビューdept_xmlの作成

また、オブジェクト型dept_tを使用せずに、SQL/XMLパブリッシング関数を使用してリレーショナル表からXMLTypeビューdept_xmlを作成することもできます。例19-18に、これを示します。

例19-18 リレーショナル・データを直接使用したXMLTypeビューdept_xmlの作成

CREATE OR REPLACE VIEW dept_xml OF XMLType
XMLSCHEMA "http://www.oracle.com/dept_complex.xsd" ELEMENT "Department"
WITH OBJECT ID (XMLCast(XMLQuery('/Department/DEPTNO'
PASSING OBJECT_VALUE RETURNING CONTENT)
AS BINARY_DOUBLE)) AS
SELECT
XMLElement(
"Department",
XMLAttributes('http://www.oracle.com/dept_complex.xsd' AS "xmlns",
'http://www.w3.org/2001/XMLSchema-instance' AS "xmlns:xsi",
'http://www.oracle.com/dept_complex.xsd
http://www.oracle.com/dept_complex.xsd'
AS "xsi:schemaLocation"),
XMLForest(d.department_id "DeptNo", d.department_name "DeptName",
d.location_id "Location"),
(SELECT XMLAgg(XMLElement("Employee",
XMLForest(e.employee_id "EmployeeId",
e.last_name "Name",
e.job_id "Job",
e.manager_id "Manager",
e.hire_date "Hiredate",
e.salary "Salary",
e.commission_pct "Commission")))
FROM employees e WHERE e.department_id = d.department_id))
FROM departments d;

注意:
XML Schemaおよび要素情報は、ビュー・レベルで指定する必要があります。これは、SELECTリストでは、基礎となる表から別のXML SchemaのXMLが任意で作成される可能性があるためです。

XMLType表からのXMLTypeビューの作成

たとえば、XMLデータを変換したり、戻される行を制限することによって、XMLType表のXMLTypeビューを作成できます。

例19-19では、基礎となるXMLType表に含まれる行を制限して、XMLTypeビューを作成します。XML Schema dept_complex.xsdを使用して、基礎となる表を作成しています。「ネストした従業員情報を使用したXMLType部門ビューの作成」を参照してください。

例19-19 XMLType表の行の制限によるXMLTypeビューの作成

CREATE TABLE dept_xml_tab OF XMLType
XMLSchema "http://www.oracle.com/dept_complex.xsd" ELEMENT "Department"
NESTED TABLE XMLDATA."EMPS" STORE AS dept_xml_tab_tab1;

CREATE OR REPLACE VIEW dallas_dept_view OF XMLType
XMLSchema "http://www.oracle.com/dept.xsd" ELEMENT "Department"
AS SELECT OBJECT_VALUE FROM dept_xml_tab
WHERE XMLCast(XMLQuery('/Department/LOC'
PASSING OBJECT_VALUE RETURNING CONTENT)
AS VARCHAR2(20))
= 'DALLAS';

CREATE OR REPLACE VIEW dallas_dept_view OF XMLType

dallas_dept_viewによって、XMLType表の行が、所在地がダラスである部門に制限されます。

例19-20は、スタイルシートを使用してXMLデータを変換することによって、XMLTypeビューを作成する方法を示しています。

例19-20 XMLType表の変換によるXMLTypeビューの作成

CREATE OR REPLACE VIEW hr_po_tab OF XMLType
ELEMENT "PurchaseOrder" WITH OBJECT ID DEFAULT AS
SELECT XMLtransform(OBJECT_VALUE, x.col1)
FROM purchaseorder p, xsl_tab x;

SQL関数REFを使用したXMLTypeビュー・オブジェクトの参照

XMLTypeビュー・オブジェクトは、SQL関数refを使用して参照できます。

SELECT ref(d) FROM dept_xml_tab d;

XMLTypeビュー参照は、次のいずれかのオブジェクトIDに基づきます。

- システム生成OID: XMLType表のビューまたはオブジェクト・ビュー

- 主キー・ベースのOID: OBJECT ID式を持つビュー

これらのREFは、OCIオブジェクト・キャッシュ内のOCIXMLTypeインスタンスをフェッチするために使用できます。また、SQL問合せ内でも使用できます。これらのREFは、オブジェクト・ビューへのREFと同様に動作します。

XMLTypeビューでのデータ操作言語(DML)

特定のXMLTypeビューは、暗黙的に更新可能でないことがあります。その場合は、すべてのデータ操作(DML)を処理するために、INSTEAD-OF TRIGGERSを作成する必要があります。XMLTypeビューが暗黙的に更新可能である場合を識別する1つの方法は、ビュー問合せを使用して、そのビューが、本来更新可能であるオブジェクト・ビューまたはオブジェクト・コンストラクタに基づいているかどうかを判断することです。例19-21に、これを示します。

例19-21 暗黙的に更新可能なXMLTypeビューの識別

CREATE TYPE dept_t AS OBJECT
(deptno NUMBER(4),
dname  VARCHAR2(30),
loc    NUMBER(4));
/

BEGIN
-- Delete schema if it already exists (else error)
DBMS_XMLSCHEMA.deleteSchema('http://www.oracle.com/dept.xsd', 4);
END;
/
COMMIT;

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL => 'http://www.oracle.com/dept_t.xsd',
SCHEMADOC => '<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xdb="http://xmlns.oracle.com/xdb"
xsi:schemaLocation="http://xmlns.oracle.com/xdb
http://xmlns.oracle.com/xdb/XDBSchema.xsd">
<xsd:element name="Department" type="DEPT_TType" xdb:SQLType="DEPT_T"
xdb:SQLSchema="HR"/>
<xsd:complexType name="DEPT_TType" xdb:SQLType="DEPT_T" xdb:SQLSchema="HR"
xdb:maintainDOM="false">
<xsd:sequence>
<xsd:element name="DEPTNO" type="xsd:double" xdb:SQLName="DEPTNO"
xdb:SQLType="NUMBER"/>
<xsd:element name="DNAME" xdb:SQLName="DNAME" xdb:SQLType="VARCHAR2">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="30"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="LOC" type="xsd:double" xdb:SQLName="LOC"
xdb:SQLType="NUMBER"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>',
LOCAL     => TRUE,
GENTYPES  => FALSE);
END;
/

CREATE OR REPLACE VIEW dept_xml of XMLType
XMLSchema "http://www.oracle.com/dept_t.xsd" element "Department"
WITH OBJECT ID (XMLCast(XMLQuery('/Department/DEPTNO'
PASSING OBJECT_VALUE RETURNING CONTENT)
AS BINARY_DOUBLE)) AS
SELECT dept_t(d.department_id, d.department_name, d.location_id)
FROM departments d;

INSERT INTO dept_xml
VALUES (
XMLType.createXML(
'<Department
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.oracle.com/dept_t.xsd" >
<DEPTNO>300</DEPTNO>
<DNAME>Processing</DNAME>
<LOC>1700</LOC>
</Department>'));

UPDATE dept_xml d
SET d.OBJECT_VALUE = updateXML(d.OBJECT_VALUE, '/Department/DNAME/text()',
'Shipping')
WHERE XMLExists('/Department[DEPTNO=300]' PASSING OBJECT_VALUE);

20 URIを介したデータのアクセス

この章では、データベース内にURLを生成および格納して、そのURLが指すデータを取り出す方法を説明します。説明するURIは3種類あります。

- DBUri: データベース内のリレーショナル・データのアドレス

- XDBUri: Oracle XML DBリポジトリ内のデータのアドレス

- HTTPUri: Hyper Text Transfer Protocol(HTTP(S))を使用するWebアドレス

この章の内容は次のとおりです。

- Oracle XML DB URLの機能の概要

- URIとURL

- URITypeとそのサブタイプ

- URITypeインスタンスを使用したデータ・アクセス

- XDBUris: リポジトリ・リソースへのポインタ

- DBUris: データベース・データへのポインタ

- パッケージURIFACTORYを使用したURITypeの新しいサブタイプの作成

- SYS_DBURIGEN SQL関数

- DBUriServlet

Oracle XML DB URLの機能の概要

この章では、次の2つの主要な機能について説明します。

- インダイレクション・メカニズムとしてのパスの使用: パスをデータベースに格納して、そのパスを参照することによって間接的にターゲットにアクセスすることができます。パスの種類としては、様々な種類のUniform Resource Identifier(URI)を使用できます。

- そのターゲット・データベース・データを使用したXML文書の生成: インダイレクションで特に使用できるURIの1つの種類であるDBUriは、データベース・データへのアドレッシングで使用できる便利なXPath表記法を提供します。DBUriを使用して、データベース・データを含み、データベースの構造を反映した構造を持つXML文書を構成できます。

URIとURL

WebベースのXMLアプリケーションの開発では、Uniform Resource Identifier(URI)を使用して、ネットワーク上にあるデータを参照することがよくあります。URL(Uniform Resource Locator)は、インターネット・プロトコルを使用してオブジェクトにアクセスするURIです。

URIには次の2つの部分があり、シャープ記号(#)で区切られています。

- 文書を識別するURL部分。

- ドキュメント内のフラグメントを識別するフラグメント部分。フラグメントの表記法は、ドキュメント・タイプによって異なります。HTML文書ではアンカー名となります。XML文書ではXPath式です。

一般的なURIは次のとおりです。

- HTML: http://www.example.com/document1#some_anchor。ここでsome_anchorは、HTML文書内の名前付きアンカーです。

- XML: http://www.example.com/xml_doc#/po/cust/custname。ここで、各項目は次のとおりです。

- http://www.example.com/xml_docはXML文書の位置を識別します。

- /po/cust/custnameは文書内のフラグメントを識別します。この部分はW3CのXPointer勧告で定義されています。

関連項目:

- HTTP(S)のURLの表記法については、http://www.w3.org/2002/ws/Activity.htmlを参照してください。

- XMLのXPathの表記法については、http://www.w3.org/TR/xpathを参照してください。

- XMLのXPointerの表記法については、http://www.w3.org/TR/xptr/を参照してください。

- MIMEタイプの詳細は、http://xml.coverpages.org/xmlMediaMIME.htmlを参照してください。

URITypeとそのサブタイプ

Oracle XML DBでは、様々な種類のパスをデータベース・オブジェクトとして表現できます。次に、使用できるパス・オブジェクト型を示します。

- HTTPURIType: この型のオブジェクトはHTTPUriと呼ばれ、http://で始まるURLを表します。HTTPURITypeを使用すると、リモートのWebページ(またはファイル)へのリンクを表すオブジェクトを作成して、オブジェクト・メソッドをコールすることでそのWebページを取得することができます。HTTPUriTypeを使用するアプリケーションは、適切なアクセス権限を持っている必要があります。HTTPUriTypeは、リモート・ページにアクセスするためのHyper Text Transfer Protocol(HTTP(S))を実装します。HTTPURITypeはパッケージUTL_HTTPを使用してデータをフェッチするため、このパッケージのセッション設定およびアクセス制御を使用してHTTPフェッチを変更することもできます。

関連項目:

- 「HTTPURIType PL/SQLメソッドGETCONTENTTYPE()」

- 外部ネットワーク・サービスへのファイングレイン・アクセスの管理は、『Oracle Databaseセキュリティ・ガイド』を参照してください。

- DBURIType: この型のオブジェクトはDBUriと呼ばれ、データベース・データ(表、1つまたは複数の行、1つの列)をターゲットとするURIを表します。DBURITypeを使用すると、データベース・データへのリンクを表すオブジェクトを作成して、オブジェクト・メソッドをコールすることでそのデータをXML形式で取得することができます。DBUriは簡単な形式のXPath式をURI構文として使用します。たとえば、次のXPath式は、表HR.employeesの、列first_nameの値がJackである行へのDBUri参照です。

/HR/EMPLOYEES/ROW[FIRST_NAME="Jack"]

関連項目:
DBUris: データベース・データへのポインタ

- XDBURIType: この型のオブジェクトはXDBUriと呼ばれ、Oracle XML DBリポジトリのリソースをターゲットにしているURIを表します。XDBURITypeを使用すると、リポジトリ・リソースへのリンクを表すオブジェクトを作成し、オブジェクト・メソッドをコールすることによって、リソースの全体または一部を取得できます。XDBUriのURI構文はリポジトリ・リソース・アドレスで、オプションでその後にXPath式が続きます。たとえば、/public/hr/doc1.xml#/purchaseOrder/lineItemは、フォルダ/public/hrのリポジトリ・ファイルdoc1.xmlにおけるルート要素purchaseOrderのlineItem子要素へのXDBUri参照です。

関連項目:
XDBUris: リポジトリ・リソースへのポインタ

これらの各オブジェクト型は、抽象オブジェクト型URITypeから導出されたものです。抽象型なのでインスタンス(オブジェクト)を持ちません。インスタンスを持つのはそのサブタイプのみです。

型URITypeには次の機能があります。

- サーバーの内外に格納されたデータへの統一アクセス。URIType値を使用してHTTP(S)およびDBUriへのポインタを格納できるので、データの場所を考慮せずに問合せおよび索引を作成できます。

- XML文書内のURIのデータベース列へのマッピング。XML文書が分解されオブジェクト・リレーショナル表と列に格納されると、文書に含まれるURIは、適切なURITypeサブタイプのデータベース列にマップされます。

リレーショナル列に格納されているデータを参照して、URIを使用して外部に公開することができます。Oracle Databaseには、DBUriを解釈する標準のサーブレットDBUriServletが用意されています。また、URL参照のフェッチに使用できる、PL/SQLパッケージUTL_HTTPとJavaクラスjava.net.URLも用意されています。

URIType列は、Oracle Database内でOracle Textを使用してネイティブに索引付けできます。特別のデータストアは不要です。

関連項目:

- 新しいURITypeサブタイプの定義は、「パッケージURIFACTORYを使用したURITypeの新しいサブタイプの作成」を参照してください。

- 第6章「XMLTypeデータの索引付け」

DBUriとXDBUri: 目的

DBUriおよびXDBUriの典型的な用途は次のとおりです。

- データベースから生成されたWebページ内でXSLTスタイルシートを参照できます。PL/SQLパッケージDBMS_METADATAでは、DBUriを使用してXSLスタイルシートを参照できます。XDBUriを使用すると、Oracle XML DBリポジトリに格納されたXSLTスタイルシートも参照できます。

- データベースに格納されたHTML、イメージおよびその他のデータを参照できます。URLを使用して、データベース表またはリポジトリ・フォルダに格納されたデータを指すことができます。

- Webサーバーをバイパスすることによって、パフォーマンスを向上できます。XML文書内にあるグローバルURLをデータベースへの参照に置換し、サーブレット、DBUri、XDBUriのいずれかを使用して、ターゲットのコンテンツを取得します。DBUriまたはXDBUriを使用すると、Webサーバーを介さずにデータベースと直接対話できるため、サーブレットを使用する場合よりパフォーマンスが向上します。

- DBUriを使用すると、SQLを使用しないでデータベース内のXML文書にアクセスできます。

- アクセス権限のあるデータベース表にリポジトリ・リソースが格納されている場合は、XDBUriやDBUriを使用してそのコンテンツにアクセスできます。

関連項目:
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_METADATAパッケージ」

URITypeメソッド

抽象オブジェクト型URITypeに含まれているPL/SQLメソッドを、その各サブタイプで使用できます。これらの各メソッドは、任意のサブタイプによってオーバーライドできます。表20-1にURITypeのPL/SQLメソッドのリストを示します。さらに、各サブタイプには、サブタイプと同名のコンストラクタが含まれます。

表20-1 URIType PL/SQLメソッド

URITypeメソッド

説明

getURL()

URITypeインスタンスのURLを戻します。

URLを直接参照せず、このメソッドを使用します。URITypeサブタイプは、このメソッドをオーバーライドして、正確なURLを提供します。たとえば、HTTPURIType は、URLを、接頭辞http://なしで格納します。getURL()は接頭辞を付加してURLの全体を戻します。

getExternalURL()

getURL()と同様ですが、getExternalURL()ではURL内の文字をエスケープし、URL仕様に準拠させます。たとえば、空白はエスケープ値%20に変換されます。

getContentType()

URIのMIMEコンテンツ・タイプを戻します。

HTTPUri: コンテンツ・タイプを戻すため、URLが後に続き、MIMEヘッダーが検査されます。

DBUri: 戻されるコンテンツ・タイプはtext/plain(スカラー値の場合)またはtext/xml(それ以外)です。

XDBUri: リポジトリ・リソースのContentTypeメタデータ・プロパティの値が戻されます。

getCLOB()

URIのターゲットがCLOB値として戻されます。データベースのキャラクタ・セットを使用してデータがエンコーディングされます。

DBUri: XMLデータが戻されます(ターゲットのデータがそのまま戻される、ノード・テストtext()が使用された場合を除く)。BLOB列がターゲットの場合、列内のバイナリ・データは16進の文字データとして変換されます。

getBLOB()

URIのターゲットがBLOB値として戻されます。文字変換は行われず、文字エンコーディングはURIターゲットのエンコーディングです。このメソッドは、バイナリ・データのフェッチにも使用できます。

DBUri: getBLOB()は、BLOB列をターゲットとするDBUriに適用されると、16進の文字データとして変換されたバイナリ・データを戻します。非バイナリ・データをターゲットとするDBUriに適用されると、データはデータベース・キャラクタ・セットで戻されます。

getXML()

URIのターゲットがXMLTypeインスタンスとして戻されます。これを使用することにより、getCLOB()およびgetBLOB()以外の操作を実行するアプリケーションは、XMLTypeメソッドを使用してそれらの操作を実行できます。URIのターゲットが整形式のXML文書でない場合は例外が発生します。

createURI()

URITypeサブタイプのいずれかのインスタンスを構成します。

HTTPURIType PL/SQLメソッドGETCONTENTTYPE()

HTTPURIType PL/SQLメソッドgetContentType()は、ターゲット文書に関するMIME情報を戻します。この情報を使用して、文書をBLOB値とCLOB値のどちらで取得するかを判断できます。たとえば、MIMEタイプx/jpegのWebページをBLOBとして処理し、MIMEタイプtext/plainまたはtext/htmlのWebページをCLOBとして処理できます。

例20-1では、データをCLOB値とBLOB値のいずれで取得するかを判断するためにHTTPコンテンツ・タイプがテストされています。コンテンツ・タイプ・データはHTTPURITypeの場合はHTTPヘッダー、DBURITypeの場合はデータベース列のメタデータです。

例20-1 HTTPURIType PL/SQLメソッドGETCONTENTTYPE()の使用

DECLARE
httpuri HTTPURIType;
y CLOB;
x BLOB;
BEGIN
httpuri := HTTPURIType('http://www.oracle.com/index.html');
DBMS_OUTPUT.put_line(httpuri.getContentType());
IF httpuri.getContentType() = 'text/html'
THEN
y := httpuri.getCLOB();
END IF;
IF httpuri.getContentType() = 'application-x/bin'
THEN
x := httpuri.getBLOB();
END IF;
END;
/
text/html

DBURIType PL/SQLメソッドGETCONTENTTYPE()

PL/SQLメソッドgetContentType()はURLのMIME情報を戻します。DBUriのターゲットがスカラー値の場合、戻されるMIMEコンテンツ・タイプはtext/plainです。それ以外の場合はtext/xmlです。

CREATE TABLE dbtab (a VARCHAR2(20), b BLOB);

次のXPath式に対応するDBUriのコンテンツ・タイプは、それぞれがXMLデータの完全な列をターゲットにしているため、text/xmlです。

- /HR/DBTAB/ROW/A

- /HR/DBTAB/ROW/B

次のXPath式に対応するDBUriのコンテンツ・タイプは、それぞれがスカラー値をターゲットにしているため、text/plainです。

- /HR/DBTAB/ROW/A/text()

- /HR/DBTAB/ROW/B/text()

DBURIType PL/SQLメソッドGETCLOB()

PL/SQLメソッドgetCLOB()がDBUriに適用される場合、ターゲットとなるデータは、ターゲットの列または表の名前をXML要素名にしたXMLデータとして戻されます。ターゲットのXPathがノード・テストtext()を使用する場合、データは、XMLタグで囲まれていないテキストとして戻されます。どちらの場合も、データはデータベース・キャラクタ・セットで戻されます。

たとえば、XPathが/HR/DBTAB/ROW/A/text()であるDBUriに適用されると、Aが非バイナリ列の場合、列Aのデータがそのまま戻されます。XPathノード・テストtext()を使用しない場合、結果はXML形式にラップされたデータです。

<HR><DBTAB><ROW><A>...data_in_column_A...</A></ROW></DBTAB></HR>

バイナリ(BLOB)列をターゲットとするDBUriに適用された場合、列内のバイナリ・データは16進の文字データに変換されます。

たとえば、XPathが/HR/DBTAB/ROW/B/text()であるDBUriに適用されると、BがBLOB列の場合、ターゲットのバイナリ・データは16進の文字データに変換されて戻されます。XPathノード・テストtext()を使用しない場合、結果はXML形式にラップされた変換データです。

<HR><DBTAB><ROW><B>...data_translated_to_hex...</B></ROW></DBTAB></HR>

DBURIType PL/SQLメソッドGETBLOB()

BLOB列をターゲットとするDBUriに適用されると、getBLOB()は16進の文字データとして変換されたバイナリ・データを戻します。非バイナリ・データをターゲットとするDBUriに適用されると、getBLOB()はデータを(BLOB値として)データベース・キャラクタ・セットで戻します。

例として表dbtabを参照してください。

CREATE TABLE dbtab (a VARCHAR2(20), b BLOB);

XPath式/HR/DBTAB/ROW/Bに対応するDBUriにgetBLOB()を適用した場合、列Bの16進文字変換をコンテンツとするルート要素Bを持つXML文書を含むBLOB値が戻されます。

XPath式/HR/DBTAB/ROW/B/text()に対応するDBUriにgetBLOB()を適用した場合、列Bのバイナリ・データの16進文字変換のみを含むBLOB値が戻されます。

非バイナリ・データをターゲットとするXPath式/HR/DBTAB/ROW/A/text()に対応するDBUriにgetBLOB()を適用した場合、列Aのデータを含むBLOB値が、データベースのキャラクタ・セットで戻されます。

URITypeインスタンスを使用したデータ・アクセス

URITypeサブタイプのインスタンスをインダイレクションに使用するには、通常、その種のインスタンスをデータベースに格納し、それを問合せでgetCLOB()などのPL/SQLメソッドとともに使用してターゲットのデータを取得します。この項ではその方法を説明します。

データベース列を作成するには、URITypeまたはそのサブタイプのいずれかを使用するか、各URIのテキストのみを文字列として格納し、その後、URIへのアクセスがあったときに、必要なURITypeインスタンスをオン・デマンドで作成します。様々なURITypeサブタイプのオブジェクトを、同一のURIType データベース列に格納できます。

URITypeサブタイプから継承した独自のオブジェクト型を定義することもできます。新しい型を導出すると、カスタムのテクニックを使用してデータを取得、変換、またはフィルタリングできます。

関連項目:

- 新しいURITypeサブタイプの定義は、「パッケージURIFACTORYを使用したURITypeの新しいサブタイプの作成」を参照してください。

- XMLデータの変換は、「XSL変換とOracle XML DB」を参照してください。

例20-2は、HTTPUriおよびDBUri (URITypeサブタイプHTTPURITypeおよびDBURITypeのインスタンス)を、同じデータベース列(URIType型)に格納しています。問合せは、各URIが指しているデータを取得します。最初のURIはWebページのURLです。2番目のURIは標準データベース・スキーマHRの表employees内のデータを参照しています(説明を簡潔にするため、Webページの最初の部分のみを示しています)。

例20-2 URI列の作成と問合せ

CREATE TABLE uri_tab (url URIType);
Table created.

INSERT INTO uri_tab VALUES (HTTPURIType.createURI('http://www.oracle.com'));
1 row created.

INSERT INTO uri_tab VALUES (DBURIType.createURI(
'/HR/EMPLOYEES/ROW[FIRST_NAME="Jack"]'));
1 row created.

SELECT e.url.getCLOB() FROM uri_tab e;

E.URL.GETCLOB()
-------------------------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
. . .

<?xml version="1.0"?>
<ROW>
<EMPLOYEE_ID>177</EMPLOYEE_ID>
<FIRST_NAME>Jack</FIRST_NAME>
<LAST_NAME>Livingston</LAST_NAME>
<EMAIL>JLIVINGS</EMAIL>
<PHONE_NUMBER>011.44.1644.429264</PHONE_NUMBER>
<HIRE_DATE>23-APR-06</HIRE_DATE>
<JOB_ID>SA_REP</JOB_ID>
<SALARY>8400</SALARY>
<COMMISSION_PCT>.2</COMMISSION_PCT>
<MANAGER_ID>149</MANAGER_ID>
<DEPARTMENT_ID>80</DEPARTMENT_ID>
</ROW>

2 rows selected.

URIType PL/SQLメソッドcreateURI()を使用するには、使用する特定のURITypeサブタイプを把握している必要があります。パッケージURIFACTORYのPL/SQLメソッドgetURI()を使用すると、かわりに遅延バインディングを使用して、実行時に特定の型情報を決定できます。

URIFACTORY.getURI()はURI文字列を引数に取ります。適切なサブタイプ(HTTPURIType、DBURITypeまたはXDBURIType)のURITypeインスタンスを、URI文字列の形式に基づいて戻します。

- URIの先頭がhttp://の場合、getURI()はHTTPUriを作成して戻します。

- URIの先頭が/oradb/または/dburi/の場合、getURI()はDBUriを作成して戻します。

- それ以外の場合はgetURI()はXDBUriを作成して戻します。

しかし、例20-3は例20-2と似ていますが、この例では、2つの異なる方法を使用してURIのターゲットとなっている文書を取得します。

- PL/SQLメソッドSYS.URIFACTORY.getURI()と絶対URI

- HTTPアドレスhttp://www.oracle.comをターゲットとするHTTPUri

- データベース・アドレス/oradb/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]をターゲットとするDBUri

- コンストラクタSYS.HTTPURIType()と相対URL (http://なし)。絶対URIの場合と同じHTTPUri、Oracleホームページを使用しています。

例20-3では、getURI()に渡されるURI文字列はハードコードされていますが、これをアプリケーションが実行時に取得する文字列値にすることも非常に簡単に可能です。

例20-3 各種の方法で作成された様々な種類のURIの使用

CREATE TABLE uri_tab (docUrl SYS.URIType, docName VARCHAR2(200));
Table created.

-- Insert an HTTPUri with absolute URL into SYS.URIType using URIFACTORY.
-- The target is Oracle home page.
INSERT INTO uri_tab VALUES
(SYS.URIFACTORY.getURI('http://www.oracle.com'), 'AbsURL');
1 row created.

-- Insert an HTTPUri with relative URL using constructor SYS.HTTPURIType.
-- Note the absence of prefix http://. The target is the same.
INSERT INTO uri_tab VALUES (SYS.HTTPURIType('www.oracle.com'), 'RelURL');
1 row created.

-- Insert a DBUri that targets employee data from table HR.employees.
INSERT INTO uri_tab VALUES
(SYS.URIFACTORY.getURI('/oradb/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]'), 'Emp200');
1 row created.

-- Extract all of the documents.
SELECT e.docUrl.getCLOB(), docName FROM uri_tab e;

E.DOCURL.GETCLOB()
-----------------
DOCNAME
------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
. . .
AbsURL

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
. . .
RelURL

<?xml version="1.0"?>
<ROW>
<EMPLOYEE_ID>200</EMPLOYEE_ID>
<FIRST_NAME>Jennifer</FIRST_NAME>
<LAST_NAME>Whalen</LAST_NAME>
<EMAIL>JWHALEN</EMAIL>
<PHONE_NUMBER>515.123.4444</PHONE_NUMBER>
<HIRE_DATE>17-SEP-03</HIRE_DATE>
<JOB_ID>AD_ASST</JOB_ID>
<SALARY>4400</SALARY>
<MANAGER_ID>101</MANAGER_ID>
<DEPARTMENT_ID>10</DEPARTMENT_ID>
</ROW>
Emp200

3 rows selected.

-- In PL/SQL
CREATE OR REPLACE FUNCTION returnclob
RETURN CLOB
IS a SYS.URIType;
BEGIN
SELECT docUrl INTO a FROM uri_Tab WHERE docName LIKE 'Emp200%';
RETURN a.getCLOB;
END;
/
Function created.

SELECT returnclob() FROM DUAL;

RETURNCLOB()
---------------------------------------------------------------
<?xml version="1.0"?>
<ROW>
<EMPLOYEE_ID>200</EMPLOYEE_ID>
<FIRST_NAME>Jennifer</FIRST_NAME>
<LAST_NAME>Whalen</LAST_NAME>
<EMAIL>JWHALEN</EMAIL>
<PHONE_NUMBER>515.123.4444</PHONE_NUMBER>
<HIRE_DATE>17-SEP-03</HIRE_DATE>
<JOB_ID>AD_ASST</JOB_ID>
<SALARY>4400</SALARY>
<MANAGER_ID>101</MANAGER_ID>
<DEPARTMENT_ID>10</DEPARTMENT_ID>
</ROW>

1 row selected.

XDBUris: リポジトリ・リソースへのポインタ

XDBURITypeは、URIを使用してOracle XML DBリポジトリのリソースを公開する方法を提供するURITypeのサブタイプです。型XDBURITypeのインスタンスはXDBUriと呼ばれます。

XDBUri URIの構文

XDBUri URIのURL部分は、ターゲットのリポジトリ・リソースの階層アドレスです。XPath式ではなく、リポジトリ・パスです。

URIのオプションのフラグメント部分はXPath構文を使用しており、シャープ記号(#)によってURL部分と区切られています。これが適切なのは、ターゲットのリソースがXML文書であり、フラグメント部分がXML文書の1つ以上の部分をターゲットとする場合のみです。ターゲットのリソースがXML文書でない場合は、フラグメントとシャープ記号を省略します。

次に、XDBUri URIの例を示します。

- /public/hr/image27.jpg

- /public/hr/doc1.xml#/PurchaseOrder/LineItem

これらのURIの形式に基づいて、次のように判断できます。

- /public/hrはOracle XML DBリポジトリのフォルダ・リソースです。

- image27.jpgおよびdoc1.xmlはフォルダ/public/hrにあるリソースです。

- リソースdoc1.xmlはファイル・リソースで、1つのXML文書を含みます。

- XPath式 /PurchaseOrder/LineItemは、XML文書doc1.xmlの要素PurchaseOrder内のLineItem子要素を参照しています。

XDBUriを作成するには、パッケージURIFACTORYのPL/SQLメソッドgetURI()を使用します。

XDBURITypeは、URIFACTORY PL/SQLメソッドgetURI()を使用してインスタンスを生成する場合にデフォルトで使用されるURITypeです。ただしURIに、認識された接頭辞http://、/dburi、および/oradbのいずれかがある場合を除きます。

たとえば、リソースdoc1.xmlがリポジトリ・フォルダ/public/hrに存在する場合、次の問合せにより、そのリソースをターゲットにしているXDBUriが戻されます。

SELECT SYS.URIFACTORY.getURI('/public/hr/doc1.xml') FROM DUAL;

型がXDBURITypeであると判断するのは特別な接頭辞がないためであり、特定のリソース・ファイル拡張子がないためや、#に続いてXPath式があるためではありません。リソース名がdoc1.xmlでなくfoo.barであったとしても、戻されるURITypeインスタンスはやはりXDBUriになります。

XDBUriの例

例20-4では、XDBUriを作成して、値を発注書表に挿入し、すべての発注書を選択します。URIFACTORY.getURI()に渡されるURIに特別な接頭辞が付いていないため、作成されるURITypeインスタンスはXDBUriになります。

例20-4 XDBUriを使用した、URIによるリポジトリ・リソースへのアクセス

DECLARE
res BOOLEAN;
postring VARCHAR2(100):= '<?xml version="1.0"?>
<ROW>
<PO>999</PO>
</ROW>';
BEGIN
res:=DBMS_XDB.createFolder('/public/orders/');
res:=DBMS_XDB.createResource('/public/orders/po1.xml', postring);
END;
/
PL/SQL procedure successfully completed.

CREATE TABLE uri_tab (poUrl SYS.URIType, poName VARCHAR2(1000));
Table created.

-- Create an abstract type column so any type of URI can be used
-- Insert an absolute URL into poUrl.
-- The factory will create an XDBURIType because there is no prefix.
-- Here, po1.xml is an XML file that is stored in /public/orders/
-- of the XML repository.
INSERT INTO uri_tab VALUES
(URIFACTORY.getURI('/public/orders/po1.xml'), 'SomePurchaseOrder');
1 row created.

-- Get all the purchase orders
SELECT e.poUrl.getCLOB(), poName FROM uri_tab e;

E.POURL.GETCLOB()
-----------------
PONAME
------
<?xml version="1.0"?>
<ROW>
<PO>999</PO>
</ROW>
SomePurchaseOrder

1 row selected.

-- Using PL/SQL, you can access table uri_tab as follows:
CREATE OR REPLACE FUNCTION returnclob
RETURN CLOB
IS a URIType;
BEGIN
-- Get absolute URL for purchase order named like 'Some%'
SELECT poUrl INTO a FROM uri_tab WHERE poName LIKE 'Some%';
RETURN a.getCLOB();
END;
/
Function created.

SELECT returnclob() FROM DUAL;

RETURNCLOB()
---------------------
<?xml version="1.0"?>
<ROW>
<PO>999</PO>
</ROW>

1 row selected.

PL/SQLメソッドgetXML()はXMLTypeインスタンスを戻すため、これをXMLQueryなどのSQL/XML関数とともに使用できます。例20-5の問合せに、これを示します。この問合せは、番号が999のすべての発注書を取得します。

例20-5 XMLCASTおよびXMLQUERYでのPL/SQLメソッドGETXML()の使用

SELECT e.poUrl.getCLOB() FROM uri_tab e
WHERE XMLCast(XMLQuery('$po/ROW/PO'
PASSING e.poUrl.getXML() AS "po"
RETURNING CONTENT)
AS VARCHAR2(24))
= '999';

E.POURL.GETCLOB()
---------------------
<?xml version="1.0"?>
<ROW>
<PO>999</PO>
</ROW>

1 row selected.

DBUris: データベース・データへのポインタ

DBUriは、データベース・データをターゲットとするURIです。URITypeサブタイプのすべてのインスタンスに関して、DBUriはデータにアクセスするためのインダイレクション・メカニズムを提供します。さらに、DBURITypeを使用すると次のことが可能です。

- XPath表記法を使用したデータベース・データのアドレッシング。これにより、XMLデータの場合と同様にデータベースをビジュアル化してアクセスできます。
たとえば、DBUriは/HR/EMPLOYEES/ROW[FIRST_NAME="Jack"]といった式を使用し、表HR.employeesの、列first_nameの値がJackである行をターゲットにできます。

- DBUriを使用してターゲットとされているデータベース・データを含み、データベースの構造を反映した構造を持つXML文書を構成できます。
たとえばXPathで/HR/DBTAB/ROW/Aと表されたDBUriを使用して、データベース構造を反映しているXML要素内の列Aのデータを囲んでおり、それに応じた名前を持っているXML文書を構成できます。

<HR><DBTAB><ROW><A>...data_in_column_A...</A></ROW></DBTAB></HR>

DBUriは、HTTPUriのようにグローバルな場所を参照することはありません。ただし、DBUriでアドレッシングされているオブジェクトにグローバルにアクセスすることは可能です。それには、DBUriを処理するサーブレットを特定するためのHTTPUriにそのDBUriを追加します。「DBUriServlet」を参照してください。

XMLデータ形式でのデータベース表示

アクセスできるデータベース・スキーマは、アクセス権限を付与されているデータベース・スキーマのみです。データベースのこの部分が、データベースのユーザー独自のビューとなります。

DBURITypeを使用すると、対応するデータベースのXMLビューを持つことができます。これはユーザーがアクセス権限を持っているデータベースの部分で、XMLデータ形式で表示されます。これは、XMLで格納されているデータに限らない、すべての種類のデータベース・データです。この方法でビジュアル化されたデータベース・データはXML要素で効率的に囲まれており、1つまたはそれ以上のXML文書が結果として生成されます。

この種の「XMLビュー」は、技術的な意味ではデータベース・ビューではありません。ここで「ビュー」と呼ばれているものは、DBURITypeの理解に有効な抽象的な観点を示すものにすぎません。DBURITypeを、データベースをXMLデータ同様にビジュアル化し、アクセスを提供するものとみなすことができます。

ただし、DBURITypeは、ビジュアル化を実行し、データベース・データへの別個のアクセス手段を提供するだけのものではありません。各「XMLビュー」はXML文書として実現されます。つまり、DBURITypeを使用すると、データベース・データを基にしてXML文書を生成できます。

以上はすべて、DBURIType ではXPath表記法を使用して(1)アクセス権限のある任意のデータベース・データのアドレッシングとアクセス、および(2)データのXML表現の構成を行うことができるということです。

図20-1はリレーショナル表HR.employees、その表の一部に対応するXMLビュー、および対応するDBUri URI(簡素化されたXPath式)の間の関係を示しています。この場合、XMLとして公開されるデータの部分は、employee_idが200である行となります。URIを使用してデータにアクセスし、「XMLビュー」を反映するXML文書を構成することができます。

図20-1 リレーショナル・データのXMLビジュアル化に対応するDBUri

「XMLビュー」内のXML要素とURI XPath式内のステップは、どちらもデータベース表と列名を反映しています。「XMLビュー」とURI XPath式のどちらにおいても、データベース表の行を示すROWの用法に注意してください。

XPath式にはルート要素ステップoradbが含まれていることにも注意してください。これは、URIが、HTTPUriやXDBUriでなくDBUriに対応していることを示すのに使用されます。この対応がコンテキストから認識されている場合は、XPathステップはスキップ可能です。たとえば、問題のパスがデータベース・データのパスであるとわかっている場合、次のURIは同じ内容になります。

- /oradb/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/LAST_NAME

- /HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/LAST_NAME

ただしURIコンテキストが不明確な場合は、接頭辞/oradbを使用して、DBUriに対応するURIであることを示す必要があります。特に、URIFACTORY PL/SQLメソッドやDBUriServletには接頭辞を指定する必要があります。

関連項目:

- 「パッケージURIFACTORYを使用したURITypeの作成」

- 「DBUriServlet」

- データベース・データからXMLを生成する他の方法は、第18章「データベースからのXMLデータの生成」を参照してください。

DBUri URIの構文

XPath式は、1つ以上のXMLノードをアドレッシングするXMLデータへのパスです。DBUriはデータベースの仮想XMLユーザー・ビジュアル化の概念を利用して、簡素化された形式のXPath式を、データベース・データをアドレッシングするURIとして使用します。これは、データの型や、データがXMLかどうかには依存しません。

このため、DBURITypeの場合、Oracle DatabaseはXPathやXPointerの構文を完全にはサポートしません。XDBUri XPath式には構文の制限はありません。DBUriには1つ例外があります。XMLType表内のデータです。XMLType表の場合、データベース内の表自身をアドレッシングするために、簡素化されたXPath形式が使用されます。その後、XPath式の残りの部分では、完全なXPathの構文を使用して表内の特定のXMLデータをアドレッシングできます。この例外はXMLTypeの表にのみ適用されます。XMLType列には適用されません。

いずれの場合も、XDBUriとは異なり、DBUri URIではシャープ記号(#)を使用してURIのURL部分とフラグメント(XPath)部分を区切ることはありません。DBURITypeではURIフラグメントは使用されません。URI全体が(簡素化された)XPath式とみなされます。

DBUriは、アクセス権限のあるあらゆるデータベース・データに作成できます。次のようなXPath式を使用できます。

- /database_schema/table

- /database_schema/table/ROW[predicate_expression]/column

- /database_schema/table/ROW[predicate_expression]/object_column/attribute

- /database_schema/XMLType_table/ROW/XPath_expression

最後の例で、XMLType_tableはXMLType表で、XPath_expressionは任意のXPath式です。XMLTypeでない表の場合は、DBUri XPath式の末尾は列である必要があります(列の内部の特定のデータをアドレッシングすることはできません)。この制限の対象には、XMLデータを含むXMLType列、LOB列、およびVARCHAR2列が含まれます。

DBUri XPath式には次のことが可能です。

- 表全体をターゲットとする。
たとえば、/HR/EMPLOYEESは、データベース・スキーマHRの表employeesをターゲットとしています。

- データベース・スキーマおよび表ステップ以外のパス内の任意のステップにXPath述語を含める。
たとえば、/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/EMAILはemployee_idが200という条件下で、表HR.employeesのemail列をターゲットとしています。

- スカラー・コンテンツを持つデータに対するtext() XPathノード・テスト。これは使用可能な唯一のノード・テストで、表および行ステップには使用できません。

DBUri (XPath)述語式では次のものを使用できます。

- ブール演算子: and、orおよびnot

- 関係演算子: <、>、<=、!=、>=、=、mod、div、*(乗算)

DBUri XPath式の使用には次の条件があります。

- child XPath軸のみを使用できます。parentなど、他の軸は使用できません。

- データベース・スキーマを指定するか、または特定のスキーマを持たない表名を解決するためにPUBLICを指定する必要があります。

- データベース・ビューまたは表名を指定する必要があります。

- データベース列がターゲットの場合はROWステップを含めます。

- 単一のデータ値を識別する必要があります。オブジェクト型のインスタンスまたはコレクションを使用できます。

- データベース・データを使用して、XMLデータを生成するために使用する場合は、結果は整形式のXMLである必要があります。
整形式のXMLを結果としないDBUriの例は/HR/EMPLOYEES/ROW/LAST_NAMEです。これは複数の<LAST_NAME>要素フラグメントを、単一のルート要素を伴わずに戻します。

- 次のものは使用できません。

- *(ワイルドカード)

- .(それ自身)

- ..(親)

- //(子孫またはそれ自身)

- countなどのXPath関数

DBUri XPath式は、オプションで接頭辞/oradbまたは/dburi (どちらも同じです)を付けて識別できます。この接頭辞では大文字/小文字が区別されません。ただし、DBUri XPath式の残りの部分は、通常のXPath式同様、大文字/小文字が区別されます。このため、たとえば表HR.employeesをDBUri XPath式として指定するには、hr/employees (または大文字と小文字の混合)ではなくHR/EMPLOYEESを使用する必要があります。表や列の名前はデフォルトで大文字だからです。

関連項目:
XPath表記法についてはhttp://www.w3.org/TR/xpath

データベースおよびセッションを有効範囲とするDBUri

データベースの「XMLビュー」のコンテンツ、つまり構成可能なXML文書のコンテンツは、指定された時点で個別のデータベース・データにアクセスするために持っている権限を反映しています。つまり、DBUriの有効範囲は指定されたデータベース・セッションなので、セッションのコンテキスト(接続しているユーザーおよびユーザーが持っている権限)に応じて、同じDBUriでも異なる結果が得られます。

少し複雑になりますが、データベース・スキーマ修飾がなくてもデータベース・データにアクセスできるXML要素PUBLICもあります。これは便利な機能ですが、混乱を招くこともあります。指定ユーザー用のデータベースのXMLビューが、そのユーザーが指定時点でデータベースに対して持っている特定のアクセス権限に依存していることを忘れないでください。

XML要素PUBLICはパブリック・シノニムの使用に対応しています。たとえば、ユーザーquineが問合せを実行する場合、次の問合せは、データベース・スキーマquineの下の表 fooを一致させようと試みますが、そのような表がない場合は、fooという名前のバブリック・シノニムを一致させようとします。

SELECT * FROM foo;

同様に、XML要素PUBLICは、指定のユーザーに表示されるすべてのデータベース・データと、パブリック・シノニムを介してそのユーザーに表示されるすべてのデータを含みます。このため、同一のDBUri URI /PUBLIC/FOOが、ユーザーquineが接続している場合はquine.fooと解決され、ユーザーcurryが接続している場合はcurry.fooと解決されます。

DBUriの例

DBUriが識別できるのは、表、行、行内の列、オブジェクト列の属性のいずれかです。次の項に、様々な種類のオブジェクトをターゲット化する方法を示します。

表のターゲット化

この構文を使用して、完全なデータベース表をターゲットにできます。

/database_schema/table

例20-6では、完全な表をターゲット化するDBUriを使用します。表のコンテンツに対応するXML文書が戻されます。最上位のXML要素の名前は表により決まります。各行の値はROW要素で囲まれます。

例20-6 DBUriを使用した完全な表のターゲット化

CREATE TABLE uri_tab (url URIType);
Table created.

INSERT INTO uri_tab VALUES
(DBURIType.createURI('/HR/EMPLOYEES'));
1 row created.

SELECT e.url.getCLOB() FROM uri_tab e;

E.URL.GETCLOB()
---------------
<?xml version="1.0"?>
<EMPLOYEES>
<ROW>
<EMPLOYEE_ID>100</EMPLOYEE_ID>
<FIRST_NAME>Steven</FIRST_NAME>
<LAST_NAME>King</LAST_NAME>
<EMAIL>SKING</EMAIL>
<PHONE_NUMBER>515.123.4567</PHONE_NUMBER>
<HIRE_DATE>17-JUN-03</HIRE_DATE>
<JOB_ID>AD_PRES</JOB_ID>
<SALARY>24000</SALARY>
<DEPARTMENT_ID>90</DEPARTMENT_ID>
</ROW>
<ROW>
<EMPLOYEE_ID>101</EMPLOYEE_ID>
<FIRST_NAME>Neena</FIRST_NAME>
<LAST_NAME>Kochhar</LAST_NAME>
<EMAIL>NKOCHHAR</EMAIL>
<PHONE_NUMBER>515.123.4568</PHONE_NUMBER>
<HIRE_DATE>21-SEP-05</HIRE_DATE>
<JOB_ID>AD_VP</JOB_ID>
<SALARY>17000</SALARY>
<MANAGER_ID>100</MANAGER_ID>
<DEPARTMENT_ID>90</DEPARTMENT_ID>
</ROW>
. . .

1 row selected.

表内の行のターゲット化

この構文を使用して、表の1行または複数の行をターゲットにできます。

/database_schema/table/ROW[predicate_expression]

例20-7では、表の中の1行をターゲット化するDBUriを使用します。XPath述語式は、従業員番号200に対応する、表の1行を識別します。結果は、ROWを最上位要素とするXML文書です。

例20-7 DBUriを使用した表内の個別行のターゲット化

CREATE TABLE uri_tab (url URIType);
Table created.

INSERT INTO uri_tab VALUES
(DBURIType.createURI('/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]'));
1 row created.

SELECT e.url.getCLOB() FROM uri_tab e;

E.URL.GETCLOB()
-------------------------------------------------------
<?xml version="1.0"?>
<ROW>
<EMPLOYEE_ID>200</EMPLOYEE_ID>
<FIRST_NAME>Jennifer</FIRST_NAME>
<LAST_NAME>Whalen</LAST_NAME>
<EMAIL>JWHALEN</EMAIL>
<PHONE_NUMBER>515.123.4444</PHONE_NUMBER>
<HIRE_DATE>17-SEP-03</HIRE_DATE>
<JOB_ID>AD_ASST</JOB_ID>
<SALARY>4400</SALARY>
<MANAGER_ID>101</MANAGER_ID>
<DEPARTMENT_ID>10</DEPARTMENT_ID>
</ROW>

1 row selected.

列のターゲット化

この構文を使用して、特定の列をターゲットにできます。

/database_schema/table/ROW[predicate_expression]/column

この構文を使用して、オブジェクト列の特定の属性をターゲットにできます。

/database_schema/table/ROW[predicate_expression]/object_column/attribute

この構文を使用して、属性が特定の値を持つ特定のオブジェクト列をターゲットにできます。

/database_schema/table/ROW[predicate_expression_with_attributes]/object_column

例20-8では、例20-7と同じ従業員について、列last_nameをターゲットするDBUriを使用します。最上位のXML要素の名前はターゲット列により決まります。

例20-8 DBUriを使用した特定の列のターゲット化

CREATE TABLE uri_tab (url URIType);
Table created.

INSERT INTO uri_tab VALUES
(DBURIType.createURI('/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/LAST_NAME'));
1 row created.

SELECT e.url.getCLOB() FROM uri_tab e;

E.URL.GETCLOB()
------------------------------
<?xml version="1.0"?>
<LAST_NAME>Whalen</LAST_NAME>

1 row selected.

例20-9では、cityおよびpostal code属性が特定の値になっているCUST_ADDRESSオブジェクト列をターゲットとするDBUriを使用します。最上位のXML要素には列の名前が付けられ、オブジェクト属性それぞれに対応する子要素が含まれます。

例20-9 DBUriを使用した、特定の属性値を持つオブジェクト列のターゲット化

CREATE TABLE uri_tab (url URIType);
Table created.

INSERT INTO uri_tab VALUES
(DBURIType.createURI(
'/OE/CUSTOMERS/ROW[CUST_ADDRESS/CITY="Poughkeepsie" and
CUST_ADDRESS/POSTAL_CODE=12601]/CUST_ADDRESS'));
1 row created.

SELECT e.url.getCLOB() FROM uri_tab e;

E.URL.GETCLOB()
---------------
<?xml version="1.0"?>
<CUST_ADDRESS>
<STREET_ADDRESS>33 Fulton St</STREET_ADDRESS>
<POSTAL_CODE>12601</POSTAL_CODE>
<CITY>Poughkeepsie</CITY>
<STATE_PROVINCE>NY</STATE_PROVINCE>
<COUNTRY_ID>US</COUNTRY_ID>
</CUST_ADDRESS>

1 row selected.

このDBUriは、CITY属性がPoughkeepsieを値に持ち、POSTAL_CODE属性が12601を値に持つオブジェクトを識別します。

列のテキスト値の取出し

多くの場合、囲みタグを取り出さずに、列のテキスト値のみを取り出す方が有効です。たとえば、XSLTスタイルシートがCLOB列に格納されている場合は、文書を列名のタグで囲まなくても、その文書を取り出すことができます。この場合は、text() XPathノード・テストを使用できます。ノードのテキスト値のみを取り出すように指定できます。次の構文を使用します。

/oradb/database_schema/table/ROW[predicate_expression]/column/text()

例20-10は、従業員番号200の従業員のlast_name列のテキスト値を、XMLタグなしで取得します。

例20-10 DBUriを使用したノードのテキスト値のみの取出し

CREATE TABLE uri_tab (url URIType);
Table created.

INSERT INTO uri_tab VALUES
(DBURIType.createURI(
'/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/LAST_NAME/text()'));

1 row created.

SELECT e.url.getCLOB() FROM uri_tab e;

E.URL.GETCLOB()
---------------
Whalen

1 row selected.

コレクションのターゲット化

Ordered Collection Tableなど、データベース・コレクションをターゲットにできます。ただし、ターゲットはその全体をターゲット化する必要があります。コレクションの個別のメンバーをターゲットにすることはできません。コレクションがターゲット化されると、DBUriにより生成されたXML文書には、各コレクションの全メンバーがそれぞれ、コレクションの型に対応する名前の要素で囲まれたXML要素として含まれます。

例20-11では、数値のコレクションをターゲット化するDBUriを使用します。最上位のXML要素はコレクションの名前が付けられ、その子はコレクションの型(NUMBER)の名前が付けられます。

例20-11 DBUriを使用したコレクションのターゲット化

CREATE TYPE num_collection AS VARRAY(10) OF NUMBER;
/
Type created.

CREATE TABLE orders (item VARCHAR2(10), quantities num_collection);
Table created.

INSERT INTO orders VALUES ('boxes', num_collection(3, 7, 4, 9));
1 row created.

SELECT * FROM orders;

ITEM
----
QUANTITIES
----------
boxes
NUM_COLLECTION(3, 7, 4, 9)

1 row selected.

SELECT DBURIType('/HR/ORDERS/ROW[ITEM="boxes"]/QUANTITIES').getCLOB() FROM DUAL;

DBURITYPE('/HR/ORDERS/ROW[ITEM="BOXES"]/QUANTITIES').GETCLOB()
--------------------------------------------------------------
<?xml version="1.0"?>
<QUANTITIES>
<NUMBER>3</NUMBER>
<NUMBER>7</NUMBER>
<NUMBER>4</NUMBER>
<NUMBER>9</NUMBER>
</QUANTITIES>

1 row selected.

パッケージURIFACTORYを使用したURITypeの作成

PL/SQLパッケージURIFACTORYを使用すると、URITypeインスタンスの作成以上のことができます。他のPL/SQLメソッドを表20-2にリストします。

表20-2 URIFACTORY PL/SQLメソッド

PL/SQLメソッド

説明

getURI()

URITypeインスタンスのURLを戻します。

escapeURI()

URIで許容されない文字を同等のエスケープ・シーケンスに置換することによって、URI文字列をエスケープします。

unescapeURI()

指定のURIからエスケープを削除します。

registerURLHandler()

特定のURLを処理するための特定の型名を登録します。その型のインスタンスを生成するためにgetURI()によってコールされます。

ブール引数を使用して、適切な型コンストラクタをコールする前に、接頭辞を削除する必要があることを示すことができます。

unregisterURLHandler()

URLハンドラを登録解除します。

特に注意を要するのは、パッケージURIFACTORYを使用して、型がURITypeの新しいサブタイプを定義できることです。そのサブタイプを使用して、URI用の特別な処理を提供することができます。特に、特定のプロトコルに対応するURITypeサブタイプを定義できます。URIFACTORYは、これらのサブタイプのインスタンスを、適切に認識して処理します。

新しい型を定義して、その型に固有のデータベース列を作成する利点は次のとおりです。

- その列に対して暗黙的な制約を提供して、その型のインスタンスのみを含むようにできます。これは、その列に特定のプロトコルのスペシャライズ・インデックスを実装する場合に有効です。たとえばDBUriの場合、SQL問合せを実行せず、ディスクから直接データをフェッチするスペシャライズ・インデックスを実装することができます。

- 型に基づいて、それぞれの列に異なる制約を規定できます。たとえばHTTPUriの場合、列に対してプロキシおよびファイアウォールの制約を定義して、HTTPを介したすべてのアクセスでプロキシ・サーバーを使用するようにできます。

パッケージURIFACTORYで新しいURITypeのサブタイプを登録

URI用の特別な処理を提供するには、次のようにして、新しいURITypeのサブタイプを定義および登録します。

1. SQL文CREATE TYPEを使用して、新しい型を作成します。この方にはPL/SQLメソッドcreateURI()が実装される必要があります。

2. オプションで、デフォルトのメソッドをオーバーライドして、データを取り出すときに特別な処理を実行するか、またはXMLデータを変換してから表示します。

3. この特別な処理に使用するURIを識別する新しいURI接頭辞を決定します。

4. PL/SQLメソッドregisterURLHandler()を使用して、新しい接頭辞を登録します。これによって、定義した新しい接頭辞で始まるURIを受け取ったパッケージURIFACTORYが、新しいサブタイプのインスタンスを作成できるようになります。

新しいサブタイプを定義すると、新しい接頭辞の付いたURIがURIFACTORYメソッドで認識され、また、新しい型のインスタンスを作成して使用できます。

たとえば、新しいプロトコル接頭辞ecom://を作成し、そのプロトコルを処理するためのURITypeのサブタイプを定義する場合を考えます。場合によると新しいサブタイプは、PL/SQLメソッドgetCLOB()用の特別なロジックを実装するか、メソッドgetXML()におけるXMLタグやデータを多少変更します。接頭辞ecom://をURIFACTORYで登録すると、getURI()へのコールにより、その接頭辞を伴うURI用に新しいURITypeサブタイプのインスタンスが生成されます。

例20-12では、新しいプロトコルecom://を処理する新しい型ECOMURITypeを作成しています。この例は1つの表に3種類の異なるURI(HTTPUri、DBUri、および新しい型ECOMURITypeのインスタンス)を格納します。この例を実行するには、各ECOMURITypeメンバー関数を定義する必要があります。

例20-12 URIFACTORY: ECOMプロトコルの登録

CREATE TABLE url_tab (urlcol varchar2(80));
Table created.

-- Insert an HTTP URL reference
INSERT INTO url_tab VALUES ('http://www.oracle.com/');
1 row created.

-- Insert a DBUri
INSERT INTO url_tab VALUES ('/oradb/HR/EMPLOYEES/ROW[FIRST_NAME="Jack"]');
1 row created.

-- Create a new type to handle a new protocol called ecom://
-- This is just an example template. For this to run, the implementations
-- of these functions must be specified.
CREATE OR REPLACE TYPE ECOMURIType UNDER SYS.URIType (
OVERRIDING MEMBER FUNCTION getCLOB RETURN CLOB,
OVERRIDING MEMBER FUNCTION getBLOB RETURN BLOB,
OVERRIDING MEMBER FUNCTION getExternalURL RETURN VARCHAR2,
OVERRIDING MEMBER FUNCTION getURI RETURN VARCHAR2,
-- Must have this for registering with the URL handler
STATIC FUNCTION createURI(url IN VARCHAR2) RETURN ECOMURIType);
/
-- Register a new handler for the ecom:// prefixes
BEGIN
-- The handler type name is ECOMURIType; schema is HR
-- Ignore the prefix case, so that URIFACTORY creates the same subtype
-- for URIs beginning with ECOM://, ecom://, eCom://, and so on.
-- Strip the prefix before calling PL/SQL method createURI(),
-- so that the string 'ecom://' is not stored inside the
-- ECOMURIType object. It is added back automatically when
-- you call ECOMURIType.getURI().
URIFACTORY.registerURLHandler (prefix => 'ecom://',
schemaname => 'HR',
typename => 'ECOMURITYPE',
ignoreprefixcase => TRUE,
stripprefix => TRUE);
END;
/
PL/SQL procedure successfully completed.

-- Insert this new type of URI into the table
INSERT INTO url_tab VALUES ('ECOM://company1/company2=22/comp');
1 row created.

-- Use the factory to generate an instance of the appropriate
-- subtype for each URI in the table.

-- You would need to define the member functions for this to work:
SELECT urifactory.getURI(urlcol) FROM url_tab;

-- This would generate:
HTTPURIType('www.oracle.com'); -- an HTTPUri
DBURIType('/oradb/HR/EMPLOYEES/ROW[FIRST_NAME="Jack"]', null); -- a DBUri
ECOMURIType('company1/company2=22/comp'); -- an ECOMURIType instance

SYS_DBURIGEN SQL関数

DBUriを作成するには、XPath式をコンストラクタDBURIType、または適切なURIFACTORY PL/SQLメソッドに対して指定します。Oracle SQL関数sys_DburiGenを使用すると、データベース列とその値から構成されたXPathを使用してDBUriを作成する方法を使用できます。

Oracle SQL関数sys_DburiGenは、引数として1つ以上の列または属性、およびオプションでrowidを取り、特定の列オブジェクトまたは行オブジェクトをターゲットにするDBUriを生成します。関数sys_DburiGenは、ノードのテキスト値が必要かどうかを示す追加のパラメータを取ります。図20-2を参照してください。

図20-2 SYS_DBURIGENの構文

参照するすべての列または属性は、同じ表内に存在する必要があります。それらはそれぞれ一意の値を参照する必要があります。複数の列を指定した場合、最初の列は行を識別し、最後の列はその行内の列を識別します。データベース・スキーマを指定しない場合、表名はパブリック・シノニムとして解釈されます。

関連項目:
『Oracle Database SQL言語リファレンス』

例20-13では、Oracle SQL関数sys_DburiGenを使用して、employee_idが206という条件下で表HR.employeesのemailをターゲットにするDBUriを生成しています。

例20-13 SYS_DBURIGEN: 列をターゲットとするDBUriの生成

SELECT sys_DburiGen(employee_id, email)
FROM employees
WHERE employee_id = 206;

SYS_DBURIGEN(EMPLOYEE_ID,EMAIL)(URL, SPARE)
-------------------------------------------------------------------
DBURITYPE('/PUBLIC/EMPLOYEES/ROW[EMPLOYEE_ID = "206"]/EMAIL', NULL)

1 row selected.

列またはオブジェクト属性をSYS_DBURIGENに渡す規則

Oracle SQL関数sys_DburiGenに渡される列または属性は、次の規則に従う必要があります。

- 同一の表: 関数sys_DburiGenで参照されるすべての列は、同じ表またはビューから取得する必要があります。

- 一意のマッピング: 列またオブジェクト属性は、元の表またはビューに一意にマップ可能である必要があります。使用可能な仮想列は、valueおよびrefで作成されたもののみです。列は、SQL TABLEコレクション式(TABLE(...))またはインライン・ビュー(そのインライン・ビューが列の名前を変更しない場合)の副問合せから取得される場合があります。
SQL TABLEコレクション式の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- キー列: ROWIDまたは一連のキー列のいずれかを指定する必要があります。キー列のリストは、列が結果内の特定の行を一意に識別できるかぎり、一意キーまたは主キーとして宣言する必要はありません。

- PUBLIC要素: ROWIDまたはキー列がターゲットとしている表またはビューがデータベース・スキーマを指定していない場合は、PUBLICキーワードが使用されます。DBUriがアクセスされると、表名は、DBUriの作成時にその名前で参照できた表、シノニムまたはデータベース・ビューに変換されます。

- オプションのtext()引数: デフォルトでは、DBURITypeはXML文書を構成します。text()をsys_DburiGenの第3の引数として使用して、テキスト・ノード(XML要素なし)をターゲットにするDBUriを作成します。次に例を示します。

SELECT sys_DburiGen(employee_id, last_name, 'text()') FROM hr.employees,
WHERE employee_id=200;

これにより、次のURIを持つDBUriが構成されます。

/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/LAST_NAME/text()

- 単一列の引数: 単一列の引数がある場合、列は、行を識別するキー列と参照列の両方として使用されます。

例20-14の問合せは、employee_idを、キー列と参照列の両方として使用します。employee_idが200の行をターゲットにするDBUriを生成します。

例20-14 SYS_DBURIGENへの単一の引数を持つ列の送信

SELECT sys_DburiGen(employee_id) FROM employees
WHERE employee_id=200;

SYS_DBURIGEN(EMPLOYEE_ID)(URL, SPARE)
-------------------------------------
DBURITYPE('/PUBLIC/EMPLOYEES/ROW[EMPLOYEE_ID=''200'']/EMPLOYEE_ID', NULL)

1 row selected.

SYS_DBURIGEN SQL関数: 例

例20-15 SYS_DBURIGENを使用したデータベース参照の挿入

CREATE TABLE doc_list_tab (docno NUMBER PRIMARY KEY, doc_ref SYS.DBURIType);
Table created.

-- Insert a DBUri that targets the row with employee_id=177
INSERT INTO doc_list_tab VALUES(1001, (SELECT sys_DburiGen(rowid, employee_id)
FROM employees WHERE employee_id=177));
1 row created.

-- Insert a DBUri that targets the last_name column of table employees
INSERT INTO doc_list_tab VALUES(1002,
(SELECT sys_DburiGen(employee_id, last_name)
FROM employees WHERE employee_id=177));
1 row created.

SELECT * FROM doc_list_tab;

DOCNO
----------
DOC_REF(URL, SPARE)
-----------------------------------------------------
1001
DBURITYPE('/PUBLIC/EMPLOYEES/ROW[ROWID=''AAAQCcAAFAAAABSABN'']/EMPLOYEE_ID', NULL)

1002
DBURITYPE('/PUBLIC/EMPLOYEES/ROW[EMPLOYEE_ID=''177'']/LAST_NAME', NULL)

2 rows selected.

部分的な結果の取得

大きい列から選択する場合、結果の一部のみを取り出し、かわりに列に対するURLを作成する場合があります。たとえば、旅行体験記についてのWebサイトを考えてみます。表にすべての旅行体験記が格納されていて、ユーザーが関連する一連の体験記を検索する場合、検索結果のページに各体験記の全体をリストするのは不都合です。そのかわりに、各体験記の最初の20文字のみを要点として表示し、体験記全体のURLを戻す方がよいでしょう。これを行うには、次の手順を実行します。

例20-16では、旅行体験記の表を作成します。

例20-16 旅行体験記の表の作成

CREATE TABLE travel_story (story_name VARCHAR2(100), story CLOB);
Table created.

INSERT INTO travel_story
VALUES ('Egypt', 'This is the story of my time in Egypt....');
1 row created.

例20-17では、旅行体験記の最初の20文字のみを戻す関数を作成します。

例20-17 最初の20文字のみを戻す関数

CREATE OR REPLACE FUNCTION charfunc(clobval IN CLOB) RETURN VARCHAR2 IS
res VARCHAR2(20);
amount NUMBER := 20;
BEGIN
DBMS_LOB.read(clobval, amount, 1, res);
RETURN res;
END;
/
Function created.

例20-18では、旅行体験記の最初の20文字のみを選択し、story列のDBUriを戻すビューを作成します。

例20-18 SYS_DBURIGENで使用するための旅行体験記ビューの作成

CREATE OR REPLACE VIEW travel_view AS
SELECT story_name, charfunc(story) short_story,
sys_DburiGen(story_name, story, 'text()') story_link
FROM travel_story;
View created.

SELECT * FROM travel_view;

STORY_NAME
----------
SHORT_STORY
-----------
STORY_LINK(URL, SPARE)
----------------------
Egypt
This is the story of
DBURITYPE('/PUBLIC/TRAVEL_STORY/ROW[STORY_NAME=''Egypt'']/STORY/text()', NULL)

1 row selected.

挿入されたオブジェクトへのRETURNING URL

DML文のRETURNING句にあるOracle SQL関数sys_DburiGenを使用すると、オブジェクトの挿入時にそのオブジェクトのURLを取得できます。

例20-19では、文書が表clob_tabに挿入されると、そのURLが表uri_tabに常に挿入されます。これを実現するには、INSERT文のRETURNING句でOracle SQL関数sys_DburiGenを使用します。

例20-19 RETURNING句でのSYS_DBURIGENの使用によるURLの取得

CREATE TABLE clob_tab (docid NUMBER, doc CLOB);
Table created.

CREATE TABLE uri_tab (docs SYS.DBURIType);
Table created.

PL/SQLでは、RETURNING句とEXECUTE IMMEDIATEを使用して、挿入された文書のURLの記憶域を挿入操作の中で指定します。

DECLARE
ret SYS.DBURIType;
BEGIN
-- execute the insert operation and get the URL
EXECUTE IMMEDIATE
'INSERT INTO clob_tab VALUES (1, ''TEMP CLOB TEST'')
RETURNING sys_DburiGen(docid, doc, ''text()'') INTO :1'
RETURNING INTO ret;
-- Insert the URL into uri_tab
INSERT INTO uri_tab VALUES (ret);
END;
/

SELECT e.docs.getURL() FROM hr.uri_tab e;
E.DOCS.GETURL()
------------------------------------------------
/ORADB/PUBLIC/CLOB_TAB/ROW[DOCID='1']/DOC/text()

1 row selected.

DBUriServlet

Oracle XML DBリポジトリ・リソースは、Oracle XML DBに組み込まれているHTTPサーバーを使用して取得できます。Oracle Databaseには、あらゆる種類のデータベース・データを、HTTP(S) URLを介して利用できるようにするサーブレットDBUriServletも含まれています。データは、プレーン・テキスト、HTMLまたはXMLとして戻されます。

WebクライアントまたはWebアプリケーションは、SQLや特別なデータベースAPIがなくてもこのデータにアクセスできます。データを取り出すには、Webページ内でそのデータにリンクさせるか、またはJava、PL/SQLまたはPerlの、HTTPを認識するAPIを介してそのデータを要求します。このデータは、Webブラウザや、XML対応スプレッドシートなどのアプリケーションで表示または処理できます。DBUriServletは、XMLデータおよび非XMLデータのコンテンツを生成でき、XSLTスタイルシートを使用して結果を変換できます。

データベース・データをWebからアクセスできるようにするには、サーブレットのアドレス(URL)と、取得するデータベース・データを指定するDBUri URIから構成されているURIを使用します。構文を次に示します。ここで、http://server:portはサーブレットのURL (サーバーとポート)、/oradb/database_schema/tableはDBUri URI (あらゆるDBUri URIを使用可能)です。

http://server:port/oradb/database_schema/table

サーブレットのURLでXPath表記法を使用する場合、一部の文字をエスケープする必要があることがあります。その場合は URIType PL/SQLメソッドgetExternalURL()を使用します。

Oracle XML DBの一部としてあらかじめインストールされているDBUriServletを使用するか、サーブレット・エンジンで実行する独自のサーブレットを作成します。このサーブレットは呼び出すURLのURI部分を読み取り、そのURIを使用してDBUriを作成し、URIType PL/SQLメソッドをコールしてデータを取得し、Webページ、XML文書、プレーン・テキスト文書などと同様の形式で値を戻します。

使用するMIMEタイプは、URIを介してサーブレットに対して指定されます。

- デフォルトでは、サーブレットはtext/xmlおよびtext/plainのMIMEタイプを作成できます。DBUriパスの末尾がtext()の場合は、text/plainが使用されます。それ以外の場合は、XML文書はMIMEタイプtext/xmlを使用して生成されます。

- サーブレットに対するcontenttype引数を使用してデフォルトのMIMEタイプをオーバーライドし、binary/x-jpegなどの値に設定できます。

関連項目:
Oracle XML DBのサーブレットの詳細は、第32章「JavaでのOracle XML DBアプリケーションの作成」を参照してください。

表20-3に、出力をカスタマイズするためにDBUriServletに渡すオプションのURLパラメータを示します。

表20-3 DBUriServlet: オプションの引数

引数

説明

rowsettag

XML文書のデフォルトのルート・タグ名を変更します。次に例を示します。

http://server:8080/oradb/HR/EMPLOYEES?rowsettag=OracleEmployees

contenttype

生成されるドキュメントのMIMEタイプを指定します。次に例を示します。

http://server:8080/oradb/HR/EMPLOYEES?contenttype=text/plain

transform

XSLスタイルシートをその位置で取得するURIFACTORYにURLを渡します。このスタイルシートは、サーブレットによって戻されたXML文書に適用されます。次に例を示します。

http://server:8080/oradb/HR/EMPLOYEES?transform=/oradb/QUINE/XSLS/DOC/text()&contenttype=text/html

URLを使用したMIMEタイプのオーバーライド

employee表のemployee_id列を取得するには、次のいずれかに類似したURLを使用できます。ここでコンピュータserver.oracle.comがOracle Databaseを実行しており、Webサービスがポート8080でリクエストをリッスンしています。ステップoradbはサーブレットにマップする仮想パスです。

- http://server.oracle.com:8080/oradb/QUINE/A/ROW[B=200]/C/text()

text/plainのコンテンツ・タイプを生成

- http://server.oracle.com:8080/oradb/QUINE/A/ROW[B=200]/C

text/xmlのコンテンツ・タイプを生成

コンテンツ・タイプをオーバーライドするには、text/htmlをcontenttypeパラメータとしてサーブレットに渡すURLを使用できます。

- http://server.oracle.com:8080/oradb/QUINE/A/ROW[B=200]/C?contenttype=text/html

text/htmlのコンテンツ・タイプを生成

DBUriServletのカスタマイズ

DBUriServletはデータベースに組み込まれています。サーブレットをカスタマイズするには、Oracle XML DB構成ファイルxdbconfig.xmlを編集する必要があります。これは、WebDAV、FTP、Oracle Enterprise Manager、PL/SQLのいずれかを使用して、データベース・スキーマ(ユーザー・アカウント) XDBで編集できます。FTPまたはWebDAVを使用してファイルを更新するには、文書をダウンロードし、編集し、データベースに再度保存します。

関連項目:

- 第32章「JavaでのOracle XML DBアプリケーションの作成」

- 第34章「Oracle XML DBの管理」

- データベース・スキーマXDBの詳細は、『Oracle Database 2日でセキュリティ・ガイド』を参照してください。

DBUriServletのインストール先は/oradb/*で、これはxdbconfig.xmlのservlet-patternタグで指定されているアドレスです。アスタリスク(*)は、oradb以降のすべてのパスが同じサーブレットにマップされることを示すために必要です。oradbは仮想パスとして公開されます。サーブレットにアクセスするために使用するパスを変更できます。

例20-20では、DBUriServletを/dburi/*にインストールするように構成ファイルが変更されています。

例20-20 DBUriServletのインストール先の変更

DECLARE
doc XMLType;
doc2 XMLType;
BEGIN
doc := DBMS_XDB.cfg_get();
SELECT
updateXML(doc,
'/xdbconfig/sysconfig/protocolconfig/httpconfig/webappconfig/servletconfig/
servlet-mappings/servlet-mapping[servlet-name="DBUriServlet"]/servlet-pattern/
text()',
'/dburi/*')
INTO doc2 FROM DUAL;
DBMS_XDB.cfg_update(doc2);
COMMIT;
END;
/

セキュリティ・パラメータ、サーブレットの表示名および説明も、xdbconfig.xml構成ファイル内でカスタマイズできます。サーブレットは、servlet-patternを削除することによって削除できます。また、Oracle SQL関数updateXMLを使用してservlet-mapping要素をNULLに更新することによっても削除できます。

DBUriServletのセキュリティ

サーブレットのセキュリティは、Oracle Databaseでロールを使用することによって処理されます。サーブレットにログインするユーザーは、ユーザー自身のデータベース・ユーザー名およびパスワードを使用します。サーブレットは、ログインするユーザーが、構成ファイルに指定されているロールのいずれかを持っているかどうかを、パラメータsecurity-role-refを使用して確認します。デフォルトでは、サーブレットはロールauthenticatedUser、および有効なデータベース・パスワードを使用してサーブレットにログインし、このロールを持っているあらゆるユーザーが利用できます。

ロール・パラメータを変更して、特定のデータベース・ロールにアクセスを制限できます。デフォルトのauthenticatedUserロールから、ユーザーが作成したロールに変更するには、Oracle XML DB構成ファイルを変更します。

例20-21では、デフォルト・ロールauthenticatedUserをロールservlet-users(ユーザーが作成したという想定のもの)に変更します。

例20-21 サーブレット・アクセスのデータベース・ロールへの制限

DECLARE
doc  XMLType;
doc2 XMLType;
doc3 XMLType;
BEGIN
doc := DBMS_XDB.cfg_get();
SELECT updateXML(doc,
'/xdbconfig/sysconfig/protocolconfig/httpconfig/webappconfig/servletconfig/
servlet-list/servlet[servlet-name="DBUriServlet"]/security-role-ref/role-name/
text()',
'servlet-users')
INTO doc2 FROM DUAL;
SELECT updateXML(doc2,
'/xdbconfig/sysconfig/protocolconfig/httpconfig/webappconfig/servletconfig/
servlet-list/servlet[servlet-name="DBUriServlet"]/security-role-ref/role-link/
text()',
'servlet-users')
INTO doc3 FROM DUAL;
DBMS_XDB.cfg_update(doc3);
COMMIT;
END;
/

DBUriを処理するためのパッケージURIFACTORYの構成

http://server/servlets/oradbといったURLはDBUriServlet (またはカスタム・サーブレット)により処理されます。この種のURLがURITypeインスタンスとして格納される場合、サブタイプDBURITypeを使用すると便利です。これは、このURIがデータベース・データをターゲットにしているためです。

ただし、URITypeインスタンスが、パッケージURIFACTORYのPL/SQLメソッドを使用して作成された場合は、デフォルトで使用されるサブタイプは、DBURITypeではなくHTTPURITypeです。これは、URIFACTORYがURI接頭辞のみに注目し、http://を検出して、URIターゲットがWebページであると想定するためです。これにより、不要な通信レイヤーが作成され、無駄な文字変換が行われます。

効率を向上させるには、URIFACTORYに対し、指定された形式のURIはデータベース・アクセスを表しているので、HTTPUriでなくDBUriとして実現すべきだと指示します。そのためには、このURIのハンドラを接頭辞として登録し、生成するインスタンスの型としてDBURITypeを指定します。

例20-22では、URIFACTORYに対して、http://server/servlets/oradbで始まるあらゆるURI文字列がデータベース・アクセスに対応していることを効率的に通知しています。

例20-22 DBUri接頭辞用のハンドラの登録

BEGIN
URIFACTORY.registerURLHandler('http://server/servlets/oradb',
'SYS', 'DBURIType', true, true);
END;
/

このコードを実行すると、同一のセッションにおけるすべてのgetURI()コールにより、接頭辞http://server/servlets/oradbを持つあらゆるURI用のDBUriが自動的に作成されます。

関連項目:
URIFACTORYファンクションの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

第V部

Oracle XML DBリポジトリ

第V部では、Oracle XML DBリポジトリについて説明します。データのバージョンを管理する方法、セキュリティを実装および管理する方法、また関連付けられたOracle XML DB APIを使用してリポジトリのデータにアクセスおよび操作する方法を説明します。

第V部に含まれる章は、次のとおりです。

- 第21章「Oracle XML DBリポジトリのデータへのアクセス」

- 第22章「Oracle XML DBリポジトリの構成」

- 第23章「Oracle XML DBでのXLinkおよびXIncludeの使用」

- 第24章「リソースのバージョン管理」

- 第25章「RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス」

- 第26章「PL/SQLを使用したリポジトリへのアクセス」

- 第27章「リポジトリのアクセス制御」

- 第28章「プロトコルを使用したリポジトリへのアクセス」

- 第29章「ユーザー定義のリポジトリ・メタデータ」

- 第30章「Oracle XML DBリポジトリ・イベント」

- 第31章「Oracle XML DB Content Connectorの使用」

- 第32章「JavaでのOracle XML DBアプリケーションの作成」

- 第33章「ネイティブなOracle XML DB Webサービスの使用」

21 Oracle XML DBリポジトリのデータへのアクセス

この章では、FTP、HTTP(S)、WebDAVなどの標準プロトコルおよびその他のOracle XML DB Resource Application Program Interfaces (API)を使用して、Oracle XML DBリポジトリのデータにアクセスする方法を説明します。また、リポジトリ・データにアクセスおよび操作するためのSQLメカニズムとしてRESOURCE_VIEWおよびPATH_VIEWを使用する方法も説明します。様々なResource APIを使用したリポジトリ操作を比較する表を示します。

この章の内容は次のとおりです。

- Oracle XML DBリポジトリの概要

- リポジトリの用語と提供されているリソース

- Oracle XML DBリポジトリ・リソース

- Oracle XML DBリポジトリ・リソースにアクセスする2つの方法

- リポジトリ・リソースへのナビゲーショナル・アクセスまたはパス・アクセス

- リポジトリ・リソースへの問合せベースのアクセス

- リポジトリ・リソースへのサーブレット・アクセス

- リポジトリ・リソースに対する操作

Oracle XML DBリポジトリの概要

Oracle XML DBリポジトリを使用すると、従来のリレーショナル・データベース構造ではなく、階層構造のデータベースにコンテンツを格納できます。

図21-1に、典型的なツリーとして表示されるOracle XML DBリポジトリのフォルダおよびファイルの階層構造の例を示します。ツリーの上部は、ルート・フォルダ(/)です。

図21-1 リポジトリの階層構造を示すフォルダ・ツリー

注意:
フォルダ/sysは、Oracle XML DBによって、システム定義のXML Schemaやアクセス制御リスト(ACL)などをメンテナンスするために使用されます。フォルダ/sysのデータを変更したり追加したりしないでください。

フォルダリングによって、アプリケーションでは、データベース・コンテンツがファイル・システムに格納されている場合と同様に、FTP、HTTP(S)およびWebDAVの標準プロトコルを使用して、データベース内の階層的に索引付けられたコンテンツにアクセスできます。リポジトリのフォルダおよびリソースに対するアクセス制御権限を設定できます。

この章では、標準プロトコルを使用して、Oracle XML DBリポジトリ・フォルダのデータにアクセスする方法の概要を説明します。Java、SQLおよびPL/SQLを使用してリポジトリ・オブジェクト階層にアクセスするために使用できるAPIについて説明します。

関連項目:

- 第25章「RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス」

- 第26章「PL/SQLを使用したリポジトリへのアクセス」

- 第27章「リポジトリのアクセス制御」

- 第28章「プロトコルを使用したリポジトリへのアクセス」

Oracle XML DBリポジトリ・リソースにアクセスする2つの方法

Oracle XML DBは、リソースにアクセスするための方法が2つあります。

- ナビゲーションベースまたはパスベースのアクセス。リソースの階層索引が使用されます。各リソースは、階層内の場所を反映する、1つ以上の一意のパス名を持ちます。XPath式を使用して、任意のリポジトリ・リソースへナビゲートできます。
リポジトリ・リソースは、データベース内の既存のXMLTypeオブジェクトへの参照として作成できます。このようなデータベース・オブジェクトには、XPathを使用してナビゲートできます。「リポジトリ・リソースへのナビゲーショナル・アクセスまたはパス・アクセス」を参照してください。

- リポジトリへのSQLアクセス。リソースのプロパティおよびパス名を公開し、階層アクセス演算子をOracle XML DB Schemaへマップする特別のビューを使用することにより行います。「リポジトリ・リソースへの問合せベースのアクセス」を参照してください。

関連項目:

- アクセス方法の選択の詳細は、「Oracle XML DBリポジトリへのアクセス」を参照してください。

- アクセス方法の比較の概要は、表21-3「Oracle XML DBリポジトリへのアクセス: APIオプション」を参照してください。

Uniform Resource Locator(URL)を使用して、Oracle XML DBリソースにアクセスできます。URLには、オブジェクトのホスト名、プロトコル情報、パス名およびリソース名が含まれます。

リポジトリの用語と提供されているリソース

Oracle XML DBリポジトリは、すべてのXML Schemaおよびデータベース・スキーマに対する一連のデータベース・オブジェクトです。これらのデータベース・オブジェクトはパス名にマップされます。リポジトリは、単一のルート・ノード(/)を持ち、リソースを連結、分岐した非環式脚注 1 で図式化したものです。図式内の各リソースは、関連付けられた1つ以上のパス名を持ちます。リポジトリは、指定されたリソースへの複数のリンクをサポートします。リポジトリは、ファイルではなくオブジェクトのファイル・システムと考えられます。

リポジトリの用語

次に、Oracle XML DBリポジトリで使用される用語について説明します。

- リソース: リポジトリ階層内のオブジェクトまたはノード。リソースはURLで識別されます。

関連項目:

- 「Oracle XML DBリポジトリの概要」

- 「Oracle XML DBリポジトリ・リソース」

- フォルダ: 他のリソースを含むことができるリソース。ディレクトリと呼ばれることもあります。

- パス名: リソースへの絶対パスを表す階層形式の名前。リポジトリのルートを表すスラッシュ(/)と、それに続くスラッシュで区切られたゼロ個以上のパス要素で構成されています。「.」または「..」のみをパス要素とできませんが、それ以外の形であれば、ピリオド(.)をパス要素で使用できます。パス要素は、データベース・キャラクタ・セットの任意の文字で構成されます。ただし、スラッシュ(/)およびバックスラッシュ(\)の他、構成パラメータ/xdbconfig/sysconfig/invalid-pathname-charsを使用したOracle XML DBの構成ファイル/xdbconfig.xmlに指定された文字は除きます。

- リソース名(またはリンク名): 親フォルダ内のリソースの名前。この名前が、パス名の中で最も右端のパス要素となります。リソース名は、それらを直接含むフォルダ内で一意である必要があり、大/小文字は区別されます。

- リソース・コンテンツ: リソースの本体、つまりデータ。これは、リソースをファイルとして処理してそのコンテンツを要求したときに取得されるものです。型は常にXMLTypeです。

- XDBBinary要素: バイナリデータを含むXML要素。Oracle XML DB XML Schemaで定義されています。XDBBinary要素は、非構造化バイナリ・データがOracle XML DBにアップロードされたときに、リポジトリに格納されます。

- アクセス制御リスト(ACL): 1つ以上の個別リソースへのアクセスを許可されたプリンシパル(ユーザーまたはロール)のセット。

関連項目:
第27章「リポジトリのアクセス制御」

表21-1に示すとおり、Oracle XML DBで使用される多くの用語には、他のコンテキストでの共通の同義語が存在します。

表21-1 Oracle XML DBリポジトリの用語の同義語

同義語

リポジトリの用語

用途

コレクション

フォルダ

WebDAV

ディレクトリ

フォルダ

オペレーティング・システム

権限

権限

権限

権利

権限

様々

WebDAVフォルダ

フォルダ

Webフォルダ

ロール

グループ

アクセス制御

リリース

バージョン

RCS、CVS

ファイル・システム

リポジトリ

オペレーティング・システム

階層

リポジトリ

様々

ファイル

リソース

オペレーティング・システム

バインド

リンク

WebDAV

提供されているファイルとフォルダ

次に、現行のOracle XML DBリポジトリで提供されるファイルおよびフォルダのリストを示します。これらの他に、必要に応じて、独自のフォルダまたはファイルを作成できます。

/public
/sys
/sys/acls
/sys/acls/all_all_acl.xml
/sys/acls/all_owner_acl.xml
/sys/acls/bootstrap_acl.xml
/sys/acls/ro_all_acl.xml
/sys/apps
/sys/asm
/sys/log
/sys/schemas
/sys/schemas/PUBLIC
/sys/schemas/PUBLIC/www.w3.org
/sys/schemas/PUBLIC/www.w3.org/2001
/sys/schemas/PUBLIC/www.w3.org/2001/xml.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBFolderListing.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBResource.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBSchema.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBStandard.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/acl.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/dav.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/log
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/log/ftplog.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/log/httplog.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/log/xdblog.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/stats.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/xdbconfig.xsd
/xdbconfig.xml

Oracle XML DBリポジトリ・リソース

Oracle XML DBリポジトリ・リソースは、XMLスキーマXDBResource.xsdに準拠します。リソースの要素には、作成日、変更日、WebDAVロック、所有者、ACL、言語、キャラクタ・セットなどのWebDAV定義のプロパティを永続的に格納するために必要な要素が含まれます。

関連項目:
「XDBResource.xsd: Oracle XML DBリソースのためのXML Schema」

リソース索引には、リソースのコンテンツを含む、Contentsという特別な要素が含まれます。

リソースのXML Schemaでは、maxoccurs属性が無制限のany要素も定義します。any要素は、Oracle XML DBのXML名前空間外のすべての要素を含むことができます。任意のインスタンス定義のプロパティをリソースと関連付けることができます。

リポジトリ・データが格納される場所

Oracle XML DBは、Oracle XML DBリポジトリのデータを、アクセス可能な一連の表および索引に格納します。XML Schemaを登録し、Oracle XML DBによって表が生成されるように要求した場合、表はユーザーのデータベース・スキーマに作成されます。このため、それらを参照または変更することができます。他のユーザーは、表を参照する権限を付与されないかぎり、その表を参照できません。

生成された表の名前

生成された表の名前は、Oracle XML DBによって割り当てられ、ユーザーのXML Schema文書(またはデフォルトのXML Schema文書)のxdb:defaultTable属性を検索することによって取得できます。XML Schemaを登録する場合、Oracle XML DBによって作成されたデフォルト名でなく、ユーザー独自の表名を指定することもできます。表でXML記憶域が指定されている場合、文書はXML形式にエンコードされてから表内に格納されます。

関連項目:
「XML Schemaの登録時に作成されるデフォルト表」

リソース用の構造化記憶域の定義

リソース用の構造化記憶域を定義する必要があるアプリケーションでは、次のいずれかの操作で行います。

- Oracle XML DBリソース・タイプをサブクラス化します。Oracle XML DBリソースのサブクラス化には、XDB$RESOURCE表に対する権限が必要です。

- 参照可能な登録済XML Schemaに準拠するデータを格納します。

関連項目:
第7章「XML Schemaの格納と問合せ: 基本」

Oracle ASM仮想フォルダ

Oracle Automatic Storage Management(Oracle ASM)の仮想フォルダ/sys/asmには、前項の説明は当てはまりません。フォルダの内容は、Oracle ASMにより自動管理されるOracle ASMファイルとフォルダです。

関連項目:

- 「プロトコルとリソースAPIを使用したOracle ASMファイルへのアクセス(DBA用)」

- 『Oracle Automatic Storage Management管理者ガイド』

パス名の解決

フォルダをそのフォルダの内容に関連付けるデータは、Oracle XML DBの階層リポジトリ索引によって管理されます。これによって、オペレーティング・システムのファイル・システムで使用されるディレクトリ・メカニズムと同様に、パス名を評価するための高速なメカニズムが提供されます。

フォルダであるリソースでは、要素ResourceのContainer属性がtrueに設定されます。

フォルダ内のリソース名を解決するには、現行のユーザーに次の権限が必要です。

- フォルダに対するresolve権限

- フォルダのリソースに対するread-properties権限

ユーザーがこれらの権限を所有していない場合、access deniedエラーが発生します。そのリソースに対するread-properties権限が拒否されている場合、フォルダのリストおよびその他の問合せによって行は戻されません。

注意:
パス名の解決におけるエラー処理では、ファイル・システムとの互換性に対して、無効なリソース名とフォルダでないリソースが区別されます。Oracle XML DBリソースは、SQLを使用してOracle XML DBリポジトリの外部からアクセスできるため、リソースを含むフォルダの読取りアクセスを制限しても、そのリソースへの読取りアクセスは制限されません。

関連項目:
「XDBResource.xsd: Oracle XML DBリソースのためのXML Schema」(要素Resourceおよびその属性Containerの定義用)

リンク・タイプ

Oracle XML DBにおけるリンクは、リポジトリ・リンクまたはドキュメント・リンクのいずれかです。リポジトリ・リンクには、ハード・リンクおよび弱いリンクがあります。ドキュメント・リンクについても、それらのターゲットがリポジトリ・リソースの場合は、ハード・リンクおよび弱いリンクがあります。これらの用語は、次の各項でさらに詳しく説明します。

リポジトリ・リンクとドキュメント・リンク

リソースの他に、フォルダ・リソースは他のリソース(ファイルまたはフォルダ)へのリンクも含むことができます。こうしたリポジトリ・リンク(フォルダ・リンクとも呼ばれる)は、XLink標準およびXInclude標準のリンクに相当するドキュメント・リンクと混同しないようにする必要があります。このドキュメント・リンクもOracle XML DBによりサポートされています。リポジトリ・リンクは、フォルダと子の間をナビゲートするためのリポジトリ・リソース間のリンクです。ドキュメント・リンクは、リポジトリ・リソースとは限らないドキュメント間の任意のリンクです。

リポジトリ・リンクは、リポジトリの階層関係を表しています。一方ドキュメント・リンクは、それらを使用するアプリケーションによりセマンティクスが派生する任意の関係を表しています。リポジトリ・リンクは、リポジトリの階層関係を表しているため、ファイル・システムに関連するプロトコルを使用してナビゲートできます。ドキュメント・リンクではこのようなことはできません。ドキュメント・リンクは、任意の関係を表すことができるため、リポジトリの関係も表すことが可能です。このようにリソースをターゲットとしているドキュメント・リンクはさらに、ハード・リンクおよび弱いリンクに分けることができます。

関連項目:
ドキュメント・リンクの詳細は、第23章「Oracle XML DBでのXLinkおよびXIncludeの使用」を参照してください。

ハード・リンクおよび弱いリンク

リポジトリ・リソースをターゲットとしているリンクには、ハード・リンクと弱いリンクがあります。ハード・リンクおよび弱いリンクはともに、物理データへの参照(またはポインタ)であり、(内部的な)リポジトリ・リソースの識別子です。他のリンクのシンボリック名やパスを指すものではありません。これらのターゲットは、リンクが作成される時点で解決されます。ハード・リンクおよび弱いリンクは、リソースの識別子を直接指すので、ターゲットは必ず必要です。そのかわり、ターゲットの移動や名前の変更が行われても、有効性は保持されます。ハード・リンクおよび弱いリンクの作成や削除には、同じ権限が必要です。

ハード・リンクと弱いリンクの違いは、ターゲット・リソースの削除に関連するものです。ターゲット・リソースは、ハード・リンクに対して従属関係にあります。つまり、ハード・リンクのターゲットである間は削除できません。ハード・リンクを削除すると、次のいずれも成り立つ場合、リンクのターゲットであるリソースも削除されます。

- リソースがバージョニングされていません。

- 削除するハード・リンクがそのリソースに対する最後の(したがって唯一の)ハード・リンクです。

弱いリンクには、リソースに対するこうした拘束力はありません。つまり、弱いリンクのターゲットであるリソースは(ハード・リンクのターゲットでないかぎり)削除できます。このため弱いリンクは、アクセスの頻度が高いリソースへのショートカットとして使用でき、それらのリソースの削除に影響しません。

ただし、弱いリンクには逆方向の依存性があります。弱いリンク(1つ以上)のターゲットになっているリソースを削除すると、それらの弱いリンクも自動的に削除されます。この意味でも、弱いリンクは参照先を失います。ハード・リンクおよび弱いリンクはいずれも、参照整合性を伴っています。つまり、リンクが存在すれば、そのターゲットも存在します。

ハード・リンクおよび弱いリンクには、この他にも違いがあります。祖先のフォルダへのハード・リンクは、循環を導入するため、許可されません。弱いリンクにはこのような制約はありません。弱いリンクは任意のフォルダをターゲットとでき、場合によっては循環が作成されます。Oracle XML DBリポジトリの(非環式)構造は、一連のハード・リンクによって定義されます。弱いリンクが表しているのは、その基本構造の上に追加されたマッピングです。

リポジトリ・リンク・タイプを判断するためにリポジトリ・パス・ビューPATH_VIEWに問合せを行うことができます。リンク・タイプはリンク情報に含まれています。ルート要素LINKの子要素LinkTypeに含まれるこの情報は、PATH_VIEWのXMLType列LINKに表示されます。例21-1に、これを示します。また、イベント・ハンドラ(LinkIn、LinkTo、UnlinkIn、またはUnlinkFrom)でコールバックgetLink()を使用して、リポジトリ・リンク・タイプを判断できます。

例21-1 PATH_VIEWへの問合せによるリンク・タイプの判断

SELECT RESID, XMLCast(XMLQuery('/LINK/LinkType' PASSING LINK RETURNING CONTENT)
AS VARCHAR2(24)) link_type
FROM PATH_VIEW WHERE equals_path(RES, '/home/QUINE/purchaseOrder.xml') = 1;

RESID                              LINK_TYPE
--------------------------------   ---------
DF9856CF2FE0829EE030578CCE0639C5   Weak

関連項目:

- 「リポジトリ・リソースの削除: 例」

- PATH_VIEWの詳細は、「リポジトリ・リソースへの問合せベースのアクセス」を参照してください。

- PL/SQLファンクションgetLinkの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

フォルダ階層の情報がない状況での弱いリンクの作成

ある同僚が所有しているファイル・リソースを閲覧するとします。そのリソースにアクセスしそれを閲覧できるようにする場合、そのファイルの祖先のフォルダすべてに関して権限<xdb:resolve>が付与されていないかぎり、そのリソースへのハード・リンクの作成はできません。この権限が付与されていれば、その同僚が所有するフォルダの名前、およびそのターゲット・リソースまでの階層構造をすべて知ることができます。

ただし、弱いリンクは基本的に、一連のハード・リンクによって定義されている実際のリポジトリ構造の上に追加されたマッピングを表しているため、リソースに対して、そのOIDを使用すれば、完全な名前のパス(URL)がなくても弱いリンクを作成できます。つまり、同僚が決めたファイルへのOIDパスを名前のパスのかわりに受け取れば、そのOIDパスを使用してドキュメントへの弱いリンクを作成できます。例21-2および例21-3に、これを示します。

例21-2は、ファイル・リソース/home/QUINE/purchaseOrder.xmlのOIDパスを出力したものです。ユーザーquineはこれを使用してリソースへのOIDパスを取得し、そのパスをユーザーcurryへ送信できます。またユーザーcurryは、リソースへの弱いリンクを作成できます(例21-3)。

例21-2 リソースのOIDパスの取得

DECLARE
resoid  RAW(16);
oidpath VARCHAR2(100);
BEGIN
SELECT RESID INTO :resoid FROM RESOURCE_VIEW
WHERE equals_path(RES, '/home/QUINE/purchaseOrder.xml') = 1;
oidpath := DBMS_XDB.createOIDPath(resoid)
DBMS_OUTPUT.put_line(oidpath);
END;

例21-3では、ユーザーcurryが、quinePurchaseOrder.xmlという名前の弱いリンクをフォルダ/home/CURRY内に作成します。リンクのターゲットは、URL /home/QUINE/purchaseOrder.xmlに対応するOIDパスです。ユーザーcurryは、ユーザーquineには参照可能なリポジトリの構造を認識する必要はありません。

例21-3 OIDパスを使用した弱いリンクの作成

CALL DBMS_XDB.Link(/sys/oid/1BDCB46477B59C20E040578CCE0623D3
'/home/CURRY', 'quinePurchaseOrder.xml',
DBMS_XDB.LINK_TYPE_WEAK);

複数のハード・リンクに関する制限

ハード・リンクの作成を制限し、フォルダまたはファイル(またはその両方)へのハード・リンクの複数作成を許可しない方が有効な場合があります。特に、ファイル・リソースへの複数のハード・リンクの作成を許可し、フォルダ・リソースへの複数のハード・リンクの作成を許可しないことで、UNIXやLinuxなどのファイル・システムに近い動作が実現されます。これにより、事実上、各ファイル・リソースに対して正規のハード・リンクのパスが一意に作成され、アプリケーションの設計を単純化できます。さらに、リソースに対して複数のハード・リンクを作成しないことで、問合せのパフォーマンスを向上できます。

構成ファイルxdbconfig.xmlで次のブール型パラメータを使用して、複数のハード・リンクの作成を回避するよう構成できます。各パラメータのデフォルト値はtrueで、複数のハード・リンクを作成できます。

- folder-hard-links: falseの場合、フォルダ・リソースへの複数のハード・リンクの作成を回避します。

- non-folder-hard-links: falseの場合、ファイル・リソースへの複数のハード・リンクの作成を回避します。

関連項目:
「xdbconfig.xmlを使用したOracle XML DBの構成」

リポジトリ・リソースへのナビゲーショナル・アクセスまたはパス・アクセス

Oracle XML DBリポジトリのフォルダは、多くのオペレーティング・システムにより使用されている標準的なプロトコルをサポートしています。これによって、リポジトリ・フォルダは、サポートされているオペレーティング・システム環境で、ネイティブ・フォルダ(ディレクトリ)と同様に機能します。たとえば、次の操作を実行できます。

- Windowsエクスプローラを使用して、Windows NTファイル・システムの他のディレクトリまたはリソースにアクセスする場合と同じ方法で、Oracle XML DBのフォルダおよびリソースを開いたり、アクセスできます(図21-2を参照してください)。

- Webフォルダを参照する場合などは、Internet ExplorerブラウザからHTTP(S)またはWebDAVを使用して、Oracle XML DBリポジトリ・データにアクセスできます(図21-3を参照してください)。図21-3に、URL http://xdbdemo:8080/にアクセスしたWebブラウザを示しています。接続先サーバーはxdbdemoで、HTTPポート番号は8080です。

関連項目:
HTTPポート番号の構成の詳細は、「プロトコル・サーバーのパラメータの構成」を参照してください。

図21-2 WindowsエクスプローラでのOracle XML DBのフォルダ

図21-3 HTTPやWebDAVおよびナビゲーショナル・アクセスを使用した、IEブラウザからリポジトリ・データへのアクセス: Webフォルダの参照

インターネット・プロトコルを使用したOracle XML DBリソースへのアクセス

Oracle Net Servicesでは、データベース・リソースのアクセス方法が提供されます。インターネット・プロトコルをサポートしているOracle XML DBでは、データベース・リソースにアクセスする別の方法が提供されます。

Oracle XML DBのプロトコル・アクセスを使用できる場所

Oracle Net Servicesは、レコード指向のデータに対して最適化されています。インターネット・プロトコルは、バイナリ・ファイルやXMLテキスト・ドキュメントなどのストリーム指向のデータ用に設計されています。次のような場合は、Oracle Net ServicesよりOracle XML DBのプロトコル・アクセスを使用することをお薦めします。

- ファイル・システムのようなデータベースを使用した、ファイル指向アプリケーションからデータベースへの直接アクセス

- 均一なデータ・アクセス方法(MS SQL Server、Exchange、Notes、多くのXMLデータベース、株価情報サービス、ニュース配信を含む多くのデータ・サーバーによってサポートされているHTTPを介したXMLなど)を必要とする異機種間アプリケーション・サーバー環境

- XMLテキスト形式のデータを必要とするアプリケーション・サーバー環境

- 多くのアプリケーション処理を必要とせずに、クライアント側のXSLを使用して、データグラムをフォーマットするWebアプリケーション

- データベース内で実行するJavaサーブレットを使用するWebアプリケーション

- XML指向のストアド・プロシージャに対するWebアクセス

プロトコル・アクセスの使用

プロトコルを使用したOracle XML DBリソースへのアクセスは次のように行われます。

1. 接続オブジェクトが確立されます。また、プロトコルによってリクエストの一部が読み取られる場合があります。

2. プロトコルによって、認証済のユーザーが既存のセッションを再利用できるか、または接続を再認証する必要があるか(通常はこちら)が決定されます。

3. 既存のセッションがセッション・プールから取り出されるか、または新しいセッションが作成されます。

4. 認証が行われず、リクエストがHTTPのgetまたはheadの場合、セッションはANONYMOUSユーザーとして実行されます。セッションがすでにANONYMOUSユーザーとして認証されている場合は、そのまま既存のセッションを再利用できます。認証が行われている場合は、データベースの再認証ルーチンを使用して、接続が認証されます。

5. リクエストが解析されます。

6. (HTTPのみ)要求されたパス名がサーブレットにマップされる場合、サーブレットはJava仮想マシン(VM)を使用して起動されます。サーブレット・コードがレスポンス・ストリームに対するレスポンスを書き出すか、またはXMLTypeインスタンスにレスポンスを書き出すように要求します。

Oracle XML DBリソースの取出し

プロトコルがリソースの取出しを示した場合、リソースへのパス名が解決されます。フェッチされているリソースは、常にXMLとして配信されます。ただし、XMLバイナリ・データ型として定義済の要素であるXDBBinary要素を含むリソースで、そのコンテンツがRAWフォームで配信されるものは除きます。

Oracle XML DBリソースの格納

プロトコルがリソースを格納する必要があることを示した場合、Oracle XML DBは、文書のファイル名の拡張子が.xml、.xsl、.xsdなどであることを確認します。文書がXMLである場合、事前解析が実行されます。その場合、文書のルート要素のXML schemaLocationおよびnamespaceを判断するために十分なリソースが読み取られます。登録されたスキーマが、schemaLocation URLに配置されていて、現在の文書のルート要素に対する定義を持っている場合、その要素に対して指定されたデフォルト表を使用して、リソースのコンテンツが格納されます。

インターネット・プロトコルおよびXMLTypeの使用: ストリームへのXMLTypeの直接書込み

Oracle XML DBは、Java XMLTypeメソッドwriteToStream()を使用することによって、XMLTypeレベルでインターネット・プロトコルをサポートします。このメソッドはネイティブに実装され、XMLTypeデータをプロトコルのリクエスト・ストリームに直接書き込みます。これによって、Javaデータ型を介したデータベース・データの変換およびJavaオブジェクトの作成に伴うJava VMの実行コストとオーバーヘッドが回避され、パフォーマンスが大幅に向上します。パフォーマンスをさらに向上させるには、Javaコードが多くのリーフ要素を検索せずにルートに近いXML要素ツリーのみを処理し、作成するJavaオブジェクトの数が相対的に少なくなるようにします。

関連項目:
第28章「プロトコルを使用したリポジトリへのアクセス」

プロトコルとリソースAPIを使用したOracle ASMファイルへのアクセス(DBA用)

Oracle Automatic Storage Management(Oracle ASM)を使用すると、データベース・ファイルはディスク・グループに整理され、管理が簡潔になるとともに、データベースのミラー化やI/Oバランシングなどの利用が可能になります。

プロトコルやリソースAPI(DBMS_XDBなど)を使用したリポジトリ・アクセスは、Oracle ASMのファイルも対象にします。これらのファイルには、仮想リポジトリ・フォルダ/sys/asmからアクセスします。ただし、このアクセスはDBA用に予約されたものです。開発者の使用は想定していません。

この種のアクセスの典型的な使用方法は、データベース・インスタンス相互の間でのOracle ASMファイルのコピーです。たとえばDBAでは、WebDAVプロトコルを使用してGraphical User Interface(GUI)でフォルダ/sys/asmを表示し、データ・ポンプ・ダンプセットのコピーを、Oracle ASMディスク・グループからオペレーティング・システムのファイル・システムにドラッグ・アンド・ドロップすることができます。

仮想フォルダ/sys/asmは、デフォルトではOracle XML DBのインストール時に作成されます。データベースがOracle ASMを使用するよう構成されていない場合は、フォルダは空で、フォルダに関する操作は許可されません。

フォルダ/sys/asmには、Oracle ASMの完全修飾ファイル名の構造で定義された階層に従うフォルダやサブフォルダが含まれます。

- マウントされている各ディスク・グループに対応するサブフォルダが含まれます。

- ディスク・グループ・フォルダには、そのディスク・グループを使用するデータベースに対応するサブフォルダが含まれます。ディスク・グループ・フォルダにはさらに、管理者によって作成されたOracle ASMエイリアスに対応するファイルやフォルダが含まれることがあります。

- データベース・フォルダには、ファイル・タイプ・フォルダが含まれます。

- ファイル・タイプ・フォルダには、バイナリのOracle ASMファイルが含まれます。

この階層を図21-4に示します。ただし、図を簡潔にするために、エイリアス用に作成されるディレクトリは省略しています。

図21-4 Oracle ASM仮想フォルダの階層

仮想フォルダ/sys/asmには、使用方法が次のように制限されます。次のことはできません。

- SQLを使用した/sys/asmの問合せ

- 通常のファイルの/sys/asmへの配置(ここに置けるのはOracle ASMファイルのみ)

- Oracle ASMファイルの、他のOracle ASMディスク・グループや、Oracle ASM外部のフォルダへの移動(名前の変更)

- 既存のOracle ASMファイルまたはディレクトリへのハード・リンクの作成

また、次の点があげられます。

- フォルダ/sys/asmを表示するには、ロールDBAの権限が必要です。

- Oracle XML DBプロトコルを使用して/sys/asmにアクセスするには、SYS以外のユーザーとしてログインする必要があります。

繰り返しますが、Oracle ASM仮想フォルダの操作はデータベース管理者による使用を想定したもので、開発者用ではありません。

関連項目:

- /sys/asmでのFTPプロトコルの使用については、「Oracle ASMファイルに対するFTPの使用」を参照してください。

- 完全修飾Oracle ASMファイル名の構文や仮想フォルダ構造の詳細は、『Oracle Automatic Storage Management管理者ガイド』を参照してください。

リポジトリ・リソースへの問合せベースのアクセス

SQLによるOracle XML DBリポジトリへのアクセスを可能にするビューは2つあります。

- PATH_VIEW

- RESOURCE_VIEW

表21-2に、PATH_VIEWとRESOURCE_VIEWの違いを示します。

表21-2 PATH_VIEWとRESOURCE_VIEWの違い

PATH_VIEW

RESOURCE_VIEW

リンク・プロパティを含みます。

リンク・プロパティを含みません。

リポジトリの一意の各パスに1つの行を持ちます。

リポジトリの各リソースに1つの行を持ちます。

これら2つのリポジトリ・ビュー内の行の型はXMLTypeです。RESOURCE_VIEWでは、リソースに関連付けられる単一のパスは、そのリソースを参照している可能なパスの中から任意に選択されます。Oracle XML DBにはunder_pathなどのSQL関数が用意されており、アプリケーションから特定のフォルダ内に(再帰的に)含まれているリソースを検索したり、リソースの深さを取得したりできます。

リポジトリ・ビュー上でDMLを使用すると、リソースのプロパティおよびコンテンツの挿入、名前の変更、削除および更新ができます。その他の操作(既存のリソースへのリンクの作成など)に対しては、プログラムAPIを使用する必要があります。

関連項目:

- Oracle XML DBリポジトリへのSQLアクセスの詳細は、第25章「RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス」を参照してください。

- 第27章「リポジトリのアクセス制御」

リポジトリ・リソースへのサーブレット・アクセス

Oracle XML DBは、JavaサーブレットAPIバージョン2.2を実装します。ただし、次の例外があります。

- すべてのサーブレットが配布可能である必要があります。これらのサーブレットは、異なる仮想マシンで実行可能である必要があります。

- WARおよびweb.xmlファイルはサポートされていません。Oracle XML DBはこのファイルのXML構成のサブセットをサポートしています。XSLスタイルシートをweb.xmlに適用して、サーブレットの定義を生成できます。外部ツールを使用して、web.xmlファイルに定義されたサーブレットのデータベース・ロールを作成する必要があります。

- JavaServer Pages(JSP)サポートをサーブレットとしてインストールし、手動で構成できます。

- HTTPSessionおよび関連するクラスはサポートされません。

- 1つのサーブレット・コンテキスト(1つのWebアプリケーション)のみがサポートされます。

関連項目:
第32章「JavaでのOracle XML DBアプリケーションの作成」

リポジトリ・リソースに対する操作

Oracle XML DBリポジトリに格納されているデータは、次のいずれかを使用して操作できます。

- Oracle XML DB Resource APIs for Java

- Oracle XML DB Resource View APIとOracle XML DB Resource API for PL/SQLの組合せ

- インターネット・プロトコル(HTTP(S)、WebDAVおよびFTP)およびOracle XML DBプロトコル・サーバー

- Oracle XML DB Content Connector、およびそれを介した標準のContent Repository API for Java(JCR)

アクセスには、様々な方法を同等に使用できます。つまり、リポジトリにコンテンツを追加する方法と、リポジトリからコンテンツを取り出す方法は、自由に選択できます。たとえば、コンテンツをリポジトリに追加する際にSQLまたはPL/SQLを使用して、コンテンツを取り出す際にインターネット・プロトコルを使用できます。使用する方法が逆でも同様です。

表21-3に、一般的なOracle XML DBリポジトリの操作を示し、いくつかのアクセス方法を使用してこれらの操作をどのように実行できるかを説明します。この表ではそれぞれの方法に共通の機能を示しますが、それらすべての方法が、特定のタスクに対して同じように適しているわけではありません。特に説明がなければ、この表で使用される「リソース」とは、ファイル・リソースまたはフォルダ・リソースのいずれかを表します。

表21-3は、各操作に必要なリソース権限も示しています。表にリストされている権限に加え、操作により影響を受ける各リソースに対しては権限xdb:read-propertiesが必要です。また、その操作のターゲットとなるリソースに加え、リソースの親フォルダに影響を与える操作を実行するには、その親フォルダに対しても権限xdb:read-propertiesが必要です。たとえば、あるリソースに対する削除操作は、削除するリソースおよびその親フォルダに影響を及ぼします。したがってこの場合は、対象のリソースおよびその親フォルダに対して権限xdb:read-propertiesが必要です。

表21-3 Oracle XML DBリポジトリへのアクセス: APIオプション

データ・アクセス

SQLおよびPL/SQL

プロトコル

必要なリソース権限

JCRのサポート

リソースの作成

DBMS_XDB.createResource('/public/T1/testcase.txt',
'ORIGINAL text');
INSERT INTO RESOURCE_VIEW (ANY_PATH, RES)
SELECT '/public/T1/copy1.txt', RES
FROM RESOURCE_VIEW
WHERE equals_path(RES,
'/public/T1/testcase.txt')
= 1;

HTTP:PUT;

FTP: PUT

親フォルダに対するDAV::bind

サポート

リソース・コンテンツの更新

UPDATE RESOURCE_VIEW
SET RES =
updateXML(
RES,
'/Resource/Contents/text/text()',
'NEW text',
'xmlns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd')
WHERE equals_path(RES,
'/public/T1/copy1.txt') = 1;

HTTP: PUT;

FTP: PUT

リソースに対するxdb:write-content

サポート

リソース・プロトコルの更新

UPDATE RESOURCE_VIEW
SET RES =
updateXML(
RES,
'/Resource/DisplayName/text()',
'NewName1.txt',
'xmlns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd')
WHERE equals_path(RES,
'/public/T1/copy1.txt') = 1;

WebDAV:

PROPPATCH;

リソースに対するDAV::write-properties

サポート

リソースACLの更新

EXEC DBMS_XDB.setACL(
'/public/T1/copy1.txt',
'/sys/acls/all_owner_acl.xml');

適用なし

リソースに対するDAV::write-acl

非サポート

リソースのリンク解除(最新のリンクの削除)

EXEC DBMS_XDB.deleteResource()
DELETE FROM RESOURCE_VIEW
WHERE equals_path(RES, path) > 0

HTTP:

DELETE;

FTP:delete

親フォルダに対するDAV::unbind

リソースに対するxdb:unlink-from

サポート

リソースへのすべてのリンクの強制削除

DBMS_XDB.deleteResource()
DELETE FROM PATH_VIEW
WHERE
XMLCast(
XMLQuery(
'declare namespace n1=
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
//n1:DisplayName'
PASSING RES RETURNING CONTENT)
AS VARCHAR2(256))
= 'My resource'

FTP:

quote

rm_rf

resource

すべての親フォルダに対するDAV::unbind

リソースに対するxdb:unlink-from

サポート

リソースの移動

UPDATE PATH_VIEW
SET path = '/public/T1/copy2.txt'
WHERE equals_path(RES,
'/public/T1/copy1.txt')
= 1;

WebDAV:

MOVE;

FTP: rename

ソース親フォルダに対するDAV::unbind

ターゲット親フォルダに対するDAV::bind

リソースに対するxdb:unlink-fromおよびxdb:link-to

サポート

リソースのコピー

INSERT INTO PATH_VIEW (path, RES, link)
SELECT '/public/T1/copy3.txt', RES, link
FROM PATH_VIEW
WHERE equals_path(RES,
'/public/T1/copy2.txt')
= 1;

WebDAV:

COPY;

新規コピー:

ターゲット親フォルダに対するDAV::bind

リソースに対するDAV::read

上書きコピー(置換):

リソースに対するDAV::read

既存のターゲット・リソースに対するDAV::write-propertiesおよびDAV::write-content

サポート

既存リソースへのハード・リンクの作成

EXEC DBMS_XDB.link('/public/T1/copy3.txt',
'/public/T1',
'myhardlink');

適用なし

親フォルダに対するDAV::bind

リソースに対するxdb:link-to

非サポート

既存リソースへの弱いリンクの作成

EXEC DBMS_XDB.link('/public/T1/copy3.txt',
'/public/T1',
'myweaklink',
DBMS_XDB.LINK_TYPE_WEAK);

適用なし

親フォルダに対するDAV::bind

リソースに対するxdb:link-to

非サポート

リソースの所有者の変更

UPDATE RESOURCE_VIEW
SET RES =
updateXML(
RES,
'/Resource/Owner/text()',
'U2')
WHERE equals_path(RES, '/public/T1/copy3.txt')
= 1;

適用なし

リソースに対するDAV::take-ownership

サポート

リソース・コンテンツのバイナリ表現またはテキスト表現の取得

SELECT XDBURIType(path).getBLOB()
FROM DUAL;

SELECT
XMLQuery(
'declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd";(: :)
$r/Resource/Contents'
PASSING RES AS "r" RETURNING CONTENT)
FROM RESOURCE_VIEW
WHERE equals_path(RES, '/public/T1/copy2.text') = 1;

HTTP: GET;

FTP: get

リソースに対するxdb:read-contents

サポート

リソース・コンテンツのXMLType表現の取得

SELECT XDBURIType('/public/T1/res.xml').getXML
FROM DUAL;

SELECT
XMLQuery(
'declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd";(: :)
$r/Resource/Contents/*'
PASSING RES AS "r" RETURNING CONTENT)
FROM RESOURCE_VIEW
WHERE equals_path(RES, '/public/T1/res.xml') = 1;

適用なし

リソースに対するxdb:read-contents

非サポート

リソース・プロトコルの取得

SELECT
XMLCast(
XMLQuery(
'declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd";(: :)
$r/Resource/LastModifier'
PASSING RES AS "r" RETURNING CONTENT)
AS VARCHAR2(128))
FROM RESOURCE_VIEW
WHERE equals_path(RES, '/public/T1/res.xml') = 1;

WebDAV:

PROPFIND

(depth = 0);

リソースに対するxdb:read-properties

サポート

フォルダ内のリソースのリスト

SELECT PATH FROM PATH_VIEW
WHERE under_path(res, '/public/T1') = 1;

WebDAV:

PROPFIND

(depth = 0);

フォルダに対するxdb:read-contents

サポート

フォルダの作成

Call DBMS_XDB.createFolder('/public/T2');

WebDAV:

MKCOL;

FTP: mkdir

親フォルダに対するDAV::bind

サポート

フォルダのリンク解除

DBMS_XDB.deleteResource('/public/T2')

HTTP:

DELETE;

FTP: rmdir

親フォルダに対するDAV::unbind

リソースに対するxdb:unlink-from

サポート

フォルダおよびそのフォルダに対するすべてのリンクの強制削除

DBMS_XDB.deleteResource(
'/public/T2',
DBMS_XDB.DELETE-RECURSIVE_FORCE);

適用なし

すべての親フォルダに対するDAV::unbind

フォルダ・リソースに対するxdb:unlink-from

サポート

行ロックされたリソースの取得

SELECT ...
FROM RESOURCE_VIEW
FOR UPDATE ...;

適用なし

リソースに対するxdb:read-propertiesおよびxdb:read-contents

非サポート

リソースへのWebDAVロックの追加

EXEC DBMS_XDB.LockResource('/public/T1/res.xml',
TRUE,
TRUE);

WebDAV:

LOCK;

FTP:

quote lock

リソースに対するDAV::write-properties

非サポート

WebDAVロックの削除

DECLARE...
BEGIN
DBMS_XDB.GetLockToken('/public/T1/res.xml',
locktoken);
DBMS_XDB.UnlockResource('/public/T1/res.xml',
locktoken);
END;

WebDAV: UNLOCK;

FTP:

quote unlock

リソースに対するDAV::write-propertiesおよびDAV::unlock

非サポート

ファイル・リソースのチェックアウト

EXEC DBMS_XDB_VERSION.checkOut(
'/public/T1/res.xml');

適用なし

リソースに対するDAV::write-properties

非サポート

ファイル・リソースのチェックイン

EXEC DBMS_XDB_VERSION.checkIn(
'/public/T1/res.xml');

適用なし

リソースに対するDAV::write-properties

非サポート

ファイル・リソースのチェックアウトのキャンセル

EXEC DBMS_XDB_VERSION.unCheckOut(
'/public/T1/res.xml');

適用なし

リソースに対するDAV::write-properties

非サポート

ファイル・リソースのバージョニング

EXEC DBMS_XDB_VERSION.makeVersioned(
'/public/T1/res.xml');

適用なし

リソースに対するDAV::write-properties

非サポート

イベント・ハンドラの削除

DBMS_XEVENT.remove

適用なし

リソースまたは親フォルダ(コンテキストによる)に対するxdb:write-config

非サポート

変更のコミット

COMMIT;

各リクエスト後の自動コミット

適用なし

サポート

変更のロールバック

ROLLBACK;

適用なし

適用なし

サポート

関連項目:

- 第25章「RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス」

- 第26章「PL/SQLを使用したリポジトリへのアクセス」

- 第28章「プロトコルを使用したリポジトリへのアクセス」

- 第31章「Oracle XML DB Content Connectorの使用」

- 新規PL/SQLパッケージDBMS_XDBの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- 新規PL/SQLパッケージDBMS_XDB_VERSIONの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- 新規PL/SQLパッケージDBMS_XEVENTの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

脚注の凡例

脚注1: グラフは、リポジトリ構造を定義するハード・リンクによって定義され、ハード・リンクを使用した循環は許可されません。ただし弱いリンクを使用して循環を導入できます。「ハード・リンクおよび弱いリンク」を参照してください。

22 Oracle XMLDBリポジトリの構成

この章では、Oracle XML DBリポジトリを構成する方法について説明します。内容は次のとおりです。

- リソースを構成するリソース構成ファイル

- リソースの構成

- 共通の構成パラメータ

この章では、すべてのリポジトリ・リソースに適用される一般的な構成について説明します。特定のリソースの用途に関する構成パラメータについては説明していません。特に、イベント処理やXLinkおよびXInclude処理の管理に関する構成パラメータについては説明していません。

関連項目:

- 「リポジトリ・イベントの構成」

- XLinkおよびXIncludeのためのリソースの構成

- XDBResource.xsd: Oracle XML DBリソースのためのXML Schema

- XDBResConfig.xsd: リソース構成のためのXML Schema

リソースを構成するリソース構成ファイル

リソース構成は、イベント、MIMEタイプ・マッピング、サーブレット・パラメータ、XLinkおよびXInclude処理、デフォルトのACL仕様などに使用できる一般的なメカニズムです。

Oracle XML DBリポジトリ・リソースは、リソースについて構成可能なパラメータを定義するリソース構成ファイルと関連付けて、あらゆる目的で構成します。リソース構成ファイルは、パス/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBResConfig.xsdにあるOracle XML DBリポジトリでアクセスできるXML Schema XDBResConfig.xsdに準拠するXMLファイルです。このXML SchemaはOracle XML DBで定義されているため、変更できません。

リソース構成ファイル自体がOracle XML DBリポジトリのリソースです。PL/SQLプロシージャDBMS_RESCONFIG.addResConfigを使用して、構成ファイルにリソースをマップします。1つのリソース構成ファイルをリポジトリ内のすべてのリソースに適用することもできます。その場合は、PL/SQLプロシージャDBMS_RESCONFIG.addRepositoryResConfigを使用して、リソースをまとめてリポジトリにマップします。

同じリソース構成ファイルを使用して、必要に応じて複数のリソースを構成できます。同一の構成が有効である場合は、このようにリソース間で構成ファイルを共有させることをお薦めします。これにより実行時のパフォーマンスを向上させることができます。また、1箇所で構成を更新した場合に変更が複数のリソースに適用されることにより、リポジトリ管理が簡略化されます。

複数の、同一のリソース構成ファイルを作成しないでください。パフォーマンスに悪影響を与える可能性があります。Oracle XML DBにより重複したリソース構成ファイルが検出されると、エラーが発生します。

通常、1つのアプリケーションに対して使用するリソースを1つ構成します。1つのリソースを複数のアプリケーションで共有するには、異なるアプリケーションがリソースを様々な方法で構成できることが必要です。そのためには、複数のリソース構成ファイルを作成し、それらを同じリソースにマップします。これにより、各リソースはリソース構成リストという構成リストに関連付けられます。構成リストに含まれる構成は、リストに記載された順番に処理されます。

リポジトリ自体が、リポジトリ内のすべてのリソースの構成を意味する、リポジトリ全体の構成に対するリソース構成ファイルのリストを持っています。同じ構成ファイルをリポジトリ自体と特定のリソースの両方で使用しないでください。そうでない場合は、エラーが発生します。また、同じリソース構成ファイルが任意のリソース構成リストに複数回表示される場合にもエラーが発生します。

注意:
リポジトリ全体の構成で125を超えるリソース構成ファイルを作成しようとすると、エラーが発生します。

新規リソースのリソース構成リストは、新規リソースの親フォルダのすべてのリソース構成ファイルのconfiguration要素に記述された情報に基づいています。該当する情報がない(構成ファイルがない、またはファイルにdefaultChildConfig要素がない)場合は、リポジトリのリソース構成リストのconfiguration要素が使用されます。その情報も欠落している場合は、新規リソースのリソース構成リストは空になります。

特定リソースの構成リストを表示する場合は、ビューRESOURCE_VIEWの列RESから要素/Resource/RCListを抽出するか、PL/SQLプロシージャDBMS_RESCONFIG.getResConfigPathを使用します。リポジトリの構成リストをまとめて表示する場合は、PL/SQLプロシージャDBMS_RESCONFIG.getRepositoryResConfigPathを使用します。リポジトリ全体の構成リストを変更するには、ロールXDBADMINが必要です。

関連項目:
「構成要素defaultChildConfig」

リソースの構成

Oracle XML DBリポジトリ・リソースまたはリポジトリをまとめて(リソースをすべて)構成するには、次の手順に従ってください。

1. 構成を定義するリソース構成ファイルを作成します。このXMLファイルは、XML Schema XDBResConfig.xsdに準拠している必要があります。

2. リソース構成ファイルを、それ自体をリソースである構成リソースとしてリポジトリに追加します。追加するには、PL/SQL関数DBMS_XDB.createResourceを使用できます。

3. この構成リソースを、この構成リソースが構成するリソースに、あるいはすべてのリソースに適用される場合はリポジトリにマップします。PL/SQLプロシージャDBMS_RESCONFIG.addResConfigまたはDBMS_RESCONFIG.appendResConfigを使用して、個々のリソースをマップします。DBMS_RESCONFIG.addRepositoryResConfigを使用して、リポジトリをまとめてマップします。

4. コミットします。

注意:
リソース構成ファイルを使用する操作を実行する前に、COMMIT操作を行う必要があります。それまでは、構成ファイルを使用するたびに、「ORA-22881 REFの参照先がありません」エラーが発生します。

PL/SQLパッケージDBMS_RESCONFIGには、構成リストからの構成の削除、構成リスト内の構成へのパスのリストの取得などを行う、その他のプロシージャが記述されています。

注意:
他のリソースにより参照されているリソース構成ファイルを削除する場合、構成されているリソースにアクセスしようとするたびに「REFの参照先がありません」エラーが発生します。

関連項目:

- 単純なリソース構成ファイルの例は、例22-1を参照してください。

- 完全な構成リソースの例は、「リポジトリ・イベントの構成」を参照してください。

- 「XDBResConfig.xsd: リソース構成のためのXML Schema」

- DBMS_RESCONFIGパッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

共通の構成パラメータ

この項では、共通で使用される構成パラメータ、つまり構成ファイル内の要素について説明します。特定の構成の型に固有のパラメータについては、他の項で説明します。

構成要素ResConfig

リソース構成ファイルの最上位要素はResConfigです。namespace属性およびschemaLocation属性の他に、オプションとしてenable属性を含めることができます。属性の値をenableからfalseに設定し、リソース構成ファイルを無効にします。これにより、そのファイルにマップされたリソースには影響がなくなります。これは、アプリケーションの無効化やデバッグには便利です。enableのデフォルト値はtrueで、属性が存在しない場合に使用されます。

構成要素defaultChildConfig

この構成要素はフォルダにのみ適用されます。この構成要素には、フォルダ内のすべての子リソースに適用させる構成情報が保持されています。要素defaultChildConfigには1つ以上のconfiguration子要素があり、それぞれにフォルダ内のリソースに可能な構成が定義されています。

configuration要素には、次の子要素があります。

- pre-condition(オプション): この要素はpath要素(次を参照)で識別されたリソース構成がデフォルト構成として使用可能になるために満たす必要がある条件を指定します。要素pre-conditionがない場合、pathでターゲットにされているリソース構成ファイルはフォルダ内のすべてのリソースに適用されます。つまり、前提条件はTRUEとみなされます。
pre-condition要素には、オプションのexistsNode子要素があります。existsNode要素には、必須のXPath子要素とオプションのnamespace子要素があり、どちらも文字列です。これらの要素は、リソースの有無を確認する場合に使用するXPath 1.0式と名前空間をそれぞれ定義します。そのリソースが存在する場合は前提条件が満たされるため、pathで識別されるリソース構成ファイルは、フォルダ内のすべての子リソースのデフォルト・リソース構成ファイルとして使用されます。XPath要素の第1コンポーネントはResourceである必要があります。

注意:
要素XPathの複雑なXPath式は、パフォーマンスに悪影響を与える可能性があります。

複数のconfiguration要素の前提条件がTRUEの場合、関連付けられたpath要素により識別される各リソース構成ファイルは、フォルダ内のすべてのリソースに適用されます。

- path(必須): この要素は、要素pre-conditionで指定された前提条件を満たしている場合は必ず、新規リソースのデフォルトの構成として使用されるリソース構成ファイルへの絶対リポジトリ・パスを指定します。

通常、path要素の値は、path要素を含むファイルである現在のリソース構成ファイルへのパスです。例22-1は、リソース構成ファイルがリポジトリのパス/cm/app_rc.xmlにあるという前提でパスを示しています。この例では、コンテンツの型がxmlのResourceノードが存在することが前提条件です。前提条件を満たした場合、例22-1のリソース構成ファイルは、構成ファイル(/cm/app_rc.xml)と同じフォルダにあるすべてのリソースに適用されます。

例22-1リソース構成ファイル

<ResConfig xmlns="http://xmlns.oracle.com/xdb/XDBResConfig.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/XDBResConfig.xsd
http://xmlns.oracle.com/xdb/XDBResConfig.xsd">
<defaultChildConfig>
<configuration>
<pre-condition>
<existsNode>
<XPath>/Resource[ContentType="xml"]</XPath>
</existsNode>
</pre-condition>
<path>/cm/app_rc.xml<path>
</configuration>
</defaultChildConfig>
</ResConfig>

構成要素applicationData

アプリケーション固有データを格納するには、要素applicationDataを使用します。通常、アプリケーションは、ハンドラが動作している場合はこのデータをイベント・ハンドラに渡します。要素applicationDataに入れたい任意のXMLコンテンツを使用できます。イベント・ハンドラは、PL/SQL関数DBMS_XEVENT.getApplicationDataまたはJava関数oracle.xdb.XMLType.getApplicationDataを使用して、イベント・リスナーのリソース構成ファイルのapplicationDataにあるデータにアクセスします。

例22-2に、Oracle Spatialアプリケーションで使用するapplicationData要素を示します。

例22-2 applicationData要素

<applicationData>
<spatial:data xmlns:spatial="http://oracle/cartridge/spatial.xsd">
<spatial:xpos>5</spatial:xpos>
<spatial:ypos>10</spatial:ypos>
</spatial:data>
</applicationData>

関連項目:

- PL/SQL関数DBMS_XEVENT.getApplicationDataの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- Java関数oracle.xdb.XMLType.getApplicationDataの詳細は、『Oracle Database XML Java API Reference』のXDBRepositoryEventクラスに関する項を参照してください。

- イベント・リスナーのリソース構成ファイルの例は、例30-1「前提条件のあるJavaイベント・リスナーのリソース構成ファイル」を参照してください。

23 Oracle XML DBでのXLinkおよびXIncludeの使用

この章では、Oracle XML DBリポジトリのリソースでXLinkおよびXincludeを使用する方法について説明します。内容は次のとおりです。

- XLinkおよびXIncludeの概要

- XLinkおよびXIncludeのリンク・タイプ

- XInclude: 複合ドキュメント

- Oracle XML DBでのXLinkの使用

- Oracle XML DBでのXIncludeの使用

- DOCUMENT_LINKSビューを使用したXLinkリンクおよびXIncludeリンクの検証

- XLinkおよびXIncludeのためのリソースの構成

- DBMS_XDB.processLinksを使用したXLinkリンクおよびXIncludeリンクの管理

XLinkおよびXIncludeの概要

ドキュメント指向、またはコンテンツ管理アプリケーションでは原則として、ドキュメント間の関係が追跡されます。これらの関係は通常、様々な形のリンクとして表され、操作されます。このようなリンクは、ドキュメント・コンテンツや、マウス・クリックなどのユーザー操作に対するレスポンスなどを含め、様々な面でアプリケーションの動作に影響を与えます。

W3C勧告では、XMLリポジトリで管理されるドキュメントに関して、このような場合に適した次の2つの仕様を推奨しています。

- XLink: リソース間のリンクの様々なタイプを定義します。これらのリンクにより、ドキュメント間の任意の関係をモデル化できます。ドキュメントの場所については、リポジトリの内部と外部のどちらでもかまいません。

- XInclude: 複数のXML文書またはXMLフラグメントのコンテンツを単一の情報セットにまとめる方法を定義します。これにより、包含関係をモデル化した複合ドキュメントを作成できます。複合ドキュメントとは、別のドキュメントを含めるドキュメントのことです。つまり、ドキュメントまたはドキュメント・フラグメントを含めるファイル・リソースです。含められるオブジェクトは、同じリポジトリ内のファイル・リソース、またはリポジトリの外部にあるドキュメントやフラグメントです。

これらの標準はそれぞれ非常に一般的なものであり、XML文書間の関係をモデル化する以外にも使用されます。XLinkを使用してリンクされたドキュメントや、XIncludeを使用してXML文書に含められたドキュメントは、必ずしもXML文書である必要はありません。

XLinkやXIncludeを使用してドキュメント間の関係を表すことにより、アプリケーションの柔軟性が高まるだけでなく、コンポーネント・ドキュメントが再利用しやすくなり、それに対するファイングレインな操作(アクセス制御、バージョニング、メタデータなど)が可能になります。XMLのデータ構造(祖先-子階層)を使用してモデル化された関係は、相対的に固定されたものですが、XLinkやXIncludeを使用してモデル化された関係は、容易に変更されます。

注意:
XML Schemaに基づくドキュメントでXLinkやXIncludeの属性を使用可能にするには、XML Schemaでこれらの属性を明示的に宣言するか、または任意の属性の使用を許可する必要があります。

関連項目:

- XLink標準の詳細は、http://www.w3.org/TR/xlinkを参照してください。

- XInclude標準の詳細は、http://www.w3.org/TR/xincludeを参照してください。

XLinkおよびXIncludeのリンク・タイプ

この項では、XLinkおよびXIncludeのリンク・タイプ、およびそれらのリンクとOracle XML DBリポジトリのリンクとの関係について説明します。XLinkリンクは、リポジトリ・リンクよりも一般的です。XLinkリンクには、単純リンクと拡張リンクがあります。Oracle XML DBでは単純XLinkリンクのみサポートしており、拡張リンクはサポートされていません。

XLinkリンクおよびXIncludeリンクによるドキュメント間関係のモデル化

XLinkリンクおよびXIncludeリンクを使用すると、ドキュメント間の任意の関係がモデル化されます。関係の意味と動作は、リンクを使用するアプリケーションに依存します。リンク自体によっては決定されません。XLinkリンクおよびXIncludeリンクは、Oracle XML DBのドキュメント・リンクにマップできます。Oracle XML DBリポジトリのリソースをターゲットとするドキュメント・リンクは、(構成オプションに応じて)ハード・リンクか弱いリンクかのいずれかになります。この点については、リポジトリ・リンクと同様です。ただし、リポジトリ・リンクはFTPやHTTPなどのファイル・システムに関連するプロトコルによってナビゲートできるのに対し、ドキュメント・リンクはこうしたプロトコルではナビゲートできません。ドキュメント・リンクをナビゲートするには、XPath 2.0関数fn:docを使用します。

関連項目:
「ハード・リンクおよび弱いリンク」

XLinkおよびXIncludeのリンク・タイプ

XLinkおよびXIncludeでは、他のドキュメントへのリンクを設定できます。XIncludeの場合、属性hrefおよびxpointerを使用してターゲット・ドキュメントを指定します。

XLinkリンクには、単純リンクと拡張リンクがあります。単純リンクは、ソースからターゲットへの単方向にのみ機能します。拡張リンク(複合リンクともいう)では、複数のドキュメント間の関係を、様々な方向でモデル化できます。単純リンクと拡張リンクはどちらも、リンク・メタデータを含む場合があります。XLinkリンクをXMLデータ内で表すには、事前定義された接頭辞xlinkを持つ名前空間http://www.w3.org/1999/xlinkの様々な属性を使用します。単純リンクは、XMLデータ内ではxlink:type = "simple"のように属性typeと値simpleを使用して表されます。拡張XLinkリンクは、xlink:type = "extended"で表されます。

サード・パーティの拡張XLinkリンクは、関係がモデル化されるいずれのドキュメントにも含まれません。そのためサード・パーティのリンクは、パイナリ・ファイルなど、それ自体ではリンクの表現手段を持たないドキュメントの関連付けに使用できます。

単純XLinkリンクのソース側(つまりリンクを含むドキュメント)は、XML文書である必要があります。単純リンクのターゲット側には任意のドキュメントを使用できます。拡張リンクには、こうした制約はありません。例23-3は、単純リンクの例を示したものです。リンクのターゲットは、属性xlink:hrefにより表されています。

XInclude: 複合ドキュメント

XIncludeは、複数のXML文書の情報セットを単一の情報セットにマージする構文および処理モデルに関するW3C勧告です。他のドキュメントを含める場合は要素xi:includeを使用し、属性hrefの値としてそのURIを指定します。要素xi:includeはネストできます。つまり、含められたドキュメント自体も、別のドキュメントを含めることができます。

(ただし、包含が循環しているとOracle XML DBでエラーが発生します。リソースは作成されますが、包含を展開するとエラーが発生します。)

このようにXIncludeによって、複合ドキュメント(他のXML文書またはXMLフラグメントを含めたリポジトリ・ファイル・リソース)を作成できます。含められるオブジェクトは、同じリポジトリ内のファイル・リソース、またはリポジトリの外部にあるドキュメントやフラグメントです。

1冊の本をコンテンツ管理システムで管理すると想定すると、その本は典型的な複合ドキュメントの1つと考えられます。それぞれの本には、各章ドキュメントが含められます。各章ドキュメントは、それぞれのURLを持つ別々のオブジェクトとして管理できます。章ドキュメントに対しては、それぞれ固有のメタデータおよびアクセス制御の設定が可能であり、バージョニングも可能です。1冊の本は、章ドキュメントの特定のバージョンを含める(参照する)場合があります。同一の章ドキュメントは、複数の本のドキュメントに含め、再利用できます。包含関係はXIncludeによりモデル化されるため、コンテンツ管理が容易になります。たとえば、1つの本の中である章を別の章に差し替えることも容易です。

例23-1は、4つのドキュメントを含むXMLのBook要素を示したものです。また、これらのドキュメントの1つであるpart1.xmlも示されています。ドキュメントpart1.xmlには、章を表す別のドキュメントが含まれています。

例23-1 本のドキュメントに部および章を含めるためのXIncludeの使用方法

本を表す最上位のドキュメントには、要素Bookがあります。

<Book xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href=toc.xml"/>
<xi:include href=part1.xml"/>
<xi:include href=part2.xml"/>
<xi:include href=index.xml"/>
</Book>

本の主要部分であるファイル(リソース)part2.xmlには、複数の章ドキュメントを含むPart要素があります。

<?xml version="1.0"?>
<Part xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="chapter5.xml"/>
<xi:include href="chapter6.xml"/>
<xi:include href="chapter8.xml"/>
<xi:include href="chapter9.xml"/>
</Part>

XIncludeには、その他に次の機能もあります。

- プレーン・テキストの包含: 属性parseに値textを指定したparse = "text"を使用し、未解析の非XMLテキストを含めることができます。

- XMLフラグメントの包含: xi:include要素のxpointer属性を使用し、ドキュメント全体ではなくXMLフラグメントを指定して、それを含めることができます。

- フォールバック処理: 含まれたドキュメントのURIにアクセスできないエラー、xi:include構文エラー、xpointer参照がNULLを戻すエラーなどが発生した場合、XIncludeでは、xi:fallback要素に指定されている処理が実行されます。通常は、含まれる代替要素を指定します。この代替要素では、他ドキュメントを含めるために、これ自体がxi:includeを使用します。

Oracle XML DBでのXLinkの使用

Oracle XML DBでは単純XLinkリンクのみサポートしており、拡張XLinkリンクはサポートされていません。

XLinkの属性を含むXML文書が、リソース・コンテンツまたはユーザー定義のリソース・メタデータとしてOracle XML DBリポジトリに追加された場合は、リポジトリまたは個々のリポジトリ・リソースの構成に基づいて特殊な処理が実行される場合があります。この処理は、リソース構成ドキュメントXDBResConfig.xsdの要素XLinkConfigによって指定されます。たとえば、XLinkリンクを無視したり、XLinkリンクをOracle XML DBのドキュメント・リンクにマップするようにリソースを構成できます。後者の場合は、構成でドキュメント・リンクをハード・リンクにするか弱いリンクにするかを指定できます。ハード・ドキュメント・リンクおよび弱いドキュメント・リンクにはそれぞれ、ハード・リポジトリ・リンクおよび弱いリポジトリ・リンクと同じプロパティがあります。

ドキュメント・リンクの作成や更新に必要な権限は、リポジトリ・リンクの作成や更新に必要な権限と同じです。ドキュメントを部分的に更新する場合でも、ドキュメント全体の削除や再挿入を行う場合と同じ権限が必要です。たとえばドキュメント・リンクを1つしか更新しない場合でも、そのリンクを含むドキュメントにリンクされている各ドキュメントの削除権限と挿入権限が必要です。

構成によりXLinkリンクがドキュメント・リンクにマップされている場合は、XLinkリンクを含むドキュメントがリポジトリに追加されるたびに、XLink情報が抽出され、システム・リンク表に格納されます。リンクのターゲット(リンク先)の場所は、リソースOIDに基づくダイレクト・パスに置き換えられます。構成では、ドキュメント取得の際にOIDパスを名前付きパス(URL)に置き換えるかどうかも指定できます。名前付きパスのかわりにOIDパスを使用すると、通常は、リソース・コンテンツを取得する場合も含め、リンク処理の際のパフォーマンスが向上します。

XLinkは、リソース・コンテンツ内では使用できますが、リソース・メタデータ内では使用できません。

関連項目:

- 「DOCUMENT_LINKSビューを使用したXLinkリンクおよびXIncludeリンクの検証」

- 第29章「ユーザー定義のリポジトリ・メタデータ」

- 「ハード・リンクおよび弱いリンク」

- 「XLinkおよびXIncludeのためのリソースの構成」

- 「XDBResConfig.xsd: リソース構成のためのXML Schema」

Oracle XML DBでのXIncludeの使用

Oracle XML DBでは、複合ドキュメント管理の標準メカニズムとしてXInclude1.0をサポートしています。ただし、属性xpointerおよびドキュメント・フラグメントの包含はサポートしていません。包含対象は完全なドキュメントのみです(属性hrefを使用)。

XIncludeを使用すると、既存のコンテンツを含めたXML文書を作成できます。また、XInclude包含参照を含む一連のリポジトリ・リソースを作成し、スキーマに基づかないXML文書の暗黙的な分解を構成することもできます。

含められるドキュメントのコンテンツは、XMLデータまたはプレーン・テキスト(属性parse = "text"を使用)である必要があります。XIncludeでは、バイナリ・コンテンツは直接含めることはできません。ただし、XLinkを使用してバイナリ・コンテンツにリンクできます。

XIncludeは、リソース・コンテンツ内では使用できますが、リソース・メタデータ内では使用できません。

関連項目:
「DOCUMENT_LINKSビューを使用したXLinkリンクおよびXIncludeリンクの検証」

複合ドキュメントにおける包含の展開

Oracle XML DBリポジトリから複合ドキュメントを取得する際、次のいずれかを選択できます。

- xi:include要素を残した状態で、そのまま取得します。これがデフォルトの動作です。

- xi:include要素を再帰的にそのターゲットに置き換えた(つまり、すべての包含を展開した)後に取得します。いずれかのxi:include要素が解決できない場合はエラーが発生します。

展開された形でドキュメントを取得するために、PL/SQLコンストラクタXDBURITypeを使用して、値'1'または'3'を2番目の引数(フラグ)として渡します。例23-2に、これを示します。XDBURITypeコンストラクタの2番目の引数として渡せるのは、次のいずれかの値です。

- 1: Xinclude包含をすべて展開した後で結果を戻します。これらの包含をXIncludeの標準的なフォールバック・セマンティクスに基づいて解決できない場合はエラーが発生します。

- 2: ドキュメント取得時に発生する可能性のあるすべてのエラーが抑止されます。たとえば、参照先がないhrefポインタなどのエラーです。

- 3: 1と2を指定した場合の処理が同時に行われます。

例23-2では、リポジトリ・フォルダpublic/bookdirにあるすべてのドキュメントを取得し、それぞれの包含を展開します。

例23-2 XDBURITypeによるドキュメントの包含の展開

SELECT XDBURIType(ANY_PATH, '1').getXML() FROM RESOURCE_VIEW
WHERE under_path(RES, '/public/bookdir') = 1;

XDBURITYPE(ANY_PATH,'1').GETXML()
---------------------------------
<Book>
<Title>A book</Title>
<Chapter id="1">
<Title>Introduction</Title>
<Body>
<Para>blah blah</Para>
<Para>foo bar</Para>
</Body>
</Chapter>
<Chapter id="2">
<Title>Conclusion</Title>
<Body>
<Para>xyz xyz</Para>
<Para>abc abc</Para>
</Body>
</Chapter>
</Book>

<Chapter id="1">
<Title>Introduction</Title>
<Body>
<Para>blah blah</Para>
<Para>foo bar</Para>
</Body>
</Chapter>

<Chapter id="2">
<Title>Conclusion</Title>
<Body>
<Para>xyz xyz</Para>
<Para>abc abc</Para>
</Body>
</Chapter>

3 rows selected.

(ここに示されている結果は、例23-8のリソースbookfile.xmlと、それに含まれているリソースchap1.xmlおよびchap2.xmlに対応するものです。)

関連項目:

- 展開時のアクセス制御の詳細は、「複合ドキュメントのバージョニング、ロックおよびアクセス制御」を参照してください。

- XDBURITypeの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

複合ドキュメントの検証

複合ドキュメントの検証は、XML文書の検証と同じ方法で行います。ただし、複合ドキュメントの検証は、xi:include要素をそのまま使用するか、ターゲットに置き換えた形で行うかを選択できます。

また、展開されていない形での検証と展開された形での検証に、別々のXML Schemaを使用するように選択できます。たとえば、あるXML Schemaを使用して、最初は記憶域構造を設定できるよう展開せずに検証を行い、次に展開したドキュメントの格納後に、別のXML Schemaを使用して検証できます。

複合ドキュメントの更新

複合ドキュメントは、リソースと同じ方法で更新できます。その場合、リソースが新規の値で置き換えられます。したがって、リソースを削除し、リソースを挿入する処理に相当します。つまり、元のリソース内のxi:include要素は削除されます。置換後の(挿入された)ドキュメント内のxi:include要素は、挿入時に定義された構成に従って通常どおり処理されます。

複合ドキュメントのバージョニング、ロックおよびアクセス制御

複合ドキュメントは、それぞれ個別のリソースで構成されます。したがって、このようなリソースのバージョンニング、ロックおよびアクセス制御も、それぞれ個別に行われます。

- バージョン管理されたリソース(VCR)へのドキュメント・リンクは、常にターゲット・リソースの最新バージョン、または現在のワークスペース内で選択されたバージョンに解決されます。ただし、OIDベースのパスでターゲット・リソースを識別すると、特定のバージョンを明示的に参照できます。

- xi:include要素を含むドキュメントをロックしても、含まれているドキュメントはロックされません。また、含まれているドキュメントをロックしても、それを含むドキュメントはロックされません。

- 展開した形で複合ドキュメントを取得する場合は、常に各参照ドキュメントのアクセス制御リスト(ACL)がチェックされます。このチェックには、現行ユーザーの権限(起動者の権限)を使用します。含まれているドキュメントのいずれかについて権限が不十分な場合、展開はキャンセルされエラーが発生します。

関連項目:

- 「複合ドキュメントにおける包含の展開」

- VCRの詳細は、第24章「リソースのバージョン管理」を参照してください。

- リソースのACLの詳細は、第27章「リポジトリのアクセス制御」を参照してください。

DOCUMENT_LINKSビューを使用したXLinkリンクおよびXIncludeリンクの検証

読取り専用のパブリック・ビューDOCUMENT_LINKSに問い合せ、XLinkリンクおよびXIncludeリンクから導出されたドキュメント・リンクについてのシステム情報を取得できます。このビューでは、それぞれのリンクについて次の各列に情報が表示されます。

- SOURCE_ID: ソース・リソースのOID。RAW(16)。

- TARGET_ID: ターゲット・リソースのOID。RAW(16)。

- TARGET_PATH: 常にNULL。今後の使用のために確保されています。VARCHAR2(4000)。

- LINK_TYPE: ドキュメント・リンクのタイプ。HardまたはWeak。VARCHAR2(8)。

- LINK_FORM: 元のリンクの形式。XLinkまたはXInclude。VARCHAR2(8)。

- SOURCE_TYPE: 常にResource Content。VARCHAR2(17)。

次の条件を満たしている場合のみ、リソースに関する情報をこのビューから取得できます。

- リソースがリンク・ソースであり、それに対して権限read-contentsまたはread-propertiesが付与されていること。

- リソースがリンク・ターゲットであり、それに対して権限read-propertiesが付与されていること。

関連項目:
パブリック・ビューDOCUMENT_LINKSの詳細は、『Oracle Databaseリファレンス』を参照してください。

XLink情報に関するDOCUMENT_LINKSへの問合せ

例23-3は、リソース作成時にXLinkリンクを処理する方法、およびドキュメント・リンクに関するシステム情報をビューDOCUMENT_LINKSから取得する方法を示したものです。リソースが格納されているフォルダは、XLinkリンクをハード・ドキュメント・リンクにマップするように構成されているとみなされます。

例23-3 XLinkリンクからマップされたドキュメント・リンクの問合せ

DECLARE
b BOOLEAN;
BEGIN
b := DBMS_XDB.createResource(
'/public/hardlinkdir/po101.xml',
'<PurchaseOrder id="101" xmlns:xlink="http://www.w3.org/1999/xlink">
<Company xlink:type="simple"
xlink:href="/public/hardlinkdir/oracle.xml">Oracle Corporation</Company>
<Approver xlink:type="simple"
xlink:href="/public/hardlinkdir/quine.xml">Willard Quine</Approver>
</PurchaseOrder>');

b := DBMS_XDB.createResource(
'/public/hardlinkdir/po102.xml',
'<PurchaseOrder id="102" xmlns:xlink="http://www.w3.org/1999/xlink">
<Company xlink:type="simple"
xlink:href="/public/hardlinkdir/oracle.xml">Oracle Corporation</Company>
<Approver xlink:type="simple"
xlink:href="/public/hardlinkdir/curry.xml">Haskell Curry</Approver>
<ReferencePO xlink:type="simple"
xlink:href="/public/hardlinkdir/po101.xml"/>
</PurchaseOrder>');
END;
/

SELECT r1.ANY_PATH source, r2.ANY_PATH target, dl.LINK_TYPE, dl.LINK_FORM
FROM DOCUMENT_LINKS dl, RESOURCE_VIEW r1, RESOURCE_VIEW r2
WHERE dl.SOURCE_ID = r1.RESID and dl.TARGET_ID = r2.RESID;

SOURCE                        TARGET                         LINK_TYPE LINK_FORM
----------------------------- ------------------------------ --------- ---------
/public/hardlinkdir/po101.xml /public/hardlinkdir/oracle.xml Hard      XLink
/public/hardlinkdir/po101.xml /public/hardlinkdir/quine.xml  Hard      XLink
/public/hardlinkdir/po102.xml /public/hardlinkdir/oracle.xml Hard      XLink
/public/hardlinkdir/po102.xml /public/hardlinkdir/curry.xml  Hard      XLink
/public/hardlinkdir/po102.xml /public/hardlinkdir/po101.xml  Hard      XLink

関連項目:
XLinkリンクがハード・リンクにマップされるようなフォルダの構成例は、「OIDによる取得時のXIncludeリンクからハード・ドキュメント・リンクへのマッピング」を参照してください。

XInclude情報に関するDOCUMENT_LINKSへの問合せ

例23-4は、すべてのドキュメント・リンクを表示するビューDOCUMENT_LINKSに対する問合せを示します。

例23-4 XIncludeリンクからマップされたドキュメント・リンクの問合せ

DECLARE
ret BOOLEAN;
BEGIN
ret := DBMS_XDB.createResource(
'/public/hardlinkdir/book.xml',
'<Book xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="/public/hardlinkdir/toc.xml"/>
<xi:include href="/public/hardlinkdir/part1.xml"/>
<xi:include href="/public/hardlinkdir/part2.xml"/>
<xi:include href="/public/hardlinkdir/index.xml"/>
</Book>');
END;

SELECT r1.ANY_PATH source, r2.ANY_PATH target, dl.LINK_TYPE, dl.LINK_FORM
FROM DOCUMENT_LINKS dl, RESOURCE_VIEW r1, RESOURCE_VIEW r2
WHERE dl.SOURCE_ID = r1.RESID and dl.TARGET_ID = r2.RESID;

SOURCE                       TARGET                        LINK_TYPE LINK_FORM
------                       ------                        --------- ---------
/public/hardlinkdir/book.xml /public/hardlinkdir/toc.xml   Hard      XInclude
/public/hardlinkdir/book.xml /public/hardlinkdir/part1.xml Hard      XInclude
/public/hardlinkdir/book.xml /public/hardlinkdir/part2.xml Hard      XInclude
/public/hardlinkdir/book.xml /public/hardlinkdir/index.xml Hard      XInclude

XLinkおよびXIncludeのためのリソースの構成

リポジトリ・リソースの他の処理と同様に、Oracle XML DBリポジトリ・リソースのXLinkおよびXInclude処理を構成します。「リソースの構成」を参照してください。この項の後半では、他のリソースのXLinkおよびXInclude処理を構成する場合にリソースとして使用するリソース構成ファイルについて説明します。

リソース構成ファイルは、パス/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBResConfig.xsdにあるOracle XML DBリポジトリでアクセス可能な、XML Schema XDBResConfig.xsd準拠のXMLファイルです。XLinkおよびXIncludeの処理を構成するにはそれぞれ、要素ResConfigの子要素XLinkConfigおよびXIncludeConfigを使用します。これらのうち、いずれかの要素が存在しない場合、その要素に対応するタイプのリンクは処理できません。

XLinkConfigおよびXIncludeConfigの両方で、属性UnresolvedLinkと、子要素LinkTypeおよびPathFormatを使用できます。また要素XIncludeConfigでは、子要素ConflictRuleも使用できます。ただし、LinkType要素のコンテンツがNoneの場合、PathFormat要素およびConflictRule要素は使用できません。

XLinkConfigおよびXIncludeConfigには、事前条件は定義できません。新規リソースのXLinkリンクおよびXIncludeリンクの処理は、リポジトリ・リソースの作成時に親フォルダのResConfig要素によって指定されます。親フォルダにResConfig要素がない場合は、リポジトリ全般の構成が適用されます。

リソース構成ファイルの変更内容は、構成ファイルの変更後に作成または更新されたドキュメントにのみ適用されます。既存ドキュメント内のリンクを処理するには、適切なリソース構成パラメータを指定した上で、PL/SQLプロシージャDBMS_XDB.processLinksを使用します。

関連項目:

- 「DBMS_XDB.processLinksを使用したXLinkリンクおよびXIncludeリンクの管理」

- 第22章「Oracle XML DBリポジトリの構成」

未解決リンクの処理の構成: UnresolvedLink属性

LinkConfig要素には、Error (デフォルト値)またはSkipの値のUnresolvedLink属性を使用できます。これは、ドキュメントをリポジトリに挿入する(リソースを作成する)際、XLinkリンクまたはXIncludeリンクを解決できない場合の処理を指定します。Errorを指定すると、エラーが発生し、現在の操作がロールバックされます。Skipを指定すると、XLinkリンクまたはXIncludeリンクの処理がスキップされます。処理がスキップされると、対応するドキュメント・リンクを含まずにリソースが作成され、そのリソースのHasUnresolvedLinks属性がtrueに設定されます。これは、リソースに未解決リンクが含まれていることを表すものです。

弱いリンクの循環を含むリソースを作成する場合は特に、属性UnresolvedLinkの値としてSkipを指定すると便利です。この値を指定しない場合は、リソース作成中に未解決リンクのエラーが発生します。スキップされたリンクは、リソースおよびそれにリンクするすべてのリソースが作成された後に、PL/SQLプロシージャDBMS_XDB.processLinksを使用して処理できます。このプロシージャによってすべてのXLinkリンクおよびXIncludeリンクが解決されると、属性HasUnresolvedLinksはfalseに設定されます。

削除済リソースへの弱いリンクのあるリソースには、リソース要素HasUnresolvedLinksもtrueに設定されます。このため、リソースを削除すると、そのリソースに対する弱いリンクも事実上削除されます。特に、リソースへの最後のハード・リンクを削除した場合は、リソースそのものも削除され、削除されたリソースを弱いリンクで示すすべてのリソースで、属性HasUnresolvedLinksがtrueに設定されます。

関連項目:

- 「ハード・リンクおよび弱いリンク」

- 「DBMS_XDB.processLinksを使用したXLinkリンクおよびXIncludeリンクの管理」

作成するドキュメント・リンクの構成: LinkType要素

リソース構成ファイルのLinkType要素を使用して、ドキュメントのOracle XML DBリポジトリへの格納の際、XLinkリンクまたはXIncludeリンクが検出された場合に作成されるドキュメント・リンクのタイプを指定します。LinkType要素に指定できる値(要素のコンテンツ)は次のとおりです。

- None(デフォルト): XLinkリンクおよびXIncludeリンクが無視され、対応するドキュメント・リンクは作成されません。

- Hard: XLinkリンクまたはXIncludeリンクが、リポジトリ・ドキュメント内のハード・ドキュメント・リンクにマップされます。

- Weak: XLinkリンクまたはXIncludeリンクが、リポジトリ・ドキュメント内の弱いドキュメント・リンクにマップされます。

関連項目:

- 例23-5

- 例23-6

取得に使用するパス形式の構成: PathFormat要素

xlink:href属性またはxi:include:href属性を含むドキュメントの取得時に使用されるパス形式を指定するには、リソース構成ファイルのPathFormat要素を使用します。ハード・ドキュメント・リンクおよび弱いドキュメント・リンクのそれぞれについて、PathFormat要素に指定できる値(要素のコンテンツ)は次のとおりです。

- OID(デフォルト): XLinkまたはXIncludeのhrefパスが、リポジトリ・ドキュメント内のOIDベースのパスにマップされます。つまり、OIDが直接使用されます。

- Named: XLinkまたはXIncludeのhrefパスが、リポジトリ・ドキュメント内の名前付きパス(URL)にマップされます。このパスは、ドキュメント取得時に内部OIDを基にして計算されます。そのため、OIDパスを直接使用する場合に比べ、取得に時間がかかります。

関連項目:

- 例23-5

- 例23-6

XIncludeに関する競合解決の構成: ConflictRule要素

リソース構成ファイルのConflictRule要素を使用して、構成要素ドキュメントに対して計算済のパスがすでにOracle XML DBリポジトリ内にある場合に使用する競合解決ルールを指定します。ConflictRule要素に指定できる値(要素のコンテンツ)は次のとおりです。

- Error(デフォルト): エラーが発生します。

- Overwrite: 既存のリポジトリ・パスのターゲットとなっているドキュメントを、含まれているドキュメントに置き換えると更新されます。既存のドキュメントがバージョン管理されたリソースであれば、バージョニングが自動的に行われる場合を除いて、事前にチェックアウトされます。そうでない場合は、エラーが発生します。

- Syspath: 含まれているドキュメントへのパスが、新規システム定義のパスに変更されます。

関連項目:
バージョン管理されたリソースの詳細は、第24章「リソースのバージョン管理」を参照してください。

XIncludeを使用したドキュメントの分解の構成: SectionConfig要素

リソース構成ファイルのSectionConfig要素を使用して、XInclude包含参照を含む一連のリソースを作成するために、スキーマに基づかないXML文書をOracle XML DBリポジトリに追加する際、このXML文書がどのように分解されるかを指定します。またリソース構成ファイルでは、単純なXPath式を使用して、ドキュメントのどの部分を個々のリソースにマップするか、およびマップ先のリソースはどれかを指定します。

要素SectionConfigには1つ以上のSection要素があり、それぞれに次の子要素が含まれています。

- sectionPath: セクションのルートを指定する単純なXPath 1.0式。ここではchild軸およびdescendant軸のみを使用し、ワイルドカードは使用できません。

- documentPath (オプション): 単純なXPath 1.0式。この式を評価することにより、sectionPathに従って分解されたドキュメントから作成されるリソースを識別します。このXPath式では、child軸、descendant軸、およびattribute軸のみを使用します。

- namespace(オプション): sectionPathおよびdocumentPathの実際の名前空間。

また要素Sectionには、作成するセクションのタイプを指定するtype属性があります。値がDocumentの場合は、ドキュメントが作成されます。デフォルト値Noneの場合は何も作成されません。Noneを使用することは、SectionConfig要素を削除した場合に相当します。このため、type属性をNoneに設定すると、SectionConfig要素を削除せずに一時的に無効にできます。再度有効にする場合は、設定をDocumentに戻します。

リポジトリに追加されたドキュメント内の要素が、複数のsectionPath値と一致する場合は、(ドキュメントの順序における)最初の式のみが使用されます。

documentPath要素が存在しない場合、作成されたリソースにはシステム定義名が設定され、元のドキュメントに対して指定されたフォルダ内に格納されます。

関連項目:

- 例23-7「XIncludeを使用したドキュメントの分解の構成」

- 例23-8「生成されたxi:include要素を表示するポジトリ・ドキュメント」

XLinkおよびXIncludeの構成例

例23-5は、XInclude処理を構成する構成ファイルのセクションを示します。ここではXInclude属性をOracle XML DBリポジトリのハード・ドキュメント・リンクにマップします。取得したリソース内のリポジトリ・パスは、リソースのOIDに基づいて構成されます。

例23-5 OIDによる取得時のXIncludeリンクからハード・ドキュメント・リンクへのマッピング

<ResConfig>
. . .
<XIncludeConfig UnresolvedLink="Skip">
<LinkType>Hard</LinkType>
<PathFormat>OID</PathFormat>
</XIncludeConfig>
. . .
</ResConfig>

例23-6は、XLinkリンクをリポジトリ内の弱いドキュメント・リンクにマップするためのXLinkConfigセクションを示したものです。この場合、ドキュメントの取得には名前付きパス(URL)が使用されます。

例23-6 名前付きパスによる取得時のXLinkリンクから弱いリンクへのマッピング

<ResConfig>
. . .
<XLinkConfig UnresolvedLink="Skip">
<LinkType>Weak</LinkType>
<PathFormat>Named</PathFormat>
</XLinkConfig>
. . .
</ResConfig>

例23-7は、入力ドキュメントをOracle XML DBリポジトリに追加する際、入力ドキュメントの各Chapter要素が別々のリポジトリ・ファイルになるように指定するSectionConfigセクションを示します。作成されたファイルのリポジトリ・パスは、構成要素documentPathによって指定され、このパスは、例23-6のリソース構成ファイルの場所に対する相対パスです。

例23-7 XIncludeを使用したドキュメントの分解の構成

<ResConfig>
. . .
<SectionConfig>
<Section type = "Document">
<sectionPath>//Chapter</sectionPath>
<documentPath>concat("chap", @id, ".xml")</documentPath>
</Section>
</SectionConfig>
. . .
</ResConfig>

この例のXPath式では、XPath関数concatによって次の文字列が連結され、使用するリポジトリ・パスが生成されます。

- chap: (接頭辞)chap

- 入力ドキュメント内の要素Chapterの属性idの値

- ファイル拡張子.xml

たとえばchap27.xmlのリポジトリ・パスは、入力ドキュメントのChapter要素のid属性の値が27の場合に生成されます。

<Chapter id="27"> ... </Chapter>

例23-6の構成ドキュメント、およびXInclude要素を含む本のドキュメントがリポジトリ・フォルダ/public/bookdirに格納されている場合、XInclude分解によって生成された個々の章ファイルは、ファイル/public/bookdir/chapN.xmlに取り込まれます。ただし、Nの値は、Chapter要素のid属性に指定された値です。

リポジトリに追加された本のドキュメントは、入力された本のドキュメントから生成されます。入力された本のドキュメントに埋め込まれているChapter要素は、生成された章ドキュメントを参照するxi:include要素に置き換えられます。例23-8にこれを示します。

例23-8 生成されたxi:include要素を表示するリポジトリ・ドキュメント

SELECT XDBURIType('/public/bookdir/bookfile.xml').getclob() FROM DUAL;

XDBURITYPE('/PUBLIC/BOOKDIR/BOOKFILE.XML').GETCLOB()
--------------------------------------------------------------------------------
<Book>
<Title>A book</Title>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="/public/bookdir/chap1.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="/public/bookdir/chap2.xml"/>
</Book>

関連項目:

- 第22章「Oracle XML DBリポジトリの構成」

- XDBResConfig.xsd: リソース構成のためのXML Schema

- 「XIncludeを使用したドキュメントの分解の構成: SectionConfig要素」

DBMS_XDB.processLinksを使用したXLinkリンクおよびXIncludeリンクの管理

PL/SQLプロシージャDBMS_XDB.processLinksを使用して、単一ドキュメント内、または1つのフォルダに格納された全ドキュメント内のXLinkリンクおよびXIncludeリンクをすべて手動で処理できます。ハード・リンクされたすべてのサブフォルダを再帰的に処理する場合は、RECURSIVEをモード引数としてこのプロシージャに渡します。すべてのXLinkリンクおよびXIncludeリンクは、対応する構成パラメータに従って処理されます。リソース内のいずれかのリンクを解決できない場合は、そのリソースのHasUnresolvedLinks属性がtrueに設定され、リソースに未解決リンクが含まれていることが示されます。属性HasUnresolvedLinksのデフォルト値はfalseです。

関連項目:
「未解決リンクの処理の構成: UnresolvedLink属性」

24 リソースのバージョン管理

この章では、Oracle XML DBリソースのバージョンを作成および管理する方法を説明します。

この章の内容は次のとおりです。

- Oracle XML DBバージョニングの概要

- バージョニングおよびリソースID

- バージョニングおよびACL

- リソースのバージョニングの例

Oracle XML DBバージョニングの概要

バージョニングによって、Oracle XML DBのリポジトリのリソースの異なるバージョンを作成および管理できます。バージョン管理されたOracle XML DBリソースに対するすべての変更の記録または履歴が保持されます。バージョン管理されたリソースを更新すると、Oracle XML DBは、更新前のコンテンツを異なるリソース・バージョン(履歴記録のスナップショット)として格納します。

バージョニング機能には次のものが含まれます。

- リソースのバージョン管理。
Oracle XML DBリポジトリ・リソースのバージョン管理を有効または無効にするオプションがあります。

- バージョン管理されたリソースの更新。
Oracle XML DBは、バージョン管理されたリソースを更新するときに、リソースの新しいバージョンを作成します。この新しいバージョンは、バージョン管理されたリソースを削除しても、データベースから削除されません。

- バージョン管理されたリソースへのアクセス。
バージョン管理されたリソースには、他のリソースへのアクセスと同じ方法でアクセスできます。

- リソース・バージョンへのアクセス。
リソースの特定のバージョンにアクセスするには、そのバージョンのリソースIDを使用します。リソースIDは、リソース・バージョン履歴またはバージョン管理されたリソース自身から取得できます。「バージョニングおよびリソースID」を参照してください。

表24-1に、この章で使用する用語について示します。

表24-1 Oracle XML DBバージョニングの用語

用語

説明

バージョン対応リソース

バージョン管理可能なリソース。フォルダおよびACLを除くOracle XML DBリソースをすべて使用できます。

バージョン管理されたリソース

バージョン管理されるリソース。

バージョン・リソース

バージョン管理されたリソースの特定のバージョン。バージョン・リソースはリソースそのものです。システム生成であり、関連するパス名はありません。読取り専用です(更新または削除できません)。

checkOut、checkIn、unCheckOut

バージョン管理されたリソースを管理するための操作。バージョン管理されたリソースを変更する前にcheckOutを使用する必要があります。変更を永続的にする場合はcheckInを使用します。変更をキャンセルする場合はunCheckOutを使用します(これらの各操作の後にCOMMITを使用します)。

注意:
Oracle XML DBは、Oracle XML DBリソースのみのバージョン管理をサポートしています。Oracle Databaseのユーザー定義の表またはデータのバージョン管理はサポートされません。
バージョンのリソースIDは、チェックインからチェックアウト間での保持が保証されません。最新のバージョンのリソースID以外はすべて保持されます。

Oracle XML DBでは、XML Schemaに基づかないXMLリソースのバージョニングをサポートします。また、基礎となる表に関連付けられているトリガーや制約がない場合にかぎり、XML Schemaに基づくリソース、およびXML Schemaに基づくメタデータを含むリソースのバージョン管理もサポートします。

表の階層が有効な場合は、表にトリガーが含まれます。これには、XML Schema登録の一部として作成される表が含まれ、デフォルトの動作によって階層が有効になります。

また、リソースの基礎となる表の1つを問い合せる場合は、その問合せで複数のバージョンのリソースからデータを戻すことができることにも注意してください。これは、行ごとに異なるリソース・バージョンのデータが基礎となる同じ表に格納されるためです。

バージョニングおよびリソースID

リソース・オブジェクトID(リソースID)は、Oracle XML DBリソースに対する一意で定数のシステム生成の識別子です。各リソースにはそれぞれリソースIDが含まれます。これには、パス名を含まないシステム生成のリソースであるバージョン・リソースが含まれます。リソースIDは、RESIDと呼ばれる場合があります。

リソースをバージョン管理し、異なるバージョンのリソースを管理するには、PL/SQLパッケージDBMS_XDB_VERSIONを使用します。DBMS_XDB_VERSION一部のルーチンは、バージョン管理されたリソースのパス名を引数として使用し、関連するバージョン・リソースのリソースIDを戻します。

たとえば、リソースをバージョン管理、つまりバージョン管理されたリソースにするには、ファンクションDBMS_XDB_VERSION.makeVersionedを使用します。これは、引数としてリソースのリポジトリ・パスを使用します。

バージョン管理された特定のリソースで様々なバージョニング操作を実行する場合は、同じパス名を使用する必要はありませんが、使用するパス名はすべて同じリソースを参照する必要があります。

バージョン管理されたリソースを表す引数としてパス名が渡されると、使用されるリソースの最新(現在)のバージョンになります。パス名は常に最新のバージョンを表します。現在のバージョン以外のバージョンを参照する唯一の方法は、そのリソースIDを使用することです。

指定されたバージョンのリソースIDは定数です。バージョンはそれ自体リソースで、リソースのリソースIDは変更されないことに注意してください。

バージョン管理されたリソースをチェックインするたびに、Oracle XML DBによって、リソースの新しいバージョンが作成されます。バージョン・リソースとは、リソースIDが付いたリソース(そのコンテンツおよびメタデータ)のスナップショットです。バージョン管理された特定のリソースのバージョン・リソースのコレクションによって、前のバージョンの履歴順序、バージョン・シリーズまたはリソースの履歴が構成されます。

リソースID Rを持つバージョン管理されたリソースをチェックインする場合、Oracle XML DBは新しいリソースID Pを作成します。これは最後にチェックアウトされる前と同様に、リソース(コンテンツおよびメタデータの両方)のスナップショットを参照します。スナップショットはチェックアウト前に作成されますが、関連するバージョン・リソース(およびそのリソースID P)はチェックイン時に作成されます。新しいリソースID Pおよびそれを参照するスナップショットはともに、リソースの現在ではなく前のバージョンを表すことになります。リソースID Rは引き続き現在のバージョンを参照します。

つまり、バージョン管理されたリソースをチェックインすると、バージョン管理されたリソースの前の状態を表すバージョン・リソースが作成されます。新しいリソースと同様、この新しいバージョン・リソースには新しいリソースID(P)が割り当てられます。

ファイルのバックアップ・コピーの作成を検討する方法で、バージョン・リソースの作成(チェックイン)を検討できます。バックアップ・ファイルに新しい名前を付けるのと同じように、リソースの前のバージョンのスナップショットに、新しいリソースIDが付けられます。作業ファイルが元の名前を保持するのと同じように、現在のリソースは元のリソースIDを保持します。

つまり、新しいバージョンを作成するためにリソースをチェックインすると、新しいバージョン・リソースは、実際は古い(前の)バージョンを表すバージョン・リソース(リソースID PおよびそのリソースIDで参照されるスナップショット)になります。リソースの最新のバージョン(R)が実際の現在のバージョンです。新しいバージョン・リソース = リソースのコンテンツおよびメタデータの古い(前のバージョン)となります。

リソースID Rは、バージョン管理された時点から削除されるまで、バージョン管理されたリソースの現在のバージョンを参照します。最新のバージョンのリソースには、常に元のリソースIDを使用してアクセスできます。

前のバージョンのリソースを参照する必要がある場合は、そのリソースIDを使用して参照する必要があります。パス名を使用することはできません。ファンクションDBMS_XDB_VERSION.getPredsByRESIDを使用すると、指定されたリソースの前のバージョンのリソースIDを取得できます。

注意:
リソースを削除すると、リソースIDやパス名に関係なく、そのリソースの後続の参照でエラー(通常はORA-31001: リソース・ハンドルまたはパス名が無効です)が発生します。バージョン管理されたリソースを削除すると、そのバージョンにはアクセスできません。

バージョニングおよびACL

バージョン・リソースは不変です。これはリソースのコンテンツおよびメタデータのスナップショットで、リソースIDと、スナップショットおよびIDの両方は静的です。同様に、バージョン・リソースのACLは変更できません。

バージョン管理されたリソースをチェックアウトすると、そのACLを変更することはできません。ACLをチェックインすると、変更されたACLには引き続き現在(最新)のバージョンのリソースが関連付けられ、前のバージョン(新しく作成されたバージョン・リソース)は、変更前のACLに関連付けられます。つまり、前のバージョンは前のACLに関連付けられ、現在のバージョンは更新済のACLに関連付けられます。

注意する重要な点は次のとおりです。

- リソースのバージョンごとに異なるACLを関連付けることができます。

- 現在のバージョンに関連付けられたACLは、リソースのチェックアウト後に変更できます。

- チェックインすると、新しく作成されたバージョン・リソース(リソースの前のバージョン)にチェックアウト前のACLが関連付けられます。

- 指定されたバージョンに関連付けられたACLは同じままです。

リソースのバージョニングの例

この項では、次の操作の実行例について説明します。

- リソースのバージョン管理(バージョン管理されたリソースの作成): 例24-2

- リソースIDの参照によるリソースのコンテンツの取出し: 例24-3

- バージョン管理されたリソース(すべてのユーザー)のチェックアウト: 例24-4

- リソース・コンテンツの更新: 例24-5

- リソースのチェックイン: 例24-6

- 新しいバージョンおよび古いバージョンのリソースのコンテンツおよびメタデータの取出し: 例24-7、例24-8、例24-9

- リソースのチェックアウトのキャンセル: 例24-10

例24-3では、Oracle XML DBリポジトリ・リソースをリポジトリ・パス/public/t1.txtで作成します。リソースにはコンテンツとしてテキストMary had a little lambが含まれます。この例では、SQL*PlusコマンドVARIABLEを使用して、この項の別の例で使用されているバインド変数targetPath、current_RESIDおよびprevious_RESIDを宣言します。

例24-1 リポジトリ・リソースの作成

VARIABLE targetPath      VARCHAR2(700)
VARIABLE current_RESID   VARCHAR2(32)
VARIABLE previous_RESID  VARCHAR2(32)

DECLARE
res BOOLEAN;
BEGIN
:targetPath  := '/public/t1.txt';
IF (DBMS_XDB.existsResource(:targetPath))
THEN DBMS_XDB.deleteResource(:targetPath);
END IF;
res := DBMS_XDB.createResource(:targetPath, 'Mary had a little lamb');
END;
/

新しいリソースはバージョン管理されません。例24-2では、PL/SQL関数makeVersionedを使用して、バージョン管理の対象にします。この関数は、バージョン管理されたリソースの最初のバージョン・リソースのリソースIDを戻します。この関数では自動コミットは行われません。明示的にCOMMITを使用する必要があります。

例24-2 バージョン管理されたリソースの作成

DECLARE
resid DBMS_XDB_VERSION.RESID_TYPE;
BEGIN
resid := DBMS_XDB_VERSION.makeVersioned(:targetPath);
:current_RESID := resid;
COMMIT;
END;
/

例24-2では、新しいバージョン・リソースのリソースIDをバインド変数current_RESIDにコピーします。例24-3に、型コンストラクタXDBUritypeとPL/SQLファンクションcreateOIDPathを使用し、リソースIDを参照してリソース・コンテンツを取り出す方法を示します。

例24-3 リソースIDの参照によるリソース・コンテンツの取出し

SELECT XDBURIType(DBMS_XDB.createOIDPath(:current_RESID)).getClob() FROM DUAL;

XDBURITYPE(DBMS_XDB.CREATEOIDPATH(:CURRENT_RESID)).GETCLOB()
------------------------------------------------------------
Mary had a little lamb

1 row selected.

例24-4では、バージョン管理されたリソースをチェックアウトして(コミットし)、このリソースを変更できるようにします。チェックアウトされたリソースは変更できません。

例24-4 バージョン管理されたリソースのチェックアウト

BEGIN
DBMS_XDB_VERSION.checkOut(:targetPath);
COMMIT;
END;
/

例24-5では、チェックアウトしたリソースのコンテンツを更新します。(LOB)コンテンツを更新する前に、リソースをロックする必要があります。この例では、リソースの表示名(スカラー属性)のダミー更新を使用して、この操作を実行します。

例24-5 リソース・コンテンツの更新

DECLARE
content        BLOB;
newContentBlob BLOB;
newContentClob CLOB;
source_offset  INTEGER := 1;
target_offset  INTEGER := 1;
warning        INTEGER;
lang_context   INTEGER := 0;
BEGIN
-- Lock the resource using a dummy update.
UPDATE RESOURCE_VIEW
SET RES =
updateXML(RES, '/Resource/DisplayName/text()',
XMLCast(XMLQuery(
'declare namespace ns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource/ns:DisplayName/text()'
PASSING RES AS "r" RETURNING CONTENT)
AS VARCHAR2(128)))
WHERE equals_path(res, :targetPath) = 1;
-- Get the LOB locator.
SELECT XMLCast(XMLQuery('declare namespace ns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource/ns:XMLLob'
PASSING RES AS "r" RETURNING CONTENT)
AS BLOB)
INTO content FROM RESOURCE_VIEW
WHERE equals_path(RES, :targetPath) = 1;
-- Update the LOB.
newContentClob := 'Hickory dickory dock, the mouse ran up the clock';
DBMS_LOB.createTemporary(newContentBlob, false, DBMS_LOB.CALL);
DBMS_LOB.convertToBlob(newContentBlob, newContentClob,
DBMS_LOB.getLength(newContentClob),
source_offset, target_offset,
nls_charset_id('AL32UTF8'), lang_context, warning);
DBMS_LOB.open(content, DBMS_LOB.lob_readwrite);
DBMS_LOB.trim(content, 0);
DBMS_LOB.append(content, newContentBlob);
DBMS_LOB.close(content);
DBMS_LOB.freeTemporary(newContentBlob);
DBMS_LOB.freeTemporary(newContentClob);
COMMIT;
END;
/

例24-5では、LOBロケータを使用してLOBコンテンツを取得します。これは要素/ns:Resource/ns:XMLLobです。これにより既存のコンテンツは空になり、パッケージDBMS_LOB内のPL/SQLプロシージャtrimおよびappendを使用して、新しいコンテンツが追加されます。コンテンツの変更がコミットされます。

関連項目:
LOBの更新の詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照してください。

この時点でコンテンツは変更されていますが、この変更はバージョン・シリーズに記録されていません。例24-6では、リソースをチェックインし、チェックインをコミットします。

例24-6 バージョン管理されたリソースのチェックイン

DECLARE
resid DBMS_XDB_VERSION.RESID_TYPE;
BEGIN
resid := DBMS_XDB_VERSION.checkIn(:targetPath);
:previous_RESID := DBMS_XDB_VERSION.getPredsByRESID(resid)(1);
COMMIT;
END;
/

PL/SQL関数checkInは現在のバージョンのリソースIDを戻し、これはcurrent_RESIDと同じです。例24-6では、この値をPL/SQL関数getPredsByRESIDに渡します。この関数は、引数の直前のリソースの、リソースIDのリストを戻します。脚注 1  例24-6では、このリストの最初(かつ唯一)の要素をバインド変数previous_RESIDに割り当てます。

この時点で、current_RESIDの値は現在のバージョンのリソースIDで、previous_RESIDの値は前のバージョンのリソースIDです。

リソースのコンテンツまたはメタデータは、次の方法を使用して取り出すことができます。

- XDBURITypeとPL/SQLファンクションDBMS_XDB.createOIDPath: コンテンツを取り出します。例24-3および例24-7を参照してください。

- PL/SQLファンクションDBMS_XDB_VERSION.getContentsCLOBByRESID: コンテンツを取り出します。例24-8を参照してください。

- PL/SQLファンクションDBMS_XDB_VERSION.getResourceByRESID: メタデータを取り出します。例24-9を参照してください。

XDBURITypeとcreateOIDPathを使用すると、プロトコルを使用してリソース・コンテンツにアクセスできます。たとえば、createOIDPathによって戻される値にHTML IMAGEタグのHREFを設定し、様々なバージョンのWebページ用グラフィック・イメージ・ファイルのリソースをOracle XML DBで提供できます。

例24-7から例24-9では、それぞれ異なる方法を使用して、バインド変数current_RESIDおよびprevious_RESIDで指定されるリソースの2つのバージョンをチェックイン後に取り出します。

例24-7 XDBURITYPEおよびCREATEOIDPATHを使用したリソース・バージョン・コンテンツの取出し

SELECT XDBURIType(DBMS_XDB.createOIDPath(:current_RESID)).getClob() FROM DUAL;

XDBURITYPE(DBMS_XDB.CREATEOIDPATH(:CURRENT_RESID)).GETCLOB()
------------------------------------------------------------
Mary had a little lamb

1 row selected.

SELECT XDBURIType(DBMS_XDB.createOIDPath(:previous_RESID)).getClob() FROM DUAL;

XDBURITYPE(DBMS_XDB.CREATEOIDPATH(:PREVIOUS_RESID)).GETCLOB()
-------------------------------------------------------------
Hickory dickory dock, the mouse ran up the clock

1 row selected.

例24-8 GETCONTENTSCLOBBYRESIDを使用したリソース・バージョン・コンテンツの取出し

SELECT DBMS_XDB_VERSION.getContentsCLOBByRESID(:current_RESID) FROM DUAL;

DBMS_XDB_VERSION.GETCONTENTSCLOBBYRESID(:CURRENT_RESID)
-------------------------------------------------------
Mary had a little lamb

1 row selected.

SELECT DBMS_XDB_VERSION.getContentsCLOBByRESID(:previous_RESID) FROM DUAL;

DBMS_XDB_VERSION.GETCONTENTSCLOBBYRESID(:PREVIOUS_RESID)
--------------------------------------------------------
Hickory dickory dock, the mouse ran up the clock

1 row selected.

例24-9 GETRESOURCEBYRESIDを使用したリソース・バージョン・メタデータの取出し

SELECT XMLSerialize(DOCUMENT DBMS_XDB_VERSION.getResourceByRESID(:current_RESID)
AS CLOB INDENT SIZE = 2)
FROM DUAL;
<Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd" Hidden="false"
Invalid="false" VersionID="2" ActivityID="0" Container="false"
CustomRslv="false" VersionHistory="false" StickyRef="true">
<CreationDate>2009-05-06T12:33:34.012133</CreationDate>
<ModificationDate>2009-05-06T12:33:34.280199</ModificationDate>
<DisplayName>t1.txt</DisplayName>
<Language>en-US</Language>
<CharacterSet>UTF-8</CharacterSet>
<ContentType>text/plain</ContentType>
<RefCount>1</RefCount>
<ACL>
<acl description="Public:All privileges to PUBLIC"
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd"
shared="true">
<ace>
<grant>true</grant>
<principal>PUBLIC</principal>
<privilege>
<all/>
</privilege>
</ace>
</acl>
</ACL>
<Owner>HR</Owner>
<Creator>HR</Creator>
<LastModifier>HR</LastModifier>
<SchemaElement>http://xmlns.oracle.com/xdb/XDBSchema.xsd#text</SchemaElement>
<Contents>
<text>Mary had a little lamb</text>
</Contents>
<VCRUID>69454F2EF12E3375E040578C8A1764B5</VCRUID>
<Parents>69454F2EF12F3375E040578C8A1764B5</Parents>
</Resource>

1 row selected.

SELECT XMLSerialize(DOCUMENT DBMS_XDB_VERSION.getResourceByRESID(:previous_RESID)
AS CLOB INDENT SIZE = 2)
FROM DUAL;
<Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd" Hidden="false"
Invalid="false" VersionID="1" Container="false" CustomRslv="false"
VersionHistory="false" StickyRef="true">
<CreationDate>2009-05-06T12:33:34.012133</CreationDate>
<ModificationDate>2009-05-06T12:33:34.012133</ModificationDate>
<DisplayName>t1.txt</DisplayName>
<Language>en-US</Language>
<CharacterSet>UTF-8</CharacterSet>
<ContentType>text/plain</ContentType>
<RefCount>0</RefCount>
<ACL>
<acl description="Public:All privileges to PUBLIC"
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd"
shared="true">
<ace>
<grant>true</grant>
<principal>PUBLIC</principal>
<privilege>
<all/>
</privilege>
</ace>
</acl>
</ACL>
<Owner>HR</Owner>
<Creator>HR</Creator>
<LastModifier>HR</LastModifier>
<SchemaElement>http://xmlns.oracle.com/xdb/XDBSchema.xsd#text</SchemaElement>
<Contents>
<text>Hickory dickory dock, the mouse ran up the clock</text>
</Contents>
<VCRUID>69454F2EF12E3375E040578C8A1764B5</VCRUID>
</Resource>

1 row selected.

PL/SQLファンクションDBMS_XDB_VERSION.unCheckOutを使用すると、チェックアウトをキャンセルできます。例24-10に、これを示します。

例24-10 UNCHECKOUTを使用したチェックアウトのキャンセル

DECLARE
resid DBMS_XDB_VERSION.RESID_TYPE;
BEGIN
resid := DBMS_XDB_VERSION.unCheckOut(:targetPath);
END;
/

表24-2は、この章で説明するPL/SQLパッケージDBMS_XDB_VERSIONのサブプログラムをまとめたものです。

表24-2 パッケージDBMS_XDB_VERSIONのPL/SQLファンクションおよびプロシージャ

ファンクションまたはプロシージャ

説明

makeVersioned(pathname VARCHAR2) RETURN DBMS_XDB_VERSION.RESID_TYPE;

パス名が指定されたリソースをバージョン管理されたリソースに変換します。

2つ以上のパス名が同じリソースを参照する場合、そのリソースはコピーされ、引数のパス名はコピーにバインドされます。新しいリソースは、バージョン管理されます。他のすべてのパス名は、引続き元のリソースを参照します。

引数はバージョン管理するリソースのパス名です。

バージョン管理されたリソースの最初のバージョン・リソースのリソースIDを戻します。

これは、自動コミットのSQL操作ではありません。フォルダ、バージョン・リソースまたはACLでmakeVersionedをコールする場合や、ターゲット・リソースが存在しない場合、エラーが発生します。注意: バージョン管理されたリソースでmakeVersionedをコールする場合、エラーまたは警告は発生しません。

checkOut(pathname VARCHAR2);

バージョン管理されたリソースをチェックアウトします。チェックアウトするまで、バージョン管理されたリソースは更新または削除できません。チェックアウトはすべてのユーザー対象: チェックアウトされたリソースは変更できません。

引数は、バージョン管理されたチェックアウト対象のリソースのパス名です。これは、自動コミットのSQL操作ではありません。バージョン管理された同じリソースを2人のユーザーが同時にチェックアウトする場合は、一方のユーザーがロールバックする必要があります。注意する点として、リソースをチェックアウトしてから更新するまでコミットしてください。ターゲット・リソースがバージョン管理されていない場合や存在しない場合、またはチェックアウト済の場合はエラーが発生します。

checkIn (pathname VARCHAR2) RETURN DBMS_XDB_VERSION.RESID_TYPE;

バージョン管理されたチェックアウト済のリソースをチェックインします。

pathname - チェックアウトしたリソースのパス名。

新しく作成されたバージョンのリソースIDを戻します。

これは、自動コミットのSQL操作ではありません。チェックアウトに使用したパス名と同じパス名を使用する必要はありません。しかし、チェックインのパス名とチェックアウトのパス名は同じリソースを参照する必要があります。そうでない場合は、予期しない結果になります。

リソースの名前が変更された場合は、チェックイン時に新しい名前を使用する必要があります。パス名で参照するリソースがないと、エラーが発生します。

unCheckOut(pathname VARCHAR2) RETURN DBMS_XDB.RESID_TYPE;

チェックアウトしたリソースをチェックインします。

引数はチェックアウトしたリソースのパス名です。

リソースがチェックアウトされる前にバージョンのリソースIDを戻します。これは、自動コミットのSQL操作ではありません。チェックアウトに使用したパス名と同じパス名を使用する必要はありません。しかし、unCheckOutのパス名とチェックアウトのパス名は同じリソースを参照する必要があります。そうでない場合は、予期しない結果になります。

リソースの名前が変更された場合は、unCheckOutに新しい名前を使用する必要があります。パス名で参照するリソースがないと、エラーが発生します。

getPredecessors(pathname VARCHAR2) RETURN RESID_LIST_TYPE;

getPredsByRESID(resid DBMS_XDB.RESID_TYPE) RETURN RESID_LIST_TYPE;

バージョン・リソースまたはバージョン管理されたリソースを参照するパス名を指定すると、先行のリソースが戻されます。

ファンクションgetPredsByRESIDを使用して先行のリソースをリソースIDで取り出すことは、ファンクションgetPredecessorsを使用してパス名で取り出す方法よりも効率的です。

戻される先行リソースのリストに含まれる要素(親)は1つのみです。Oracle XML DBでは、ブランチがサポートされていません。

getSuccessors(pathname VARCHAR2) RETURN RESID_LIST_TYPE;

getSuccsByRESID(resid DBMS_XDB.RESID_TYPE) RETURN RESID_LIST_TYPE;

指定されたバージョン・リソースまたはバージョン管理されたリソースで、後続のリソースを戻します。

ファンクションgetSuccsByRESIDを使用して後続のリソースをリソースIDで取り出すことは、ファンクションgetSuccessorsを使用してパス名で取り出す方法よりも効率的です。

戻される後続リソースに含まれる要素(親)は1つのみです。Oracle XML DBでは、ブランチがサポートされていません。

getResourceByRESID(resid DBMS_XDB.RESID_TYPE) RETURN XMLType;

指定されたリソースIDで、リソースをXMLTypeインスタンスとして戻します。

脚注の凡例

脚注1: Oracle XML DBでは、バージョン・リソースには常に単一の先行リソース(その直前の単一のバージョン)が含まれます。WebDAV標準では、複数の先行リソースの選択肢が用意されます。

25 RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス

この章では、Oracle XML DBリポジトリ・データへのアクセスを提供する、事前定義されたパブリック・ビューRESOURCE_VIEWおよびPATH_VIEWについて説明します。Oracle SQL関数under_pathおよびequals_pathについて説明します。これはパス名と、リソースのパス名および深さをそれぞれ戻すpathおよびdepthに基づきリソースを問い合せます。

この章の内容は次のとおりです。

- Oracle XML DBのRESOURCE_VIEWとPATH_VIEWの概要

- RESOURCE_VIEWおよびPATH_VIEW SQL関数

- RESOURCE_VIEWおよびPATH_VIEW SQL関数の使用

- 複数のOracle XML DBリソースの操作

- Oracle XML DBリポジトリ操作のパフォーマンス・チューニング

- Oracle Textを使用したリソースの検索

関連項目:

- ビューPATH_VIEWの詳細は、『Oracle Databaseリファレンス』を参照してください。

- ビューRESOURCE_VIEWの詳細は、『Oracle Databaseリファレンス』を参照してください。

Oracle XML DBのRESOURCE_VIEWとPATH_VIEWの概要

図25-1に、Oracle XML DBのRESOURCE_VIEWおよびPATH_VIEWが、SQLを使用してOracle XML DBリポジトリに格納されているデータにアクセスするメカニズムを提供する方法を示します。FTPやWebDAVなどのプロトコルまたはApplication Program Interface(API)を使用してリポジトリに格納されたデータには、RESOURCE_VIEWおよびPATH_VIEWの値を使用してSQLでアクセスできます。

RESOURCE_VIEWは、問合せ可能なリソース名を含むリソース(それ自体はXMLType)、ACLおよびプロパティ(静的または拡張可能)で構成されます。

- リソースを構成するコンテンツがXMLType表またはビュー内に格納されているXMLデータである場合、RESOURCE_VIEWはそのコンテンツを格納するXMLType行を指します。

- コンテンツがXMLデータではない場合、RESOURCE_VIEWはそれをLOBとして格納します。

注意:
Oracle Database リリース11.2.0.1.0以降では、表内にLOBとして格納されるリポジトリ・コンテンツは、SecureFile LOB記憶域を使用します。それ以前は、BasicFile LOB記憶域を使用していました。

フォルダ間の親子関係(階層を構築するために必要です)は、リポジトリの階層索引を使用して効率的に保持および検索されます。テキスト索引はリソースのプロパティの検索に使用でき、名前およびACLに対する内部Bツリー索引によって、リソースXMLTypeのこれらの属性に対するアクセスが高速化されます。

RESOURCE_VIEWとPATH_VIEWをPL/SQLパッケージDBMS_XDBとともに使用すると、Oracle XML DBへの問合せベースのアクセス、およびAPIを使用して利用可能なすべてのDML機能が提供されます。

RESOURCE_VIEWの実表はXDB.XDB$RESOURCEです。この表には、RESOURCE_VIEWまたはDBMS_XDB APIを介してのみアクセスできます。

関連項目:
第3章「Oracle XML DBの使用」

図25-1 RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリ・リソースへのアクセス

注意:
ルート・フォルダ(/)リソースは、RESOURCE_VIEWとPATH_VIEWのいずれにも含まれません。他のリポジトリ・リソースはすべて含まれます。

RESOURCE_VIEWの定義および構造

RESOURCE_VIEWには、Oracle XML DBリポジトリの各リソースに対して1つの行が含まれます(ルート・フォルダ・リソースを除く)。表25-1に、その構造を示します。

表25-1 RESOURCE_VIEWの構造

列

データ型

説明

RES

XMLType

リポジトリ内のリソース(ルート・フォルダ・リソースを除く)

ANY_PATH

VARCHAR2

リソースへの(絶対)パス

RESID

RAW

リソースのOID。リソースの一意のハンドル。

PATH_VIEWの定義および構造

PATH_VIEWには、Oracle XML DBリポジトリのリソースにアクセスするための一意のパスごとに1行が含まれます(ルート・フォルダ・リソースを除く)。各リソースは、リンクともいう複数のパスを持つ場合があります。表25-2に、その構造を示します。

表25-2 PATH_VIEWの構造

列

データ型

説明

PATH

VARCHAR2

リポジトリ・リソースRESへの(絶対)パス

RES

XMLType

列PATHにより参照されるリソース

LINK

XMLType

リンクのプロパティ

RESID

RAW

リソースOID

図25-2にRESOURCE_VIEWとPATH_VIEWの構造を示します。

RESOURCE_VIEW内のパスは任意のパスであり、そのリソースへのアクセスに使用できるパスのいずれかです。Oracle SQL関数under_pathでは、アプリケーションで特定のフォルダ内のリソースを再帰的に検索したり、リソースの深さを取得したりできます。PATH_VIEWおよびRESOURCE_VIEWの列内の各行は、XMLTypeです。リポジトリ・ビュー上でDMLを使用すると、リソースのプロパティおよびコンテンツの挿入、名前の変更、削除および更新ができます。既存のリソースへのリンクの作成などの一部の操作には、プログラムAPIを使用する必要があります。

RESOURCE_VIEWのANY_PATH列およびPATH_VIEWのPATH列のパスは絶対パスで、ルートから始まります。

注意:
Oracle SQL関数equals_pathを使用して、リソースパスの等価テストequals_path('/my/path') = 1を行ってください。絶対パスについては、ANY_PATHの等価テストANY_PATH = '/my/path'は行わないでください。

path関数で戻されるパスは、関数under_pathによって指定されたパス名の下にある相対パスです。たとえば、パス名/a/b/cと/a/dがそれぞれ指している2つのリソースがある場合、フォルダ/aの下にあるパスを取得するpath式は、相対パスb/cおよびdを戻します。

同じリソースに対するハード・リンクが複数ある場合は、関数under_pathによって指定されたパス名の下にあるパスのみが戻されます。/a/b/c、/a/b/dおよび/a/eがすべて同じリソースへのリンクの場合、/a/bの下にあるすべてのパスを取得するPATH_VIEWの問合せは、/a/b/cおよび/a/b/dのみを戻し、/a/eは戻しません。

図25-2 RESOURCE_VIEWとPATH_VIEWの構造

RESOURCE_VIEWとPATH_VIEWの違いの理解

ビューRESOURCE_VIEWとPATH_VIEWの違いは次のとおりです。

- PATH_VIEWでは、特定のリソースに対するすべてのパス名が表示されます。RESOURCE_VIEWでは、リソースに対する可能なパス名のうちの1つが表示されます。

- PATH_VIEWは、リンクのプロパティも表示します。

図25-3にRESOURCE_VIEWとPATH_VIEWの違いを示します。

多くのインターネット・アプリケーションでは1つのURLがあればリソースにアクセスできるため、RESOURCE_VIEWは広範囲に適用できます。

PATH_VIEWには、リンク・プロパティおよびリソース・プロパティが含まれますが、RESOURCE_VIEWには、リソース・プロパティのみが含まれます。

パフォーマンスを高めるため、可能なかぎりPATH_VIEWではなくRESOURCE_VIEWを使用してください。PATH_VIEWを使用すると、複数のパスの情報が処理されるため、アクセスに時間がかかることがあります。RESOURCE_VIEWを使用すれば、必要なパスが1つだけであることがデータベースにより判断され、索引でアクセス可能なすべてのパスを判断するための作業を軽減することができます。

注意:
RESOURCE_VIEWを使用すると、関数under_pathまたはequals_pathを使用してパスを指定する場合に、そのパスが、通常そのリソースを表示するためにRESOURCE_VIEWを使用して選択する任意のパスであるかどうかにかかわらず、リソースが検索されます。

図25-3 RESOURCE_VIEWとPATH_VIEWの解説

UNDER_PATHおよびEQUALS_PATHを使用して実行できる操作

Oracle SQL関数のunder_pathとequals_pathを使用して、次の操作を実行できます。

- パス名を指定した場合

- リソースまたはそのOIDの取得

- パス名で指定されたディレクトリのリスト

- リソースの作成

- リソースの削除

- リソースの更新

- under_pathまたは他のSQL関数を使用する条件を指定した場合

- リソースの更新

- リソースの削除

- 複数のリソースまたはそのOIDの取得

「RESOURCE_VIEWおよびPATH_VIEW SQL関数の使用」とequals_pathを参照してください。

RESOURCE_VIEWおよびPATH_VIEW SQL関数

この項では、RESOURCE_VIEWおよびPATH_VIEWで使用するOracle SQL関数について説明します。

UNDER_PATH SQL関数

Oracle SQL関数under_pathは、Oracle XML DBリポジトリの階層索引を使用して、特定のパスの下に存在するすべてのハード・リンクのパスを戻します。この索引は、(最も一般的な用途である)パスの検索の際、高速にアクセスできるように設計されています。

ただし、問合せ述語の他の部分の選択性が高い場合、リポジトリを下から上に検索するunder_pathの機能実装を選択できます。この場合、検索が必要なリンクの数が少なくなるため、より効率的です。図25-4にunder_pathの構文を示します。

図25-4 UNDER_PATHの構文

表25-3にOracle SQL関数under_pathのシグネチャに関する詳細を示します。

表25-3 UNDER_PATH SQL関数のシグネチャ

構文

説明

under_path(resource_column, pathname);

リソースが指定されたパスの下に存在するかどうかを判断します。

パラメータ:

- resource_column: PATH_VIEWまたはRESOURCE_VIEWのRESOURCE列の列名または列の別名。

- pathname: 解決するパス名。

under_path(resource_column, depth, pathname);

depth引数で検索するレベルの数を制限して、リソースが指定されたパスの下に存在するかどうかを判断します。

パラメータ:

- resource_column: PATH_VIEWまたはRESOURCE_VIEWのRESOURCE列の列名または列の別名。

- depth: 検索する深さの最大値。負でない整数。

- pathname: 解決するパス名。

under_path(resource_column, pathname, correlation);

関連のSQL関数に対してcorrelation引数を指定して、リソースが指定されたパスの下に存在するかどうかを判断します。

パラメータ:

- resource_column: PATH_VIEWまたはRESOURCE_VIEWのRESOURCE列の列名または列の別名。

- pathname: 解決するパス名。

- correlation: under_pathを関連のSQL関数(pathおよび depth)に関連付けるために使用できる整数。

under_path(resource_column, depth, pathname, correlation);

depth引数で検索するレベルの数を制限し、関連のSQL関数に対してcorrelation引数を指定して、リソースが指定されたパスの下に存在するかどうかを判断します。

パラメータ:

- resource_column: PATH_VIEWまたはRESOURCE_VIEWのRESOURCE列の列名または列の別名。

- depth: 検索する深さの最大値。負でない整数。

- pathname: 解決するパス名。

- correlation: under_pathを関連のSQL関数(pathおよび depth)に関連付けるために使用できる整数。

戻されるリソースのpath引数の下には、そのリソースにアクセス可能なパスが1つしか必要ないことに注意してください。

注意:
このような検索は循環する場合があるため、関数under_pathが弱いリンクの後に続くことはありません。under_pathに対する弱いリンクの引数は正しく解決されますが、そのパスのリソースを検索する場合、弱いリンクの後に続くことはありません。

EQUALS_PATH SQL関数

Oracle SQL関数depthを使用して、指定されたパス名のリソースを検索します。これはunder_pathの深さの制約がゼロの場合と機能的に同等です。

equals_path(resource_column, pathname);

パラメータは次のとおりです。

- resource_columnはPATH_VIEWまたはRESOURCE_VIEWのRESOURCE列の列名または列の別名です。

- pathnameは、解決する(絶対)パス名です。このパス名には、ハード・リソース・リンクまたは弱いリソース・リンクが構成要素として含まれます。

図25-5に、equals_pathの完全な構文を示します。

図25-5 EQUALS_PATHの構文

注意:

- Oracle SQL関数equals_pathを使用して、リソースパスの等価テストequals_path('/my/path') = 1を行ってください。絶対パスについては、ANY_PATHの等価テストANY_PATH = '/my/path'は行わないでください。

- ハードコードされた文字列ではなく、バインド変数をequals_pathとともに使用してください。

PATH SQL関数

Oracle SQL関数pathは、指定されたpathname引数の下にあるリソースの絶対パス名を戻します。RESOURCE_VIEWのパス列には、常にリソースの絶対パスが含まれることに注意してください。pathの構文は次のとおりです。

path(correlation);

パラメータは次のとおりです。

- correlationは、under_pathを関連のSQL関数(pathおよび depth)に関連付けるために使用できる整数です。

注意:
指定されたpathname引数の下にパスがない場合、NULL値が現行のパスの出力として戻されます。

図25-6に、pathの構文を示します。

図25-6 PATHの構文

DEPTH SQL関数

Oracle SQL関数depthは指定された起動パスの下にあるリソースのフォルダ階層を戻します。

depth(correlation);

パラメータは次のとおりです。

correlationは、under_pathを関連のSQL関数(pathおよび depth)に関連付けるために使用できる整数です。

RESOURCE_VIEWおよびPATH_VIEW SQL関数の使用

次のRESOURCE_VIEWとPATH_VIEWの例では、Oracle SQL関数under_path、equals_path、pathおよびdepthを使用します。

リポジトリ・データ・パス、リソースおよびリンクへのアクセス: 例

次の例は、Oracle XML DBリポジトリのリポジトリ・パス、リソースおよびリンク・プロパティにアクセスする方法を示します。初めの方の例では、次のパスで指定されたリソースを使用します。

/a/b/c
/a/b/c/d
/a/e/c
/a/e/c/d

例25-1では、Oracle SQL関数pathを使用してパス/a/bの下の相対パスを取得します。

例25-1 あるパスの下にあるパスの判別: 相対

SELECT path(1) FROM RESOURCE_VIEW WHERE under_path(RES, '/a/b', 1) = 1;

PATH(1)
-------
c
c/d

2 rows selected.

例25-2では、ANY_PATHを使用してパス/a/bの下の絶対パスを取得します。

例25-2 あるパスの下にあるパスの判別: 絶対

SELECT ANY_PATH FROM RESOURCE_VIEW WHERE under_path(RES, '/a/b') = 1;

ANY_PATH
--------
/a/b/c
/a/b/c/d

2 rows selected.

例25-3は例25-2と同じ例ですが、等しい(=)ものでなく等しくない(!=)ものを選び出している点が異なります。例25-3の問合せでは、リポジトリ内でパス/a/bの下にないすべてのパスを検索します。

例25-3 あるパスの下にないパスの判別

SELECT ANY_PATH FROM RESOURCE_VIEW WHERE under_path(RES, '/a/b') != 1

ANY_PATH
--------
/a
/a/b
/a/e
/a/e/c
/a/e/c/d
/home
/home/OE
/home/OE/PurchaseOrders
/home/OE/PurchaseOrders/2002
/home/OE/PurchaseOrders/2002/Apr
/home/OE/PurchaseOrders/2002/Apr/AMCEWEN-20021009123336171PDT.xml
/home/OE/PurchaseOrders/2002/Apr/AMCEWEN-20021009123336271PDT.xml
/home/OE/PurchaseOrders/2002/Apr/EABEL-20021009123336251PDT.xml
. . .
/public
/sys
/sys/acls
/sys/acls/all_all_acl.xml
/sys/acls/all_owner_acl.xml
/sys/acls/bootstrap_acl.xml
/sys/acls/ro_all_acl.xml
/sys/apps
/sys/apps/plsql
/sys/apps/plsql/xs
/sys/apps/plsql/xs/netaclrc.xml
/sys/apps/plsql/xs/netaclsc.xml
/sys/databaseSummary.xml
/sys/log
/sys/schemas
/sys/schemas/OE
/sys/schemas/OE/localhost:8080
. . .

326 rows selected.

例25-4 複数のcorrelationを使用したパスの判別

SELECT ANY_PATH, path(1), path(2)
FROM RESOURCE_VIEW
WHERE under_path(RES, '/a/b', 1) = 1 OR under_path(RES, '/a/e', 2) = 1;

ANY_PATH   PATH(1)  PATH(2)
---------- -------- --------
/a/b/c     c
/a/b/c/d   c/d
/a/e/c              c
/a/e/c/d            c/d

4 rows selected.

例25-5 3レベルのリソースの相対パス名

SELECT path(1) FROM RESOURCE_VIEW WHERE under_path(RES, 3, '/sys', 1) = 1;

これによって、次のような結果が戻されます。

PATH(1)
-------
acls
acls/all_all_acl.xml
acls/all_owner_acl.xml
acls/bootstrap_acl.xml
acls/ro_all_acl.xml
apps
apps/plsql
apps/plsql/xs
databaseSummary.xml
log
schemas
schemas/OE
schemas/OE/localhost:8080
schemas/PUBLIC
schemas/PUBLIC/www.w3.org
schemas/PUBLIC/xmlns.oracle.com

93 rows selected.

例25-6 UNDER_PATHを使用したリソース・メタデータの抽出

SELECT ANY_PATH,
XMLQuery('declare namespace ns = "http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource' PASSING RES AS "r" RETURNING CONTENT)
FROM RESOURCE_VIEW WHERE under_path(RES, '/sys') = 1;

これによって、次のような結果が戻されます。

ANY_PATH
--------
XMLQUERY('DECLARENAMESPACENS="HTTP://XMLNS.ORACLE.COM/XDB/XDBRESOURCE.XSD";(::)$
--------------------------------------------------------------------------------
/sys/acls
<Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd">
<CreationDate>2008-06-25T13:17:45.164662</CreationDate>
<ModificationDate>2008-06-25T13:17:47.865163</ModificationDate>
<DisplayName>acls</DisplayName>
<Language>en-US</Language>
<CharacterSet>UTF-8</CharacterSet>
<ContentType>application/octet-stream</ContentType>
<RefCount>1</RefCount>
</Resource>

/sys/acls/all_all_acl.xml
<Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd">
<CreationDate>2008-06-25T13:17:47.759806</CreationDate>
<ModificationDate>2008-06-25T13:17:47.759806</ModificationDate>
<DisplayName>all_all_acl.xml</DisplayName>
<Language>en-US</Language>
<CharacterSet>UTF-8</CharacterSet>
<ContentType>text/xml</ContentType>
<RefCount>1</RefCount>
</Resource>
. . .
41 rows selected.

例25-7 関数PATHとDEPTHのPATH_VIEWでの使用

SELECT path(1) path, depth(1) depth FROM PATH_VIEW
WHERE under_path(RES, 3, '/sys', 1) = 1;

これによって、次のような結果が戻されます。

PATH                                      DEPTH
----                                      -----
acls                                      1
acls/all_all_acl.xml                      2
acls/all_owner_acl.xml                    2
acls/bootstrap_acl.xml                    2
acls/ro_all_acl.xml                       2
apps                                      1
apps/plsql                                2
apps/plsql/xs                             3
databaseSummary.xml                       1
log                                       1
schemas                                   1
schemas/OE                                2
schemas/OE/localhost:8080                 3
schemas/PUBLIC                            2
schemas/PUBLIC/www.w3.org                 3
schemas/PUBLIC/xmlns.oracle.com           3
. . .

例25-8 リンクおよびリソース情報のPATH_VIEWからの抽出

SELECT PATH,
XMLCast(XMLQuery(
'declare namespace ns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$l/ns:LINK/ns:Name' PASSING LINK AS "l" RETURNING CONTENT)
AS VARCHAR2(256)),
XMLCast(XMLQuery(
'declare namespace ns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$l/ns:LINK/ns:ParentName' PASSING LINK AS "l" RETURNING CONTENT)
AS VARCHAR2(256)),
XMLCast(XMLQuery(
'declare namespace ns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$l/ns:LINK/ns:ChildName' PASSING LINK AS "l" RETURNING CONTENT)
AS VARCHAR2(256)),
XMLCast(XMLQuery(
'declare namespace ns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource/ns:DisplayName'
PASSING RES AS "r" RETURNING CONTENT)
AS VARCHAR2(128))
FROM PATH_VIEW WHERE PATH LIKE '/sys%';

これによって、次のような結果が戻されます。

/sys/schemas/PUBLIC/www.w3.org/1999/xlink.xsd
xlink.xsd

/sys/schemas/PUBLIC/www.w3.org/1999/xlink
xlink

/sys/schemas/PUBLIC/www.w3.org/1999/csx.xlink.xsd
csx.xlink.xsd

. . .

118 rows selected.

例25-9 特定の深さまでの、あるパス以下のすべてのリポジトリ・パス

SELECT path(1) FROM PATH_VIEW WHERE under_path(RES, 3, '/sys', 1) > 0;

これによって、次のような結果が戻されます。

PATH(1)
-------
acls
acls/all_all_acl.xml
acls/all_owner_acl.xml
acls/bootstrap_acl.xml
acls/ro_all_acl.xml
apps
apps/plsql
apps/plsql/xs
databaseSummary.xml
log
principals
principals/groups
principals/users
schemas
schemas/PUBLIC
schemas/PUBLIC/www.opengis.net
schemas/PUBLIC/www.w3.org
schemas/PUBLIC/xmlns.oracle.com
workspaces
. . .

43 rows selected.

例25-10 EQUALS_PATHを使用したリポジトリ・パスの特定

SELECT ANY_PATH FROM RESOURCE_VIEW WHERE equals_path(RES, '/sys') > 0;

ANY_PATH
--------
/sys

1 row selected.

例25-11 指定したリソースのリソースIDの取得

SELECT RESID FROM RESOURCE_VIEW
WHERE XMLCast(XMLQuery(
'declare namespace ns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource/ns:DisplayName'
PASSING RES AS "r" RETURNING CONTENT)
AS VARCHAR2(128))
= 'example';

これによって、次のような結果が戻されます。

RESID
--------------------------------
F301A10152470252E030578CB00B432B

1 row selected.

例25-12 RESIDからのリソースのパス名の取得

DECLARE
resid_example RAW(16);
path          VARCHAR2(4000);
BEGIN
SELECT RESID INTO resid_example FROM RESOURCE_VIEW
WHERE XMLCast(XMLQuery(
'declare namespace ns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource/ns:DisplayName'
PASSING RES AS "r" RETURNING CONTENT)
AS VARCHAR2(128))

= 'example';
SELECT ANY_PATH INTO path FROM RESOURCE_VIEW WHERE RESID = resid_example;
DBMS_OUTPUT.put_line('The path is: ' || path);
END;
/
The path is: /public/example

PL/SQL procedure successfully completed.

例25-13 指定したパスの下にあるフォルダ

SELECT ANY_PATH FROM RESOURCE_VIEW
WHERE under_path(RES, 1, '/sys') = 1
AND XMLExists('declare namespace ns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource[@Container = xs:boolean("true")]'
PASSING RES AS "r");

これによって、次のような結果が戻されます。

ANY_PATH
--------
/sys/acls
/sys/apps
/sys/log
/sys/schemas

4 rows selected.

例25-14 RESOURCE_VIEWのXMLType表への結合

SELECT ANY_PATH, XMLQuery('$p/PurchaseOrder/LineItems'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
FROM purchaseorder po, RESOURCE_VIEW rv
WHERE ref(po)
= XMLCast(XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
fn:data(/Resource/XMLRef)'
PASSING rv.RES RETURNING CONTENT)
AS REF XMLType)
AND ROWNUM < 2;

ANY_PATH
--------------------------------------------------------------------------------
XMLQUERY('$P/PURCHASEORDER/LINEITEMS'PASSINGPO.OBJECT_VALUEAS"P"RETURNINGCONTENT
--------------------------------------------------------------------------------
/home/OE/PurchaseOrders/2002/Apr/AMCEWEN-20021009123336171PDT.xml
<LineItems>
<LineItem ItemNumber="1">
<Description>Salesman</Description>
<Part Id="37429158920" UnitPrice="39.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="2">
<Description>Big Deal on Madonna Street</Description>
<Part Id="37429155424" UnitPrice="29.95" Quantity="1"/>
</LineItem>
<LineItem ItemNumber="3">
<Description>Hearts and Minds</Description>
<Part Id="37429166321" UnitPrice="39.95" Quantity="1"/>
</LineItem>

. . .

<LineItem ItemNumber="23">
<Description>Great Expectations</Description>
<Part Id="37429128022" UnitPrice="39.95" Quantity="4"/>
</LineItem>
</LineItems>

1 row selected.

リポジトリ・リソースの削除: 例

この項の例は、リソースおよびパスを削除する方法を示します。

リーフ・リソースのみを削除するには、例25-15のようにDELETE FROM RESOURCE_VIEWを使用します。

例25-15 リソースの削除

DELETE FROM RESOURCE_VIEW WHERE equals_path(RES, '/public/myfile') = 1';

同じリソースへの複数のリンクの場合、RESOURCE_VIEWから削除すると、リソースはそのリンクすべてとともに削除されます。PATH_VIEWから削除すると、指定したパスのリンクのみが削除されます。

例25-16に、これを示します。

例25-16 リソースへのリンクの削除

たとえば、'/home/myfile1'が'/public/myfile'へのリンクだとします。

CALL DBMS_XDB.link('/public/myfile', '/home', 'myfile1');

次のSQL DML文は、パス/home/myfile1に検出されたOracle XML DBリポジトリ内のものを、リンクやリソースも含めすべて削除します。

DELETE FROM RESOURCE_VIEW WHERE equals_path(RES, '/home/myfile1') = 1;

次のDML文は、パス/home/file1のリンクのみを削除します。

DELETE FROM PATH_VIEW WHERE equals_path(RES, '/home/file1') = 1;

空でないフォルダ・リソースの削除

DELETE DML演算子は、空でないフォルダに対しては使用できません。空でないフォルダを削除する場合、先にフォルダの内容を削除してから、空になったフォルダを削除する必要があります。この規則は、ターゲット・フォルダに含まれるすべてのフォルダにも再帰的に適用されます。

しかし、WHERE句から戻されるパスの順番は保証されず、DELETE演算子ではその表式の副句でORDER BY句を使用できません。次のことは実行できません。

DELETE FROM (SELECT 1 FROM RESOURCE_VIEW
WHERE under_path(RES, '/public', 1) = 1
ORDER BY depth(1) DESCENDING);

例25-17は、空でないフォルダの削除方法を示しています。この例では、フォルダexampleが、サブフォルダexample1とともに削除されています。

例25-17 空でないフォルダの削除

SELECT PATH FROM PATH_VIEW WHERE under_path(RES, '/home/US1') = 1;

PATH
--------------------------
/home/US1/example
/home/US1/example/example1

2 rows selected.

DECLARE
CURSOR c1 IS
SELECT ANY_PATH p FROM RESOURCE_VIEW
WHERE under_path(RES, '/home/US1', 1) = 1
AND XMLExists('declare namespace ns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource[ns:Owner="US1"]' PASSING RES AS "r")
ORDER BY depth(1) DESC;
del_stmt VARCHAR2(500) :=
'DELETE FROM RESOURCE_VIEW WHERE equals_path(RES, :1)=1';
BEGIN
FOR r1 IN c1 LOOP
EXECUTE IMMEDIATE del_stmt USING r1.p;
END LOOP;
END;
/

PL/SQL procedure successfully completed.

SELECT PATH FROM PATH_VIEW WHERE under_path(RES, '/home/US1') = 1;

no rows selected

注意:
この場合も、複数の行に対して操作を行う場合、同時トランザクションでのデッドロックが発生しないように注意する必要があります。

リポジトリ・リソースの更新例

この項では、リソースおよびパスを更新する方法を説明します。

例25-18は、パス/test/HR/example/paperのリソースを変更します。

例25-18 リソースの更新

これは、更新操作前の完全なリソースです。

SELECT XMLSerialize(DOCUMENT r.RES AS CLOB)
FROM RESOURCE_VIEW r WHERE equals_path(r.RES, '/test/HR/example/paper') = 1;

XMLSERIALIZE(DOCUMENTR.RESASCLOB)
--------------------------------------------------------------------------------
<Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd" Hidden="false" Inv
alid="false" Container="false" CustomRslv="false" VersionHistory="false" StickyR
ef="true">
<CreationDate>2005-04-29T16:30:01.588835</CreationDate>
<ModificationDate>2005-04-29T16:30:01.588835</ModificationDate>
<DisplayName>paper</DisplayName>
<Language>en-US</Language>
<CharacterSet>UTF-8</CharacterSet>
<ContentType>application/octet-stream</ContentType>
<RefCount>1</RefCount>
<ACL>
<acl description="Public:All privileges to PUBLIC" xmlns="http://xmlns.oracl
e.com/xdb/acl.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sch
emaLocation="http://xmlns.oracle.com/xdb/acl.xsd                           http:
//xmlns.oracle.com/xdb/acl.xsd">
<ace>
<principal>PUBLIC</principal>
<grant>true</grant>
<privilege>
<all/>
</privilege>
</ace>
</acl>
</ACL>
<Owner>TESTUSER1</Owner>
<Creator>TESTUSER1</Creator>
<LastModifier>TESTUSER1</LastModifier>
<SchemaElement>http://xmlns.oracle.com/xdb/XDBSchema.xsd#binary</SchemaElement
>
<Contents>
<binary>4F7261636C65206F7220554E4958</binary>
</Contents>
</Resource>

1 row selected.

ここに示されたすべてのXML要素は、リソースのコンテンツを含むContentsを除き、リソースのメタデータ要素です。

このUPDATE文は、DisplayNameメタデータ要素を更新します。

UPDATE RESOURCE_VIEW r
SET r.RES = updateXML(r.RES, '/Resource/DisplayName/text()', 'My New Paper')
WHERE equals_path(r.RES, '/test/HR/example/paper') = 1;

1 row updated.

SELECT XMLSerialize(DOCUMENT r.RES AS CLOB)
FROM RESOURCE_VIEW r WHERE equals_path(r.RES, '/test/HR/example/paper') = 1;

XMLSERIALIZE(DOCUMENTR.RESASCLOB)
--------------------------------------------------------------------------------
<Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd" Hidden="false" Inv
alid="false" Container="false" CustomRslv="false" VersionHistory="false" StickyR
ef="true">
<CreationDate>2005-04-29T16:30:01.588835</CreationDate>
<ModificationDate>2005-04-29T16:30:01.883838</ModificationDate>
<DisplayName>My New Paper</DisplayName>
<Language>en-US</Language>

. . .

<Contents>
<binary>4F7261636C65206F7220554E4958</binary>
</Contents>
</Resource>

1 row selected.

関連項目:
リソース・メタデータの更新の例は、第29章「ユーザー定義のリポジトリ・メタデータ」を参照してください。

デフォルトでは、DisplayName要素のコンテンツpaperは、リソース・パス/test/HR/example/paperの最後のロケーション・ステップと同じテキストだったことに注意してください。ただし、これはデフォルト値にすぎません。DisplayNameはリソース・パスからは独立なので、更新してもパスは変わりません。

要素DisplayNameはWebDAV標準によって定義されていて、WebDAVアプリケーションにより認識されています。FTPクライアントなど、WebDAVベースでないアプリケーションは、リソースのDisplayNameを認識しません。FTPクライアントは、UPDATE操作の後であっても、(たとえばFTPコマンドlsを使用して)リソースをpaperとしてリストします。

例25-19では、リソースのパスを/test/HR/example/paperから/test/myexampleへと変更します。これはUNIXまたはLinuxコマンドmv /test/HR/example/paper /test/myexampleの使用に類似しています。

例25-19 PATH_VIEW内のパスの更新

SELECT ANY_PATH FROM RESOURCE_VIEW WHERE under_path(RES, '/test') = 1;

ANY_PATH
--------
/test/HR
/test/HR/example
/test/HR/example/paper

3 rows selected.

UPDATE PATH_VIEW
SET PATH = '/test/myexample' WHERE PATH = '/test/HR/example/paper';

ANY_PATH
--------
/test/HR
/test/HR/example
/test/myexample

3 rows selected.

関連項目:
RESOURCE_VIEWとPATH_VIEWに適用されるSQL関数を使用する、この他の例は表21-3「Oracle XML DBリポジトリへのアクセス: APIオプション」を参照してください。

複数のOracle XML DBリソースの操作

表21-3 に示されていたリポジトリ操作は通常、1回につき1つのリソースにのみ適用されます。複数のOracle XML DBリソースに同じ操作を実行するか、または一連の特定基準を満たす1つ以上のOracle XML DBリソースを検索するには、SQLでRESOURCE_VIEWおよびPATH_VIEWを使用します。

たとえば、次の操作を実行できます。

- 属性に基づいた更新 - 例25-20を参照

- フォルダ内のリソースの検索 - 例25-21を参照

- 一連のOracle XML DBリソースのコピー - 例25-22を参照

例25-20 属性に基づいたリソースの更新

UPDATE RESOURCE_VIEW
SET RES = updateXML(RES, '/Resource/DisplayName/text()', 'My New Paper')
WHERE XMLCast(XMLQuery(
'declare namespace ns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource/ns:DisplayName'
PASSING RES AS "r" RETURNING CONTENT)
AS VARCHAR2(128))
= 'My Paper';

1 row updated.

SELECT ANY_PATH FROM RESOURCE_VIEW
WHERE XMLCast(XMLQuery('declare namespace ns =
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
$r/ns:Resource/ns:DisplayName'
PASSING RES AS "r" RETURNING CONTENT)
AS VARCHAR2(128))
= 'My New Paper';

ANY_PATH
---------------
/test/myexample

1 row selected.

例25-21 フォルダ内のリソースの検索

SELECT ANY_PATH FROM RESOURCE_VIEW
WHERE under_path(resource, '/sys/schemas/PUBLIC/xmlns.oracle.com/xdb') = 1;

ANY_PATH
--------------------------------------------------------------
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBFolderListing.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBResource.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBSchema.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBStandard.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/acl.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/dav.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/log
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/log/ftplog.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/log/httplog.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/log/xdblog.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/stats.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/xdbconfig.xsd

12 rows selected.

例25-22のSQL DML文では、フォルダpublic内のすべてのリソースをフォルダnewlocationにコピーします。これはUNIXまたはLinuxコマンドcp /public/* /newlocationに類似しています。ターゲット・フォルダnewlocationはコピーの前に存在している必要があります。

例25-22 リソースのコピー

SELECT PATH FROM PATH_VIEW WHERE under_path(RES, '/test') = 1;

PATH
-----------------
/test/HR
/test/HR/example
/test/myexample

3 rows selected.

INSERT INTO PATH_VIEW
SELECT '/newlocation/' || path(1), RES, LINK, NULL FROM PATH_VIEW
WHERE under_path(RES, '/test', 1) = 1
ORDER BY depth(1);

3 rows created.

SELECT PATH FROM PATH_VIEW WHERE under_path(RES, '/newlocation') = 1;

PATH
------------------------
/newlocation/HR
/newlocation/HR/example
/newlocation/myexample

3 rows selected.

Oracle XML DBリポジトリ操作のパフォーマンス・チューニング

この項では、リソースの作成や問合せなどのリポジトリ操作のパフォーマンスを高めるためのガイドラインを示します。

リポジトリ・リソースへの問合せのパフォーマンスを最適化するため、リソース作成後にプロシージャDBMS_XDB_ADMIN.gatherRepositoryStatsを使用して、オプティマイザの統計を収集してください。gatherRepositoryStatsを使用するためには、権限ANALYZE ANYを持つDBAロール、またはXDBADMINロールが必要です。

フォルダに多数のリソースが含まれる場合、特に多数のリソースを作成または削除するときに、並行性が低下することがあります。一般的に、フォルダに含めるリソースは10,000以下に抑えてください。経験的限界は、データベース・ブロック・サイズとファイル名の平均長によって決まります。

リソースを一括で作成する場合は、少なくとも1,000リソースに1回ずつCOMMIT操作を実行してください。コミットの頻度が高すぎる場合も、1,000リソースの作成ごとに1回より頻度が低い場合も、パフォーマンスが低下することがあります。

既知のXML Schemaに基づく文書であるファイル・リソースを作成する場合、PL/SQLファンクションDBMS_XDB.createResourceへのパラメータとしてXML Schema URLを指定します。これにより、文書が事前に解析されてXML Schemaが判別されます。

Oracle XML DBは、システムおよびプロトコル環境の構成に構成ファイルxdbconfig.xmlを使用します。このファイルには、RESOURCE_VIEWキャッシュの動的メモリー内のサイズを定義する要素パラメータresource-view-cache-sizeが含まれています。デフォルト値は、1048576です。

RESOURCE_VIEWおよびPATH_VIEWの問合せは、resource-view-cache-sizeをチューニングすることによってパフォーマンスが向上する場合があります。一般に、キャッシュ・サイズが大きいほど、問合せは高速化します。デフォルトのresource-view-cache-sizeはほとんどの場合に適していますが、大規模なRESOURCE_VIEWを問い合せるときに、resource-view-cache-size要素を大きくすると有効な場合があります。

次の要素に対するデフォルトの制限は、あまり厳しくありません。制限を超えると、システムが自動的に適応します。

- xdbcore-loadableunit-size: この要素は、ロード可能ユニット(パーティション)の増加可能最大サイズをKBで示します。パーティションがメモリーに読み取られる場合、または新規ドキュメントの使用時にパーティションが作成される場合、そのパーティションは最大サイズに達するまで作成されます。デフォルト値は、16KBです。

- xdbcore-xobmem-bound: この要素は、1つのドキュメントが占有できる最大メモリーをKBで示します。デフォルト値は、1024KBです。ドキュメントがこの数値を超えると、一部のロード可能ユニット(パーティション)のスワッピングが行われます。

関連項目:

- 第34章「Oracle XML DBの管理」

- PL/SQLファンクションDBMS_XDB.createResourceの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- データベース・スキーマXDBの詳細は、『Oracle Database 2日でセキュリティ・ガイド』を参照してください。

Oracle Textを使用したリソースの検索

データベース・スキーマXDBの表XDB$RESOURCEは、リポジトリ・リソースに対応するメタデータおよびデータを格納します。RESOURCE_VIEWまたはPATH_VIEWでOracle SQL関数containsを使用して、特定のキーワードを含むリソースを検索できます。

例25-23 「Paper」を含むすべてのリソースの検索

SELECT PATH FROM PATH_VIEW WHERE contains(RES, 'Paper') > 0;

PATH
-----------------------
/newlocation/myexample
/test/myexample

2 rows selected.

例25-24 特定のパスの下にあり、「Paper」を含むすべてのリソースの検索

SELECT ANY_PATH FROM RESOURCE_VIEW
WHERE contains(RES, 'Paper') > 0 AND under_path(RES, '/test') > 0;

ANY_PATH
----------------
/test/myexample

1 row selected.

このような問合せを評価するには、まずXDB$RESOURCE表にConText索引を作成する必要があります。Oracle XML DBに格納されたドキュメント・タイプに応じて次のいずれかのオプションを選択して、ConText索引を作成します。

- Oracle XML DBにXML文書のみが含まれる場合、つまりバイナリ・データが含まれない場合は、通常のContext索引をXDB$RESOURCE表に作成できます。例25-24がその例です。

CREATE INDEX xdb$resource_ctx_i ON XDB.XDB$RESOURCE(OBJECT_VALUE)
INDEXTYPE IS CTXSYS.CONTEXT;

関連項目:
第4章「XMLTypeの操作」および第12章「XMLデータの全文検索」

- Oracle XML DBにバイナリ・データが含まれる場合(Microsoft Word文書など)、索引付けの前にこのような文書をフィルタリングするユーザー・フィルタが必要です。Context索引の作成と構成には、パッケージDBMS_XDBT(dbmsxdbt.sql)を使用します。

-- Install the package - connected as SYS
@dbmsxdbt
-- Create the preferences
EXEC DBMS_XDBT.createPreferences;
-- Create the index
EXEC DBMS_XDBT.createIndex;

関連項目:

- DBMS_XDBTのインストールおよび使用方法は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- 「XML用のAPI」

パッケージDBMS_XDBTには、索引の同期と最適化に使用するプロシージャも含まれています。プロシージャconfigureAutoSync()を使用し、ジョブ・キューを使用して索引を自動的に同期化できます。

26 PL/SQLを使用したリポジトリへのアクセス

この章では、Oracle XML DB Resource API for PL/SQL (PL/SQLパッケージDBMS_XDB)について説明します。内容は次のとおりです。

- PL/SQLパッケージDBMS_XDBの概要

- DBMS_XDB: リソース管理

- DBMS_XDB: ACLベースのセキュリティ管理

- DBMS_XDB: 構成管理

PL/SQLパッケージDBMS_XDBの概要

PL/SQLパッケージDBMS_XDBは、Oracle XML DBのPL/SQL用リソースAPIです。これは、PL/SQLフォルダリングAPIともいいます。このAPIは、PL/SQLを使用して、Oracle XML DBリポジトリ・リソースにアクセスして管理するためのファンクションとプロシージャを提供します。また、リソースのセキュリティおよびOracle XML DBの構成の管理方法も説明します。

Oracle XML DBリポジトリはXMLでモデル化されており、すべてのデータに対するデータベース・ファイル・システムを提供します。リポジトリは、XMLTypeのデータベース・オブジェクトにパス名(またはURL)をマップし、これらのオブジェクトの管理機能を提供します。

PL/SQLパッケージDBMS_XDBはAPIで、これを使用することにより次のすべてを管理できます。

- Oracle XML DBリソース

- Oracle XML DBセキュリティは、アクセス制御リスト(ACL)に基づいています。ACLは、どのリソースへのアクセス権をどのプリンシパル(ユーザーまたはロール)が持つかを決定するアクセス制御エントリ(ACE)のリストです。

- Oracle XML DBの構成

関連項目:

- 『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

- 「XML用のAPI」

DBMS_XDB: リソース管理

表26-1は、DBMS_XDBのOracle XML DBリソースの管理用ファンクションおよびプロシージャの説明です。

表26-1 DBMS_XDBのリソース管理用ファンクションおよびプロシージャ

ファンクションおよびプロシージャ

説明

appendResourceMetadata

ユーザー定義のメタデータをリソースに追加します。

createFolder

新しいフォルダ・リソースを作成します。

createOIDPath

オブジェクト識別子(OID)に基づいてリソースへの仮想パスを作成します。

createResource

新しいファイル・リソースを作成します。

deleteResource

リポジトリからリソースを削除します。

deleteResourceMetadata

指定したユーザー定義のメタデータをリソースから削除します。

existsResource

絶対パスを指定されたリソースが存在するかどうかを示します。

getLockToken

指定されたリソースのパスを使用して、現行のユーザーに対するリソースのロック・トークンを戻します。

getResOID

絶対パスで指定したリソースのオブジェクト識別子(OID)を戻します。

getXDB_tablespace

データベース・スキーマ(ユーザー・アカウント)XDBの現行の表領域を戻します。

link

既存のリソースへのリンクを作成します。

lockResource

指定されたリソースのパスを使用して、WebDAV形式のロックを取得します。

purgeResourceMetadata

すべてのユーザー定義のメタデータをリソースから削除します。

renameResource

リソースの名前を変更します。

unlockResource

ロック・トークンとパスで指定したリソースのロックを解除します。

updateResourceMetadata

ユーザー定義のリソース・メタデータを変更します。

ヒント:
リポジトリ・リソースへの問合せのパフォーマンスを最適化するため、リソース作成後にプロシージャDBMS_XDB_ADMIN.gatherRepositoryStatsを使用して、オプティマイザの統計を収集してください。gatherRepositoryStatsを使用するためには、権限ANALYZE ANYを持つXDBADMINロール、またはDBAロールが必要です。

関連項目:
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

この項の例では、これらのファンクションおよびプロシージャの使用方法を説明します。

例26-1では、パッケージDBMS_XDBを使用してリポジトリ・リソースを管理します。次のものが作成されます。

- フォルダ/publicの下にフォルダmydocs

- 2つのファイル・リソースemp_selby.xmlおよびemp_david.xml

- ファイル・リソースへの2つのリンクperson_selby.xmlおよびperson_david.xml

続いて、新しく作成されたリソースとリンクが削除されます。フォルダを削除する前にフォルダの内容が削除されます。

例26-1 DBMS_XDBを使用したリソースの管理

DECLARE
retb BOOLEAN;
BEGIN
retb := DBMS_XDB.createfolder('/public/mydocs');
retb := DBMS_XDB.createresource('/public/mydocs/emp_selby.xml',
'<emp_name>selby</emp_name>');
retb := DBMS_XDB.createresource('/public/mydocs/emp_david.xml',
'<emp_name>david</emp_name>');
END;
/
PL/SQL procedure successfully completed.

CALL DBMS_XDB.link('/public/mydocs/emp_selby.xml',
'/public/mydocs',
'person_selby.xml');
Call completed.

CALL DBMS_XDB.link('/public/mydocs/emp_david.xml',
'/public/mydocs',
'person_david.xml');
Call completed.

CALL DBMS_XDB.deleteresource('/public/mydocs/emp_selby.xml');
Call completed.

CALL DBMS_XDB.deleteresource('/public/mydocs/person_selby.xml');
Call completed.

CALL DBMS_XDB.deleteresource('/public/mydocs/emp_david.xml');
Call completed.

CALL DBMS_XDB.deleteresource('/public/mydocs/person_david.xml');
Call completed.

CALL DBMS_XDB.deleteresource('/public/mydocs');
Call completed.

関連項目:
appendResourceMetadataおよびdeleteResourceMetadataを使用した例は、第29章「ユーザー定義のリポジトリ・メタデータ」を参照してください。

DBMS_XDB: ACLベースのセキュリティ管理

表26-2 は、DBMS_XDBのOracle XML DB ACLに基づくセキュリティ管理用ファンクションおよびプロシージャのリストです。

表26-2 DBMS_XDB: セキュリティ管理用のファンクションおよびプロシージャ

ファンクションおよびプロシージャ

説明

ACLCheckPrivileges

現行のユーザーに付与されたすべてのアクセス権限をACLで確認します。

ChangePrivileges

リソースACLにACEを追加します。

checkPrivileges

現行のユーザーに付与された、あるリソースへのアクセス権限を確認します。

getACLDocument

リソースのパス名で指定された、リソースを保護しているACL文書を取得します。

getPrivileges

現行のユーザーに付与された、あるリソースへのすべての権限を戻します。

setACL

リソースにACLを設定します。

関連項目:

- 『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

- 『Oracle XML Developer's Kitプログラマーズ・ガイド』

この項の例では、これらのファンクションおよびプロシージャの使用方法を説明します。

例26-2では、データベース・ユーザーHRが、フォルダ/public/mydocsと、それに含まれるファイルemp_selby.xmlの、2つのリソースを作成します。プロシージャgetACLDocumentがファイル・リソースでコールされて、文書の<principal>ユーザーがPUBLICであることを示しています。

例26-2 DBMS_XDB.GETACLDOCUMENTの使用

CONNECT hr
Enter password: password

Connected.

DECLARE
retb BOOLEAN;
BEGIN
retb := DBMS_XDB.createFolder('/public/mydocs');
retb := DBMS_XDB.createResource('/public/mydocs/emp_selby.xml',
'<emp_name>selby</emp_name>');
END;
/
PL/SQL procedure successfully completed.

SELECT XMLSerialize(DOCUMENT
DBMS_XDB.getACLDocument('/public/mydocs/emp_selby.xml')
AS CLOB)
FROM DUAL;

XMLSERIALIZE(DOCUMENTDBMS_XDB.GETACLDOCUMENT('/PUBLIC/MYDOCS/EMP_SELBY.XML')ASCL
--------------------------------------------------------------------------------
<acl description="Public:All privileges to PUBLIC" xmlns="http://xmlns.oracle.co
m/xdb/acl.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaL
ocation="http://xmlns.oracle.com/xdb/acl.xsd                           http://xm
lns.oracle.com/xdb/acl.xsd" shared="true">
<ace>
<grant>true</grant>
<principal>PUBLIC</principal>
<privilege>
<all/>
</privilege>
</ace>
</acl>

1 row selected.

例26-3では、システム管理者がプロシージャsetACLに接続して、所有者(データベース・スキーマHR)に、例26-2で作成されたファイル・リソースにおけるすべての権限を付与しています。プロシージャgetACLDocumentは、続いて<principal>ユーザーが所有者(HR)であるdav:ownerであることを示しています。

例26-3 DBMS_XDB.SETACLの使用

CONNECT SYSTEM
Enter password: password

Connected.

-- Give all privileges to owner, HR.
CALL DBMS_XDB.setACL('/public/mydocs/emp_selby.xml',
'/sys/acls/all_owner_acl.xml');
Call completed.
COMMIT;
Commit complete.

SELECT XMLSerialize(DOCUMENT
DBMS_XDB.getACLDocument('/public/mydocs/emp_selby.xml')
AS CLOB)
FROM DUAL;

XMLSERIALIZE(DOCUMENTDBMS_XDB.GETACLDOCUMENT('/PUBLIC/MYDOCS/EMP_SELBY.XML')ASCL
--------------------------------------------------------------------------------
<acl description="Private:All privileges to OWNER only and not accessible to oth
ers" xmlns="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:dav="DAV:" xmlns:xsi="htt
p://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.
com/xdb/acl.xsd http://xmlns.oracle.com/xdb/acl.xsd" shared="true">
<ace>
<grant>true</grant>
<principal>dav:owner</principal>
<privilege>
<all/>
</privilege>
</ace>
</acl>

1 row selected.

例26-4では、ユーザーHRがファンクションchangePrivilegesに接続して、新しいアクセス制御エントリ(ACE)をACLに追加して、リソースemp_selby.xmlにおけるすべての権限をユーザーoeに付与しています。プロシージャgetACLDocumentは、新しいACEがACLに追加されたことを示します。

例26-4 DBMS_XDB.CHANGEPRIVILEGESの使用

CONNECT hr
Enter password: password

Connected.

SET SERVEROUTPUT ON

-- Add an ACE giving privileges to user OE
DECLARE
r        PLS_INTEGER;
ace      XMLType;
ace_data VARCHAR2(2000);
BEGIN
ace_data := '<ace xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd
DAV:http://xmlns.oracle.com/xdb/dav.xsd">
<principal>OE</principal>
<grant>true</grant>
<privilege><all/></privilege>
</ace>';
ace := XMLType.createXML(ace_data);
r := DBMS_XDB.changePrivileges('/public/mydocs/emp_selby.xml', ace);
END;
/

PL/SQL procedure successfully completed.

COMMIT;

SELECT XMLSerialize(DOCUMENT
DBMS_XDB.getACLDocument('/public/mydocs/emp_selby.xml')
AS CLOB)
FROM DUAL;

XMLSERIALIZE(DOCUMENTDBMS_XDB.GETACLDOCUMENT('/PUBLIC/MYDOCS/EMP_SELBY.XML')ASCL
--------------------------------------------------------------------------------
<acl description="Private:All privileges to OWNER only and not accessible to oth
ers" xmlns="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:dav="DAV:" xmlns:xsi="htt
p://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.
com/xdb/acl.xsd                           http://xmlns.oracle.com/xdb/acl.xsd" s
hared="false">
<ace>
<grant>true</grant>
<principal>dav:owner</principal>
<privilege>
<all/>
</privilege>
</ace>
<ace>
<grant>true</grant>
<principal>OE</principal>
<privilege>
<all/>
</privilege>
</ace>
</acl>

1 row selected.

例26-5では、ユーザーoeは接続してDBMS_XDB.getPrivilegesをコールし、リソースemp_selby.xmlでユーザーoeに付与されたすべての権限を表示します。

例26-5 DBMS_XDB.GETPRIVILEGESの使用

CONNECT oe
Enter password: password

Connected.

SELECT XMLSerialize(DOCUMENT
DBMS_XDB.getPrivileges('/public/mydocs/emp_selby.xml')
AS CLOB)
FROM DUAL;

XMLSERIALIZE(DOCUMENTDBMS_XDB.GETPRIVILEGES('/PUBLIC/MYDOCS/EMP_SELBY.XML')ASCLO
--------------------------------------------------------------------------------
<privilege xmlns="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:xsi="http://www.w3.
org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl
.xsd http://xmlns.oracle.com/xdb/acl.xsd DAV: http://xmlns.oracle.com/xdb/dav.xs
d" xmlns:xdbacl="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:dav="DAV:">
<read-properties/>
<read-contents/>
<write-config/>
<link/>
<unlink/>
<read-acl/>
<write-acl-ref/>
<update-acl/>
<resolve/>
<link-to/>
<unlink-from/>
<dav:lock/>
<dav:unlock/>
<dav:write-properties/>
<dav:write-content/>
<dav:execute/>
<dav:take-ownership/>
<dav:read-current-user-privilege-set/>
</privilege>

1 row selected.

DBMS_XDB: 構成管理

表26-3は、DBMS_XDBのOracle XML DBの構成管理用ファンクションおよびプロシージャの説明です。

表26-3 DBMS_XDB: 構成管理用のファンクションおよびプロシージャ

ファンクションおよびプロシージャ

説明

CFG_Get

現行セッションの構成情報を戻します。

CFG_Refresh

現行のOracle XML DB構成ファイルxdbconfig.xmlを使用してセッションの構成情報をリフレッシュします。

cfg_update

Oracle XML DB構成情報を更新します。構成ファイルxdbconfig.xmlが書き込まれます。

getFTPPort

現行のFTPポート番号を戻します。

getHTTPPort

現行のHTTPポート番号を戻します。

setFTPPort

Oracle XML DB FTPポートを、指定したポート番号に設定します。

setHTTPPort

Oracle XML DB HTTPポートを、指定したポート番号に設定します。

関連項目:
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

この項の例では、これらのファンクションおよびプロシージャの使用方法を説明します。

例26-6では、ファンクションcfg_getを使用して、Oracle XML DB構成ファイルxdbconfig.xmlを取得しています。

例26-6 DBMS_XDB.CFG_GETの使用

CONNECT SYSTEM
Enter password: password

Connected.

SELECT DBMS_XDB.cfg_get() FROM DUAL;

DBMS_XDB.CFG_GET()
--------------------------------------------------------------------------------
<xdbconfig xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd" xmlns:xsi="http://w
ww.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/x
db/xdbconfig.xsd                                     http://xmlns.oracle.com/xdb
/xdbconfig.xsd">
<sysconfig>
<acl-max-age>19</acl-max-age>
<acl-cache-size>32</acl-cache-size>
<invalid-pathname-chars/>
<case-sensitive>true</case-sensitive>
<call-timeout>6000</call-timeout>
<max-link-queue>65536</max-link-queue>
<max-session-use>100</max-session-use>
<persistent-sessions>false</persistent-sessions>
<default-lock-timeout>3600</default-lock-timeout>
<xdbcore-logfile-path>/sys/log/xdblog.xml</xdbcore-logfile-path>
<xdbcore-log-level>0</xdbcore-log-level>
<resource-view-cache-size>1048576</resource-view-cache-size>
<protocolconfig>
<common>
. . .
</common>
<ftpconfig>
. . .
</ftpconfig>
<httpconfig>
<http-port>0</http-port>
<http-listener>local_listener</http-listener>
<http-protocol>tcp</http-protocol>
<max-http-headers>64</max-http-headers>
<max-header-size>16384</max-header-size>
<max-request-body>2000000000</max-request-body>
<session-timeout>6000</session-timeout>
<server-name>XDB HTTP Server</server-name>
<logfile-path>/sys/log/httplog.xml</logfile-path>
<log-level>0</log-level>
<servlet-realm>Basic realm=&quot;XDB&quot;</servlet-realm>
<webappconfig>
. . .
</webappconfig>
<authentication>
. . .
</authentication>
</protocolconfig>
<xdbcore-xobmem-bound>1024</xdbcore-xobmem-bound>
<xdbcore-loadableunit-size>16</xdbcore-loadableunit-size>
<acl-evaluation-method>ace-order</acl-evaluation-method>
</sysconfig>
</xdbconfig>

1 row selected.

例26-7は、プロシージャcfg_updateの使用方法を説明しています。現行の構成がXMLTypeインスタンスとして取得され、変更されます。続いてcfg_updateを使用してリライトされます。

例26-7 DBMS_XDB.CFG_UPDATEの使用

DECLARE
configxml    SYS.XMLType;
configxml2   SYS.XMLType;
BEGIN
-- Get the current configuration
configxml := DBMS_XDB.cfg_get();

-- Modify the configuration
SELECT updateXML(
configxml,
'/xdbconfig/sysconfig/protocolconfig/httpconfig/http-port/text()',
'8000',
'xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd"')
INTO configxml2 FROM DUAL;

-- Update the configuration to use the modified version
DBMS_XDB.cfg_update(configxml2);
END;
/

PL/SQL procedure successfully completed.

SELECT DBMS_XDB.cfg_get() FROM DUAL;

DBMS_XDB.CFG_GET()
--------------------------------------------------------------------------------
<xdbconfig xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd" xmlns:xsi="http://w
ww.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/x
db/xdbconfig.xsd http://xmlns.oracle.com/xdb/xdbconfig.xsd">
<sysconfig>
<acl-max-age>15</acl-max-age>
<acl-cache-size>32</acl-cache-size>
<invalid-pathname-chars/>
<case-sensitive>true</case-sensitive>
<call-timeout>6000</call-timeout>
<max-link-queue>65536</max-link-queue>
<max-session-use>100</max-session-use>
<persistent-sessions>false</persistent-sessions>
<default-lock-timeout>3600</default-lock-timeout>
<xdbcore-logfile-path>/sys/log/xdblog.xml</xdbcore-logfile-path>
<resource-view-cache-size>1048576</resource-view-cache-size>
<protocolconfig>
<common>
. . .
</common>
<ftpconfig>
. . .
</ftpconfig>
<httpconfig>
<http-port>8000</http-port>
. . .
</httpconfig>
</protocolconfig>
<xdbcore-xobmem-bound>1024</xdbcore-xobmem-bound>
<xdbcore-loadableunit-size>16</xdbcore-loadableunit-size>
<acl-evaluation-method>ace-order</acl-evaluation-method>
</xdbconfig>

1 row selected.

27 リポジトリのアクセス制御

Oracle Databaseでは、データベース・ユーザーが行レベルおよび列レベルでセキュアにアクセスできるなど、従来型のデータベース・セキュリティが提供されています。また、Oracle XML DBリポジトリ内のリソースに対するファイングレイン・アクセス制御も提供されています。この章では、後者について説明します。アクセス制御リスト(ACL)の作成、設定、変更方法、およびACLセキュリティと他のOracle Databaseセキュリティ・メカニズムとの相互作用の方法も説明します。

この章の内容は次のとおりです。

- アクセス制御の概念

- リポジトリ操作のためのデータベース権限

- 権限

- ACLおよびACE

- アクセス制御リスト(ACL)の使用

- ACLキャッシング

- リポジトリ・リソースおよびデータベース表のセキュリティ

- Oracle XML DBのLDAPとの統合

関連項目:

- WebDAVの詳細は、第28章「プロトコルを使用したリポジトリへのアクセス」を参照してください。

- リソース・セキュリティの構成および管理の詳細は、第34章「Oracle XML DBの管理」を参照してください。

- リソース・セキュリティの管理に使用できるPL/SQL APIの詳細は、「XML用のAPI」を参照してください。

アクセス制御の概念

この項では、アクセス制御の用語および概念について説明します。ここで説明するエンティティ(ユーザー、ロール、プリンシパル、権限、アクセス制御リスト(ACL)およびアクセス制御エントリ(ACE))はそれぞれ、XML文書またはフラグメントとして宣言的に実装されます。

セキュアな認可を行うためには、どのユーザー、アプリケーションまたは関数が、どのような種類の操作を実行するために、どのデータにアクセスできるかを定義することが必要です。つまり、(1)どのユーザーが(2)どの操作を(3)どのデータに対して実行できるか、という3つの局面があります。この3つの局面をそれぞれ、(1)プリンシパル、(2)権限、(3)オブジェクトと呼びます。プリンシパルは、ユーザーまたはロールです。

プリンシパルと権限(局面1と2)は、アクセス制御リストを定義することにより、宣言的に関連付けられます。その後、これらは3番目の局面であるデータに、様々な方法で宣言的または手続き的に関連付けられます。たとえば、Oracle XML DBリポジトリのリソースまたは表データを保護するには、PL/SQLプロシージャDBMS_XDB.setACLを使用して、それを制御するACLを設定します。

プリンシパル: ユーザーまたはロール

ファイングレイン・データベース・アクセス制御との関連において、プリンシパルはユーザーまたはロールです。ユーザーは、データベース内の情報にアクセスする個人またはアプリケーションです。ロールは、ユーザーまたは他のロールで構成されますが、この再帰は循環型にできません。最終的には、各ロール(つまり各プリンシパル)はユーザーのセットに対応します。

ユーザーは、アクセス制御の目的で要素userを持つXMLフラグメントで表されます。ロールは、要素roleを持つフラグメントで表されます。

Oracle Databaseでは、プリンシパルとして次のものをサポートしています。

- データベース・ユーザーおよびデータベース・ロール。データベース・ユーザーは、データベース・スキーマまたはユーザー・アカウントと呼ばれることもあります。個人またはアプリケーションはデータベースにログオンするとき、データベース・ユーザー(スキーマ)およびパスワードを使用します。データベース・ロールは、データベース・ユーザー、アプリケーションまたは他のデータベース・ロールに付与できるデータベース権限のセットに対応しています(「データベース・ロールによるデータベース権限のユーザーへのマップ」 — を参照)。

- LDAPユーザーおよびLDAPユーザー・グループ。LDAPプリンシパルの使用方法の詳細は、「Oracle XML DBのLDAPとの統合」を参照してください。

この章で「ユーザー」または「ロール」のように何も付かない語が使用されている場合、その語はすべてのタイプのユーザーまたはロールに適用されます。タイプを区別することが重要な場合は、「データベース」または「LDAP」という語が付いています。

データベース・ロールによるデータベース権限のユーザーへのマップ

データベース・ユーザーに権限を付与できるのと同様、データベース・ロールにも権限が付与されます。データベース・ロールは、データベース権限をデータベース・ユーザー(およびアプリケーション)にマップするための媒介として機能します。つまり、ロールに権限が付与されてから、そのロールがユーザーに付与されます(それによりユーザーに権限が付与されます)。ユーザーのグループと、それらのユーザーに付与された権限のグループとの違いは、データベース・ロールの概念においては少しあいまいです。データベース・ロールによって、ユーザーにマップされた権限をグループ化したり、権限がマップされたユーザーをグループ化したりすることもできるためです。マッピングは、ロールを定義してユーザーに付与することにより行われます。従来のデータベース用語では、ロールを、それに割り当てられた権限のセットと同じものとして考えます。

ファイングレイン・アクセス制御の関連においては、別のメカニズムであるアクセス制御リスト(ACL)が、権限をユーザーにマップする媒介として使用されます。ロールは単なるユーザーのセットです。この場合、権限をユーザーおよびロールに関連付ける操作はデータベース権限ではありません。この操作は、ACLのランタイム評価やACL競合の解消とともに、宣言的なACLエントリです。

混同しないように、この用語の違いに注意してください。権限をユーザーにマップする手段として、アクセス制御では(1)プリンシパル、(2)権限、(3)ACLとして分類されている機能のいくつかは、データベース・ロールではまとめられています。アクセス制御の用語においては、ロールはユーザーとともにプリンシパルとして分類されます。これに対し、従来のデータベース用語においては、ロールは権限のセットとして分類されます。

プリンシパルDAV::owner

プリンシパルDAV::ownerを特定のOracle XML DBリポジトリと組み合せて使用して、リソース所有者を参照できます。リソースの所有者は、リソースのプロパティの1つです。通常、リソースの所有者は特別な権限を持っているため、プリンシパルDAV::ownerを使用すると、プリンシパル間でのACLの共有が簡単になります。

権限

権限とは、プリンシパルに対して付与または拒否される特定の権限です。権限は、集約権限または基本権限になります。

- 集約権限: 他の権限が含まれる権限。

- 基本権限: 他の権限は含まれない権限。それ以上分割できません。

集約権限は、権限の数が多くなった場合の操作性を簡略化し、ACLクライアント間の相互運用性を高めます。「権限」を参照してください。

集約権限はそのまま保持され、対応する基本(リーフ)権限に分割されません。WebDAVの用語において、Oracle Databaseの集約権限は抽象的でありません。つまり、集約権限は、それらのコンポーネントのコピーではなく、そのコンポーネント権限へのポインタのセットとして機能します。したがって、コンポーネントの定義が変更された場合でも、集約権限は常に最新の状態を保持します。

プリンシパルに付与された権限のセットによって、プリンシパルが保護するデータに対して特定の操作を実行できるかどうかが制御されます。たとえば、プリンシパル(データベース・ユーザー)HRが特定のリソースに対してread操作を実行するには、読取り操作の前にHRに読取り権限が付与されている必要があります。

アクセス制御エントリ(ACE)

アクセス制御エントリ(ACE)とは、アクセス制御リスト(ACL)内のエントリであるXML要素(ace)のことです。ACEは、特定のプリンシパル(ユーザーまたはロール)によるリポジトリ・リソースまたはその他のデータベース・データへのアクセスを許可または拒否します。ACE自身は、保護対象のデータを指定しません。この指定はACEおよびACLの外側で、ACLをターゲット・データに関連付けることによって行われます。その関連付けを行う方法として、PL/SQLプロシージャDBMS_XDB.setACLを使用する方法があります。

「ACLおよびACEの評価」を参照してください。

Oracle XML DB ACEは、プリンシパルの権限を付与または拒否します。ace要素は、次を含みます。

- 操作grant: true(grant)またはfalse(deny)アクセスのいずれか。

- 有効なプリンシパル(要素principal)またはプリンシパルの完了済リスト(要素invert)のいずれか。

- 権限: 特定のプリンシパルに対して付与または拒否される権限のセット(要素privilege)。

- プリンシパル書式(オプション): プリンシパルの書式。LDAPの識別名(DN)、短縮名(データベース・ユーザー/ロールまたはLDAPのニックネーム)またはLDAP GUID。デフォルト値はshort nameです。プリンシパル名がデータベース・ユーザーとLDAPニックネームの両方に一致している場合は、LDAPのニックネームを示すとみなされます。

- コレクション(オプション): プリンシパルがユーザーのコレクション(LDAPグループまたはデータベース・ロール)であるか、単一のユーザー(LDAPまたはデータベース・ユーザー)であるかどうかを指定するBOOLEAN属性。

- 開始日と終了日(オプション): ACEが有効な期間を定義する属性。「ACE妥当性の期間」を参照してください。

例27-1に、プリンシパルDAV::ownerに権限DAV::allを付与する単純なACEを示します。つまり、ACLが適用されるリソースの所有者にすべての権限を付与します。

例27-1 権限を付与する単純なアクセス制御エントリ(ACE)

<ace>
<grant>true</grant>
<principal>DAV::owner</principal>
<privilege>
<DAV::all/>
</privilege>
</ace>

アクセス制御リスト(ACL)

アクセス制御リスト(ACL)とは、アクセス制御エントリ(ACE)のリストです。デフォルトでは、リスト内の順序に意味があります(「ACLおよびACEの評価」を参照)。例27-2に、例27-1のACEのみを含む単純なACLを示します。

例27-2 権限を付与する単純なアクセス制御リスト(ACL)

<acl description="myacl"
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:dav="DAV:"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd">
<ace>
<grant>true</grant>
<principal>dav:owner</principal>
<privilege>
<dav:all/>
</privilege>
</ace>
</acl>

リポジトリ操作のためのデータベース権限

表27-1に、Oracle XML DBリポジトリのリソースに対するいくつかの一般的な操作に必要なデータベース権限を示します。必要な権限列に示された権限の他に、そのリソースが属するフォルダおよびその親フォルダすべて(ルート・フォルダまで)に対するresolve権限が必要です。

表27-1 Oracle XML DBリソースの操作に必要なデータベース権限

操作

説明

必要な権限

CREATE

フォルダFに新しいリソースを作成します。

フォルダFに対するupdateおよびlink。

DELETE

フォルダFからリソースRを削除します。

Rに対するupdateおよびunlink-from、フォルダFに対するupdateおよびunlink。

UPDATE

リソースRのコンテンツまたはプロパティを更新します。

Rに対するupdate。

GET

FTPまたはHTTP(S)によるリソースRの取出し。

Rに対するread-properties、read-contents。

SET_ACL

リソースRのACLを設定します。

Rに対するDAV:write-acl。

LIST

フォルダFのリソースをリストします。

フォルダFに対するread-properties、フォルダFのリソースに対するread-properties。ユーザーがread-properties権限を所有しているリソースのみがリストされます。

関連項目:
アップグレードの際のデータベース・アクセス権限の処理の詳細は、「既存のOracle XML DBのインストールのアップグレード」を参照してください。

権限

この項では、Oracle Databaseで提供されている権限について説明します。権限には、WebDAV名前空間であるDAV:脚注1を使用する標準WebDAV権限、およびOracle XML DB ACL名前空間であるhttp://xmlns.oracle.com/xdb/acl.xsd(事前定義された接頭辞xdbが付く)を使用するオラクル固有権限があります。

関連項目:
RFC 3744: 2004年5月の「Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol」の「IETF Network Working Group Request For Comments #3744」を参照してください。

基本権限

表27-2に基本権限を示します。

表27-2 基本権限

基本権限

説明

データベースでの操作

DAV::lock

WebDAVロックを使用してリソースをロックします。

UPDATE

DAV::read-current-user-privilege-set

リソースのDAV::current-user-privilege-setプロパティにアクセスします。

なし

DAV::take-ownership

リソースの所有権を取得します。

なし

DAV::unlock

WebDAVロックを使用してロックされたリソースのロックを解除します。

UPDATE

DAV::write-content

リソースのコンテンツを変更します。

UPDATE

DAV::write-properties

リソースのプロパティを変更します。リソースをロックまたはロック解除します。変更可能なプロパティには、Author、DisplayName、Language、CharacterSet、ContentType、SBResExtra、Owner、OwnerID、CreationDate、Modification Date、ACL、ACLOID、Lock、およびLocktokenが含まれます。

UPDATE

xdb:link

リソースからのリンクの作成を可能にします。

INSERT

xdb:link-to

リソースへのリンクの作成を可能にします。

なし

xdb:read-acl

リソースのACLを読み取ります。

SELECT

xdb:read-contents

リソースのコンテンツを読み取ります。

SELECT

xdb:read-properties

リソースのプロパティを読み取ります。

SELECT

xdb:resolve

フォルダを検索します(フォルダの場合のみ)。

SELECT

xdb:unlink

リソースからのリンクの削除を可能にします。

DELETE

xdb:unlink-from

リソースへのリンクの削除を可能にします。

なし

xdb:update-acl

リソースのACLのコンテンツを変更します。

UPDATE

xdb:write-acl-ref

リソースのACLOIDを変更します。

UPDATE

集約権限

表27-3に、集約権限、およびそれらを構成する基本権限を示します。

表27-3 集約権限

集約権限

コンポーネントの基本権限

DAV:all

すべての基本DAV権限

xdb:all

すべての基本DAV権限(xdb:link-toを含む)

DAV::bind

xdb:link

DAV::unbind

xdb:unlink

DAV::read

xdb:read-properties、xdb:read-contents、xdb:resolve

DAV::read-acl

xdb:read-acl

DAV::write

DAV::write-content、DAV::write-properties、xdb:link、xdb:unlink、xdb:unlink-from

DAV::write-acl

xdb:write-acl-ref、xdb:update-acl

DAV::update

DAV::write-content、DAV::write-properties

xdb:update

DAV::write-properties、DAV::write-content

ACLおよびACE

アクセス制御リスト(ACL)は、Javaなどの言語やMicrosoft Windowsなどのオペレーティング・システムで使用される、標準のセキュリティ・メカニズムです。ACLは、WebDAV標準の一部でもあります。ACLは、リソースを保護するために使用されます。Oracle Databaseの場合、Oracle XML DBリポジトリ内のリソース(ファイルおよびフォルダ)のいずれかです。

リポジトリのリソースには、WebDAVを使用してアクセスできます。リソースを保護するACLは、WebDAV ACLとして機能します。各リポジトリ・リソースは、ACLによって保護されます。リソースを保護するACLは、リソースのアクセス方法(WebDAV、SQL、またはその他の方法)にかかわらず適用されます。

Oracle XML DBリポジトリに新しいリソースが作成されると、デフォルトでは、親フォルダのACLを使用してリソースが保護されます。リソースの作成後に、新しいACLを設定できます。

Oracle Database内のACLは、/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/acl.xsdのOracle XML DBリポジトリにあるOracle Database ACL XMLスキーマに基づいて検証されるXML文書です。ACL自体はリポジトリ内にリソースとして格納され、管理されます。

ACLで保護されたデータに対してプリンシパルが操作を実行する前に、保護されたデータに対するユーザー権限が確認されます。確認される権限は、実行される操作によって異なります。

集約権限は、他の権限で構成されます。ACLが保存されると、そのACLが参照する集約権限は、それらのコンポーネント権限へのポインタのセットとなります。

すべてのACLは、データベース・ユーザーXDBが所有するXDB$ACLという表に格納されます。この表は、XML Schemaに基づくXMLType表です。したがって、この表のすべての行(つまり各ACL)に、OBJECT_IDという名前の列としてアクセスできるシステム生成のオブジェクトID(OID)があります。

Oracle XML DBリポジトリのすべてのリソースには、ACLOIDという名前のプロパティがあります。ACLOIDには、リソースを保護するACLのOIDが格納されます。ACL自身はリソースであり、ACL(たとえば/sys/acls/all_all_acl.xml)のXMLRefプロパティは、ACLの内容を含む表XDB$ACL内の行に対するREFです。これらの2つのプロパティが、Oracle XML DBリソースを格納する表XDB$RESOURCEと表XDB$ACLをリンクしています。

関連項目:

- ACL XML Schemaの詳細は、付録A「Oracleが提供するXML Schemaおよび例」を参照してください。

- データベース・スキーマXDBの詳細は、『Oracle Database 2日でセキュリティ・ガイド』を参照してください。

システムACL

一部のACLは事前定義されており、Oracle Databaseで提供されています。これらのACLはシステムACLと呼ばれます。

自己保護型のACL(それ自体の内容によって保護されるACL)は1つしかありません。これはブートストラップACLと呼ばれるシステムACLであり、Oracle XML DBリポジトリの/sys/acls/bootstrap_acl.xmlにあります。ブートストラップACLは、すべてのユーザーにREAD権限を付与します。また、ブートストラップACLは、データベース・ロールXDBADMIN (Oracle XML DB ADMIN)およびDBAにFULL ACCESS権を付与します。データベース・ロールXDBADMINは特に、グローバルXML Schemaの登録を必要とするユーザーに役立ちます。

この他に、次のようなACLがあります。いずれもブートストラップACLにより保護されています。

- all_all_acl.xml: すべての権限をすべてのユーザーに付与します。

- all_owner_acl.xml: すべての権限をリソースの所有者に付与します。

- ro_all_acl.xml: read権限をすべてのユーザーに付与します。

システムACLは、ファイル・ネーミング規則<privilege>_<users>_acl.xmlを使用します。ここで<privilege>は付与される権限を示し、<users>はリソースへのアクセスを許可されるユーザーを示します。独自のACLを定義する場合は、任意の名前を使用できます。

関連項目:
「ローカルXML SchemaおよびグローバルXML Schema」

ACLおよびACEの評価

プリンシパルが、1つ以上のACLによって保護されたリポジトリ・リソースへのアクセスを許可される前に、権限が確認されます。この確認は、そのプリンシパルのACLの保護を順に評価することによって行われます。このようなACLごとに、プリンシパルに適用されるACEが順に検査されます。

1つのACEが現行ユーザーになんらかの権限を付与し、他のACEがユーザーに対してその権限を拒否すると、競合が発生します。同一のプリンシパルに対するACE間の競合を管理する方法は2つあります。

- ace-orderと呼ばれるデフォルトの動作では、指定されたプリンシパルに対して発生する最初のACEのみが使用されます。そのプリンシパルに対する追加のACEは無効です。この場合、ACEの順序に意味があります。

- ただし、deny-trumps-grantという代替の動作を使用するようにデータベースを構成できます。この場合、特定のプリンシパルに対して子denyを持つACEはいずれも、そのプリンシパルに対してgrantの子を持つ他のACEの有無にかかわらず、そのプリンシパルへの権限を拒否します。この場合、denyは常にgrantよりも優先され、ACEの順序は関係ありません。

構成ファイルxdbconfig.xml内の構成パラメータacl-evaluation-methodをace-orderまたはdeny-trumps-grantのいずれかに設定し、ACL評価の動作を構成できます。デフォルトの構成ファイルではace-methodが指定されますが、メソッドが指定されない場合に使用される要素acl-evaluation-methodはdeny-trumps-grantです。

注意:
Oracle Database 11gリリース1より前のリリースでは、ACL評価動作は、deny-trumps-grantの1つのみが利用可能でした(ただし、構成ファイル内では指定されません)。
ace-orderをデフォルト動作として使用するように変更すると、データベースのバージョン間でのアップグレードおよびダウングレードに重大な影響を及ぼします。「既存のOracle XML DBのインストールのアップグレード」を参照してください。

ACL検証

ACLは作成されると、ACL用のXML Schemaに基づいて検証され、いくつかの正確性テスト(ACEの開始日と終了日が時間的に矛盾していないことの確認など)が実行されます。ACLの作成時に、ACL間のリレーションについての完全チェックは行われません。たとえば、親ACLが存在しているかどうか、およびそれらが正しいかどうかはチェックされません。(「ACL継承」を参照してください。)

このようなACLの正確性に関する完全なチェックをACL妥当性チェックと呼びます。これをXML Schemaの妥当性と混同しないでください。ACLが(ACLとして)有効になるためには、同時にXML Schemaでも有効である必要がありますが、その逆は言えません。

プリンシパルに操作を行うための適切な権限があるかどうかをチェックするためにACLが評価されるたびに、完全なACL妥当性チェックが実行時に行われます。このチェックによりACLが無効であると判断された場合、そのACLが指定されたプリンシパルに付与するすべての権限は拒否されます。

PL/SQLプロシージャDBMS_XDBZ.validateACLを起動して、ACLの妥当性を、権限確認のための実行時使用とは無関係に確認することもできます。この確認をあらかじめ行うことで、ACLが無効であるためにランタイム・エラーや権限否認が発生することを回避できます。

ACL継承

ACLは、別のACLから権限(プリンシパルと権限のアソシエーション)を継承できます。継承を使用すると、定義の柔軟性が高まり、アクセス制御ポリシーの再利用性が高まります。

権限付与はACEで定義されるので、権限付与の継承には、ACL継承連鎖および関連ACESの検索が含まれます。しかしACL継承およびその結果の権限付与の継承は、再帰的に行われることが可能です。ACL A1がACL A2から継承された場合、A1により定義された権限付与はA2のACEに存在する必要はありません。かわりに、ACL A3のACEにある可能性があります。A2はA3から(直接的または間接的に)継承します。

ACL継承は単一であり、多重継承ではありません。つまり、ACLは最大で1つの他のACLからしか継承しません。継承連鎖において循環は許可されていません。つまり、ACL自身から直接的または間接的に継承したACLは無効です。存在しないACLから継承したACLも無効です。

ACLで宣言される権限はACESで明示的に定義される権限です。ACLに宣言される権限はACESで定義され、それによって継承される権限です。

ACL継承には拡張継承と制約継承の2種類があり、それぞれ要素extends-fromまたは要素constrained-withを使用して指定されます。どちらの要素も、継承元のACLを参照します。1つのACLは、最大で1つのextends-fromまたはconstrained-with要素を持つことができます。例27-3にextends-from要素を示します。例27-4にconstrained-with要素を示します。

例27-3 要素extends-from

<extends-from type="simple" href="/sys/acls/extend_acl.xml"/>

例27-4 要素constrained-with

<constrained-with type="simple" href="/sys/acls/constrain_acl.xml"/>

拡張継承は、継承元のACL(親ACL)により定義されているいくつかの権限によって、継承するACL(子ACL)内で宣言されている権限を拡張します。たとえば、ACL A1がACL A2から拡張することを宣言している場合、A1にはA2で定義された権限を含めることができます。

制約継承は、継承するACL内で宣言されている権限を、継承元のACLによっても定義されている権限に制限します。たとえば、ACL A1が制約継承によりACL A2から継承することを宣言している場合、A1内のすべての権限がA2でも定義されている必要があります。

拡張継承は設定されたunion操作であり、制約継承は設定されたintersection操作です。ACL A1がACL A2から拡張する場合、A1とA2の権限を結合して、特定のプリンシパルに特定の権限が付与されているかどうかを判別できます。ACL A1がACL A2によって制約される場合、A1とA2の両方に共通の権限のみが権限付与の判別に使用されます。

より正確には、ACL A1がACL A2から継承し、特定のプリンシパルに特定の権限セットが付与されているかどうかを調べるためにA1が確認される場合、判別の処理は次のように実行されます。

- A1がA2から拡張する場合: A1で明示的に宣言されているACEが最初に検査されます。ACEで対象となる権限全部がプリンシパルに付与されているわけではない場合、または権限のいずれかが拒否されている場合、A1の親extending-fromで定義されているACEが検査されます。このため、A2で明示的に宣言されているACEで、対象となる権限全部がプリンシパルに付与されているわけではない場合、または権限のいずれかが拒否されている場合、A2がA3から拡張していれば、A3が検査されます。その他の場合も同様です。

- A1がA2により制約される場合: A1で明示的に宣言されているACEと、A2に定義されているACEがそれぞれ個別に検査され、どちらも指定されたプリンシパルに対して対象となる権限全部が付与されていることが確認されます。A2がACL A3により制約される場合も、同じ方法でA2のチェックが行われます。

言い換えると、拡張継承は付与された権限を蓄積し、制約継承は拒否された権限を蓄積します。拡張継承においては、子または親のACLがプリンシパルに権限を付与した場合、その権限が付与されます。制約継承においては、子または親のACLが権限を拒否した場合、その権限は拒否されます。

関連項目:
拡張継承を使用するACLは、例27-5を参照してください。

ACE要素invertでのプリンシパルの補完

別のプリンシパル・セットを補完することによりプリンシパル・セットを定義するほうが便利な場合もあります。ACE要素invertは、この目的で使用します。追加するプリンシパルをすべてリストするのではなく、要素invertを使用して、除外するプリンシパルのリストを囲みます。

例27-5の最初のACEは、IntranetUsers以外のすべてのプリンシパルに対して権限privilege1を拒否しています。(デフォルトで)ACEは出現順に考慮されるため、後続のACEはすべて最初のACEによりオーバーライドされます。このため、プリンシパルNonIntraNetUserは明示的に権限を付与されているにもかかわらず、権限privilege1を拒否されます。

例27-5 要素invertを使用したプリンシパル・セットの補完

<acl description="invert ACL"
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:dav="DAV:"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd">
<extends-from type="simple" href="/sys/acls/parent_acl.xml"/>
<ace>
<grant>false</grant>
<invert><principal>dav:owner</principal></invert>
<privilege><read-contents/></privilege>
</ace>
<ace>
<grant>true</grant>
<principal>GERONIMO</principal>
<privilege><read-contents/></privilege>
</ace>
</acl>

ACE妥当性の期間

(XML SchemaタイプdateTimeの)オプションの属性start_dateおよびend_dateを使用して、ACEの有効期間を定義できます。start_dateが指定されている場合、その日からACEは有効になります。end_dateが指定されている場合、その日からACEは無効になります。end_dateの値は時間的にstart_dateより後の値か、または同じ値である必要があります。そうでない場合、ACEおよびそのACLは無効になります。XML SchemaのdateTime値でタイムゾーンが指定されていない場合、GMT(UTC)が想定されます。例27-6に、開始日と終了日が指定されたACEを示します。

例27-6 開始日と終了日が指定されたACE

<ace start_date="2008-02-12T00:00:00Z" end_date="2008-12-31T00:00:00Z">
<grant>true</grant>
<principal>GERONIMO</principal>
<privilege><read-contents/></privilege>
</ace>

アクセス制御リスト(ACL)の使用

Oracle Databaseのアクセス制御リスト(ACL)はそれ自身がOracle XML DBリポジトリ内のリソースなので、リポジトリのリソースを操作するメソッドはすべてACLにも適用されます。さらに、ACLsinパッケージDBMS_XDBに固有のAPIもいくつかあります。これらのプロシージャやファンクションを使用すると、PL/SQLを使用してOracle XML DBのセキュリティ・メカニズムにアクセスし、特定のACLに基づいてユーザーの権限を確認して、特定のACLやリソースに対して現行ユーザーが所有している権限のセットをリストできます。

関連項目:
第34章「Oracle XML DBの管理」

DBMS_XDB.CREATERESOURCEを使用したACLの作成

例27-7では、ACLをファイル・リソース/TESTUSER/acl1.xmlとして作成します。リソースに適用されると、このACLはすべての権限をリソースの所有者に付与します。

例27-7 CREATERESOURCEを使用したACLの作成

DECLARE
b BOOLEAN;
BEGIN
b := DBMS_XDB.createFolder('/TESTUSER');
b := DBMS_XDB.createResource(
'/TESTUSER/acl1.xml',
'<acl description="myacl"
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:dav="DAV:"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd">
<ace>
<grant>true</grant>
<principal>dav:owner</principal>
<privilege>
<dav:all/>
</privilege>
</ace>
</acl>',
'http://xmlns.oracle.com/xdb/acl.xsd',
'acl');
END;

注意:
現在のトランザクション中に作成されたACLファイル・リソースを使用する操作を実行する前に、COMMIT操作を実行する必要があります。それまでは、ACLファイルを使用するたびにORA-22881エラー「REFの参照先がありません」が発生します。

リポジトリのパスがある場合のACL文書の取得

例27-8は、ACL文書のOracle XML DBリポジトリ内の場所がわかっている場合にACL文書を取得する方法を示しています。

例27-8 リポジトリのパスがある場合のACL文書の取得

SELECT a.OBJECT_VALUE FROM RESOURCE_VIEW rv, XDB.XDB$ACL a
WHERE ref(a)
= XMLCast(XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
fn:data(/Resource/XMLRef)'
PASSING rv.RES RETURNING CONTENT)
AS REF XMLType)
AND equals_path(rv.RES, '/TESTUSER/acl1.xml') = 1;

OBJECT_VALUE
--------------------------------------------------------------------------------
<acl description="myacl" xmlns="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:dav="
DAV:" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://xmlns.oracle.com/xdb/acl.xsd                                    http://xm
lns.oracle.com/xdb/acl.xsd" shared="true">
<ace>
<grant>true</grant>
<principal>dav:owner</principal>
<privilege>
<dav:all/>
</privilege>
</ace>
</acl>

リソースのACLの設定

例27-9では、リソース/TESTUSER/po1.xmlを作成し、PL/SQLプロシージャDBMS_XDB.setACLを使用してそのACLを/TESTUSER/acl1.xmlに設定します。

例27-9 リソースのACLの設定

DECLARE
b BOOLEAN;
BEGIN
b := DBMS_XDB.createResource('/TESTUSER/po1.xml', 'Hello');
END;
/

CALL DBMS_XDB.setACL('/TESTUSER/po1.xml', '/TESTUSER/acl1.xml');

ACLの削除

例27-10に、プロシージャDBMS_XDB.deleteResourceを使用してACLを削除する方法を示します。この例では、例27-7で作成したACLを削除します。

例27-10 ACLの削除

CALL DBMS_XDB.deleteResource('/TESTUSER/acl1.xml');

リソースが削除するACLによって保護されている場合は、ACLを削除する前にそのリソースのACLを変更してください。

ACLの更新

ACLの更新は、リソースを更新するための標準メソッドを使用して実行できます。特にACLはXML文書なので、ACLの操作にはOracle SQL関数updateXMLやその他のXML更新関数を使用できます。COMMITは、ACLの変更後に実行する必要があります。

Oracle XML DB ACLは、高速評価のためにキャッシュされます。ACLを更新するトランザクションがコミットされると、Oracle XML DBの構成ファイル/xdbconfig.xmlに指定されたタイムアウトの経過後、既存のデータベース・セッションによって、変更済のACLが取得されます。このtimoutパラメータのXPath位置は、/xdbconfig/sysconfig/acl-max-ageです。値を表す単位は秒です。ACLの変更後に開始されるセッションでは、新しいACLが遅延なしに使用されます。

ACLリソースが非ACLコンテンツで更新される場合、ACLの削除と同じ規則が適用されます。つまり、リソースが更新対象のACLによって保護されている場合は、最初にそのACLを変更してください。

関連項目:
ここでXMLデータの更新に使用されているOracle SQL関数の詳細は、「XMLデータの更新」を参照してください。

FTPまたはWebDAVを使用してACLを更新できます。これらのプロトコルの使用方法の詳細は、第28章「プロトコルを使用したリポジトリへのアクセス」を参照してください。RESOURCE_VIEWを使用して、ACLの更新や、アクセス制御エントリ(ACE)の変更を行えます。

例27-11では、Oracle SQL関数updateXMLを使用して、ACL /TESTUSER/acl1.xmlを完全に置換することによって更新しています。その結果、プリンシパル値DAV::ownerがTESTUSERで置換されます。置換ACLの他の部分は以前と同じだからです。

例27-11 アクセス制御リストの更新(置換)

UPDATE RESOURCE_VIEW r
SET r.RES =
updateXML(
r.RES,
'/r:Resource/r:Contents/a:acl',
'<acl description="myacl"
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:dav="DAV:"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd">
<ace>
<grant>true</grant>
<principal>TESTUSER</principal>
<privilege>
<dav:all/>
</privilege>
</ace>
</acl>',
'xmlns:r="http://xmlns.oracle.com/xdb/XDBResource.xsd"
xmlns:a="http://xmlns.oracle.com/xdb/acl.xsd"')
WHERE equals_path(r.RES, '/TESTUSER/acl1.xml') = 1;

例27-12では、Oracle SQL関数appendChildXMLを使用して、既存のACLにACEを追加しています。このACEは、ユーザーHRに、権限read-propertiesおよびread-contentsを付与します。

例27-12 アクセス制御リストへのACEの追加

UPDATE RESOURCE_VIEW r
SET r.RES =
appendChildXML(
r.RES,
'/r:Resource/r:Contents/a:acl',
XMLType('<ace xmlns="http://xmlns.oracle.com/xdb/acl.xsd">
<grant>true</grant>
<principal>HR</principal>
<privilege>
<read-properties/>
<read-contents/>
</privilege>
</ace>'),
'xmlns:r="http://xmlns.oracle.com/xdb/XDBResource.xsd"
xmlns:a="http://xmlns.oracle.com/xdb/acl.xsd"')
WHERE equals_path(r.RES, '/TESTUSER/acl1.xml') = 1;

例27-13では、Oracle SQL関数deleteXMLを使用して、既存のACLからACEを削除しています。最初のACEは削除されます。

例27-13 アクセス制御リストからのACEの削除

UPDATE RESOURCE_VIEW r
SET r.RES =
deleteXML(r.RES,
'/r:Resource/r:Contents/a:acl/a:ace[1]',
'xmlns:r="http://xmlns.oracle.com/xdb/XDBResource.xsd"
xmlns:a="http://xmlns.oracle.com/xdb/acl.xsd"')
WHERE equals_path(r.RES, '/TESTUSER/acl1.xml') = 1;

指定されたリソースを保護するACL文書の取得

例26-2は、関数DBMS_XDB.getACLDocumentを指標して、指定されたリソースを保護するACL文書を取得する方法を示しています。

例27-14 リソースのACL文書の取得

SELECT XMLSerialize(DOCUMENT DBMS_XDB.getACLDocument('/TESTUSER/po1.xml')
AS CLOB)
FROM DUAL;

XMLSERIALIZE(DOCUMENTDBMS_XDB.GETACLDOCUMENT('/TESTUSER/PO1.XML')ASCLOB)
--------------------------------------------------------------------------------
<acl description="myacl" xmlns="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:dav="
DAV:" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://xmlns.oracle.com/xdb/acl.xsd                                     http://x
mlns.oracle.com/xdb/acl.xsd">
<ace>
<grant>true</grant>
<principal>TESTUSER</principal>
<privilege>
<dav:all/>
</privilege>
</ace>
<ace xmlns="http://xmlns.oracle.com/xdb/acl.xsd">
<grant>true</grant>
<principal>HR</principal>
<privilege>
<read-properties/>
<read-contents/>
</privilege>
</ace>
</acl>

1 row selected.

関連項目:
例26-2「DBMS_XDB.GETACLDOCUMENTの使用」

特定のリソースに対して現行ユーザーに付与された権限の取得

例27-15に、DBMS_XDB.getPrivilegesファンクションを使用して現行ユーザーに付与された権限を取得する方法を示します。

例27-15 特定のリソースに対して現行ユーザーに付与された権限の取得

SELECT XMLSerialize(DOCUMENT DBMS_XDB.getPrivileges('/TESTUSER/po1.xml')
AS CLOB)
FROM DUAL;

XMLSERIALIZE(DOCUMENTDBMS_XDB.GETPRIVILEGES('/TESTUSER/PO1.XML')ASCLOB)
--------------------------------------------------------------------------------
<privilege xmlns="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:xsi="http://www.w3.
org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl
.xsd http://xmlns.oracle.com/xdb/acl.xsd DAV: http://xmlns.oracle.com/xdb/dav.xs
d" xmlns:xdbacl="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:dav="DAV:">
<read-acl/>
<dav:execute/>
<read-contents/>
<update-acl/>
<dav:write-content/>
<dav:read-current-user-privilege-set/>
<link-to/>
<resolve/>
<dav:lock/>
<unlink-from/>
<write-config/>
<dav:write-properties/>
<dav:unlock/>
<link/>
<write-acl-ref/>
<read-properties/>
<dav:take-ownership/>
<unlink/>
</privilege>

1 row selected.

現行ユーザーがリソースに対する権限を所有しているかどうかの確認

例27-16に、DBMS_XDB.checkPrivilegesファンクションを使用して、現行ユーザーがリソースに対する特定の権限セットを所有しているかどうかを確認する方法を示します。ユーザーがその権限を所有している場合、このファンクションは、0(ゼロ)以外の値を戻します。

例27-16 あるリソースに対してユーザーが特定の権限を所有しているかどうかの確認

SELECT DBMS_XDB.checkPrivileges(

'/TESTUSER/po1.xml',
XMLType('<privilege
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:dav="DAV:"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd">
<read-contents/>
<read-properties/>
</privilege>'))
FROM DUAL;

DBMS_XDB.CHECKPRIVILEGES('/TESTUSER/PO1.XML',
---------------------------------------------
1

1 row selected.

例27-16では、リソース/TESTUSER/po1.xmlに対するアクセス権限read-contentsおよびread-propertiesが、現行ユーザーに付与されているかどうかを確認しています。戻り値が正の整数であれば、ユーザーがその権限を持っていることを示しています。

ユーザーがACLおよびリソース所有者を使用する権限を所有しているかどうかの確認

ファンクションDBMS_XDB.ACLCheckPrivilegesは、通常、ユーザーによる操作の実行を許可する前に、独自にACLの評価を実行する必要のあるアプリケーションによって使用されます。

例27-17では、ACL /TESTUSER/acl1.xmlにより、権限read-contentsおよびread-propertiesが、現行ユーザーshに付与されているかどうかを確認しています。2番目の引数TESTUSERは、確認時にACLのDAV::ownerに置き換えられたユーザーです。ユーザーshは、指定された権限を付与されたユーザーのいずれにも一致しないため、戻り値はゼロです。

例27-17 ACLCheckPrivilegesを使用したユーザー権限の確認

CONNECT sh
Enter password: <password>

Connected.

SELECT DBMS_XDB.ACLCheckPrivileges(
'/TESTUSER/acl1.xml',
'TESTUSER',
XMLType('<privilege
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:dav="DAV:"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd">
<read-contents/>
<read-properties/>
</privilege>'))
FROM DUAL;

DBMS_XDB.ACLCHECKPRIVILEGES('/TESTUSER/ACL1.XML','TESTUSER',
------------------------------------------------------------
0

1 row selected.

指定されたリソースを保護するACLのパスの取得

例27-18では、RESOURCE_VIEW問合せを使用して、特定のリソースを保護するACLのパスを取得します。問合せでは、リソースの要素XMLRefおよびACLOIDが、ACLとリソースをリンクしているという事実が使用されます。

例27-18 特定のリソースを保護するACLのパスの取得

SELECT rv1.ANY_PATH
FROM RESOURCE_VIEW rv1
WHERE
XMLCast(XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
fn:data(/Resource/XMLRef)'
PASSING rv1.RES RETURNING CONTENT)
AS REF XMLType)
= make_ref(XDB.XDB$ACL,
(SELECT XMLCast(XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
fn:data(/Resource/ACLOID)'
PASSING rv2.RES RETURNING CONTENT)
AS REF XMLType)
FROM RESOURCE_VIEW rv2
WHERE equals_path(rv2.RES, '/TESTUSER/po1.xml') = 1));

ANY_PATH
------------------
/TESTUSER/acl1.xml

例27-18は、ACLによって保護されたリソースの指定を受けて、ACLへのパスを取得しています。保護されたリソース(r)のACLOIDには、それを保護しているACLリソース(a)のOIDが格納されています。ACLリソースのREFは、保護されたリソースACLOIDにより識別されるオブジェクトのものと同じです。

リソースACLOIDのREFは、Oracle SQL関数make_refを使用して取得できます。指定されたOIDを持つオブジェクト行へのREFが戻されます。

この例では、make_refは、リソース/TESTUSER/po1.xmlに対して、OIDが/Resource/ACLOIDである表XDB$ACLの行へのREFを戻しています。内部問合せがリソースのACLOIDを取得します。外部問合せが、対応するACLへのパスを戻します。

指定されたACLによって保護されるすべてのリソースのパスの取得

例27-19では、特定のACLにより保護されているすべてのリソースのパスを取得します。

例27-19 特定のACLによって保護されたすべてのリソースのパスの取得

SELECT rv1.ANY_PATH
FROM RESOURCE_VIEW rv1
WHERE make_ref(XDB.XDB$ACL,
XMLCast(XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
fn:data(/Resource/ACLOID)'
PASSING rv1.RES RETURNING CONTENT)
AS REF XMLType))
= (SELECT XMLCast(XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
fn:data(/Resource/XMLRef)'
PASSING rv2.RES RETURNING CONTENT)
AS REF XMLType)
FROM RESOURCE_VIEW rv2
WHERE equals_path(rv2.RES, '/TESTUSER/acl1.xml') = 1);

ANY_PATH
-----------------
/TESTUSER/po1.xml

1 row selected.

例27-19では、パスが/TESTUSER/acl1.xmlであるACLリソースのREFに対してACLOID REFが一致しているリソースへのパスを取得します。ファンクションmake_refはリソースACLOID REFを戻します。

内部問合せは、指定されたACLのREFを取得します。外部問合せは、ACLOID REFが指定されたACLのREFに一致するリソースのパスを選択します。

ACLキャッシング

ACLはその保護対象データへのアクセスのたびに確認されるため、ACLの確認操作のパフォーマンスは、Oracle XML DBリポジトリ・リソースを含むこのようなデータのパフォーマンスにとって重要な問題です。Oracle XML DBでは、このリポジトリ操作に必要なパフォーマンスは、複数のキャッシュを使用することによって達成されます。

ACLは、データベース・インスタンス内のすべてのセッションが共有するキャッシュに保存されます。ACLが更新されると、キャッシュ内のACLエントリが、そのすべての従属オブジェクトとともに無効化されます。ACLが次に使用されるときに、その新しいコピーがキャッシュに入れられます。可能なかぎり、リソース間でACLを共有することをお薦めします。

特定のACLによって特定のユーザーに付与された権限の、セッション固有のキャッシュがあります。このキャッシュのエントリには、Oracle XML DB構成ファイル(/xdbconfig.xml)の要素<acl-max-age>によって、タイムアウト(秒単位)が指定されます。パフォーマンスを最大限にするために、このタイムアウトは可能なかぎり長く設定してください。ただし、この場合トレードオフが存在します。タイムアウトが長いほど、現行セッションが更新されたACLを取り出す時間が長くなります。

Oracle XML DBは、LDAPプリンシパル(LDAPグループまたはユーザー)が設定されたACLの使用時にも、パフォーマンスを向上させるためにキャッシュを保持します。これらのキャッシュの目的は、LDAPサーバーとのネットワーク通信を最小化することです。キャッシュの1つは、LDAP GUIDを対応するLDAPのニックネームおよび識別名(DN)にマップする共有キャッシュです。これは、ACL文書が表示されているとき(または、XMLTypeインスタンスからCLOB値またはVARCHAR2値に変換されているとき)に使用されます。このキャッシュを消去する場合は、プロシージャDBMS_XDBZ.PurgeLDAPCacheを使用します。もう1つのキャッシュは、セッション固有のキャッシュで、LDAPグループをそのメンバー(ネストされたメンバーシップ)にマップします。Oracle XML DBでは、LDAPグループをセッションで最初に検出するたびに、LDAPサーバーからそのグループのネストされたメンバーシップを取得します。そのため、可能なかぎりメンバーとネスト・レベルの少ないグループを使用することをお薦めします。

リポジトリ・リソースおよびデータベース表のセキュリティ

Oracle XML DBリポジトリのリソースには、次の2タイプがあります。

- LOBベース(コンテンツはリソースの一部であるLOBに格納されます)。アクセスは、リソースを保護するACLによってのみ決定されます。

- REFベース(コンテンツはXMLであるため、データベース表に格納されます)。ユーザーは、XMLコンテンツが格納されている基礎となる表またはビューに対する適切な権限、およびリソースに対するACLを介した権限を所有している必要があります。

REFベースのリソースのコンテンツは表に格納されるため、その表に対するSQL問合せを使用してこのデータに直接アクセスできます。均一なアクセス制御メカニズムは、アクセスに必要な権限がアクセスの方法(FTP、HTTPまたはSQLなど)に依存しないメカニズムです。ACLを使用した均一なセキュリティ・メカニズムを提供するためには、最初に、表の行を参照するリソースをOracle XML DBに挿入する前に、基礎となる表が階層に対応している必要があります。

XML Schemaの登録により作成されたデフォルト表は、階層対応になっています。つまり、階層の有効化はXML SchemaをOracle XML DBに登録したときのデフォルトの動作です。登録後に階層を有効化することもできます。それにはプロシージャDBMS_XDBZ.enable_hierarchyを使用します。

リソース表で階層を有効にすると、次の動作が行われます。

- 表の行を参照するリソースのACLOIDおよびOWNERを格納する非表示列が2つ追加されます。

- その表に行レベルのセキュリティ(RLS)・ポリシーが追加されます。このポリシーは、SELECT文、UPDATE文またはDELETE操作がその表に対して実行されるたびに、ACLを確認します。

- コンテンツが格納されているXMLType表で表が更新されたとき、それに対応する最後に変更されたリソース情報が常に更新されることを保証する、パス索引トリガーと呼ばれるデータベース・トリガーが作成されます。

関連項目:

- プロシージャDBMS_XMLSCHEMA.registerSchemaの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- プロシージャDBMS_XDBZ.enable_hierarchyの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

指定された任意の表で、オブジェクトの一部のみがOracle XML DBリソースにマップされることがあります。マップされたオブジェクトのみがACLチェックを受けますが、すべてのオブジェクトに表レベルのセキュリティがあります。

注意:
表外に格納する場合は、XMLType表のデータを他のユーザーに対して非表示にすることはできません。表外のデータは、ACLセキュリティによって保護されません。

最適化: 不要な場合にaclベースのセキュリティを適用しない

ACLベースのセキュリティでは、XMLコンテンツへのアクセスを単に表ごとではなく文書ごとに制御できます。PL/SQLプロシージャDBMS_XMLSCHEMA.register_chemaをコールすると、作成される表でACLベースのセキュリティがデフォルトで有効になります。

この効果の1つは、このような表のXMLコンテンツにSQL文を使用してアクセスすると、sys_checkACLへのコールが問合せのWHERE句に自動的に追加されることです。これによって、定義されたACLセキュリティがSQLレベルで適用されます。

ただし、ACLベースのセキュリティを適用すると、SQL問合せのオーバーヘッドが増加します。ACLベースのセキュリティが必要でない場合は、パッケージDBMS_XDBZ内のプロシージャdisable_hierarchyを使用して、ACLによる確認をオフにします。

ACLベースのセキュリティがXMLType表で有効になると、その表に対する問合せの実行計画の出力には、次のようなフィルタが含まれます。

3 - filter(SYS_CHECKACL("ACLOID","OWNERID",xmltype(''<privilege
xmlns="http://xmlns.oracle.com/xdb/acl.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd
DAV:http://xmlns.oracle.com/xdb/dav.xsd">
<read-properties/><read-contents/></privilege>''))=1)

この例のフィルタは、SQL問合せを実行するユーザーに、アクセスする各文書に対するread-contents権限があることを確認します。

DBMX_XDBZ.disable_hierarchyをコールすると、同じ問合せの実行計画では、フィルタにSYS_CHECKACLが表示されません。

関連項目:
プロシージャDBMS_XDBZ.disable_hierarchyの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

Oracle XML DBのLDAPとの統合

この項では、LDAPユーザーがACLを含むOracle XML DBの機能を使用できるようにするための処理について説明します。典型的なシナリオでは、単一の共有データベース・スキーマ(ユーザー)に、複数のLDAPユーザーがマップされています。このマッピングは、Oracle Internet Directoryで維持されています。エンド・ユーザーは、LDAPユーザー名およびパスワードを使用して、データベースにログインできます。ログインすると、対応する共有データベース・スキーマに自動的にマップされます。(ログインには、SQLまたはOracle XML DBでサポートされている任意のプロトコルを使用できます。)暗黙的なACL解決は、現行のLDAPユーザーおよび対応するLDAPグループのメンバーシップ情報に基づいています。

Oracle XML DB ACLのプリンシパルとしてLDAPユーザーおよびLDAPグループを使用する場合は、その前に次の条件を満たす必要があります。

- Oracle Internet Directoryが設定され、データベースがそれに登録されている必要があります。

- SSL認証がデータベースとOracle Internet Directoryの間に設定されている必要があります。

- 共有データベース・スキーマに対応するデータベース・ユーザーが作成されている必要があります。

- Oracle Internet DirectoryでLDAPユーザーが作成され、共有データベース・スキーマにマップされる必要があります。

- LDAPグループが作成され、そのメンバーが指定されている必要があります。

- LDAPグループやLDAPユーザーに対してACLが定義され、それを使用してLDAPユーザーがアクセスするリポジトリ・リソースが保護される必要があります。

関連項目:

- 『Oracle Internet Directory管理者ガイド』

- SSL認証の設定の詳細は、『Oracle Database Advanced Security管理者ガイド』を参照してください。

- エンタープライズ(LDAP)ユーザーのための共有データベース・スキーマの使用方法の詳細は、『Oracle Databaseエンタープライズ・ユーザー・セキュリティ管理者ガイド』を参照してください。

例27-20は、LDAPユーザーのACLを示しています。要素<principal>にはLDAPユーザーの完全識別名(この場合cn=user1,ou=Americas,o=oracle,l=redwoodshores,st=CA,c=US)が含まれています。

例27-20 LDAPユーザーを参照するACL

<acl description="/public/txmlacl1/acl1.xml"
xmlns="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:dav="DAV:"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd">
<ace principalFormat="DistinguishedName">
<grant>true</grant>
<principal>cn=user1,ou=Americas,o=oracle,l=redwoodshores,st=CA,c=US
</principal>
<privilege>
<dav:all/>
</privilege>
</ace>
</acl>

関連項目:
LDAPユーザー識別名の形式については『Oracle Internet Directory管理者ガイド』

例27-21は、LDAPグループのACLを示しています。要素<principal>には、LDAPグループの完全識別名が含まれています。

例27-21 LDAPグループを参照するACL

<acl xmlns="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:dav="DAV:"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
http://xmlns.oracle.com/xdb/acl.xsd">
<ace principalFormat="DistinguishedName">
<grant>true</grant>
<principal>cn=grp1,ou=Americas,o=oracle,l=redwoodshores,st=CA,c=US</principal>
<privilege>
<dav:read/>
</privilege>
</ace>
</acl>

関連項目:
LDAPグループ識別名の形式については『Oracle Internet Directory管理者ガイド』

脚注の凡例

脚注1: コロン(:)は名前空間名の一部です。DAV:は、接頭辞ではなく、名前空間そのものです。名前空間DAV:に広く使用される接頭辞はdavですが、これは慣例的なものにすぎません。davは、Oracle XML DBで事前定義されている接頭辞ではありません。

28 プロトコルを使用したリポジトリへのアクセス

この章では、FTP、HTTP(S)およびWebDAVプロトコルを使用してOracle XML DBリポジトリにアクセスする方法を説明します。

この章の内容は次のとおりです。

- Oracle XML DBプロトコル・サーバーの概要

- Oracle XML DBプロトコル・サーバーの構成管理

- FTPおよびOracle XML DBプロトコル・サーバーの使用

- HTTP(S)およびOracle XML DBプロトコル・サーバーの使用

- WebDAVおよびOracle XML DBの使用

Oracle XML DBプロトコル・サーバーの概要

第2章「Oracle XML DBを使用する前に」および第21章「Accessing Oracle XML DBリポジトリのデータへのアクセス」で説明したとおり、Oracle XML DBリポジトリは、XML用に設計された階層データ・リポジトリをデータベース内に提供します。Oracle XML DBリポジトリは、XMLTypeのデータベース・オブジェクトにパス名(またはURL)をマップし、これらのオブジェクトの管理機能を提供します。

Oracle XML DBは、Oracle XML DBプロトコル・サーバーも提供します。Oracle XML DBは、その階層リポジトリまたはファイル・システムにアクセスするための標準インターネット・プロトコルであるFTP、WebDAVおよびHTTP(S)をサポートします。HTTPSはOracle XML DBリポジトリへのセキュアなアクセスを提供します。

多くのユーザーは、これらのプロトコルによって、追加のソフトウェアをインストールせずに、Oracle XML DBに直接アクセスできます。プロトコルで使用するユーザー名およびパスワードは、SQL*Plusで使用するものと同じです。エンタープライズ・ユーザーもサポートされています。データベース管理者は、これらのプロトコルと、DBMS_XDBなどのリソースAPIを使用して、リポジトリの仮想フォルダ/sys/asmにあるOracle Automatic Storage Management (Oracle ASM)のファイルとフォルダにアクセスすることができます。

関連項目:
リポジトリ情報へのアクセスとその場合の制限事項の詳細は、第21章「Accessing Oracle XML DBリポジトリのデータへのアクセス」を参照してください。

注意:

- Oracle XML DBプロトコルを使用して仮想フォルダ/sys/asmにアクセスする場合は、ロールDBAの権限を持っているSYS以外のユーザーとしてログインする必要があります。

- Oracle XML DBのプロトコルは、EBCDICプラットフォームではサポートされません。

セッション・プーリング

Oracle XML DBプロトコル・サーバーは、セッションの共有プールを保持します。各プロトコル接続は、このプールの1つのセッションに関連付けられます。接続のクローズ後、セッションは共有プールに戻され、その後の接続で使用できます。

セッション・プーリングでは、特に、リクエストごとに新しい接続が作成されるHTTP 1.0を使用する場合、セッション状態を再作成するコストが削減され、HTTP(S)のパフォーマンスが向上します。たとえば、データベース・セッションを作成する必要がある場合に、既存のHTTP/1.1接続でいくつかの小さいファイルを取り出すことができます。Oracle XML DBのxdbconfig.xmlファイルでセッション・プール・サイズを設定することによってセッション数を調整したり、このプール・サイズを0(ゼロ)に設定することによってセッションを使用禁止にできます。

セッション・プーリングは、Javaサーブレットを作成するユーザーに影響する可能性があります。これは、他のユーザーが別のユーザーの別のリクエストによって初期化されたセッションの状態を参照できるためです。そのため、サーブレットの作成者は、Java静的変数などのセッション・メモリーのみを使用して、特定のユーザーではなくアプリケーション全体に対するデータを保持する必要があります。セッションが1人のユーザーに対してのみ存在すると想定するのではなく、ユーザーごとの状態をデータベースまたは参照表に格納する必要があります。

関連項目:
第32章「JavaでのOracle XML DBアプリケーションの作成」

図28-1に、Oracle XML DB プロトコル・サーバーのコンポーネント、およびそれらを使用してOracle XML DBリポジトリのファイルおよび他のデータにアクセスする方法を示します。この図では、リポジトリの関連するコンポーネントのみを示します。

図28-1 Oracle XML DBのアーキテクチャ: プロトコル・サーバー

Oracle XML DBプロトコル・サーバーの構成管理

Oracle XML DBプロトコル・サーバーは、/xdbconfig.xmlに格納された構成パラメータを使用して、起動状態の初期化およびセッション・レベルの構成を管理します。次の項では、Oracle XML DB構成ファイルで構成可能な、プロトコル固有の構成パラメータについて説明します。セッション・プール・サイズおよびタイムアウト・パラメータは動的に変更できません。変更内容を有効にするためには、データベースを再起動する必要があります。

関連項目:
「xdbconfig.xmlを使用したOracle XML DBの構成」

プロトコル・サーバーのパラメータの構成

図28-1に、すべてのプロトコルに共通のパラメータを示します。/xdbconfigで始まるパラメータを除き、この表に含まれるすべてのパラメータ名は、Oracle XML DB構成スキーマの次のXPathに関連しています。

/xdbconfig/sysconfig/protocolconfig/common

- FTP固有のパラメータ: 表28-2にFTP固有のパラメータを示します。これらは、Oracle XML DB構成スキーマの次のXPathに関連しています。

/xdbconfig/sysconfig/protocolconfig/ftpconfig

- サーブレット関連のパラメータ以外のHTTP(S)/WebDAV固有のパラメータ: 表28-3はHTTP(S)/WebDAV固有のパラメータを示します。これらのパラメータは、Oracle XML DB構成スキーマの次のXPathに関連しています。

/xdbconfig/sysconfig/protocolconfig/httpconfig

関連項目:

- /xdbconfig.xml構成ファイルの詳細は、第34章「Oracle XML DBの管理」を参照してください。

- 「xdbconfig.xsd: Oracle XML DBを構成するためのXML Schema」

- schemaLocation-mappingsパラメータの詳細は、「デフォルトの名前空間のスキーマの場所へのマッピングの構成」

- xml-extensionsパラメータの詳細は、「XMLファイル拡張子の構成」を参照してください。

これらのパラメータの使用例については、構成ファイル/xdbconfig.xmlを参照してください。

表28-1 共通プロトコルの構成パラメータ

パラメータ

説明

extension-mappings/mime-mappings

ファイル拡張子のマッピングをMIMEタイプに指定します。リソースがOracle XML DBリポジトリに格納され、そのMIMEタイプが指定されていない場合、このマッピング・リストを使用してそのMIMEタイプが設定されます。

extension-mappings/lang-mappings

ファイル拡張子のマッピングを言語に指定します。リソースがOracle XML DBリポジトリに格納され、その言語が指定されていない場合、このマッピング・リストを使用してその言語が設定されます。

extension-mappings/encoding-mappings

ファイル拡張子のマッピングをエンコーディングに指定します。リソースがOracle XML DBリポジトリに格納され、そのエンコーディングが指定されていない場合、このマッピング・リストを使用してそのエンコーディングが設定されます。

xml-extensions

Oracle XML DBによってXMLコンテンツとして処理されるファイル名の拡張子のリストを指定します。

session-pool-size

プロトコル・サーバーのセッション・プールに保持されるセッションの最大数を指定します。

/xdbconfig/sysconfig/call-timeout

接続がこの時間(100分の1秒単位)の間アイドル状態であった場合、接続を行っている共有サーバーは、他の接続のために解放されます。

session-timeout

プロトコル・サーバーがセッション(およびそれに対応する接続)を終了するまでの、接続のアイドル状態の経過時間(100分の1秒単位)を指定します。このパラメータは、特定のプロトコルのセッション・タイムアウトが構成に存在しない場合にのみ使用されます。

schemaLocation-mappings

指定された名前空間のデフォルトのスキーマの場所を指定します。このパラメータは、インスタンスのXML文書にxsi:schemaLocation属性が明示的に含まれていない場合に使用されます。

/xdbconfig/sysconfig/default-lock-timeout

リソースのWebDAVロックが無効になるまでの時間を指定します。これは、リソースをロックするクライアントが指定したタイムアウトでオーバーライドできます。

表28-2 FTP固有の構成パラメータ

パラメータ

説明

buffer-size

FTPのput操作でネットワークからデータを読み取るのに使用されるバッファのサイズ(バイト単位)。buffer-sizeを大きな値に設定すると、putのパフォーマンスが向上します。putのパフォーマンスとメモリー使用量の間にはトレードオフがあります。値の範囲は1024から1048496です。デフォルト値は8192です。

ftp-port

FTPサーバーがリスニングするポートを指定します。デフォルトではこれは0になっており、これはFTPが無効であることを意味します。FTPがデフォルトで無効なのは、FTP仕様ではパスワードをクリアテキストで送信することが要求されており、セキュリティ・ハザードになる可能性があるためです。FTPを有効にするには、このパラメータを使用するFTPポート(2100など)に設定します。

ftp-protocol

FTPサーバーを実行するプロトコルを指定します。デフォルトはtcpです。

ftp-welcome-message

FTPクライアントがサーバーに接続したときに表示される、ユーザー定義のウェルカム・メッセージ。このパラメータが空または欠落している場合は、「Unauthorized use of this FTP server is prohibited and may be subject to civil and criminal prosecution.」(このFTPサーバーの不正使用は禁じられており、民事および刑事訴追の対象となる場合があります。)というデフォルト・ウェルカム・メッセージが表示されます。

session-timeout

プロトコル・サーバーがFTP接続を終了するまでの、接続のアイドル状態の経過時間(100分の1秒単位)を指定します。

表28-3 HTTP(S)またはWebDAV固有の構成パラメータ(サーブレット・パラメータを除く)

パラメータ

説明

http-port

HTTP(S)またはWebDAVサーバーがプロトコルhttp-protocolを使用してリスニングするポート。デフォルトではこれは0になっており、これはHTTPが無効であることを意味します。このパラメータが空の場合は(<http-port/>)、デフォルトの0が適用されます。パラメータを空にしておくことはお薦めしません。

このパラメータは、空であるかどうかに関係なく、存在する必要があります。存在しない場合、XML Schema xdbconfig.xsdに対するxdbconfig.xmlの検証は失敗します。値はhttp2-portの値と異なっている必要があります。そうでない場合は、エラーが発生します。

http2-port

HTTP(S)またはWebDAVサーバーがプロトコルhttp2-protocolを使用してリスニングするポート。

このパラメータはオプションですが、存在する場合は、http2-protocolが存在する必要があります。そうでない場合は、エラーが発生します。値はhttp-portの値と異なっている必要があります。そうでない場合は、エラーが発生します。パラメータ(<http2-port/>)が空の場合もエラーが発生します。

http-protocol

ポートhttp-port上でHTTP(S)またはWebDAVサーバーを実行するプロトコル。TCPまたはTCPSである必要があります。

このパラメータは存在する必要があります。存在しない場合、XML Schema xdbconfig.xsdに対するxdbconfig.xmlの検証は失敗します。パラメータ(<http-protocol/>)が空の場合もエラーが発生します。

http2-protocol

ポートhttp2-port上でHTTP(S)またはWebDAVサーバーを実行するプロトコル。TCPまたはTCPSである必要があります。このパラメータが空の場合は(<http2-protocol/>)、デフォルトのTCPが適用されます。(パラメータを空にしておくことはお薦めしません。)

このパラメータはオプションですが、存在する場合は、http2-portが存在する必要があります。そうでない場合は、エラーが発生します。

session-timeout

プロトコル・サーバーがHTTP(S)セッション(およびそれに対応する接続)を終了するまでの、接続のアイドル状態の経過時間(100分の1秒単位)を指定します。

max-header-size

HTTP(S)ヘッダーの最大サイズ(バイト単位)を指定します。

max-request-body

HTTP(S) Request Bodyの最大サイズ(バイト単位)を指定します。

webappconfig/welcome-file-list

「ウェルカム・ファイル」とみなされるファイル名のリストを指定します。サーバーは、コンテナに対するHTTP(S) getリクエストを受信すると、これらのいずれかの名前を持つコンテナのリソースが存在するかどうかを最初に確認します。そのようなリソースが存在する場合、コンテナ内のリソースのリストではなく、そのファイルのコンテンツが送信されます。

default-url-charset

受信URLがUTF-8またはリクエストのContent-TypeフィールドのCharsetパラメータに指定されたキャラクタ・セットでエンコードされていない場合に、HTTP(S)プロトコル・サーバーは、受信URLがこのキャラクタ・セットでエンコードされていると想定します。

allow-repository-anonymous-access

ロック解除されたANONYMOUSユーザー・アカウントを使用した、Oracle XML DBリポジトリ・データへの匿名HTTPアクセスが許容されるかどうかを示します。デフォルト値はfalseで、これはリポジトリ・データへの非認証アクセスがブロックされることを意味します。「HTTPを使用したOracle XML DBリポジトリへの匿名アクセス」を参照してください。

expire

URLの期限切れ日時を指定するHTTPヘッダー。「URL期限切れ時間の制御」を参照してください。

セキュアHTTP(HTTPS)の構成

Oracle XML DBリポジトリによるセキュアHTTP接続(HTTPS)の使用を有効にするには、データベース管理者(DBA)がデータベースを適切に構成する必要があります。パラメータhttp2-portおよびhttp2-protocolを構成し、HTTP ListenerによるSSL使用を有効にし、TCPS Dispatcherの起動を有効にします。それが完了したら、DBAがデータベースおよびリスナーを停止して再起動する必要があります。

関連項目:
Oracle XML DBパラメータ構成の詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください。

HTTP ListenerによるSSLの使用の有効化

データベース管理者は次の手順を実行して、SSLに対してHTTP Listenerを構成する必要があります。

注意:
SSLに対してHTTP Listenerを構成するには、オプションのOracle Advanced Securityが必要です。

1. サーバー用のウォレットを作成し、証明書をインポートします。Oracle Wallet Managerを使用して次の操作を行います。

1. サーバー用のウォレットを作成します。

2. サーバーの識別名(DN)を持つ有効な証明書がない場合は、証明書リクエストを作成して認証局に送信します。有効な証明書を認証局から取得します。

3. サーバーの識別名(DN)を持つ有効な証明書をサーバーにインポートします。

4. 新しいウォレットを不明瞭化した形式で保存し、パスワードなしで開けるようにします。

関連項目:
ウォレットの作成方法の詳細は、『Oracle Database Advanced Security管理者ガイド』を参照してください。

2. ウォレットの場所をサーバーに対して指定します。Oracle Net Managerで行います。構成がディスクに保存されたことを確認します。この手順により、ファイルsqlnet.oraおよびlistener.oraが更新されます。

3. サーバー側でのクライアント認証を無効にします。大部分のWebクライアントには証明書がないからです。Oracle Net Managerを使用します。この手順により、ファイルsqlnet.oraが更新されます。

4. TCP/IPをSSLで使用するリスニング・エンド・ポイントを作成します。Oracle Net Managerを使用します。この手順により、ファイルlistener.oraが更新されます。

関連項目:
手順1から4の詳細は、『Oracle Database Advanced Security管理者ガイド』を参照してください。

TCPS Dispatcherの有効化

データベース管理者は、データベースのpfileを編集して、データベース起動時のTCPS Dispatcherの起動を有効にする必要があります。ファイルに次の行を追加します。ここでSIDはデータベースのSIDです。

dispatchers=(protocol=tcps)(service=SIDxdb)

データベースのpfileの場所はオペレーティング・システムにより異なります。次を参照してください。

- MS Windows: PARENT/admin/orcl/pfile。ここでPARENTはフォルダORACLE_HOMEの親フォルダ

- UNIX、Linux: $ORACLE_HOME/admin/$ORACLE_SID/pfile

Oracle XML DBファイル・システムのリソースとの相互作用

プロトコル仕様のRFC 959(FTP)、RFC 2616(HTTP)およびRFC 2518(WebDAV)では、暗黙的にサーバー側の抽象的な階層ファイル・システムを想定しています。これはOracle XML DBリポジトリにマッピングされます。リポジトリにより実現されるものは次のとおりです。

- 名前解決。

- アクセス制御リスト(ACL)に基づいたセキュリティ。ACLは、指定されたリソースへのアクセス権を持つプリンシパルを決定するアクセス制御エントリのリストです。第27章「リポジトリのアクセス制御」も参照してください。

- 任意のコンテンツを格納し、取り出す機能。リポジトリは、FTPを介したバイナリ・データ入力と、XML Schemaに基づく文書の両方を格納できます。

関連項目:

- http://www.ietf.org/rfc/rfc959.txt

- http://www.ietf.org/rfc/rfc2616.txt

- http://www.ietf.org/rfc/rfc2518.txt

プロトコル・サーバーによるXML Schemaに基づくXML文書または基づかないXML文書の処理

Oracle XML DBプロトコル・サーバーは、挿入中のXML文書がOracle XML DBリポジトリに登録されたXML Schemaに基づいているかどうかを常に確認することによって、プロトコルを拡張します。

- 受信するXML文書がXML Schemaを指定する場合、使用するOracle XML DB記憶域はそのXML Schemaによって決定されます。この機能は、SQL文を使用するのではなく、FTPやWebDAVなどの単純なプロトコルを使用して、XML文書をオブジェクト・リレーショナル形式でデータベースに格納する必要がある場合に有効です。

- 受信するXML文書がXML Schemaに基づいていない場合は、バイナリ・ドキュメントとして格納されます。

イベントベース・ロギング

プロトコル・サーバーが受信したリクエストおよびプロトコル・サーバーから送信されたレスポンスを記録すると有効な場合があります。これを行うには、イベント番号31098をレベル2に設定します。このイベントを設定するには、次の行をinit.oraファイルに追加し、データベースを再起動します。

event="31098 trace name context forever, level 2"

FTPおよびOracle XML DBプロトコル・サーバーの使用

次の項では、Oracle XML DBでサポートされているFTP機能について説明します。

Oracle XML DBプロトコル・サーバー: FTP機能

ファイル転送プロトコル(FTP)は、インターネット上で最も古く、最も一般的なプロトコルの1つです。FTPはRFC959で規定され、異機種間のファイル・システムへの均一な方法でのアクセスを提供します。FTPは、クライアントとサーバー間で通信するための定義済のコマンド(メソッド)を提供することによって動作します。1回の接続でコマンド・メッセージの転送とステータスの取得が実行されます。ただし、データ転送用に、クライアントとサーバー間で新しい接続がオープンされます。HTTP(S)を使用すると、1回の接続でコマンドとデータが転送されます。

FTPは、オペレーティング・システムの専用クライアント、ファイル・システムのエクスプローラ・クライアントおよびブラウザで実装されています。FTPは、一般的にセッション指向であり、明示的なログインによってユーザー・セッションが作成され、ファイルまたはディレクトリがダウンロードおよび参照された後、接続がクローズされます。

注意:
セキュリティ上の理由で、FTPはデフォルトで無効になっています。IETF FTPプロトコルの仕様ではパスワードをクリアテキストで送信することが要求されているためです。無効化は、FTPサーバーのポートをゼロ(0)にすることで実現しています。FTPを有効にするには、ftp-portパラメータを、使用するFTPポート(2100など)に設定します。

関連項目:

- RFC 959: FTPプロトコル仕様: http://www.ietf.org/rfc/rfc959.txt

- パラメータ構成の詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください。

サポートされていないFTPの機能

Oracle XML DBは、RFC 959で定義されたFTPを実装しますが、次のオプション機能は除きます。

- レコード指向のファイル、たとえば、STRUメソッドは、FILE構造のみサポートされています。これは、ファイルの転送に最も広範囲に使用されている構造です。これは、仕様で指定されているデフォルトでもあります。構造マウントはサポートされません。

- 追加。

- 割当て。ファイル転送の前に領域を事前に割り当てます。

- アカウント。安全性の低いTelnetプロトコルを使用します。

- 強制終了。

サポートされているFTPクライアント・メソッド

リポジトリにアクセスするために、Oracle XML DBは次のFTPクライアント・メソッドをサポートしています。

- cdup: 作業ディレクトリを親ディレクトリに変更します。

- cwd: 作業フォルダを変更します。

- dele: ファイルを削除します(ディレクトリは対象外)。

- list、nlst: 作業ディレクトリのファイルをリストします。

- mkd: ディレクトリを作成します。

- noop: 何もしません(接続のタイムアウト・カウンタはリセットされます)。

- pasv、port: TCPデータ接続を確立します。

- pwd: 作業フォルダを取得します。

- quit: 接続を閉じてFTPセッションを終了します。

- retr: 確立された接続を使用してデータを取得します。

- rmd: ディレクトリを削除します。

- rnfr、rnto: ファイル名を変更します(2ステップ・プロセス: ファイルから、ファイルへ)。

- stor: 確立された接続を使用してデータを格納します。

- syst: システムのバージョンを取得します。

- type: データ型を変更します。asciiまたはimageバイナリ型のみが可能です。

- user、pass: ユーザーのログインです。

関連項目:

- サポートされているFTPのquoteメソッドについては「FTP Quoteメソッド」

- FTPメソッドproxyの使用については「Oracle ASMファイルに対するFTPの使用」

FTP Quoteメソッド

Oracle Databaseは、Oracle XML DBに直接情報を提供するFTP quoteメソッドを複数サポートしています。

- rm_r: ファイルまたはフォルダ<resource_name>を削除します。フォルダの場合、<resource_name>に含まれるすべてのファイルとフォルダを再帰的に削除します。

quote rm_r <resource_name>

- rm_f: リソースを強制的に削除します。

quote rm_f <resource_name>

- rm_rf: rm_rおよびrm_fを組み合せます。ファイルとフォルダを強制的かつ再帰的に削除します。

quote rm_rf <resource_name>

- set_nls_locale: FTPメソッドでファイル名やディレクトリ名に使用する(メソッド・レスポンスでの名前を含む)キャラクタ・セット・エンコーディングを指定します(<charset_name>)。

quote set_nls_locale {<charset_name> | NULL}

<charset_name>に対して指定できるのは、IANAキャラクタ・セット名のみです。nls_localeがNULLまたは設定されていない場合、こデータベース・キャラクタ・セットが使用されます。

- set_charset: サーバーに送信されるデータのキャラクタ・セットを指定します。

quote set_charset  {<charset_name> | NULL}

set_charsetメソッドは、構成ファイルxdbconfig.xmlで定義されているMIMEタイプへのファイル拡張子マッピングで決定されているとおり、テキスト・ファイルのみに適用され、バイナリ・ファイルには適用されません。

set_charsetに提供されているパラメータが<charset_name> (NULLではない)場合、これによってデータのキャラクタ・セットが指定されます。

set_charsetに提供されているパラメータがNULLの場合や、set_charsetコマンドが指定されていない場合は、データのMIMEタイプによって、そのデータのキャラクタ・セットが決定されます。

- MIMEタイプがtext/xmlでない場合は、データはXMLとは仮定されません。データベース・キャラクタ・セットが使用されます。

- MIMEタイプがtext/xmlでない場合は、データはXMLとは仮定されません。
XML文書内にバイト・オーダー・マーク脚注1(BOM)がある場合、それによってデータのキャラクタ・セットが決定されます。

BOMが ない場合、次のようになります。

- XML文書にエンコーディング宣言がある場合、それによりデータのキャラクタ・セットが決定されます。

- エンコーディング宣言がない場合、UTF-8キャラクタ・セットが使用されます。

Oracle ASMファイルに対するFTPの使用

Oracle Automatic Storage Management(Oracle ASM)を使用すると、データベース・ファイルはディスク・グループに整理され、管理が簡潔になるとともに、データベースのミラー化やI/Oバランシングなどの利用が可能になります。データベース管理者は、プロトコルやリソースAPIを使用して、Oracle XML DBリポジトリの仮想フォルダ/sys/asmのOracle ASMファイルにアクセスできます。/sys/asmにあるファイルはすべてバイナリです。

一般的な用途は、Oracle ASMのファイルやフォルダに対するリスト表示、コピー、移動、作成、および削除です。例28-1はOracle ASMの仮想フォルダのナビゲートとサブフォルダ内のファイルのリスト表示の例です。

Oracle ASM仮想フォルダ/sys/asmの構造は、第21章「Oracle XML DBリポジトリのデータへのアクセス」で説明しています。例28-1では、ディスク・グループがDATAおよびRECOVERY、データベース名がMFG、エイリアス用に作成されたディレクトリがdbsおよびtmpです。この例はサブフォルダにナビゲートし、ファイルをリストし、ファイルの1つをローカルのファイル・システムにコピーしています。

例28-1 Oracle ASMフォルダのナビゲート

ftp> open myhost 7777
ftp> user system
Password required for SYSTEM
Password: password
ftp> cd /sys/asm
ftp> ls
DATA
RECOVERY
ftp> cd DATA
ftp> ls
dbs
MFG
ftp> cd dbs
ftp> ls
t_dbl.f
t_axl.f
ftp> binary
ftp> get t_dbl.f, t_axl.f
ftp> put my_db2.f

例28-1では、データベースmyhostに接続およびログインし(最初の4行)、FTPメソッドcdおよびlsを使用して、それぞれフォルダをナビゲートおよびリスト表示しています。フォルダ/sys/asm/DATA/dbs内でFTPコマンドgetを使用して、ファイルt_db1.fおよびt_ax1.fがローカルのファイル・システムの現行のフォルダにコピーします。続いてFTPコマンドputを使用して、ファイルmy_db2.fをローカルのファイル・システムからフォルダ/sys/asm/DATA/dbsにコピーしています。

データベース管理者はOracle Automatic Storage Management(Oracle ASM)ファイルをデータベース・サーバー間でコピーしたり、データベースとローカルのファイル・システムの間でコピーできます。例28-2は2つのデータベース間でのコピーを示しています。この場合、proxy FTPクライアント・メソッドを使用できます。proxyメソッドを使用すると、2つの異なるリモートFTPサーバーに直接接続できます。

例28-2では、Oracle ASMファイルをデータベース間でコピーしています。接尾辞1が付いた語はデータベースserver1に対応しています。接尾辞2が付いた語はデータベースserver2に対応しています。一部のFTPクライアントでは、入力したパスワードが画面に表示されることがあります。パスワードが他人の目に触れないよう、十分注意してください。

例28-2 FTP proxyメソッドによる、Oracle ASMファイルのデータベース間転送

1 ftp> open server1 port1
2 ftp> user username1
3 Password required for USERNAME1
4 Password: password-for-username1
5 ftp> cd /sys/asm/DATAFILE/MFG/DATAFILE
6 ftp> proxy open server2 port2
7 ftp> proxy user username2
8 Password required for USERNAME2
9 Password: password-for-username2
10 ftp> proxy cd /sys/asm/DATAFILE/MFG/DATAFILE
11 ftp> proxy put dbs2.f tmp1.f
12 ftp> proxy get dbs1.f tmp2.f

例28-2

- 1行目でOracle XML DB FTPサーバーserver1へのFTP制御接続を開きます。

- 2から4行目で、データベース管理者がUSERNAME1としてserver1にログインします。

- 5行目でserver1の/sys/asm/DATAFILE/MFG/DATAFILEにナビゲートします。

- 6行目で第2のデータベース・サーバーserver2へのFTP制御接続を開きます。この時点で、FTPコマンドproxy ?を発行して、第2の接続で利用できるFTPコマンドを参照することができます。(これは表示されていません。)

- 7から9行目で、データベース管理者がUSERNAME2としてserver2にログインします。

- 10行目でserver2の/sys/asm/DATAFILE/MFG/DATAFILEにナビゲートします。

- 11行目で、Oracle ASMファイルdbs2.fを、server2から、server1上のOracle ASMファイルtmp1.fにコピーします。

- 12行目で、Oracle ASMファイルdbs1.fを、server1から、server2上のOracle ASMファイルtmp2.fにコピーします。

Oracle XML DBのデフォルト・ポートでなく標準ポート上でのFTP使用

Oracle XML DBの構成ファイル/xdbconfig.xmlを使用して、任意のポートでリスニングするようにFTPを構成できます。FTPはデフォルトで、非標準の保護されないポートでリスニングを行います。標準ポート21でFTPを使用するには、データベース管理者が次のことを実行する必要があります。

1. (UNIXのみ)このシェル・コマンドを使用して、実行可能ファイルtnslsnrの所有者とグループが必ずrootになるようにします。

% chown root:root $ORACLE_HOME/bin/tnslsnr

2. (UNIXのみ)リスナー・ファイルlistener.oraに次のエントリを追加します。ここで、hostnameは使用するホスト名です。

(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP) (HOST = hostname) (PORT = 21))
(PROTOCOL_STACK = (PRESENTATION = FTP) (SESSION = RAW)))

3. (UNIXのみ)シェル・コマンドidを使用して、Oracle Databaseのインストールに使用されたuser_idおよびgroup_idを特定します。oracle_installation_userは、データベースをインストールしたユーザーの名前です。

% id oracle_installation_user
uid=user_id(oracle_installation_user) gid=group_id(dba)

4. (UNIXのみ)次のシェル・コマンドを使用して、リスナーを停止して再起動します。ここで、user_idおよびgroup_idは、手順3で取得したUNIXユーザー識別子およびグループ識別子です。

% lsnrctl stop
% tnslsnr LISTENER -user user_id -group group_id &

2番目のコマンドをバックグラウンドで実行するにはアンパサンド(&)を使用します。リスナーを起動するためにlsnrctl startを使用しないでください。

5. 次のようにSYS as SYSDBAでPL/SQLプロシージャDBMS_XDB.setftpportを使用して、Oracle XML DB構成ファイル/xdbconfig.xmlでFTPポート番号を21に設定します。

SQL> exec DBMS_XDB.setFTPPort(21);

6. 次のSQL文を使用してデータベースが必ずリスナーとともに登録されるようにします。

SQL> ALTER SYSTEM REGISTER;

7. このシェル・コマンドを使用して、リスナーが適切に構成されていることを確認します。

% lsnrctl status

関連項目:

- リスナーのパラメータおよびファイルlistener.oraの詳細は『Oracle Database Net Servicesリファレンス』を参照してください。

- 特権ポートの詳細は『Oracle Database Net Servicesリファレンス』の、ポート番号の制限に関する項を参照してください。

FTPでのIPv6 IPアドレスの使用

11gリリース2(11.2)以上のOracle Databaseでは、(Internet Protocol Version 4に加えて)Internet Protocol Version 6(IPv6)がサポートされています。例28-3に、FTPでIPv6アドレス2001::0db8:ffff:ffff:ffffに接続する方法を示します。

例28-3 IPv6を使用したFTP接続

ftp> open 2001::0db8:ffff:ffff:ffff 1521
Connected to 2001::0db8:ffff:ffff:ffff.
220- xmlhost.example.com
Unauthorized use of this FTP server is prohibited and may be subject to civil and criminal prosecution.
220- xmlhost.example.com FTP server (Oracle XML DB/Oracle Database) ready.
User (2001::0db8:ffff:ffff:ffff:(none)): username
331 pass required for USERNAME
Password: password-for-username
230 USERNAME logged in
ftp>

関連項目:
IPv6の詳細は、『Oracle Database Net Servicesリファレンス』を参照してください。

FTPサーバーのセッション管理

Oracle XMLL DBプロトコル・サーバーは、FTPプロトコルのセッション管理も提供します。FTPは、新しいコマンドの入力をショート・ウェイトした後、プロトコル・レイヤーに戻ります。このショート・ウェイト時間は、Oracle XML DB構成ファイルのcall-timeoutパラメータを変更することによって構成できます。通信量が多いサイトでは、call-timeoutを短くし、より多くの接続を確立できるようにする必要があります。接続で新しいデータが受信されると、FTPサーバーは最新のデータを使用して再起動されます。そのため、FTPが長時間実行する性質を持っていても、プロトコル・サーバーに確立可能な接続の数には影響しません。

関連項目:
Oracle XML DBパラメータ構成の詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください。

エラー421の処理。FTPセッションのデフォルトのタイムアウト値の変更

頻繁にサーバーから切断され、次の操作を実行する前に、再接続してディレクトリ全体を検索する必要がある場合は、FTPセッションに対するデフォルトのタイムアウト値を変更する必要がある可能性があります。この時間の経過後もセッションがアイドル状態である場合、そのセッションは切断されます。タイムアウトの値(デフォルト= 6000センチセカンド)を大きくするには、次のように構成ドキュメントを変更した後、データベースを再起動します。

例28-4 FTPセッションのデフォルトのタイムアウト値の変更

DECLARE
newconfig XMLType;
BEGIN
SELECT
updateXML(
DBMS_XDB.cfg_get(),
'/xdbconfig/sysconfig/protocolconfig/ftpconfig/session-timeout/text()',
123456789)
INTO newconfig
FROM DUAL;
DBMS_XDB.cfg_update(newconfig);
END;/
COMMIT;

パッシブ・モードでのFTPクライアントの障害

listener.oraでHOSTNAMEがlocalhostまたは127.0.0.1.と構成されているサーバーにリモートから接続する場合、FTPをパッシブ・モードで使用しないでください。サーバー・ファイルlistener.oraで指定されているHOSTNAMEがlocalhostまたは127.0.0.1の場合、サーバーはローカルでの使用専用に構成されています。FTPをパッシブ・モードで使用してサーバーにリモートから接続しようとすると、FTPクライアントに障害が発生します。これはサーバーがIPアドレス127.0.0.1(HOSTNAMEから導出)をクライアントに渡すためで、これによりクライアントはサーバーでなく自分自身に接続しようとしてしまいます。

HTTP(S)およびOracle XML DBプロトコル・サーバーの使用

Oracle XML DBは、RFC2616仕様に定義されているHyperText Transfer Protocol(HTTP)のHTTP 1.1を実装します。

Oracle XML DBプロトコル・サーバー: HTTP(S)機能

Oracle XML DBプロトコル・サーバーのOracle XML DB HTTPコンポーネントは、次のオプション機能を除いて、RFC2616仕様を実装します。

- gzipおよび圧縮転送エンコーディング

- バイト範囲ヘッダー

- TRACEメソッド(プロキシ・エラーのデバッグに使用します。)

- キャッシュ制御ディレクティブ(コンテンツの期限日を指定する必要があります。一般には使用されません。)

- TE、Trailer、VaryおよびWarningヘッダー

- 弱いエンティティ・タグ

- Web共通ログ・フォーマット

- マルチホームWebサーバー

関連項目:
RFC 2616: HTTP 1.1プロトコル仕様: http://www.ietf.org/rfc/rfc2616.txt

サポートされていないHTTP(S)の機能

Digest認証(RFC 2617)はサポートされません。Oracle XML DBはBasic認証をサポートします。この認証では、クライアントが、ユーザー名およびパスワードをAuthorizationヘッダーにクリアテキストで送信します。

サポートされているHTTP(S)クライアント・メソッド

リポジトリにアクセスするために、Oracle XML DBは次のHTTP(S)クライアント・メソッドをサポートしています。

- OPTIONS: 利用できる通信オプションについての情報を取得します。

- GET: 文書/データ(ヘッダーとも)を取得します。

- HEAD: 文書の本文なしで、ヘッダーのみを取得します。

- PUT: データをリソースに格納します。

- DELETE: リソースを削除します。

これらのHTTP(S)メソッドのセマンティクスはWebDAVに従っています。サーブレットとWebサービスは、POSTなどこの他のHTTP(S)メソッドをサポートする場合があります。

関連項目:
WebDAVに関係する、サポートされているHTTP(S)クライアント・メソッドについては「サポートされているWebDAVクライアント・メソッド」

Oracle XML DBのデフォルト・ポートでなく標準ポート上でのHTTP(S)使用

Oracle XML DBの構成ファイル/xdbconfig.xmlを使用して、任意のポートでリスニングするようにHTTP(S)を構成できます。HTTP(S)はデフォルトで、非標準の保護されないポートでリスニングを行います。HTTPまたはHTTPSを標準ポート(HTTPでは80、HTTPSでは443)で使用するには、データベース管理者が次のことを実行する必要があります。

1. (UNIXのみ)このシェル・コマンドを使用して、実行可能ファイルtnslsnrの所有者とグループが必ずrootになるようにします。

% chown root:root $ORACLE_HOME/bin/tnslsnr

2. (UNIXのみ)リスナー・ファイルlistener.oraに次のエントリを追加します。ここで、hostnameは使用するホスト名、port_numberは、HTTPでは80、HTTPSでは443です。

(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP) (HOST = hostname) (PORT = port_number))
(PROTOCOL_STACK = (PRESENTATION = HTTP) (SESSION = RAW)))

3. (UNIXのみ)シェル・コマンドidを使用して、Oracle Databaseのインストールに使用されたuser_idおよびgroup_idを特定します。oracle_installation_userは、データベースをインストールしたユーザーの名前です。

% id oracle_installation_user
uid=user_id(oracle_installation_user) gid=group_id(dba)

4. (UNIXのみ)次のシェル・コマンドを使用して、リスナーを停止して再起動します。ここで、user_idおよびgroup_idは、手順3で取得したUNIXユーザー識別子およびグループ識別子です。

% lsnrctl stop
% tnslsnr LISTENER -user user_id -group group_id &

2番目のコマンドをバックグラウンドで実行するにはアンパサンド(&)を使用します。リスナーを起動するためにlsnrctl startを使用しないでください。

5. 次のようにSYS as SYSDBAでPL/SQLプロシージャDBMS_XDB.sethtpportを使用して、Oracle XML DB構成ファイル/xdbconfig.xmlでHTTP(S)ポート番号をport_numberに設定します。ここでport_numberは、80(HTTP)または443(HTTPS)です。

SQL> exec DBMS_XDB.setHTTPPort(port_number);

6. 次のSQL文を使用してデータベースが必ずリスナーとともに登録されるようにします。

SQL> ALTER SYSTEM REGISTER;

7. リスナーが正しく構成されていることを確認します。

% lsnrctl status

関連項目:

- リスナーのパラメータおよびファイルlistener.oraの詳細は『Oracle Database Net Servicesリファレンス』を参照してください。

- 特権ポートの詳細は『Oracle Database Net Servicesリファレンス』の、ポート番号の制限に関する項を参照してください。

HTTP(S)でのIPv6 IPアドレスの使用

11gリリース2(11.2)以上のOracle Databaseでは、(Internet Protocol Version 4に加えて)Internet Protocol Version 6(IPv6)がサポートされています。URL内のIPv6アドレスは、大カッコ([])で囲みます。次に例を示します。

http://[2001::0db8:ffff:ffff:ffff]:8080/

関連項目:
IPv6の詳細は、『Oracle Database Net Servicesリファレンス』を参照してください。

HTTPS: セキュアHTTPのサポート

正しく構成すれば、Oracle XML DBリポジトリにHTTPSを使用してセキュアにアクセスできます。構成情報については「セキュアHTTP(HTTPS)の構成」を参照してください。

注意:
Oracle DatabaseをMicrosoft Windows XP Service Pack 2 (SP2)にインストールしている場合、Oracle XML DBリポジトリへのWebDAVアクセスには、HTTPSを使用するか、Windows XPのレジストリを適切に変更する必要があります。レジストリ変更に関する情報は、http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2netwk.mspx#XSLTsection129121120120を参照してください。

URL期限切れ時間の制御

オプションの構成パラメータexpireでは、HTTP Expiresヘッダーを指定します。このヘッダーは、HTTPクライアントへのディレクティブとして機能し、URLの期限切れ日時を指定します。

URLのターゲット文書は、キャッシュされている場合、この期限切れ日時が経過するまで、サーバーからでなくクライアント・キャッシュからフェッチできます。この日時を過ぎると、キャッシュ・コピーは期限切れとなり、ソース(サーバー)から新しいコピーを取得する必要があります。

expire構成要素で使用されるExpiresヘッダー用のThe Oracle XML DB構文は、 Apacheモジュールmod_expiresのExpiresDefaultディレクティブ用に定義されている代替構文のサブセットです。この構文の詳細は、http://httpd.apache.org/docs/2.0/mod/mod_expires.html#AltSynを参照してください。

Oracle XML DBでは、ExpiresDefault構文に対して次の制限があります。

- <base>としてaccessを使用できません。nowおよびmodificationのみ使用が許可されます。

- <type>値は、期間の経過順に指定する必要があります。たとえば、1年は1か月よりも期間が長いため、yearはmonthの後ろではなく、前に指定する必要があります。

- 異なる<type>値は、それぞれ最大1回使用できます。たとえば、複数のyearエントリや複数のdayを指定することはできません。

HTTPを使用したOracle XML DBリポジトリへの匿名アクセス

オプションの構成パラメータallow-repository-anonymous-accessは、ロック解除されたANONYMOUSユーザー・アカウントを使用した、Oracle XML DBリポジトリ・データへの匿名HTTPアクセスが許容されるかどうかを示します。デフォルト値はfalseで、これはリポジトリ・データへの非認証アクセスがブロックされることを意味します。リポジトリへのHTTPアクセスを許可するには、このパラメータをtrueに設置して、ANONYMOUSユーザー・アカウントをロック解除する必要があります。

注意:
リポジトリへの匿名アクセスを許可することには、潜在的なセキュリティ・リスクがあります。

パラメータallow-repository-anonymous-accessは、サーブレットを使用したリポジトリへの匿名アクセスは制御しません。各サーブレットには、アクセスを制御する独自のsecurity-role-refパラメータ値があります。

関連項目:

- パラメータallow-repository-anonymous-accessの詳細は、表28-3を参照してください。

- Oracle XML DBパラメータ構成の詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください。

- パラメータsecurity-role-refの詳細は、「Oracle XML DBサーブレットの構成」を参照してください。

JavaサーブレットでのHTTP(S)

Oracle XMLL DBは、Javaサーブレットをサポートします。Javaサーブレットを使用するには、その動作をカスタマイズするパラメータとともに、Oracle XML DBの構成ファイルに一意の名前で登録する必要があります。それをコンパイルして、データベースにロードする必要があります。最後に、そのサーブレット名をパターンに関連付ける必要があります。このパターンは、JavaサーブレットApplication Program Interface (API)バージョン2.2に記述されているとおり、*.jspなどの拡張子または/a/b/cや/sys/*などのパス名になります。

HTTP(S)リクエストの処理中、そのリクエストに対するパス名は登録済のパターンと一致します。一致する場合、プロトコル・サーバーは適切な初期化パラメータを使用して対応するサーブレットを起動します。Javaサーブレットの場合、既存のJava仮想マシン(JVM)インフラストラクチャが使用されます。これによって、必要に応じてJVMが起動され、Javaメソッドが起動されて、サーブレットの初期化、レスポンスの作成、オブジェクトのリクエストが実行され、それらがサーブレットに渡されて実行されます。

関連項目:
第32章「JavaでのOracle XML DBアプリケーションの作成」

埋込みPL/SQLゲートウェイ

PL/SQLゲートウェイを使用して、WebアプリケーションをPL/SQLに完全に実装できます。PL/SQLゲートウェイには2種類の実装があります。

- mod_plsql: HTTP(S)を使用してPL/SQLストアド・プロシージャを起動できる、Oracle HTTP Serverのプラグインです。Oracle HTTP Serverは、Oracle Application ServerおよびOracle Databaseのコンポーネントです。Oracle HTTP ServerとOracle XML DBプロトコル・サーバーのHTTPコンポーネントとは混同しないでください。

- 埋込みPL/SQLゲートウェイ: Oracle XML DB HTTPリスナーで実行されるゲートウェイの実装です。

PL/SQLゲートウェイ(どちらか一方の実装)を使用して、ストアド・プロシージャを識別し、それにパラメータ値を与えるURL形式で、WebブラウザからHTTP(S)リクエストが送信されます。ゲートウェイはURLを変換し、ストアド・プロシージャをパラメータ値とともに呼び出し、出力(通常はHTML)をWebブラウザ・クライアントに戻します。

埋込みPL/SQLゲートウェイを使用すると、PL/SQLベースのWebアプリケーションのインストール、構成、および管理が簡略化されます。埋込みゲートウェイは、Oracle HTTP ServerではなくOracle XML DBプロトコル・サーバーを使用します。構成は、Oracle XML DBの構成ファイル/xdbconfig.xmlで定義されます。しかし、埋込みゲートウェイを構成する方法として、/xdbconfig.xmlファイルを編集するのではなく、PL/SQLパッケージDBMS_EPGのプロシージャを使用することをお薦めします。

関連項目:

- 埋込みPL/SQLゲートウェイの構成と使用方法の詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

- xdbconfig.xmlでの埋込みゲートウェイの構成定義の詳細は、第34章「Oracle XML DBの管理」を参照してください。

- PL/SQLゲートウェイの使用に関する概念的な情報は、『Oracle Fusion Middleware Oracle HTTP Server管理者ガイド』を参照してください。

- mod_plsqlの詳細は、『Oracle HTTP Server mod_plsqlユーザーズ・ガイド』を参照してください。

クライアントからのマルチバイト・データの送信

クライアントがURLにマルチバイト・データを含めて送信する場合、RFC 2718では、クライアントが%HHフォーマット(HHはUTF-8エンコーディングでのそのバイト値の16進文字列)を使用してURLを送信する必要があることが規定されています。次に、HTTP(S)またはWebDAVコンテキストでOracle XML DBに送信可能なURLの例を示します。

http://urltest/xyz%E3%81%82%E3%82%A2
http://%E3%81%82%E3%82%A2
http://%E3%81%82%E3%82%A2/abc%E3%81%86%E3%83%8F.xml

Oracle XML DBは、リクエストされたURL、IFヘッダー内のすべてのURL、DESTINATIONヘッダー内のすべてのURL、およびマルチバイト・データを含むREFERREDヘッダー内のすべてのURLを処理します。

default-url-charset構成パラメータを使用すると、ASCII以外の文字を含む、非準拠形式のURLを使用したクライアントからのリクエストも受け入れることができます。そうした文字を含むリクエストが失敗する場合は、この値をクライアント環境のネイティブなキャラクタ・セットに設定してみます。このようなURLフィールドで使用されるキャラクタ・セットは、IANAキャラクタ・セット名で指定する必要があります。

default-url-charsetは、表記方法に従っていないURLのエンコーディングを制御します。Content-Typeのキャラクタ・セットを送信しない表記方法に従っていないクライアントが使用されていないかぎり、このパラメータを設定する必要はありません。

関連項目:

- RFC 2616: HTTP 1.1プロトコル仕様: http://www.ietf.org/rfc/rfc2616.txt

- Oracle XML DBパラメータ構成の詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください。

URL内の非ASCII文字

HTTPサーバーに渡されるURLにASCII以外の文字が含まれている場合は、UTF-8に変換し、%HHフォーマットでエスケープする必要があります。HHは、バイト値の16進文字列です。柔軟性を得るために、Oracle XML DBプロトコル・サーバーは、受信URLを解析するときに、そのURLが次のいずれかのキャラクタ・セットでエンコードされているかどうかを、記載されている順序どおりにテストします。

- UTF-8

- リクエストのContent-TypeフィールドのCharsetパラメータ(指定されている場合)

- default-url-charset構成パラメータのキャラクタ・セット(指定されている場合)

- データベースのキャラクタ・セット

関連項目:
Oracle XML DBパラメータ構成の詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください。

HTTP(S)のキャラクタ・セットの制御

次の項では、HTTP(S)を使用して転送されるデータのキャラクタ・セットの制御方法について説明します。

リクエストのキャラクタ・セット

HTTP(S) Request Bodyのキャラクタ・セットは、次のアルゴリズムを使用して決定されます。

- Content-Typeヘッダーを評価します。Content-Typeヘッダーにcharset値が指定されている場合は、指定されたcharsetを使用します。

- ドキュメントのMIMEタイプを次のように評価します。

- MIMEタイプが*/xmlの場合、キャラクタ・セットは次のように決定されます。
- BOMが存在する場合は、UTF-16を使用します。

- エンコーディング宣言が存在する場合は、指定されたエンコーディングを使用します。

- BOMもエンコーディング宣言も存在しない場合は、UTF-8を使用します。

- MIMEタイプがテキストの場合は、ISO8859-1を使用します。

- MIMEタイプが、*/xmlでもtextでもない場合は、データベース・キャラクタ・セットを使用します。

HTTP(S)とSQL間またはHTTP(S)とFTP間では処理が異なります。テキスト・ドキュメントの場合、IETF.org RFC 2616: HTTP 1.1プロトコル仕様で指定されているとおり、デフォルトはISO8859-1です。

レスポンスのキャラクタ・セット

Oracle XML DB HTTP Serverで生成されるレスポンスは、リクエストのAccept-Charsetフィールドに指定されているキャラクタ・セットです。Accept-Charsetには、キャラクタ・セットのリストを指定できます。Oracle XML DBは、q値に基づいて、変換が不要なキャラクタ・セットを選択します。選択されるキャラクタ・セットが、最大のq値を持つキャラクタ・セットではない場合があります。変換が不要なキャラクタ・セットが見つからない場合、Oracle XML DBは、最大のq値に基づいて変換を行います。

WebDAVおよびOracle XML DBの使用

Web Distributed Authoring and Versioning(WebDAV)は、ユーザーに、インターネット上でOracle XML Repositoryへのファイル・システム・インタフェースを提供するために使用されるIETF標準のプロトコルです。WebDAVサーバー・フォルダにアクセスする最も一般的な方法は、Microsoft Windowsを使用して「Webフォルダ」を使用する方法です。

WebDAVはHTTP 1.1プロトコルの拡張で、HTTPサーバーをファイル・サーバーとして使用することを可能にします。WebDAVを使用すると、クライアントは、メソッド、ヘッダー、Request BodyフォーマットおよびResponse Bodyフォーマットの一貫したセットを介して、リモートWebコンテンツのオーサリングを実行できます。たとえば、DAV対応のエディタは、ファイル・システムとまったく同様にHTTP/WebDAVサーバーと対話できます。WebDAVは、リソースの格納および取出し、リソース・コレクションのコンテンツの作成およびリスト、同時アクセスに対するリソースの調整式ロックおよびリソース・プロパティの設定および取出しを行う操作を提供します。

Oracle XML DB WebDAVの機能

Oracle XML DBは、次のWebDAV機能をサポートします。

- フォルダリング(RFC2518で指定済)

- アクセス制御

WebDAVは、HTTP(S)プロトコルへの拡張機能のセットで、リモートWebサーバーのファイルを編集または管理できます。たとえば、WebDAVを使用して、次の操作を実行できます。

- インターネット上でのドキュメントの共有

- インターネット上でのコンテンツの編集

関連項目:
RFC 2518: WebDAVプロトコル仕様: http://www.ietf.org/rfc/rfc2518.txt

サポートされていないWebDAVの機能

Oracle XML DBは、RFC2518の内容をサポートしますが、次の例外があります。

- ロックNULLリソースは、長さが0(ゼロ)のリソースをファイル・システムに作成します。ロックNULLリソースは、フォルダには変換できません。

- COPY、MOVEおよびDELETEの各メソッドは、インターネット・ドラフト「Binding Extensions to WebDAV」の第2項に準拠しています。

- 無限の深さのロックはサポートされません。

- Basic認証のみサポートされます。

サポートされているWebDAVクライアント・メソッド

リポジトリにアクセスするために、Oracle XML DBは次のHTTP(S)/WebDAVクライアント・メソッドをサポートしています。

- PROPFIND(WebDAV固有): リソースのプロパティを取得します。

- PROPPATCH(WebDAV固有): リソースのプロパティを設定または削除します。

- LOCK(WebDAV固有): リソースをロックします(ロックの作成またはリフレッシュ)。

- UNLOCK(WebDAV固有): リソースをロック解除します(ロックの削除)。

- COPY(WebDAV固有): リソースをコピーします。

- MOVE(WebDAV固有): リソースを移動します。

- MKCOL(WebDAV固有): フォルダ・リソース(コレクション)を作成します。

関連項目:

- HTTP(S)クライアント・メソッドの詳細は、「サポートされているHTTP(S)クライアント・メソッド」を参照してください。

- WebDAV権限の詳細は、「権限」 を参照してください。

- 「WebDAV PROPPATCHを使用したメタデータの追加」

Microsoft Windows XP SP2でのWebDAVの使用

Oracle DatabaseをMicrosoft Windows XPService Pack 2 (SP2)にインストールしている場合、Oracle XML DBリポジトリへのWebDAVアクセスには、セキュアな接続(HTTPS)を使用するか、Windows XPのレジストリを適切に変更する必要があります。

関連項目:

- Windows XPのレジストリに加える必要な変更の詳細は、http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2netwk.mspx#XSLTsection129121120120を参照してください。

- 「セキュアHTTP(HTTPS)の構成」

Oracle XML DBおよびWebDAVを使用したMicrosoft WindowsでのWebフォルダの作成

Windows 2000でWebフォルダを作成するには、次の手順を実行します。

1. 「スタート」→「マイ ネットワーク」を選択します。

2. 「ネットワーク プレースの追加」をダブルクリックします。

3. 「次へ」をクリックします。

4. フォルダの場所を入力します。次に例を示します。

http://Oracle_server_name:HTTP_port_number

図28-2を参照してください。

5. 「次へ」をクリックします。

6. このWebフォルダを識別する任意の名前を入力します。

7. 「完了」をクリックします。

これで、Windowsフォルダへのアクセスと同様に、Oracle XML DBリポジトリにアクセスできます。

図28-2 Microsoft WindowsでのWebフォルダの作成

脚注の凡例

脚注1: BOMとは、後続のバイト・ストリームの順序を示すUnicode標準のシグネチャです。

29 ユーザー定義のリポジトリ・メタデータ

この章では、XMLデータと関連付けてOracle XML DBリポジトリに格納するXMLメタデータの作成と使用について説明します。

この章の内容は次のとおりです。

- メタデータとXMLの概要

- XML Schemaによるリソース・メタデータの定義

- リソース・メタデータの追加、更新、削除

- XML Schemaに基づくリソース・メタデータの問合せ

- バイナリ・イメージ・メタデータからのXMLイメージ・メタデータ

- XML Schemaに基づかないリソース・メタデータの追加

- リソース・メタデータに影響するPL/SQLプロシージャ

メタデータとXMLの概要

使用するデータが、コンテンツの一部ではない追加情報に関連付けられていることがよくあります。データを様々な方法で処理するには、この種のメタデータをデータのグループ化や分類に使用します。たとえば、多数の写真に対して、カラー合成、焦点長などの写真の特性や、場所、被写体の種類(風景か人物か)などの付随情報といったメタデータをそれぞれの写真に関連付けたい場合があります。

Oracle XML DBリポジトリのリソースは、メタデータとデータの両方を含むXML文書です。データは、要素Contentsのコンテンツです。リソース内の他のすべての要素にはメタデータが含まれます。リソースのデータはXMLでなくてもかまいません。

Oracle XML DBリポジトリを、ユーザーが定義したメタデータに関連付けることができます。こうしたユーザー定義のメタデータの他に、各リポジトリ・リソースにも、Oracle XML DBにより自動作成され、リソース管理に(透過的に)使用されている関連のメタデータがあります。こうしたシステム定義のメタデータには、各リソースの所有者や作成日などのプロパティが含まれています。

システム定義のメタデータを除き、リソース情報のいずれをデータ、いずれをメタデータとみなすかはユーザーの判断です。写真リソースの場合、写真に関する付随情報は通常、バイナリ・イメージである写真データの一部とはみなされません。しかしテキストの場合は、特定の情報をリソースのコンテンツ(データ)に含めるか、別扱いにして、メタデータとしてコンテンツに関連付けるかを選択できる場合があります。こうした選択は、多くの場合、データを使用または作成するアプリケーションに左右されます。

メタデータの種類 - 用語の用法

リソース・メタデータ(システム定義またはユーザー定義)の他に、「メタデータ」という語は次のものを指すことがあります。

- XML Schemaは、XML文書のクラスを示すメタデータです。

- XMLタグ(要素名または属性名)は、要素のコンテンツや属性値に名前を付けたり整理したりするのに使用されるメタデータです。

次のようにして、メタデータをリポジトリ・リソースのコンテンツであるXML文書に関連付けることができます。

- メタデータ情報を含む追加のXML要素をリソースのコンテンツに追加することができます。たとえば、デジタル・イメージ・データを、写真に関する説明を要素として含むXML文書の中に入れることもできます。この場合、データとそのメタデータは、同じリソースのコンテンツであることによって関連付けられています。それらを分離したり、正しく関連させたりする処理はアプリケーションが担当します。

- 特定のリソースのメタデータをリポジトリに、別のリソースのコンテンツとして追加することもできます。この場合、このリソースをメタデータとして処理し、データに関連付けるのはアプリケーションが担当します。

- リソースのメタデータ情報を、リポジトリのリソース・メタデータとして追加できます。この場合、Oracle XML DBはメタデータをそのままの形で認識します。アプリケーションは、リポジトリに問い合せることによってこのメタデータを検出します。アプリケーションは、メタデータが存在するかどうかや、データとの関連付けについて独自に知っている必要はありません。

関連項目:
「Oracle XML DBリポジトリ・リソース」

ユーザー定義のリソース・メタデータ

これらの様々なメタデータ処理の方法のうち、この章では、上で最後にあげた、ユーザー定義のリソース・メタデータについて説明します。こうしたメタデータは、それ自身XMLで表現されています。他のXMLデータに関連付けられたXMLデータであり、その説明や、補足情報、関連情報を提供します。

リソースのユーザー定義のメタデータはXML Schemaに基づいている場合も、そうでない場合もあります。

- XML Schemaに基づくリソース・メタデータは別個の(オンラインでない)表に格納されます。これらはリソースOIDによってリソース表に関連付けられており、メタデータ表の非表示のオブジェクト列RESIDに格納されます。

- XML Schemaに基づかないリソース・メタデータはリソース表のCLOB列に格納されます。

XML Schemaに基づくメタデータは、リソースに対して問合せやDML操作を効率的に実行する際に有効です。この章では、XML Schemaに基づくリソース・メタデータに関する次のタスクの実行方法を説明します。

- 特定の種類のリソースに対してメタデータを定義するXML Schemaの作成と登録。

- リポジトリ・リソースへのメタデータの追加とその更新(変更)。

- 関連付けられているコンテンツを検索するためのリソース・メタデータの問合せ。

- リソースに関連付けられているメタデータの削除と、リソースに関連付けられているすべてのメタデータの消去。

この他、XML Schemaに基づかないメタデータをリソースに追加する方法も説明します。

一般に、ユーザー定義のリソース・メタデータはリソース・データを使用する場合と同様に使用できます。バージョニングとアクセス制御については特にそれが成り立ちます。

リソース・メタデータの典型的な使用方法には、ワークフロー・アプリケーション、ユーザー権限の強制管理、リソース所有権の追跡、リソース有効期間の管理などがあります。

シナリオ: 写真コレクションのメタデータ

XML Schemaに基づくリソース・メタデータの使用方法を説明するために、この章ではリポジトリ・リソースに格納されている写真のイメージ・ファイルに関連付けられているメタデータを取り上げます。必要なだけ多くの種類のメタデータを作成して、同じリソースに関連付けることができます。イメージ・ファイルの例では、(1)写真の技術的な側面、および(2)写真のテーマや用途に関する情報のメタデータを作成します。この2種類の関連メタデータを使用して写真リソースを問い合せます。

XML Schemaによるリソース・メタデータの定義

この項では、まず各写真に関連付けるメタデータをXML Schemaを使用して定義します。それぞれのメタデータの種類(技術、カテゴリ)について、XML Schemaを作成して登録します。

例29-1のXML Schemaは、写真イメージ・ファイルの技術的側面を記述するのに使用するメタデータを定義します。ここではPL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaを使用してXML Schemaを登録します。このスキーマをリポジトリ・リソース・メタデータを定義するものとして識別するためには、enableHierarchyパラメータの値にENABLE_HIERARCHY_RESMETADATAを使用します。リソースのコンテンツ(データ)は、かわりに値ENABLE_HIERARCHY_CONTENTS(デフォルト値)を使用して定義します。

例29-1で定義するプロパティは、イメージの高さ、幅、色深度、タイトル、および簡単な説明です。

例29-1 写真の技術情報を扱うXML Schemaの登録

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL       => 'imagetechnique.xsd',
SCHEMADOC       => '<xsd:schema targetNamespace="inamespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
xmlns="inamespace">
<xsd:element name="ImgTechMetadata"
xdb:defaultTable="IMGTECHMETADATATABLE">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Height"      type="xsd:float"/>
<xsd:element name="Width"       type="xsd:float"/>
<xsd:element name="ColorDepth"  type="xsd:integer"/>
<xsd:element name="Title"       type="xsd:string"/>
<xsd:element name="Description" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>',
enableHierarchy => DBMS_XMLSCHEMA.ENABLE_HIERARCHY_RESMETADATA);
END;
/

例29-2のXML Schemaは写真イメージ・ファイルの分類に使用するメタデータを定義します。この簡単な例では、分類用のCategoryという名前の、単一の汎用プロパティを定義します。

例29-2 写真のカテゴリを扱うXML Schemaの登録

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL       => 'imagecategories.xsd',
SCHEMADOC       => '<xsd:schema targetNamespace="cnamespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
xmlns="cnamespace">
<xsd:element name="ImgCatMetadata"
xdb:defaultTable="IMGCATMETADATATABLE">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Categories"
type="CategoriesType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="CategoriesType">
<xsd:sequence>
<xsd:element name="Category" type="xsd:string"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>',
enableHierarchy => DBMS_XMLSCHEMA.ENABLE_HIERARCHY_RESMETADATA);
END;
/

メタデータのXML Schema定義には、その情報を任意の特定の種類のデータへの関連付けに制限するものはないということに注意してください。任意の型のメタデータを任意の型のリソースに、自由に関連付けできます。同一のリソースに複数の型のメタデータを関連付けることもできます。

また、XML Schemaは、それ自身では、関連付けられているデータをメタデータであると定義してはいません。そうした特徴付けは、enableHierarchyの値ENABLE_HIERARCHY_RESMETADATAを介するスキーマ登録によって行われます。enableHierarchyの値ENABLE_HIERARCHY_CONTENTS(デフォルト値)に同じスキーマが登録されると、リソースに対応するメタデータでなく、同じ情報を持つリソース・コンテンツが定義されます。同一のXML Schemaを、同じ名前で複数回登録することはできません。

注意:
XML Schemaに基づいたユーザー定義メタデータは、デフォルトではCLOBとして格納されます。また、XML Schema登録のためのOPTIONSパラメータをREGISTER_BINARYXMLに設定することにより、これをバイナリXMLとして格納できます。

リソース・メタデータの追加、更新、削除

ユーザー定義のリソース・メタデータの追加、更新、および削除は、次の方法で行うことができます。

- パッケージDBMS_XDB内のPL/SQLプロシージャの使用

- appendResourceMetadata - リソースへのメタデータの追加

- updateResourceMetadata - リソース・メタデータの変更

- deleteResourceMetadata - リソースからの特定のメタデータの削除

- purgeResourceMetadata – すべてのメタデータのリソースからの削除

- SQL DML文INSERT、UPDATE、およびDELETEの使用による、直接的なリソースの更新

- WebDAVプロトコル・メソッドPROPPATCHの使用

メタデータの追加と同じ方法でメタデータを更新または削除するには、SQL DM文とWebDAVメソッドPROPPATCHを使用します。これらの操作のいずれかで、完全なResource要素を指定する場合は、それぞれのリソース・メタデータのプロパティがResource要素の(ただの子孫でなく)子でなければいけないことに注意してください。同じ種類のメタデータ要素を複数使用する場合、それらを1つの親メタデータ要素の子として収集する必要があります。こうした最上位のユーザー定義では、リソース・メタデータ・プロパティの順序は重要ではなく、Oracle XML DBにおいても必ずしも維持されません。

パッケージDBMS_XDB内の各種PL/SQLプロシージャの使用方法はよく似ています。いずれも、XML Schemaに基づいている、またはXML Schemaに基づかないメタデータとともに使用できます。一部のプロシージャのいくつかの形式(シグネチャ)は、XML Schemaに基づくメタデータにのみ適用されます。ここでは、プロシージャappendResourceMetadataおよびdeleteResourceMetadataについて、例を使用して説明します。

関連項目:
PL/SQLパッケージDBMS_XDBのプロシージャは、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

APPENDRESOURCEMETADATAを使用したメタデータの追加

プロシージャDBMS_XDB.appendResourceMetadataを使用して、ユーザー定義のメタデータをリソースに追加できます。

例29-3では、写真リソースを作成し、型がImgTechMetadataの、XML Schemaに基づくメタデータを追加することにより、写真に関する技術情報を記録しています。

例29-3 メタデータのリソースへの追加 - 写真の技術情報

DECLARE
returnbool BOOLEAN;
BEGIN
returnbool := DBMS_XDB.createResource(
'/public/horse_with_pig.jpg',
bfilename('MYDIR', 'horse_with_pig.jpg'));
DBMS_XDB.appendResourceMetadata(
'/public/horse_with_pig.jpg',
XMLType('<i:ImgTechMetadata
xmlns:i="inamespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="inamespace imagetechnique.xsd">
<Height>1024</Height>
<Width>768</Width>
<ColorDepth>24</ColorDepth>
<Title>Pig Riding Horse</Title>
<Description>Picture of a pig riding a horse on the beach,
taken outside hotel window.</Description>
</i:ImgTechMetadata>'));
END;
/

例29-4では、型がImgTechMetadataのメタデータを例29-3と同じリソースに追加することにより、写真をいずれかのユーザー定義のコンテンツ・カテゴリに分類しています。

例29-4 メタデータのリソースへの追加 - 写真のコンテンツ・カテゴリ

BEGIN
DBMS_XDB.appendResourceMetadata(
'/public/horse_with_pig.jpg',
XMLType('<c:ImgCatMetadata
xmlns:c="cnamespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="cnamespace imagecategories.xsd">
<Categories>
<Category>Vacation</Category>
<Category>Animals</Category>
<Category>Humor</Category>
<Category>2005</Category>
</Categories>
</c:ImgCatMetadata>'));
END;
/

PL/SQL procedure successfully completed.

SELECT * FROM imgcatmetadatatable;

SYS_NC_ROWINFO$
--------------------------------------------------------------------------------
<c:ImgCatMetadata xmlns:c="cnamespace" xmlns:xsi="http://www.w3.org/2001/XMLSche
ma-instance" xsi:schemaLocation="cnamespace imagecategories.xsd">
<Categories>
<Category>Vacation</Category>
<Category>Animals</Category>
<Category>Humor</Category>
<Category>2005</Category>
</Categories>
</c:ImgCatMetadata>

1 row selected.

DELETERESOURCEMETADATAを使用したメタデータの削除

プロシージャDBMS_XDB.deleteResourceMetadataを使用して、リソースに関連付けられている特定のメタデータを削除できます。あるリソースに関連付けられているメタデータをすべて削除するには、プロシージャDBMS_XDB.purgeResourceMetadataを使用します。

例29-5では、例29-4で写真リソースに追加されたカテゴリ・メタデータを削除しています。デフォルトでは、メタデータへのリソース・リンク(REF)と、そのリンクにより識別されるメタデータ表の両方が削除されます。リンクのみを削除するように指定するオプションのパラメータを使用できます。その場合、メタデータ表はそのまま残りますが、リソースへの関連性はなくなります。この例では、デフォルトの動作が使用されています。

例29-5 リソースからの特定のメタデータの削除

BEGIN
DBMS_XDB.deleteResourceMetadata('/public/horse_with_pig.jpg',
'cnamespace',
'ImgCatMetadata');
END;
/

PL/SQL procedure successfully completed.

SELECT * FROM imgcatmetadatatable;

no rows selected

SQL DMLを使用したメタデータの追加

プロシージャDBMS_XDB.appendResourceMetadataを使用せずにリソース・メタデータ表を追加、更新、および削除するには、DML文INSERTおよびUPDATEを使用してRESOURCE_VIEWを更新します。

この方法によるリソース・メタデータの追加を例29-6で説明します。この例は、SQL文UPDATEを使用して、メタデータを直接RESOURCE_VIEWに挿入することにより、例29-3と同じことを実行する方法を示しています。他のSQL DML文も同様に使用できます。

例29-6 RESOURCE_VIEWでのDMLの使用によるリソースへのメタデータの追加

UPDATE RESOURCE_VIEW
SET RES =
insertChildXML(
RES,
'/r:Resource',
'c:ImgCatMetadata',
XMLType('<c:ImgCatMetadata
xmlns:c="cnamespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="cnamespace imagecategories.xsd">
<Categories>
<Category>Vacation</Category>
<Category>Animals</Category>
<Category>Humor</Category>
<Category>2005</Category>
</Categories>
</c:ImgCatMetadata>'),
'xmlns:r="http://xmlns.oracle.com/xdb/XDBResource.xsd"
xmlns:c="cnamespace"')
WHERE equals_path(RES, '/public/horse_with_pig.jpg') = 1;
/

SELECT * FROM imgcatmetadatatable;

SYS_NC_ROWINFO$
--------------------------------------------------------------------------------
<c:ImgCatMetadata xmlns:c="cnamespace" xmlns:xsi="http://www.w3.org/2001/XMLSche
ma-instance" xsi:schemaLocation="cnamespace imagecategories.xsd">
<Categories>
<Category>Vacation</Category>
<Category>Animals</Category>
<Category>Humor</Category>
<Category>2005</Category>
</Categories>
</c:ImgCatMetadata>

1 row selected.

次の問合せは、メタデータ表imgcatmetadatatableを直接指定してではなく、RESOURCE_VIEWを使用して挿入したメタデータを抽出します。(ここではわかりやすいように、この結果をフォーマット出力しています。)

SELECT XMLQuery('declare namespace r
= "http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
declare namespace c
= "cnamespace"; (: :)
/r:Resource/c:ImgCatMetadata'
PASSING RES RETURNING CONTENT)
FROM RESOURCE_VIEW
WHERE equals_path(RES, '/public/horse_with_pig.jpg') = 1;

XMLQUERY('DECLARENAMESPACER="HTTP://XMLNS.ORACLE.COM/XDB/XDBRESOURCE.XSD";(::)DE
--------------------------------------------------------------------------------
<c:ImgCatMetadata xmlns:c="cnamespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="cnamespace imagecategories.xsd">
<Categories>
<Category>Vacation</Category>
<Category>Animals</Category>
<Category>Humor</Category>
<Category>2005</Category>
</Categories>
</c:ImgCatMetadata>

1 row selected.

WebDAV PROPPATCHを使用したメタデータの追加

プロシージャDBMS_XDB.appendResourceMetadataを使用せずにリソース・メタデータを追加する他の方法は、WebDAVのPROPPATCHメソッドを使用する方法です。例29-7で説明します。同様にメタデータを更新および削除できます。

例29-7は、WebDAVメソッドPROPPATCHを使用してメタデータを挿入することにより、例29-4と同じことを実行する方法を示しています。適切なツールを使用することで、アプリケーションでこの種のPROPPATCH WebDAVリクエストを作成し、WebDAVサーバーに送信して処理させることができます。

ユーザー定義のメタデータを更新する場合も同様です。ユーザー定義のメタデータを削除する場合も同様のWebDAVリクエストを使用しますが、D:setをD:removeに置き換えます。

例29-7 WebDAV PROPPATCHによるメタデータの追加

PROPPATCH /public/horse_with_pig.jpg HTTP/1.1
Host: www.example.com
Content-Type: text/xml; charset="utf-8"
Content-Length: 609
Authorization: Basic dGRhZHhkYl9tZXRhOnRkYWR4ZGJfbWV0YQ==
Connection: close

<?xml version="1.0" encoding="utf-8" ?>
<D:propertyupdate xmlns:D="DAV:" xmlns:Z="http://www.w3.com/standards/z39.50/">
<D:set>
<D:prop>
<c:ImgCatMetadata
xmlns:c="cnamespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="cnamespace imagecategories.xsd">
<Categories>
<Category>Vacation</Category>
<Category>Animals</Category>
<Category>Humor</Category>
<Category>2005</Category>
</Categories>
</c:ImgCatMetadata>
</D:prop>
</D:set>
</D:propertyupdate>

XML Schemaに基づくリソース・メタデータの問合せ

enableHierarchy値ENABLE_HIERARCHY_RESMETADATAを使用してXML Schemaを登録する場合、追加の列RESIDが、メタデータの格納に使用されるXMLType表に自動的に追加されます。この列には、メタデータに関連付けられているリソースのオブジェクト識別子(OID)が格納されます。メタデータを問い合せる際に、列RESIDを使用して、メタデータを関連のデータに結合することができます。

メタデータを問い合せる方法には次のようなものがあります。

- RESOURCE_VIEWにメタデータを問い合せます。次に例を示します。

SELECT count(*) FROM RESOURCE_VIEW
WHERE
XMLExists(
'declare namespace r
= "http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
declare namespace c
= "cnamespace"; (: :)
/r:Resource/c:ImgCatMetadata/Categories/Category[text()="Vacation"]'
PASSING RES);

COUNT(*)
----------
1

1 row selected.

- XML Schemaに基づく表に対してユーザー定義のメタデータを直接問い合せ、そのメタデータをリソース表に結合し、選択するリソースを識別します。その場合は、メタデータ表のRESID列を使用します。次に例を示します。

SELECT COUNT(*) FROM RESOURCE_VIEW rs, imgcatmetadatatable ct
WHERE
XMLExists(
'declare namespace r
= "http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
declare namespace c
= "cnamespace"; (: :)
/r:Resource/c:ImgCatMetadata/Categories/Category'
PASSING RES)
AND rs.RESID = ct.RESID;

COUNT(*)
----------
1

1 row selected.

パフォーマンス向上のため、ユーザー定義のメタデータの直接問合せをお薦めします。RESOURCE_VIEWに対する直接の問合せは、XPathリライトの使用により単独で最適化することはできません。これは、Categoryなどのターゲット要素がCLOB値に格納されているか、オフラインの表に格納されているかを判断する方法がないためです。

パフォーマンスをさらに向上させるには、問合せ対象の各メタデータ列に索引を作成します。

例29-8は、両方の種類の写真リソース・メタデータに対して問合せを行い、休暇の写真(Vacation Photos)に分類されている、タイトルが「Pig Riding Horse」のリソースへのパスを取得します。

例29-8 XML Schemaに基づくリソース・メタデータの問合せ

SELECT ANY_PATH
FROM RESOURCE_VIEW rs, imgcatmetadatatable ct, imgtechmetadatatable tt
WHERE XMLExists(
'declare namespace r
= "http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
declare namespace c
= "cnamespace"; (: :)
/r:Resource/c:ImgCatMetadata/Categories/Category[text()="Vacation"]'
PASSING RES)
AND XMLExists(
'declare namespace r
= "http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
declare namespace i
= "inamespace"; (: :)
/r:Resource/i:ImgTechMetadata/Title[text()="Pig Riding Horse"]'
PASSING RES)
AND rs.RESID = ct.RESID
AND rs.RESID = tt.RESID;

ANY_PATH
--------------------------
/public/horse_with_pig.jpg

1 row selected.

バイナリ・イメージ・メタデータからのXMLイメージ・メタデータ

この章の前の項では、イメージの技術メタデータを定義する、単純なユーザー定義のXML Schema、imagetechnique.xsdを使用して、リポジトリ・リソース・メタデータの追加と変更の方法を説明しました。この単純なXML Schemaは、写真イメージの技術情報という点で実際的なものではありません。

しかし、ほとんどのデジタル・カメラでは、バイナリ・イメージ・ファイルの一部として、独自に作成したイメージ・メタデータを含んでいます。Oracle Databaseに含まれるOracle interMediaには、このバイナリ・データを抽出してXMLに変換するツールが用意されています。Oracle interMedia XML SchemaはOracle XML DBリポジトリに自動的に登録されており、次の種類のバイナリ・イメージ・メタデータをXMLデータに変換します。

- EXIF - Exchangeable Image File Format

- IPTC-NAA IIM - International Press Telecommunications Council-Newspaper Association of America Information Interchange Model

- XMP - Extensible Metadata Platform

EXIFは、デジタル・スチル・カメラのメタデータ標準です。EXIFメタデータはTIFFおよびJPEGのイメージ・ファイルに格納されています。IPTCおよびXMPメタデータは、通常、デスクトップ画像処理ソフトウェアによりイメージ・ファイルに埋め込まれます。

関連項目:

- バイナリ・イメージ・メタデータの抽出や、そのXMLへの変換など、デジタル・イメージのメタデータの操作は、『Oracle Multimediaユーザーズ・ガイド』を参照してください。

- Oracle interMediaでイメージ・メタデータを使用する際にサポートされているXML Schemaの詳細は、『Oracle Multimediaリファレンス』を参照してください。

XML Schemaに基づかないリソース・メタデータの追加

XML Schemaに基づかないユーザー定義のリソース・メタデータは、CLOBインスタンスとして、関連付けられているリソースのResource要素に格納します。リソースのデフォルトのXML Schemaでは最上位要素がany(maxOccurs= "unbounded"で宣言)なので、任意の有効なXMLデータをリソース文書に含めることができます。このメタデータは、リソース表のCLOB列に格納されます。

次のスケルトンは、XML Schemaに基づかないリソース・メタデータの構造と位置を示しています。

<Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd"
<Owner>DESELBY</Owner>
... <!-- other system-defined metadata -->
<!-- contents of the resource>
<Contents>
...
</Contents>
<!-- User-defined metadata (appearing within different namespace) -->
<MyOwnMetadata xmlns="http://www.example.com/custommetadata">
<MyElement1>value1</MyElement1>
<MyElement2>value2</MyElement2>
</MyOwnMetadata>
</Resource>

XDBResource.xsd以外の名前空間に属する、XML Schemaに基づかないリソース・メタデータを設定したり、それにアクセスしたりするには、XML Schemaに基づくリソース・メタデータのアクセスに関する前述の説明で触れた方法のいずれかを使用します。

例29-9は、SQL DML操作に関する説明で、ユーザー定義のメタデータを<RESOURCE>文書に直接追加しています。この例は、SQL DMLを使用してXML Schemaに基づかないメタデータをリソースに追加する方法を示しています。

例29-9 XML Schemaに基づかないメタデータのリソースへの追加

DECLARE
res BOOLEAN;
BEGIN
res := DBMS_XDB.createResource('/public/NurseryRhyme.txt',
bfilename('MYDIR',
'tdadxdb-xdb_repos_meta-011.txt'),
nls_charset_id('AL32UTF8'));
UPDATE RESOURCE_VIEW
SET RES = insertChildXML(RES,
'/r:Resource',
'n:NurseryMetadata',
XMLType('<n:NurseryMetadata xmlns:n="nurserynamespace">
<Author>Mother Goose</Author>
<n:NurseryMetadata>'),
'xmlns:r="http://xmlns.oracle.com/xdb/XDBResource.xsd"
xmlns:n="nurserynamespace"')
WHERE equals_path(RES, '/public/NurseryRhyme.txt') = 1;
END;
/

PL/SQL procedure successfully completed.

SELECT XMLSerialize(DOCUMENT rs.RES AS CLOB) FROM RESOURCE_VIEW rs
WHERE equals_path(RES, '/public/NurseryRhyme.txt') = 1;

XMLSERIALIZE(DOCUMENTRS.RESASCLOB)
--------------------------------------------------------------------------------
<Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd" Hidden="false" Inv
alid="false" Container="false" CustomRslv="false" VersionHistory="false" StickyR
ef="true">
<CreationDate>2005-05-24T13:51:48.043234</CreationDate>
<ModificationDate>2005-05-24T13:51:48.290144</ModificationDate>
<DisplayName>NurseryRhyme.txt</DisplayName>
<Language>en-US</Language>
<CharacterSet>UTF-8</CharacterSet>
<ContentType>text/plain</ContentType>
<RefCount>1</RefCount>
<ACL>
<acl description="Public:All privileges to PUBLIC" xmlns="http://xmlns.oracl
e.com/xdb/acl.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sch
emaLocation="http://xmlns.oracle.com/xdb/acl.xsd                           http:
//xmlns.oracle.com/xdb/acl.xsd" shared="true">
<ace>
<principal>PUBLIC</principal>
<grant>true</grant>
<privilege>
<all/>
</privilege>
</ace>
</acl>
</ACL>
<Owner>TDADXDB_META</Owner>
<Creator>TDADXDB_META</Creator>
<LastModifier>TDADXDB_META</LastModifier>
<SchemaElement>http://xmlns.oracle.com/xdb/XDBSchema.xsd#text</SchemaElement>
<Contents>
<text>Mary had a little lamb
Its fleece was white as snow
and everywhere that Mary went
that lamb was sure to go
</text>
</Contents>
<n:NurseryMetadata xmlns:n="nurserynamespace">
<Author xmlns="">Mother Goose</Author>
</n:NurseryMetadata>
</Resource>

1 row selected.

リソース・メタデータに影響するPL/SQLプロシージャ

次のPL/SQLプロシージャはリソース・メタデータを操作します。

- DBMS_XMLSCHEMA.registerSchema - XML Schemaの登録。パラメータENABLEHIERARCHYによりリソース・メタデータが影響を受けます。

- DBMS_XDBZ.enable_hierarchy - XMLTypeの表やビューに対するリポジトリ・サポートを有効にします。パラメータHIERARCHY_TYPEと値DBMS_XDBZ.ENABLE_HIERARCHY_RESMETADATAを使用すると、リソース・メタデータを有効にできます。これにより、メタデータに関連付けられているリソースを追跡するRESIDが追加されます。

- DBMS_XDBZ.disable_hierarchy - XMLTypeの表やビューに対するリポジトリ・サポートをすべて無効にします。

- DBMS_XDBZ.is_hierarchy_enabled - パラメータHIERARCHY_TYPEを使用して、指定された階層の型が、指定されたXMLTypeの表やビューに対して現在有効かどうかをテストします。リソース・メタデータが有効かどうかは、HIERARCHY_TYPEの値がDBMS_XDBZ.IS_ENABLED_RESMETADATAかどうかでテストできます。

- DBMS_XDB.appendResourceMetadata - メタデータをリソースに追加します。

- DBMS_XDB.deleteResourceMetadata - 指定したメタデータをリソースから削除します。

- DBMS_XDB.purgeResourceMetadata - すべてのユーザー定義のメタデータをリソースから削除します。XML Schemaに基づくリソースの場合、オプションのパラメータDELETE_OPTIONを使用して、メタデータ情報を単にリンク解除するだけでなく、削除するかどうかを指定できます。

- DBMS_XDB.updateResourceMetadata - リソースのメタデータを更新します。

関連項目:
PL/SQLプロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

30 Oracle XML DBリポジトリ・イベント

この章では、リポジトリ・イベントとその使用方法を説明します。内容は次のとおりです。

- リポジトリ・イベントの概要

- 可能なリポジトリ・イベント

- リポジトリ操作とイベント

- リポジトリ・イベント・ハンドラの考慮事項

- リポジトリ・イベントの構成

リポジトリ・イベントの概要

Oracle XML DBリポジトリを使用して、ファイルやフォルダなど、あらゆるリポジトリ・リソース形式のデータを格納、またはデータにアクセスできます。リポジトリ・リソース操作には、作成、削除、ロック、ロック解除、レンダリング、リンク付け、リンク解除、バージョン管理、チェックイン、チェックアウト、チェックアウト解除(チェックアウトされたバージョンの回復)、オープン、更新があります。リポジトリのデータには、任意のアプリケーションからアクセスできます。特定のリポジトリ操作が発生するたびに、アプリケーションによる特定のアクションの実行が必要な場合があります。たとえば、リソースを削除するたびに、ごみ箱への移動や他のバックアップ操作を実行する場合があります。

リポジトリ・イベント: ユースケース

リポジトリ・イベントを使用できるケースの例を次に示します。

- ごみ箱– UnLink前処理イベント・ハンドラを使用して、リソースを削除するのではなく、効率的にごみ箱に移動できます。つまり、元のリンクを削除する前にごみ箱フォルダにリンクを作成します。ごみ箱のリンクにより、リソースは削除されません。その後、削除されたリソースをごみ箱から元に戻す場合、元のリンクが再作成され、ごみ箱のリンクが削除されます。特定のパスのリソースは、そのパスから複数回リンク解除できるため、ごみ箱のリンク名は、削除されるリンク名と異なるリンク名にできます。ごみ箱には、そのパスに対応する、リンク・プロパティが異なり、それぞれ別のリソースを指している可能性のあるリンクが複数存在します。

- カテゴリ分け: アプリケーションにより、管理するリソースがMIMEタイプや他のプロパティに基づいて分類される場合があります。リポジトリ・フォルダ/my-app/gif、/my-app/txt、および/my-app/xmlからGIFファイル、テキスト・ファイル、およびXMLファイルのリンクが保持され、そのファイルが追跡されることがあります。ここでは、LinkIn、UnlinkIn、Updateの3つの後処理イベント・ハンドラを使用できます。LinkIn後処理イベント・ハンドラはリソースを調べ、リソースがまだ存在しない場合は、適切なカテゴリ・フォルダにリンクを作成します。UnlinkIn後処理イベント・ハンドラは、カテゴリ・フォルダからリンクを削除します。Update後処理イベント・ハンドラは、そのカテゴリが変更された場合に、1つのカテゴリ・フォルダから別のカテゴリ・フォルダへリソースを効率的に移動します。

リポジトリ・イベントとデータベース・トリガー

リポジトリ・イベントはデータベース・トリガーを連想させますが、追加機能があります。データベース・トリガーは、アプリケーションによるリポジトリ操作への反応には使用できません。指定のリポジトリ操作は、複数の基礎となる内部表において、複数のデータベース操作で構成されている場合があります。これらの基礎となる表はOracle XML DB内部にあるため、特定のリポジトリ操作に簡単にはマップできません。たとえば、内部表XDB$H_INDEXは、(ACLが変更された場合は)データベース更新操作、またはリンク操作により更新されます。データベース・トリガーによって同様の操作が可能な場合でも、これを使用しません。リポジトリ・イベントとは、基礎となる表の一連のデータベース・トリガーより高いレベルの抽象的概念です。

リポジトリ・イベントが発生すると、使用されているリソース・パスなど、その操作に関連した情報が対応するイベント・ハンドラに渡されます。このような情報は、データベース・トリガーを使用した場合はすぐに使用できません。

リポジトリ・イベントとデータベース・トリガーは両方ともXMLデータに適用できます。たとえば、トリガーはXMLType表で使用できます。ただし、XMLType表も(階層対応の)リポジトリ表である場合は、表に適用されるトリガー・コードをイベント・ハンドラでコピーしないでください。コピーした場合、そのコードは2回実行されます。

リポジトリ・イベント・リスナーとイベント・ハンドラ

各リポジトリ操作は、1つ以上のリポジトリ・イベントに関連付けられています。アプリケーションは、該当リソースに関連付けられたイベントのリスナーを構成します。リポジトリ・イベント・リスナーはJavaクラス、PL/SQLパッケージまたはオブジェクト型です。このリポジトリは一連のPL/SQLプロシージャまたはJavaメソッドで構成され、それぞれがイベント・ハンドラと呼ばれます。イベント・ハンドラはそれぞれ、単一のイベントを処理します。リポジトリ・イベント・リスナーは特定のリソース、またはリポジトリ全体に対して構成できます。リスナーはさらに、指定のノードの有無の前提条件を満たしている場合のみ適用されるよう制限できます。

リソース構成ファイルをリソースとマップして、リポジトリ・イベント・リスナーとリソースを関連付けます。PL/SQLパッケージDBMS_RESCONFIGを使用して、リソース構成ファイルとそれを構成するリソースと関連付けるなど、リソース構成ファイルを操作します。特に、PL/SQLファンクションDBMS_RESCONFIG.getListenersには、特定のリソースのすべてのイベント・リスナーが一覧されています。

リポジトリ・イベント構成

複数のリソース構成ファイルにより、特定のリソースが構成されます。これらはリソース構成リストに格納されており、リストに記載された順番で処理されます。リポジトリ全体も複数のリソース構成ファイルで構成される場合があります。つまり、リポジトリ自体にリソース構成リストがあります。リポジトリ全体について構成されるイベント処理は、任意のリソース固有のイベント処理前に有効になります。つまり、リポジトリ全体に渡る当該イベントはすべて、リソース固有のイベント前に処理されます。

指定のリソース構成ファイルによって構成するリソースの複数のイベント・リスナーが定義され、各イベント・リスナーによって複数のイベント・ハンドラが定義されます。

関連項目:

- 「リポジトリ・イベントの構成」

- リソース構成およびリソース構成リストの詳細は、「リソースを構成するリソース構成ファイル」を参照してください。

可能なリポジトリ・イベント

レンダリング操作は、単一のリポジトリ・イベントと関連付けられています。レンダリングを除き、すべてのリポジトリ操作は、1つ以上のイベントのペアに関連付けられています。たとえば、リソース作成は3組のイベントと関連付けられ、これらのイベントは次の順に発生します。

1. Pre-creationイベント

2. Post-creationイベント

3. Pre-link-inイベント

4. Pre-link-toイベント

5. Post-link-toイベント

6. Post-link-inイベント

表30-1に、各リポジトリ操作に関連付けられたイベントを示します。この順序をハンドラ列に示します。

表30-1 事前定義リポジトリ・イベント

リポジトリ・イベント型

説明

プリハンドラ実行

ポストハンドラ実行

Render

Renderイベントは、フォルダ・リソースではなく、file・リソースにのみ発生します。

次のいずれかを使用してリソース・コンテンツにアクセスする際に発生します。

- プロトコル

- XDBURITypeメソッドgetCLOB()、getBLOB()、およびgetXML()

次のいずれかを使用してリソース・コンテンツにアクセスする場合は発生しません。

- SELECT ... FROM RESOURCE_VIEW

- XDBURITypeメソッドgetResource()

レンダリング出力を設定できるのはRenderイベントのハンドラ1つのみです。setRenderStreamまたはsetRenderPathをコールする最初のハンドラが、レンダリングを制御します。

なし

なし

Create

リソースが作成されるときに発生します。実行されたプリハンドラとポストハンドラは、新規リソースのフォルダに定義されているハンドラです。

事前解析後、親リソースACLおよびロックの検証後、およびデフォルト値の未定義プロパティへの割当て前

リソースのシステム・リソース表への挿入後

Delete

リソースとそのコンテンツがディスクから削除される場合、つまりリソースREFカウントがゼロ(0)の場合に発生します。

リソースACLおよびロックの検証後、およびリソースのディスクからの削除前

リソースとそのコンテンツのディスクからの削除後、および親フォルダの最終変更者と変更時間の更新のためのフォルダ変更後

Update

ディスクでリソースを更新する場合に発生します。

リソースACLおよびロックの検証後、および最終変更者と変更時間の更新前

リソースのディスクへの書込み後

Lock

リソース・ロック操作中に発生します。

リソースACLおよびロックの検証後、およびリソースでの新規ロックの作成前

新規ロック作成後

Unlock

リソース・ロック解除操作中に発生します。

リソースACLおよび削除トークン検証後

ロック削除後

LinkIn

リンク操作中のLinkToイベント前に発生します。イベント・ターゲットはリンクが作成されるフォルダです。常にLinkToイベントを伴います。

リソースACLおよびロックの検証後、およびリンク作成前

LinkToポストハンドラ実行後

LinkTo

リンク操作中のLinkInイベント後に発生します。イベント・ターゲットは、リンク宛先となるリソースです。

LinkInプリハンドラ実行後、およびリンク作成前

リンク作成後、および親フォルダの最終変更者と変更時間の更新後

UnLinkIn

リンク解除操作中のUnlinkFromイベント前に発生します。常にUnlinkFromイベントを伴います。

リソースACLおよびロックの検証後、およびリンク削除前

UnlinkFromポストハンドラ実行後

UnlinkFrom

リンク解除操作中のUnlinkInイベント後に発生します。

UnlinkInプリハンドラ実行後

リンク削除後

CheckIn

リソースのチェックイン中に発生します。

リソースACLおよびロック検証後、およびリソースがバージョン管理対象であり、チェックアウト済であることを検証後

リソースのチェックイン後

CheckOut

リソースのチェックアウト中に発生します。

リソースACLおよびロック検証後、およびリソースがバージョン管理対象であり、チェックアウト前であることを検証後

リソースのチェックアウト後

UncheckOut

リソースのチェックアウト解除中に発生します。

リソースがチェックアウトされている記録の削除前

リソースのチェックアウト解除後

VersionControl

リソースのバージョン履歴が作成されるときに発生します。

注意: DBMS_XDB.MakeVersioned()は複数回コールできますが、バージョン履歴は初回コール時のみ作成されます。それ以降のコールによる影響はなく、VersionControlイベントは発生しません。

リソースのバージョン履歴作成前

リソースの最初のバージョン作成後

簡単にするため、一般的にこの章のプレゼンテーションでは、イベント型pre-link-inおよびpost-link-inの略記としてLinkInイベント型を参照するなど、リポジトリ・イベント・ペアの両方のメンバーを扱います。同様に、ここで使用するイベント型名は、JavaインタフェースXDBRepositoryEventListenerから接頭辞handlePreおよびhandlePostを削除して導出されたものです。

関連項目:
PL/SQLリポジトリ・イベント型は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

リポジトリ操作とイベント

異なるOracle XML DBリポジトリ操作で同じリポジトリ・イベントが発生する可能性があり、また指定のリポジトリ操作により複数のリポジトリ・イベントが生成される可能性があります。表30-2に、各リポジトリ操作に関連付けられたイベントを示します。同じ操作に複数のリポジトリ・イベントが発生する場合のイベントの順序は、表30-1を参照してください。

表30-2 Oracle XML DBリポジトリ操作とイベント

操作

発生しているリポジトリ・イベント

パス名によるリソース・コンテンツのバイナリ表現の取得

Render

パス名によるリソース・コンテンツのXML表現の取得

Render

リソースの作成または更新

リソースがすでに存在している場合: Create、LinkIn、LinkTo

リソースが存在していない場合(HTTPおよびFTPのみ): Update

フォルダの作成

Create、LinkIn、LinkTo

既存のリソースへのリンクの作成

リンク・ターゲットを含むフォルダではLinkIn、リンクするターゲット・リソースではLinkTo

ファイル・リソースまたは空フォルダ・リソースのリンク解除(RefCountを減少させます。これがゼロの場合はディスクからリソースを削除します。)

UnlinkIn、UnlinkFrom、(RefCountがゼロの場合は)Delete

フォルダとそのコンテンツの強制削除

リソースのリンク解除のため、再帰イベントを生成します。フォルダの子リソースは再帰的に削除され、次にフォルダが削除されます。

リソースへのすべてのリンクの強制削除

削除されたリンクごとにリンク解除イベントを生成します。

パス名によるリソースのコンテンツ、プロパティ、ACLの更新

Update

深さゼロのWebDAVロックのリソースへの配置

Lock

深さゼロのWebDAVロックのリソースからの削除

Lock

リソースの名前変更

新規の位置ではLinkInおよびLinkTo、古い位置ではUnlinkInおよびUnlinkFrom

リソースのコピー

新規の位置ではCreate、LinkIn、LinkTo

リソースのチェックアウト

CheckOut

リソースのチェックイン

CheckIn

リソースのバージョン管理への配置

VersionControl

リソースのチェックアウト解除

UncheckOut

表30-2に示すすべての操作は、次の操作を除き、基本操作です。

- フォルダとそのコンテンツの強制削除

- HTTP(のみ)を使用したパス名によるリソース・プロパティの更新

- HTTP(のみ)を使用したフォルダのコピー

関連項目:
APIおよびプロトコルを使用してリソースにアクセスする方法は、表21-3「Oracle XML DBリポジトリへのアクセス: APIオプション」を参照してください。

リポジトリ・イベント・ハンドラの考慮事項

この項では、Oracle XML DBリポジトリ・イベントのハンドラを定義する場合に考慮する点について説明します。

- すべてのハンドラ: ハンドラ内でCOMMIT、ROLLBACKまたはデータ定義言語(DDL)文を使用しないでください。DDL文と同様の動作をするPL/SQLファンクションまたはプロシージャ(DBMS_XMLSCHEMA.registerSchemaなど)をコールしないでください。Renderハンドラ: データ操作言語(DML)文を使用しないでください。
これらの制約を回避するには、ハンドラは自律型トランザクション内でこのような文を使用できます。ただし、ロック競合が発生しないようにすることが必要です。

- Renderハンドラ内で出力ストリームをクローズしないでください。(ストリームに追加できます。)

- Pre-CreateおよびPre-Update以外のハンドラ内では、クラスXDBResourceから修飾子メソッドを使用しないでください。いずれのハンドラ内でも、メソッドXDBResource.save()を使用しないでください。

- 安全なリポジトリ・イベント・ハンドラのみ開発することをお薦めします。特に、次の点に注意してください。

- xdb名前空間ではなく、アプリケーションが所有する名前空間にあるリソース・プロパティのみを記述してください。

- リソースの作成中は、リソースを削除しないでください。

- リポジトリ・イベント・ハンドラには、現在のSQL文またはプロトコル操作中にのみ存在するXDBRepositoryEventオブジェクトが渡されます。このオブジェクトでPL/SQLプロシージャとJavaメソッドを使用して、リソース、イベントおよび関連イベント・ハンドラの情報を取得できます。

- イベント・ハンドラが他のリポジトリ・イベントを生じさせる操作を実行すると、それらのカスケーディング・イベントがただちに発生します。ただし、現在のイベントのハンドラが完了した後は、これらのイベントはキューに入れられず発生しません。つまり、各イベントはその対応する操作に関連して発生します。

- 複数のリポジトリ・イベント・ハンドラが同時にコールされます。これらは対応する操作のプロセス、セッション、トランザクションにおいて実行されます。ただし、ハンドラではOracle Streamsアドバンスト・キューイング(AQ)により、他のプロセスで非同期的に処理されるリポジトリ・イベントがキューに入れられます。

- リポジトリ・イベント・ハンドラは、対応する操作のトランザクションにおいて実行されるため、その操作またはトランザクションで以前実行された他の操作によって取得したロックはアクティブなままです。イベント・ハンドラでは、そのようなロックを取得する個別セッションまたはトランザクションは開始できません。開始するとハンドラは停止します。

- リポジトリ・イベント・ハンドラは、リソース構成ファイルに出現する順にコールされます。リソース構成に前提条件が定義されている場合、前提条件を満たしているハンドラのみコールされます。

- ハンドラは構成ファイルで定義されている順にコールされますが、これにはコードを依存させないでください。ハンドラの起動時の現行ユーザーにwrite-config権限がある場合、ハンドラの起動順序は実行中のハンドラ内で変更できます。

- 指定のリポジトリ・イベント発生に該当するハンドラの全体リストは、ハンドラの起動前に決定されます。つまり、具体的には、各ハンドラの前提条件はハンドラの起動前に評価されます。

- 次の考慮事項は、リポジトリ・イベントのエラー処理に適用されます。

- 操作のアクセス確認に失敗した場合、事前操作イベント・ハンドラは起動されません。

- 指定のイベントのすべてのハンドラは、コールされる前にチェックされます。(すでに存在しないなど)どのハンドラも使用できない場合は、いずれもコールされません。

- イベント処理中にエラーが発生すると、他の後続イベント・ハンドラは同じSQL文またはプロトコル操作に対して起動されません。現在の文または操作は取り消され、その変更はすべてロールバックされます。

- 次の考慮事項は、リポジトリ・イベントのリソース・セキュリティに適用されます。

- イベント・ハンドラには起動者の権限または定義者の権限があります。パッケージを作成する際、PL/SQLパッケージの実行権限を指定します。loadjavaユーティリティを使用してJavaクラスの実行権限をデータベースにロードする際、これらの実行権限を指定します。起動者の権限を指定しても、指定のハンドラが起動者の権限に対して構成されていない場合、権限不足エラーが発生します。

- イベント・ハンドラ内では、起動者権限または定義者権限のどちらで取得されていても、現在のユーザー権限はそのACLにより指定のリソースに対して詳細に決定されます。これらの権限は、リソースに対してハンドラが処理可能な内容を決定します。たとえば、現行ユーザーが特定のリソースに対するread-propertiesおよびread-contents権限を持っている場合、イベント・ハンドラはそのリソースを読み取ることができます。

- 次の考慮事項は、リンクおよびリンク解除のリポジトリ・イベントに適用されます。

- リソースにリンクを作成後、親フォルダのリソース構成ファイルをリンク済リソースに適用させる場合は、プロシージャDBMS_RESCONFIG.appendResConfigを使用して構成ファイルをリンク済リソースに追加します。このプロシージャは、リンク済リソースのPost-LinkToイベント・ハンドラから起動できます。

- リソースのリンク解除後、リンク時に追加した該当リソース構成ファイルを削除する場合は、プロシージャDBMS_RESCONFIG.deleteResConfigを使用してリンク解除済リソースからファイルを削除します。このプロシージャは、リンク解除済リソースのPost-UnlinkFromイベント・ハンドラから起動できます。

- フォルダ/sys/schemasや、その配下のリソースでのイベントにはハンドラを定義しないでください。それらのリソースにはイベントが発生しないため、そうしたイベント・ハンドラは無視されます。つまり、リポジトリに影響を与えるXML Schema操作(登録、削除など)はイベントを生成しません。

関連項目:

- リポジトリ・イベント操作のためのPL/SQLファンクションおよびプロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- リポジトリ操作のためのJavaメソッドの詳細は、『Oracle Database XML Java API Reference』のクラスXDBRepositoryEventおよびXDBEventに関する項を参照してください。

- 起動者の権限のあるリポジトリ・イベント・ハンドラの定義は、「リポジトリ・イベントの構成」を参照してください。

リポジトリ・イベントの構成

リポジトリ・リソースの他の処理を構成するように、Oracle XML DBリポジトリ・リソースのイベント処理を構成します。「リソースの構成」を参照してください。

デフォルトではリポジトリ・イベントは有効になっていますが、パラメータXML_DB_EVENTSをDISABLEに設定して無効にできます。セッション・レベルでリポジトリ・イベントを無効にするには、次のSQL*Plusコマンドを使用します。これを行うには、ロールXDBADMINが必要です。

ALTER SESSION SET XML_DB_EVENTS = DISABLE;

システム・レベルでリポジトリ・イベントを無効にするには、次のSQL*Plusコマンドを使用した後、データベースを再起動します。以降のセッションでは、リポジトリ・イベントが無効になります。これを行うには、権限ALTER SYSTEMが必要です。

ALTER SYSTEM SET XML_DB_EVENTS = DISABLE;

再度リポジトリ・イベントを有効にするには、XML_DB_EVENTSの値をENABLEに設定します。

この項の後半では、他のリソースのイベント処理を構成する場合にリソースとして使用するリソース構成ファイルについて説明します。

リソース構成ファイルは、パス/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBResConfig.xsdにあるOracle XML DBリポジトリでアクセス可能な、XML Schema XDBResConfig.xsd準拠のXMLファイルです。要素ResConfigの子である要素event-listenersを使用してリポジトリ・イベント処理を構成します。

関連項目:
リポジトリ・リソースの構成は、第22章「Oracle XML DBリポジトリの構成」を参照してください。

構成要素event-listeners

各リソース構成ファイルには、要素ResConfigの子として1つのevent-listeners要素があります。これにより、ターゲット・リソースのすべてのイベント処理が構成されます。リソース構成ファイルが特定のリソースではなくリポジトリ全体に適用される場合、リポジトリのすべてのリソースに対してイベント処理が定義されます。

要素event-listenersには、次のオプション属性があります。

- set-invoker: リソース構成で1つ以上のリポジトリ・イベント・ハンドラが起動者権限を持つように定義する場合はtrueに設定します。デフォルト値はfalseで、これは定義者権限が使用されていることを意味します。
起動者権限のリポジトリ・イベント・ハンドラを定義する場合、データベース・ロールXDB_SET_INVOKERが必要です。このロールはDBAには付与されていますが、XDBADMINには付与されていません。ロールXDB_SET_INVOKERは、リソース構成ファイルの作成または更新時にのみチェックされます。十分な権限があることを保証するため、ロールXDB_SET_INVOKERではなく、属性set-invokerのみ実行時にチェックされます。

関連項目:
権限不足によるエラーは、「リポジトリ・イベント・ハンドラの考慮事項」を参照してください。

- default-schema: schema要素が定義されていないリスナーに使用されるデフォルトのスキーマ値です。

- default-language: language要素が定義されていないリスナーに使用されるデフォルトの言語値です。

要素event-listenersには子として一連のlistener要素があります。これにより、個々のリポジトリ・イベント・リスナーが構成されます。リスナーは、listener要素の順に実行時に処理されます。

構成要素listener

各listener要素には、次の子要素があります。sourceを除き、これらはすべてオプションで、どのような順序でも出現できます(順序は関係ありません)。

- description: リスナーの説明です。

- schema: リポジトリ・イベント・ハンドラのJavaまたはPL/SQL実装のデータベース・スキーマです。これとdefault-schemaがどちらも定義されていない場合、エラーが発生します。

- source(必須): ハンドラ・メソッドを提供するJavaクラス、PL/SQLパッケージ、またはオブジェクト型の名前です。Javaクラス名はパッケージ名で修飾されている必要があります。空のsource要素を使用して、リポジトリ・イベント・ハンドラがスタンドアロンのPL/SQLストアド・プロシージャであることを示します。

- language: リスナーのクラス(Java)またはパッケージ(PL/SQL)の実装言語です。これとdefault-languageがどちらも定義されていない場合、エラーが発生します。

- pre-condition: このリスナーのリポジトリ・イベント・ハンドラの実行のために満たす必要のある前提条件です。これは、一般リソース構成要素configurationの子pre-conditionと同じです。「構成要素defaultChildConfig」を参照してください。

- events: Render、Pre-Createなど一意のリポジトリ・イベント型名のシーケンスです。リスナーには、これらの型のリポジトリ・イベントのハンドラのみ有効化されています。可能なリポジトリ・イベント型のリストは、「可能なリポジトリ・イベント」を参照してください。要素eventsが存在しない場合、すべての型のリポジトリ・イベントのハンドラがリスナーに有効になり、無駄になります。重要性の低いリポジトリ・イベントのハンドラの起動を削減するため、要素eventsを提供します。

リポジトリ・イベント構成の例

例30-1は、2つのリスナーを定義するリソース構成ファイルの内容を示しています。各リスナーは、Post-LinkIn、Post-UnlinkIn、およびPost-Update型のリポジトリ・イベントのハンドラを定義します。リスナーは、前提条件、デフォルト言語(Java)およびデフォルトのデータベース・スキーマを定義します。

例30-1 前提条件のあるJavaイベント・リスナーのリソース構成ファイル

<ResConfig xmlns="http://xmlns.oracle.com/xdb/XDBResConfig.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/XDBResConfig.xsd
http://xmlns.oracle.com/xdb/XDBResConfig.xsd">
<event-listeners default-language="Java" default-schema="IFS">
<listener>
<description>Category application</description>
<schema>CM</schema>
<source>oracle.cm.category</source>
<events>
<Post-LinkIn/>
<Post-UnlinkIn/>
<Post-Update/>
</events>
<pre-condition>
<existsNode>
<XPath>/Resource[ContentType="image/gif"]</XPath>
</existsNode>
</pre-condition>
</listener>
<listener>
<description>Check quota</description>
<source>oracle.ifs.quota</source>
<events>
<Post-LinkIn/>
<Post-UnlinkIn/>
<Post-Update/>
</events>
<pre-condition>
<existsNode>
<XPath>r:/Resource/[ns:type="ifs-file"]</XPath>
<namespace>xmlns:r="http://xmlns.oracle.com/xdb/XDBResource.xsd"
xmlns:ns="http://foo.xsd"
</namespace>
</existsNode>
</pre-condition>
</listener>
</event-listeners>
<defaultChildConfig>
<configuration>
<path>/sys/xdb/resconfig/user_rc.xml</path>
</configuration>
</defaultChildConfig>
<applicationData>
<foo:data xmlns:foo="http://foo.xsd">
<foo:item1>1234</foo:item1>
</foo:data>
</applicationData>
</ResConfig>

最初のリスナーのハンドラは、データベース・スキーマCMで定義されたJavaクラスoracle.cm.quotaに実装されています。これらのハンドラは、ContentType image/gifのリソース上のイベントに対してのみ起動されます。

2番目のリスナーのハンドラは、データベース・スキーマIFS(このリソース構成ファイルのデフォルトのスキーマ)で定義されたJavaクラスoracle.ifs.quotaに実装されています。これらのハンドラは、名前空間http://foo.xsdのifs-file型のリソース上のイベントに対してのみ起動されます。

関連項目:
要素defaultChildConfigおよびapplicationDataは、「構成要素defaultChildConfig」を参照してください。

簡単なエンドツーエンドの説明として、リソースのMIMEタイプに従ってフォルダ/public/res-appのリソースを分類する必要があるとします。リソースのMIMEタイプがそれぞれtext/xml、image/gifまたはapplication/octet-streamのどれであるかに応じて、フォルダ/public/app/XML-TXT、/public/app/IMGおよび/public/app/FOLDERのリソースへのリンクが作成されます。これは例30-2、例30-3、例30-5で説明しています。

例30-2は、この分類の説明のため、構成ファイルを作成するPL/SQLコードを示しています。これはPre-UnlinkInおよびPost-LinkIn型のイベントを処理する単一のリスナーを定義しています。言語(PL/SQL)およびデータベース・スキーマは明示的に定義されています。前提条件は定義されていません。

例30-2 前提条件のないPL/SQLイベント・リスナーのリソース構成ファイル

DECLARE
b BOOLEAN := FALSE;
BEGIN
b := DBMS_XDB.createFolder('/public/resconfig');
b := DBMS_XDB.createResource(
'/public/resconfig/appcatg-rc1.xml',
'<ResConfig xmlns="http://xmlns.oracle.com/xdb/XDBResConfig.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/XDBResConfig.xsd
http://xmlns.oracle.com/xdb/XDBResConfig.xsd">
<event-listeners>
<listener>
<description>Category application</description>
<schema>APPCATGUSER1</schema>
<source>APPCATG_EVT_PKG1</source>
<language>PL/SQL</language>
<events>
<Pre-UnlinkIn/>
<Post-LinkIn/>
</events>
</listener>
</event-listeners>
<defaultChildConfig>
<configuration>
<path>/public/resconfig/appcatg-rc1.xml</path>
</configuration>
</defaultChildConfig>
</ResConfig>',
'http://xmlns.oracle.com/xdb/XDBResConfig.xsd',
'ResConfig');
END;
/
BEGIN
DBMS_RESCONFIG.appendResConfig('/public/res-app',
'/public/resconfig/appcatg-rc1.xml',
DBMS_RESCONFIG.APPEND_RECURSIVE);
END;
/

例30-3は、例30-2で構成されているイベント・ハンドラを実装するPL/SQLコードを示しています。Post-LinkInイベント・ハンドラは、eventObjectリソースへのリンクをリソースのMIMEタイプに応じて、フォルダ/public/app/XML-TXT、/public/app/IMG、/public/app/FOLDERのいずれかに作成します。Pre-UnlinkInイベント・ハンドラは、Post-LinkInイベント・ハンドラによって作成されたリンクを削除します。

例30-3 イベント・リスナーを実装するPL/SQLコード

CREATE OR REPLACE PACKAGE appcatg_evt_pkg1 AS

PROCEDURE handlePreUnlinkIn (eventObject DBMS_XEVENT.XDBRepositoryEvent);
PROCEDURE handlePostLinkIn (eventObject DBMS_XEVENT.XDBRepositoryEvent);

END;
/
CREATE OR REPLACE PACKAGE BODY appcatg_evt_pkg1 AS

PROCEDURE handlePreUnlinkIn (eventObject DBMS_XEVENT.XDBRepositoryEvent) AS
XDBResourceObj DBMS_XDBRESOURCE.XDBResource;
ResDisplayName VARCHAR2(100);
ResPath        VARCHAR2(1000);
ResOwner       VARCHAR2(1000);
ResDeletedBy   VARCHAR2(1000);
XDBPathobj     DBMS_XEVENT.XDBPath;
XDBEventobj    DBMS_XEVENT.XDBEvent;
SeqChar        VARCHAR2(1000);
LinkName       VARCHAR2(10000);
ResType        VARCHAR2(100);
LinkFolder     VARCHAR2(100);
BEGIN
XDBResourceObj := DBMS_XEVENT.getResource(eventObject);
ResDisplayName := DBMS_XDBRESOURCE.getDisplayName(XDBResourceObj);
ResOwner       := DBMS_XDBRESOURCE.getOwner(XDBResourceObj);
XDBPathobj     := DBMS_XEVENT.getPath(eventObject);
ResPath        := DBMS_XEVENT.getName(XDBPathObj);
XDBEventobj    := DBMS_XEVENT.getXDBEvent(eventObject);
ResDeletedBy   := DBMS_XEVENT.getCurrentUser(XDBEventobj);
BEGIN
SELECT XMLCast(
XMLQuery(
'declare namespace ns = "http://xmlns.oracle.com/xdb/XDBResource.xsd";
/ns:Resource/ns:ContentType'
PASSING r.RES RETURNING CONTENT) AS VARCHAR2(100))
INTO ResType
FROM PATH_VIEW r WHERE r.PATH=ResPath;
EXCEPTION WHEN OTHERS THEN NULL;
END;
IF ResType = 'text/xml' THEN LinkFolder := '/public/app/XML-TXT/';
END IF;
IF ResType = 'image/gif' THEN LinkFolder := '/public/app/IMG/';
END IF;
IF ResType = 'application/octet-stream' THEN LinkFolder := '/public/app/FOLDER/';
END IF;
DBMS_XDB.deleteResource(LinkFolder || ResDisplayName);
END;

PROCEDURE handlePostLinkIn (eventObject DBMS_XEVENT.XDBRepositoryEvent) AS
XDBResourceObj DBMS_XDBRESOURCE.XDBResource;
ResDisplayName VARCHAR2(100);
ResPath        VARCHAR2(1000);
ResOwner       VARCHAR2(1000);
ResDeletedBy   VARCHAR2(1000);
XDBPathobj     DBMS_XEVENT.XDBPath;
XDBEventobj    DBMS_XEVENT.XDBEvent;
SeqChar        VARCHAR2(1000);
LinkName       VARCHAR2(10000);
ResType        VARCHAR2(100);
LinkFolder     VARCHAR2(100);
BEGIN
XDBResourceObj := DBMS_XEVENT.getResource(eventObject);
ResDisplayName := DBMS_XDBRESOURCE.getDisplayName(XDBResourceObj);
ResOwner       := DBMS_XDBRESOURCE.getOwner(XDBResourceObj);
XDBPathobj     := DBMS_XEVENT.getPath(eventObject);
ResPath        := DBMS_XEVENT.getName(XDBPathObj);
XDBEventobj    := DBMS_XEVENT.getXDBEvent(eventObject);
ResDeletedBy   := DBMS_XEVENT.getCurrentUser(XDBEventobj);
SELECT XMLCast(
XMLQuery(
'declare namespace ns = "http://xmlns.oracle.com/xdb/XDBResource.xsd";
/ns:Resource/ns:ContentType'
PASSING r.RES RETURNING CONTENT) AS VARCHAR2(100))
INTO ResType
FROM PATH_VIEW r WHERE r.PATH=ResPath;
IF ResType = 'text/xml' THEN LinkFolder := '/public/app/XML-TXT';
END IF;
IF ResType = 'image/gif' THEN LinkFolder := '/public/app/IMG';
END IF;
IF ResType = 'application/octet-stream' THEN LinkFolder := '/public/app/FOLDER';
END IF;
DBMS_XDB.link(ResPath, LinkFolder, ResDisplayName);
END;
END;
/

関連項目:

- 新規PL/SQLパッケージDBMS_XDBRESOURCEの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- 新規PL/SQLパッケージDBMS_XEVENTの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

Javaの例は次に示す2行を除き例30-2と同様に構成されます。この2行は要素を例30-2にある同じ名前と置換します。

<source>category</source>
<language>Java</language>

例30-4は、イベント・ハンドラを実装するJavaコードを示しています。ロジックは例30-3と同じです。

例30-4 イベント・リスナーを実装するJavaコード

import oracle.xdb.event.*;
import oracle.xdb.spi.*;
import java.sql.*;
import java.io.*;
import java.net.*;
import oracle.jdbc.*;
import oracle.sql.*;
import oracle.xdb.XMLType;
import oracle.xdb.dom.*;

public class category
extends oracle.xdb.event.XDBBasicEventListener
{
public Connection connectToDB() throws java.sql.SQLException
{
try
{
String strUrl="jdbc:oracle:kprb:";
String strUname="appcatguser1";
String strPwd="appcatguser1 ";
Connection conn=null;
OraclePreparedStatement stmt=null;
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
conn = DriverManager.getConnection(strUrl, strUname, strPwd);
return conn;
}
catch(Exception e1)
{
System.out.println("Exception in connectToDB java function");
System.out.println("e1:" + e1.toString());
return null;
}
}
public void handlePostLinkIn (XDBRepositoryEvent eventObject)
{
XDBPath objXDBPath = null;
String strPathName="";
objXDBPath = eventObject.getPath();
strPathName = objXDBPath.getName();
XDBResource objXDBResource1;
objXDBResource1 = eventObject.getResource();
String textResDisplayName = objXDBResource1.getDisplayName();
String resType = objXDBResource1.getContentType();
String linkFolder="";
System.out.println("resType" + resType+"sumit");
System.out.println("strPathName:" + strPathName);
System.out.println("textResDisplayName:" + textResDisplayName);
if (resType.equals("text/xml")) linkFolder = "/public/app/XML-TXT/";
else if (resType.equals("image/gif")) linkFolder = "/public/app/IMG/";
else if (resType.equals("application/octet-stream"))
linkFolder = "/public/app/FOLDER/";
System.out.println("linkFolder:" + linkFolder);
try
{
Connection con1 = connectToDB();
OraclePreparedStatement stmt=null;
stmt = (OraclePreparedStatement)con1.prepareStatement(
"CALL DBMS_XDB.link(?,?,?)");
stmt.setString(1,strPathName);
stmt.setString(2,linkFolder);
stmt.setString(3,textResDisplayName);
stmt.execute();
stmt.close();
con1.close();
}
catch(java.sql.SQLException ej1)
{
System.out.println("ej1:" + ej1.toString());
}

/* Make sure the link is not in the category folders.
Then check the target resource's mime type and create a link
in the appropriate category folder. */
}
public void handlePreUnlinkIn (XDBRepositoryEvent eventObject)
{
XDBPath objXDBPath = null;
String strPathName="";
objXDBPath = eventObject.getPath();
strPathName = objXDBPath.getName();
XDBResource objXDBResource1;
objXDBResource1 = eventObject.getResource();
String textResDisplayName = objXDBResource1.getDisplayName();
String resType = objXDBResource1.getContentType();
String linkFolder="";
if (resType.equals("text/xml")) linkFolder = "/public/app/XML-TXT/";
else if (resType.equals("image/gif")) linkFolder = "/public/app/IMG/";
else if (resType.equals("application/octet-stream"))
linkFolder = "/public/app/FOLDER/";
try
{
Connection con1 = connectToDB();
OraclePreparedStatement stmt=null;
stmt = (OraclePreparedStatement)con1.prepareStatement(
"CALL DBMS_XDB.deleteResource(?)");
stmt.setString(1,linkFolder+textResDisplayName);
stmt.execute();
stmt.close();
con1.close();
}
catch(java.sql.SQLException ej1)
{
System.out.println("ej1:" + ej1.toString());
}
}
}

例30-5は、例30-3または例30-4で実装されているイベント・ハンドラの起動を示しています。

例30-5 イベント・ハンドラの起動

DECLARE
ret BOOLEAN;
BEGIN
ret := DBMS_XDB.createResource('/public/res-app/res1.xml',
'<name>TestForEventType-1</name>');
END;
/
DECLARE
b BOOLEAN := FALSE;
dummy_data CLOB := 'AAA';
BEGIN
b := DBMS_XDB.createResource('/public/res-app/res2.gif', dummy_data);
END;
/
DECLARE
b BOOLEAN := FALSE;
dummy_data CLOB := 'AAA';
BEGIN
b := DBMS_XDB.createFolder('/public/res-app/res-appfolder1');
END;

SELECT PATH FROM PATH_VIEW WHERE PATH LIKE '/public/app/%' ORDER BY PATH;

PATH
---------------------------------
/public/app/FOLDER
/public/app/FOLDER/res-appfolder1
/public/app/IMG
/public/app/IMG/res2.gif
/public/app/XML-TXT
/public/app/XML-TXT/res1.xml

6 rows selected.

-- Delete the /res-app resources. The /app resources are deleted also.
EXEC DBMS_XDB.deleteResource('/public/res-app/res2.gif');
EXEC DBMS_XDB.deleteResource('/public/res-app/res1.xml');
EXEC DBMS_XDB.deleteResource('/public/res-app/res-appfolder1');

SELECT PATH FROM PATH_VIEW WHERE PATH LIKE '/public/app/%' ORDER BY PATH;

PATH
-------------------
/public/app/FOLDER
/public/app/IMG
/public/app/XML-TXT

3 rows selected.

31 Oracle XML DB Content Connectorの使用

この章では、Oracle XML DB Content Connectorを使用してOracle XML DBリポジトリにアクセスする方法について説明します。

Oracle XML DB Content Connectorは、JSR-170としてJavaコミュニティが開発した標準Java APIであるContent Repository API for Java(JCRとも呼ばれる)を実装します。

この章の内容は次のとおりです。

- JCRおよびOracle XML DB Content Connectorの概要

- JCRで公開されるOracle XML DBリポジトリ

- Oracle XML DB Content Connectorの使用方法

- XML SchemaのJCRでの使用

JCRおよびOracle XML DB Content Connectorの概要

この項では、次の項目について説明します。

- Content Repository API for Java(JCR)について

- Oracle XML DB Content Connectorについて

Content Repository API for Java(JCR)について

JCR 1.0は、アプリケーションがコンテンツ・リポジトリと対話するための標準Java APIを定義します。

関連項目:
Java Community Processの『Content Repository for Java technology API』、http://jcp.org/en/jsr/detail?id=170。第4章(JSR-170の仕様)でJCR 1.0の簡単な概要を説明しています。

JCRはコンテンツ・リポジトリのデータをノードのツリーとしてモデル化します。ノードはそれぞれ、1つ以上の子ノードを持つことができます。ルート・ノード以外のすべてのノードは、親ノードを1つのみ持ちます。

子ノードに加えて、各ノードは1つ以上のプロパティを持つことができます。プロパティは、単純な名前と値の組合せです。たとえば、コンテンツ・リポジトリで特定のファイルを表すノードには、値がファイルの作成日であるjcr:createdというプロパティがあります。

各プロパティにはプロパティ型があります。たとえば、jcr:createdプロパティには値を有効な日時にするよう要求するDATEというプロパティ型があります。

同様に、各ノードにはノード型があります。たとえば、ファイルを表すノードにはnt:fileというノード型があります。ノード型は、ノードが持つことが可能または必要な子ノードおよびプロパティを制御します。たとえば、nt:file型のすべてのノードにはjcr:createdプロパティがあります。

ノードとプロパティには名前が付けられているため、パスで指定できます。JCRでは絶対パスと相対パスの両方がサポートされています。たとえば、絶対パス

/My Documents/pictures/puppy.jpg/jcr:created

は、ファイルpuppy.jpgのjcr:createdプロパティに変換されます。また、次の相対パスにより、このプロパティをMy Documentsフォルダに対して指定できます。

pictures/puppy.jpg/jcr:created

ノード名およびプロパティ名は、名前空間修飾にできます。XML同様、JCRはコロンで区切られた名前空間接頭辞を使用して、jcr:createdなどの名前空間修飾名を表します。XMLと異なり、JCRではリポジトリ全体の名前空間レジストリで名前空間接頭辞とURIのマッピングが記録されます。たとえば、jcr接頭辞はURI http://www.jcp.org/jcr/1.0にマップされます。

Oracle XML DB Content Connectorについて

Oracle XML DB Content Connectorにより、JCR 1.0 Java APIを使用してOracle XML DBリポジトリにアクセスできます。アプリケーションは、スタンドアロンJava仮想マシンまたはJ2EEコンテナのいずれかで動作できます。

注意:
Oracle XML DB Content ConnectorをデータベースOracle JVM(データベース・プロセス内で使用可能なJava仮想マシン)で使用できません。データベース層でContent Connectorを使用するには、スタンドアロンJava仮想マシンまたはJ2EEコンテナのいずれかを使用する必要があります。

Oracle XML DBリポジトリのファイルおよびフォルダは、JCRノード(およびそれらのノードのプロパティ)として表されます。それらは、JCR APIを使用して作成、取出し、および更新が可能です。

JCRで公開されるOracle XML DBリポジトリ

Oracle XML DB Content Connectorは、Oracle XML DBリポジトリのデータをJCRノードおよびプロパティとして表します。ファイルおよびフォルダは、それぞれ型がnt:fileとnt:folderのノードとして表されます。そのコンテンツとメタデータは、ノード型がnt:resourceのノードとして公開されます。

この項では、次の項目について説明します。

- JCRでのファイルおよびフォルダの公開例

- JCRノード型に対するOracle拡張関数

- バイナリ・コンテンツおよびXMLコンテンツ

- システム定義メタデータ

- ユーザー定義メタデータ

- ハード・リンクおよび弱いリンク

JCRでのファイルおよびフォルダの公開例

フォルダMyFolderは、Oracle XML DBリポジトリのルート・フォルダに格納されています。フォルダには、Address.xmlとCar.jpgの2つのファイルが入っています。

ファイルAddress.xmlには次のXMLコンテンツが入っています。

<Address country="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Mill Valley</city>
<state>CA</state>
<zip>90952</zip>
</Address>

ファイルCar.jpgには自動車の写真であるバイナリ・コンテンツが入っています。また、次のユーザー定義XMLメタデータが入っています。

<i:ImageMetadata>
<Height>640</Height>
<Width>480</Width>
<RGB R="44" G="123" B="74"/>
</i:ImageMetadata>

Oracle XML DB Content Connectorは、MyFolder、Address.xml、Car.jpgをJCRノードおよびプロパティとして公開します。

例31-1は、JCRノードとプロパティのツリーとして表されるフォルダMyFolderを示します。この表現では、太字体はノード、イタリック体はノード型、標準体はプロパティを示し、山カッコで囲んだイタリック体(<>)はバイナリ・データなどの省略されたデータを示します。

例31-1 MyFolderのJCRノード表現

[root] (nt:folder)
jcr:created="2001-01-01T00:00:00.000Z"
jcr:content (nt:resource)
jcr:data=null
jcr:lastModified="2001-01-01T00:00:00.000Z"
ojcr:owner="SYS"
ojcr:creator="SYS"
ojcr:lastModifier="SYS"
ojcr:displayName=""
ojcr:language="en-US"
MyFolder (nt:folder)
jcr:created="2001-01-01T00:00:00.000Z"
jcr:content (nt:resource)
jcr:data=null
jcr:lastModified="2001-01-01T00:00:00.000Z"
ojcr:owner="ALICE"
ojcr:creator="BOB"
ojcr:lastModifier="CHARLIE"
ojcr:author="BOB"
ojcr:comment="An application folder"
ojcr:displayName="MyFolder"
ojcr:language="en-US"
ojcr:links (ojcr:links)
ojcr:folderLink (ojcr:linkProperties)
ojcr:linkType="Hard"
ojcr:linkSource=<RESID of the root folder>
ojcr:linkTarget=<RESID of folder MyFolder>
ojcr:linkName="MyFolder"
Address.xml (nt:file)
jcr:created="2005-09-01T12:34:56.789Z"
jcr:content (nt:resource)
jcr:encoding="UTF-8"
jcr:mimeType="text/xml"
jcr:data=<binary representation of the XML content>
jcr:lastModified="2005-09-01T12:34:56.789Z"
ojcr:owner="ALICE"
ojcr:creator="BOB"
ojcr:lastModifier="CHARLIE"
ojcr:author="BOB"
ojcr:displayName="Address.xml"
ojcr:language="en-US"
ojcr:xmlContent (nt:unstructured)
Address
country="US"
name
jcr:xmltext
jcr:xmlcharacters="Alice Smith"
street
jcr:xmltext
jcr:xmlcharacters="123 Maple Street"
city
jcr:xmltext
jcr:xmlcharacters="Mill Valley"
state
jcr:xmltext
jcr:xmlcharacters="CA"
zip
jcr:xmltext
jcr:xmlcharacters="90952"
ojcr:links (ojcr:links)
ojcr:folderLink (ojcr:linkProperties)
ojcr:linkType="Hard"
ojcr:linkSource=<RESID of folder MyFolder>
ojcr:linkTarget=<RESID of file Address.xml>
ojcr:linkName="Address.xml"
Car.jpg (nt:file)
jcr:created="2004-02-12T16:15:23.247Z"
jcr:content (nt:resource)
jcr:mimeType="image/jpeg"
jcr:data=<binary content of file Car.jpg>
jcr:lastModified="2004-02-12T17:20:25.314Z"
ojcr:owner="ALICE"
ojcr:creator="BOB"
ojcr:lastModifier="CHARLIE"
ojcr:author="BOB"
ojcr:displayName="A shiny red car!"
ojcr:language="en-US"
i:ImageMetadata
Height
jcr:xmltext
jcr:xmlcharacters="640"
Width
jcr:xmltext
jcr:xmlcharacters="480"
RGB
R="44"
G="123"
B="74"
ojcr:links (ojcr:links)
ojcr:folderLink (ojcr:linkProperties)
ojcr:linkType="Hard"
ojcr:linkSource=<RESID of folder MyFolder>
ojcr:linkTarget=<RESID of file Car.jpg>
ojcr:linkName="Car.jpg"

JCRノード型に対するOracle拡張関数

Oracle XML DB Content Connectorがnt:file、nt:folder、およびnt:resourceの各ノード型の定義を補強することによって、Oracle XML DBリポジトリにある追加情報が取り込まれます。ノード型ojcr:folderがnt:folderのスーパータイプとして追加され、ノード型ojcr:resourceがnt:resourceのスーパータイプとして追加されます。Oracle拡張関数は、すべて名前空間http://xmlns.oracle.com/jcr/1.0にあります。この名前空間は名前空間接頭辞ojcrにマップされます。

また、ノード型mix:referenceableがnt:fileおよびnt:folderのスーパータイプとして追加され、それらのリソースIDによってすべてのファイルとフォルダにアクセスできます。

バイナリ・コンテンツおよびXMLコンテンツ

プロパティjcr:dataにはファイルのバイナリ・コンテンツが入っています。jcr:dataは、ノードnt:fileではなくその子ノードjcr:contentのプロパティです。XMLコンテンツを含むファイルの場合、ノードjjcr:contentには子ノードojcr:xmlContentがあり、そこでXMLコンテンツに一連のJCRノードとプロパティとしてアクセスできます。例31-1で参照されるファイルAddress.xmlがこのようなファイルに該当します。リポジトリのXMLファイルのXMLコンテンツは、JCRで定義されたドキュメント・ビュー・シリアライズを使用してJCRノードとプロパティにマップされます。その場合、次のようになります。

- XML要素は、JCRノードとして公開されます。

- XML属性は、JCRプロパティとして公開されます。

- XMLテキストは、jcr:xmltextというノード内のjcr:xmlcharactersというJCRプロパティとして公開されます。

システム定義メタデータ

Oracle XML DBリポジトリは、各リポジトリ・ファイルおよびフォルダのメタデータを保持します。データベース・ビューRESOURCE_VIEWおよびPATH_VIEWでは、このメタデータはXMLType列RESの一連のXML要素として表されます。JCRでは、このメタデータは名前空間jcrおよびojcrのプロパティにマップされます。表31-1で、このマッピングについて説明します。

表31-1 Oracle XML DBリソースとJCRのマッピング

XPath

ノードnt:fileまたはnt:folderからの相対パス

/Resource/CreationDate

jcr:created

/Resource/ModificationDate

jcr:content/jcr:lastModified

/Resource/Author

jcr:content/ojcr:author

/Resource/DisplayName

jcr:content/ojcr:displayName

/Resource/Comment

jcr:content/ojcr:comment

/Resource/Language

jcr:content/ojcr:language

/Resource/CharacterSet

jcr:content/jcr:encoding

/Resource/ContentType

jcr:content/jcr:mimeType

/Resource/Owner

jcr:content/ojcr:owner

/Resource/Creator

jcr:content/ojcr:creator

/Resource/LastModifier

jcr:content/ojcr:lastModifier

ユーザー定義メタデータ

ユーザー定義のXMLメタデータは、リポジトリ・ファイルまたはフォルダのjcr:content子ノードの下でJCRノードおよびプロパティとして公開されます。XMLファイル同様、XMLメタデータは、JCRで定義されるドキュメント・ビュー・シリアライズを使用してJCRノードとプロパティにマップされます。このシリアライズの詳細は、「バイナリ・コンテンツおよびXMLコンテンツ」を参照してください。

例31-1では、ファイルCar.jpgにこのユーザー定義メタデータが入っています。

<i:ImageMetadata>
<Height>640</Height>
<Width>480</Width>
<RGB R="44" G="123" B="74"/>
</i:ImageMetadata>

次のJCRパスによってWidth値を取得します。

/My Folder/Car.jpg/jcr:content/i:ImageMetadata/
Width/jcr:xmltext/jcr:xmlcharacters

ハード・リンクおよび弱いリンク

JCRでは、親ノードは各ノードとプロパティには1つのみありますが、ルート・ノードにはありません。そのため、各JCRノードまたはプロパティには絶対パスが1つのみ存在します。

しかし、Oracle XML DBリポジトリでは、リソース(ファイルまたはフォルダ)を子の寿命を制御するハード・リンクまたは子の寿命を制御しない弱いリンクのいずれかで複数の親フォルダにリンクさせることができます。その結果、リソースに複数のパスが存在することになり、リソースは複数の親を持つことができます。

パスの解決時に、Oracle XML DB Content Connectorはハード・リンクおよび弱いリンクの両方を検索します。リソースに複数のパスが存在する場合、JCRメソッドgetPath()により、そのセッションによるsave()またはrefresh(boolean)への最新のコールの後にそのリソースが最初に検出されたパスが戻されます。JCRメソッドgetParent()はそのパスのターゲットとなっているフォルダを戻します。

リソースが複数リンクのターゲットで、複数の親フォルダがある場合、リソースのすべての親のリストを取得すると便利な場合が多くあります。Oracle XML DB Content Connectorはこのリストを、ノードnt:fileまたはnt:folderに対するパスjcr:content/ojcr:links/ojcr:folderLinkを持つ型ojcr:linkPropertiesのノードとして表します。リソースの親ごとに1つのojcr:folderLinkノードが存在します。

ノードojcr:folderLinkには次のプロパティがあります。

- ojcr:linkType: リンク・タイプ(HardまたはWeak)

- ojcr:linkSource: 親フォルダのリソースID

- ojcr:linkTarget: 子ファイルまたはフォルダのリソースID

- ojcr:linkName: その親の子ファイルまたはフォルダの名前

Oracle XML DB Content Connectorの使用方法

この項では、Oracle XML DB Content Connectorを使用してOracle XML DBリポジトリの情報にアクセスする方法について説明します。内容は次のとおりです。

- CLASSPATHの設定

- JCRリポジトリ・オブジェクトの取得

- ファイルのアップロードのためのサンプル・コード

- 追加コード・サンプル

- Oracle XML DB Content ConnectorのロギングAPI

- サポートされているJCRコンプライアンス・レベル

- Oracle XML DB Content Connectorの制限

CLASSPATHの設定

Oracle XML DB Content Connectorには、Java CLASSPATH変数に次のエントリが必要です。

- $ORACLE_HOME/lib/jcr-1.0.jar

- $ORACLE_HOME/lib/ojcr.jar

- $ORACLE_HOME/lib/xmlparserv2.jar

- $ORACLE_HOME/jlib/xquery.jar

JCRリポジトリ・オブジェクトの取得

Oracle XML DB Content Connectorでは、oracle.jcr.OracleRepositoryは、JCRリポジトリへのエントリ・ポイントとなるJCRインタフェースjavax.jcr.Repositoryを実装します。例31-2のコード・フラグメントは、Oracle XML DBリポジトリのRepositoryオブジェクトの取得方法を示しています。

例31-2リポジトリ・オブジェクトの取得方法を示すコード・フラグメント

import oracle.jcr.OracleRepository;
import oracle.jcr.OracleRepositoryFactory;
import oracle.jcr.xdb.XDBRepositoryConfiguration;
import oracle.jdbc.pool.OracleDataSource;
...
XDBRepositoryConfiguration configuration =
new XDBRepositoryConfiguration();
OracleDataSource ods =
(OracleDataSource)configuration.getDataSource();
// databaseURL is a JDBC database URL.
ods.setURL(databaseURL);
// OracleRepository implements javax.jcr.Repository.
OracleRepository repository =
OracleRepositoryFactory.createOracleRepository(configuration);

OracleRepositoryは、java.io.Serializableおよびjavax.naming.Referenceableの両方を実装します。これによりアプリケーションのデプロイ時にOracleRepositoryオブジェクトを作成および構成し、JNDIディレクトリにすぐに使用できるOracleRepositoryオブジェクトを格納できます。実行時に、アプリケーションはJNDIディレクトリから構成済のOracleRepositoryオブジェクトを取得できます。JCRの仕様でお薦めするこの方法により、デプロイメントと実行時の懸案事項が区別されます。

Oracle XML DB Content Connectorでは、JCR名前空間レジストリを構成する接頭辞とURIのマッピングはOracleRepository構成の一部として格納されます。

関連項目:
『Oracle Database XML Java API Reference』、パッケージoracle.jcrを参照してください。

ファイルのアップロードのためのサンプル・コード

例31-3は、Oracle XML DB Content Connectorを使用してローカル・ファイル・システムからOracle XML DBリポジトリへファイルをアップロードするJavaプログラムです。

例31-3 Oracle XML DB Content Connectorを使用したファイルのアップロード

import java.io.FileInputStream;

import javax.jcr.Node;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;

import oracle.jcr.OracleRepository;
import oracle.jcr.OracleRepositoryFactory;

import oracle.jcr.xdb.XDBRepositoryConfiguration;

import oracle.jdbc.pool.OracleDataSource;

public class UploadFile
{
public static void main(String[] args)
throws Exception
{
String databaseURL = args[0];
String userName = args[1];
String password = args[2];
String parentPath = args[3];
String fileName = args[4];
String mimeType = args[5];

// Get the JCR Repository object.
XDBRepositoryConfiguration configuration =
new XDBRepositoryConfiguration();

OracleDataSource ods =
(OracleDataSource)configuration.getDataSource();

ods.setURL(databaseURL);

OracleRepository repository =
OracleRepositoryFactory.createOracleRepository(configuration);

// Create a JCR Session.
SimpleCredentials sc =
new SimpleCredentials(userName, password.toCharArray());

Session session = repository.login(sc);

// Get the parent node.
Node parentNode = (Node)session.getItem(parentPath);

// Get the child contents.
FileInputStream inputStream = new FileInputStream(fileName);

// Create child node.
Node node = parentNode.addNode(fileName, "nt:file");
Node contentNode = node.getNode("jcr:content");
contentNode.setProperty("jcr:mimeType", mimeType);
contentNode.setProperty("jcr:data", inputStream);

// Save changes and logout.
session.save();
session.logout();
}
}

// EOF

例31-3は、コマンドラインからコンパイルして実行できます。プログラムには、次のようなコマンドライン引数が必要です。

- JDBCデータベースURL

- ユーザーID

- ユーザー・パスワード

- ファイルをアップロードするOracle XML DBリポジトリのフォルダ

- アップロードするファイル

- MIMEタイプ

例31-4に、これを示します。

例31-4 コマンドラインを使用したファイルのアップロード

export CLASSPATH=.:$ORACLE_HOME/lib/jcr-1.0.jar:$ORACLE_HOME/lib/ojcr.jar:$ORACLE_HOME/lib/xmlparserv2.jar:$ORACLE_HOME/jlib/xquery.jar

javac UploadFile.java

java UploadFile jdbc:oracle:oci:@ quine password /public MyFile.txt text/plain

追加コード・サンプル

次の場所に追加サンプル・コードがあります。

$ORACLE_HOME/xdk/demo/java/jcr

コード・サンプルごとに、READMEファイルにその目的および使用方法が記述されています。

Oracle XML DB Content ConnectorのロギングAPI

Oracle XML DB Content Connectorは標準のjava.util.loggingフレームワークを使用します。そのフレームワークにより提供されたロギングAPIを使用して、ロギング動作を制御できます。たとえば、次のJavaコード・フラグメントはすべてのロギングを無効にします。

import java.util.logging.LogManager;
...
LogManager.getLogManager().reset();

サポートされているJCRコンプライアンス・レベル

JCRバージョン1.0を定義するJSR-170標準では、2つのコンプライアンス・レベルと一連のオプション機能が定義されています。Oracle XML DB Content Connectorでは、レベル1(読取り機能)とレベル2(書込み機能)がサポートされています。

Oracle XML DB Content Connectorの制限

この項では、Oracle XML DB Content Connectorの制限について説明します。

デフォルトのワークスペース名

単一のワークスペースがサポートされています。javax.jcr.Repositoryのlogin(Credentials, String)メソッドまたはlogin(String)メソッドをコールする場合は、ワークスペース名を必ず空の文字列("")またはNULLにしてください。

特定のノード型に制限された操作

javax.jcr.Itemのメソッドsave()およびrefresh()は、型がnt:fileまたはnt:folderのノードでのみコールできます。または、javax.jcr.Sessionのメソッドmove()およびjavax.jcr.Workspaceのメソッドcopy()およびmove()は、ノードnt:fileおよびnt:folderでのみコールできます。

ファイルまたはフォルダの状態の決定

javax.jcr.ItemのメソッドisNew()およびisModified()は、項目自体ではなく、項目を含むファイルまたはフォルダの状態を戻します。メソッドisNew()は、ファイルまたはフォルダがJCR一時レイヤーで作成されているが保存されていない場合にtrueを戻します。メソッドisModified()は、ファイルまたはフォルダがJCR一時レイヤーで変更されているが保存されていない場合にtrueを戻します。

バイナリ・コンテンツとXMLコンテンツの間の相互作用

プロパティjcr:dataにはファイルのバイナリ・コンテンツが入っています。ファイル・コンテンツがXMLの場合、そのXMLコンテンツがJCRノードおよびプロパティとして公開されている場所にojcr:xmlContentノードも存在します。ojcr:xmlContentサブツリーへの変更は、それらの変更が保存されるまでjcr:dataプロパティに反映されません。jcr:dataプロパティとojcr:xmlContentサブツリーの両方を変更した場合、それらの変更が保存されるとojcr:xmlContentサブツリーが優先されます。

変更の保存順

クラスjavax.jcr.Sessionまたはクラスjavax.jcr.Itemのsaveメソッドは、一時レイヤーで行われた変更を保存します。1つ以上のノードまたはプロパティが変更されている場合、JCRは変更の格納順を指定しません。Oracle XML DB Content Connectorは、次のものの変更を保存します。

1. 既存のファイルとフォルダに、パスでソートされた順序で更新を適用します。

2. 新しいファイルとフォルダを、パスでソートされた順序で作成します。

3. 既存のファイルとフォルダを、パスでソートされた順序の逆順で移動します。

4. 既存のファイルとフォルダを、パスでソートされた順序の逆順で削除します。

未定義のプロパティ

型UNDEFINEDの定義を持つプロパティは、STRING値として格納されます。

ノード型nt:baseは抽象

ノード型nt:baseは抽象で、新しいノードの型としては指定できません。

自動作成されるノードjcr:content

型がnt:fileまたはnt:folderのノードを作成する場合、jcr:contentノードが子として自動的に作成されます。

保存によるノードjcr:xmltextの正規化

保存すると、連続したjcr:xmltextノードが単一jcr:xmltextノードの中に結合されます。このノードはXMLコンテンツまたはユーザー定義メタデータ内のテキストを表します。

ノード型mix:referenceable

ノード型nt:file、nt:folderおよびnt:resourceは、ミックスインノード型mix:referenceableのサブタイプです。現在、すべてのnt:file、nt:folderおよびnt:resourceノードは、UUIDで参照できます。mix:referenceableはどんな型のノードにも追加できません。

全文索引

PL/SQLパッケージDBMS_XDBT使用して、ファイル・コンテンツ上に全文索引を作成することができます。これにより、問合せで関数jcr:containsをjcr:contentノードのプロパティjcr:dataに適用することができます。他のプロパティ上での全文索引はサポートされません。

XML SchemaのJCRでの使用

Oracle XML DB Content ConnectorはXML SchemaからJCRノード型を作成できます。

この項では、次の項目について説明します。

- JCRで使用する場合にXML Schemaを登録する理由

- JCRを使用したXML Schemaの登録方法

- XML SchemaからのJCRノード型の生成方法

JCRで使用する場合にXML Schemaを登録する理由

XMLデータは、ファイル・コンテンツまたはユーザー定義メタデータとしてOracle XML DBリポジトリに格納できます。いずれの場合も、XMLデータはXML Schemaに基づいて作成できます。XML Schemaに基づくデータはOracle XML DBで登録されたXML Schemaに対して検証されます。

デフォルトでは、XML文書コンテンツとユーザー定義メタデータに対応するJCRノードの型は、XMLデータがXML Schemaに基づいていてもJCRにより定義される汎用ノード型であるnt:unstructuredになります。Oracle XML DBリポジトリはXML Schemaに対してOracle XML DB Content Connectorを通して行われた変更を検証しますが、JCRでメタデータにアクセスしたり、型指定したりすることはできません。

ただし、Oracle XML DB Content ConnectorによりXML SchemaをJCRで使用できるよう登録できます。これによりContent Connectorは、XML Schema単純型、複合型、グローバルな要素宣言のJCRノード型を登録XML Schemaに生成します。

XMLデータをJCRノードとして公開する場合、Content Connectorはそのルート要素のXML属性xsi:schemaLocationまたはxsi:noNamespaceSchemaLocationの値に基づいて、XMLデータがJCRで使用するために登録されたXML Schemaに準拠するかどうか判断します。XMLデータがJCR登録XML Schemaに準拠する場合、XMLデータは、汎用ノード型nt:unstructuredを使用せずに、XML Schemaから生成されたノード型のJCRノードとして公開されます。

また、生成されたJCRノード型を使用してXML文書コンテンツおよびユーザー定義メタデータを作成したり、更新したりできます。

例31-5に、XML Schemaに基づくコンテンツを持つXML文書を示します。

例31-5 XML Schemaに基づくコンテンツを持つXML文書

<Address country="US"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"http://www.example.com/Address">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Mill Valley</city>
<state>CA</state>
<zip>90952</zip>
</Address>

例31-5のコンテンツは、例31-6で示すXML Schemaに関して有効です。

例31-6 XML Schema

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="USAddress">
<xsd:sequence>
<xsd:element name="name"   type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city"   type="xsd:string"/>
<xsd:element name="state"  type="xsd:string"/>
<xsd:element name="zip"    type="xsd:long"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN"
fixed="US"/>
</xsd:complexType>
</xsd:schema>

最初は、このXML SchemaはJCRで使用できるように登録されていません。XMLコンテンツを表すJCRノードおよびプロパティは、例31-7に示されています。

例31-7 JCRで使用するために登録されていないXMLコンテンツのJCR表現

ojcr:xmlContent (nt:unstructured)
Address (nt:unstructured)
country="US" (String)
name (nt:unstructured)
jcr:xmltext(ojcr:xmltext)
jcr:xmlcharacters="Alice Smith" (String)
street (nt:unstructured)
jcr:xmltext(ojcr:xmltext)
jcr:xmlcharacters="123 Maple Street" (String)
city (nt:unstructured)
jcr:xmltext(ojcr:xmltext)
jcr:xmlcharacters="Mill Valley" (String)
state (nt:unstructured)
jcr:xmltext(ojcr:xmltext)
jcr:xmlcharacters="CA" (String)
zip (nt:unstructured)
jcr:xmltext (ojcr:xmltext)
jcr:xmlcharacters="90952" (String)

XML SchemaはJCRで使用できるように登録されています。JCRノードおよびプロパティは例31-8に示されています。

例31-8 JCRで使用するために登録されているXMLコンテンツのJCR表現

ojcr:xmlContent (nt:unstructured)
Address (USAddress)
country="US" (String)
name (xsd:string)
jcr:xmltext(ojcr:xmltext)
jcr:xmlcharacters="Alice Smith" (String)
street (xsd:string)
jcr:xmltext(ojcr:xmltext)
jcr:xmlcharacters="123 Maple Street" (String)
city (xsd:string)
jcr:xmltext(ojcr:xmltext)
jcr:xmlcharacters="Mill Valley" (String)
state (xsd:string)
jcr:xmltext(ojcr:xmltext)
jcr:xmlcharacters="CA" (String)
zip (xsd:long)
jcr:xmltext (ojcr:xmltext)
jcr:xmlcharacters="90952" (Long)

ノードAddressのノード型はUSAddressです。同様に、ノードname、street、city、およびstateのノード型はxsd:stringです。ノードzipのノード型はxsd:longで、その子であるjcr:xmltextのjcr:xmlcharactersプロパティのプロパティ型はLONGです。

関連項目:
第29章「ユーザー定義のリポジトリ・メタデータ」

JCRを使用したXML Schemaの登録方法

JCRで使用するようXML Schemaを登録する前に、PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaを使用してOracle XML DBで使用できるよう登録する必要があります。たとえば、場所がhttp://www.example.com/AddressのXML Schemaを登録するには、まず例31-9で示すように、まずOracle XML DBで使用できるよう登録します。次に、例31-10で示すように、Oracle XML DB Content Connector Java APIを使用してJCRで使用できるよう登録します。

例31-9 Oracle XML DBで使用するためのXML Schemaの登録

BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL       => 'http://www.example.com/Address',
SCHEMADOC       => bfileContainingSchema,
LOCAL           => FALSE,
ENABLEHIERARCHY => DBMS_XMLSCHEMA.ENABLE_HIERARCHY_RESMETADATA);
END;
/

注意:
グローバルに登録されたXML Schema(local=>false)のみJCRで使用できます。

例31-10 JCRで使用するためのXML Schemaの登録

import oracle.jcr.nodetype.OracleNodeTypeManager;...
OracleNodeTypeManager ntm = (OracleNodeTypeManager)
session.getWorkspace().getNodeTypeManager();

ntm.registerXMLSchema("http://www.example.com/Address", null);

JCRで使用できるよう登録されたXML SchemaのリストはOracleRepositoryオブジェクトに格納されています。JCRの仕様でお薦めしているように、OracleRepositoryオブジェクトをJNDIディレクトリに格納することで、この登録データを保存できます。

JCRでは、各ノード型は一意の名前である必要があります。デフォルトでは、Oracle XML DB Content Connectorは登録済のXML Schemaに対応するJCRノード型をXML Schemaのターゲット名前空間に生成します。同じ名前空間の2つのXML Schemaや、名前が同じXML Schema宣言型を登録する場合、JCRノード型が生成される名前空間にオーバーライドすることで、名前のクラッシュを回避できます。詳細は、メソッドregisterXMLSchema()のJavadocを参照してください。

関連項目:

- Oracle XML DBを使用したXML Schema登録の詳細は、「DBMS_XMLSCHEMAを使用したXML Schemaの管理」を参照してください。

- JavaメソッドregisterXMLSchema()の詳細は、『Oracle Database XML Java API Reference』、パッケージoracle.jcrを参照してください。

XML SchemaからのJCRノード型の生成方法

この項では、JCRで使用できるよう登録されているXML SchemaからのOracle XML DB Content ConnectorによるJCRノード型の生成方法について説明します。

JCRおよびXML Schemaの型モデルは似ていますが、同じではありません。XML Schemaには、JCRで表現されない側面もあります。たとえば、XML Schema単純型の制約ファセットの中にはJCRから検出できないものもあります。そうした場合でも、それらはOracle XML DB Content Connectorにより適用されます。

一般的には、XML Schemaから生成されたJCRノード型は、JCRや他のインタフェース関係なく、そのXML Schemaに準拠するXMLデータが作成または更新されるときに実行されるXML Schema検証を補強したり、損ったり、変更することはありません。

組込み単純型

JCRノード型はXML Schema組込み型ごとに提供されています。たとえば、JCRノード型xsd:decimalは組込み型xsd:decimalに対応します。

JCRノード型の継承階層は、組込み型の継承階層に従います。たとえば、xsd:integerはxsd:decimalのサブタイプです。

各XML Schema組込み型は、JCRでその型の値を表す場合に使用するJCRプロパティ値型にマップします。

表31-2 JCRプロパティ値型にマップされるXML Schema組込み型

XML Schema組込み型

JCRプロパティ値型

xsd:anySimpleType

STRING

xsd:anyURI

STRING

xsd:base64Binary

BINARY

xsd:boolean

BOOLEAN

xsd:byte

LONG

xsd:date

DATE(1)

xsd:dateTime

DATE(1)

xsd:decimal

DOUBLE(2)

xsd:double

DOUBLE

xsd:duration

STRING

xsd:ENTITIES

STRING(3)

xsd:ENTITY

STRING

xsd:float

DOUBLE

xsd:gDay

STRING

xsd:gMonth

STRING

xsd:gMonthDay

STRING

xsd:gYear

STRING

xsd:gYearMonth

STRING

xsd:hexBinary

BINARY

xsd:ID

STRING

xsd:IDREF

STRING

xsd:IDREFS

STRING(3)

xsd:int

LONG

xsd:integer

LONG(2)

xsd:language

STRING

xsd:long

LONG

xsd:Name

STRING

xsd:NCName

STRING

xsd:negativeInteger

LONG

xsd:NMTOKEN

STRING

xsd:NMTOKENS

STRING(3)

xsd:nonNegativeInteger

LONG

xsd:nonPositiveInteger

LONG

xsd:normalizedString

STRING

xsd:NOTATION

STRING

xsd:positiveInteger

LONG

xsd:QName

STRING

xsd:short

LONG

xsd:string

STRING

xsd:time

DATE(1)

xsd:token

STRING

xsd:unsignedByte

LONG

xsd:unsignedInt

LONG

xsd:unsignedLong

LONG

xsd:unsignedShort

LONG

表31-2の注意:

1. JCR DATEプロパティ型はjava.util.Calendarオブジェクトを使用してアクセスされます。Calendarではすべてのフィールドを設定する必要があるため、1970-01-01T00:00:00.000+00:00のマスクを使用して、Property.getDate()またはValue.getDate()をコールしたときに欠落したフィールドのデフォルト値が提供されます。これには省略された時間/分/秒の値(xsd:date用)、年/月/日の値(xsd:time用)、タイムゾーン値(xsd:date、xsd:time、およびxsd:dateTime用)が含まれます。Property.getString()またはValue.getString()をコールすると、解析対象外文字列表現が戻されます。同様に、Property.setValue(String)またはProperty.setValue(valueFactory.createValue(String))を使用してマスクを適用せずにDATEプロパティを設定できます。

2. xsd:decimalおよびxsd:integerの値領域は、(Java doubleおよびlong値としてアクセスされた)対応するJCR型DOUBLEおよびLONGの値領域を超えます。そのため、xsd:decimalおよびxsd:integer値のいくつかは文字列としてJCRでのみアクセスできます。たとえば、bigIntegerProperty.getLong()はjavax.jcr.ValueFormatExceptionを発生させますが、bigIntegerProperty.getString()は解析対象外文字列表現を戻します。同様に、Property.setValue(String)またはProperty.setValue(valueFactory.createValue(String))を使用して、DOUBLEまたはLONGプロパティをJCR値領域外の値に設定できます。

3. xsd:ENTITIES、xsd:IDREFSおよびxsd:NMTOKENSは複数値のSTRINGプロパティとしてJCRで表現されます。

XML Schema定義単純型

JCRノード型はXML Schemaで定義された単純型ごとに作成されます。JCRノード型の継承階層は、XML Schema型の継承階層に従います。

リスト単位で派生した単純型は、複数値のJCRプロパティ定義により表現されます。

共用体単位で派生した単純型は、プロパティ型がUNDEFINEDのJCRプロパティ定義により表現されます。

無名単純型に対応するJCRノード型には、統合名anonymousNodeType#sequenceNumberがあります。アプリケーションは統合名に応じて決まるものではありません。統合名はセッション間で同じであることが保証されず、JCRで使用するためにXML Schemaが登録または登録抹消されたり、登録XML Schemaの定義が変更されたりするときに変更される可能性があります。

複合型

JCRノード型はXML Schemaで定義された複合型ごとに作成されます。JCRノード型の継承階層は、XML Schema型の継承階層に従います。

XML Schema複合型に対応するJCRノード型:

- 複合型の属性宣言ごとにプロパティ定義が作成されます。複合型で名前により参照される属性宣言または属性グループは、調和して定義されているかのように処理されます。

- 複合型に属性ワイルド・カードがある場合に、未処理のプロパティ定義が作成されます。

- 子ノード定義は、複合型の内容モデルの一意の名前の要素宣言ごとに作成されます。名前により参照される要素宣言またはモジュール・グループは、調和して定義されているかのように処理されます。要素宣言が代用グループの先頭にある場合、子ノード定義も代用グループ内の要素宣言ごとに作成されます。

- 複合型に要素ワイルド・カードがある場合に、未処理の子ノード定義が作成されます。

- xsd:mixed = "true"であるため、またはxsd:simpleContent定義であるため、複合型によりXMLテキストが可能な場合にjcr:xmltext子ノード定義が作成されます。

複合型のJCRノード型は子ノードを順序付けします。

型がJCRを使用して拡張関数で得られたのか、制限で得られたのかを判断することはできません。

無名複合型に対応するJCRノード型には、統合名anonymousNodeType#sequenceNumberがあります。アプリケーションは統合名に応じて決まるものではありません。統合名はセッション間で同じであることが保証されず、JCRで使用するためにXML Schemaが登録または登録抹消されたり、登録XML Schemaの定義が変更されたりするときに変更される可能性があります。

グローバルな要素宣言

JCRノード型はXML Schemaのグローバルな要素宣言ごとに作成されます。生成されたノード型のローカル名は、アンダースコア(_)をグローバルな要素宣言のローカル名の先頭に追加して作成されます。たとえば、名前空間修飾発注書XML Schemaでは、po:_purchaseOrderというノード型はpo:purchaseOrderというグローバル要素について作成されます。

32 JavaでのOracle XML DBアプリケーションの作成

この章では、Oracle XML DBアプリケーションをJavaで作成する方法を説明します。サーブレットを含むJavaアプリケーションを作成する場合の設計のガイドライン、およびOracle XML DBサーブレットを構成する方法を説明します。

この章の内容は次のとおりです。

- Oracle XML DBのJavaアプリケーションの概要

- 設計のガイドライン: データベース内外でのJava

- JavaでのOracle XML DB HTTPサーブレットの作成

- Oracle XML DBサーブレットの構成

- Oracle XML DBサーブレットに対するHTTPリクエストの処理

- セッション・プールおよびOracle XML DBサーブレット

- ネイティブなXMLストリームのサポート

- Oracle XML DBサーブレットのAPI

- Oracle XML DBサーブレットの例

Oracle XML DBのJavaアプリケーションの概要

Javaコードは次の方法で使用できます。

- データベースでのJava仮想マシン(JVM)の使用。

- クライアント・サーバーまたはアプリケーション・サーバーでのJDBC用のOCIドライバの使用。

データベース内のJavaは、データベース・サーバー・プロセスのコンテキストで実行されるため、Javaコードをデプロイする方法は、次のいずれかに制限されます。

- SQLまたはPL/SQLから起動するストアド・プロシージャとしてJavaコードを実行できます。

- Javaサーブレットを実行できます。

ストアド・プロシージャは、SQLコードおよびPL/SQLコードと簡単に統合できます。Oracle DatabaseにアクセスするプロトコルとしてOracle Net Servicesを使用する必要があります。

サーブレットは、Oracle Databaseへの最上位のエントリ・ポイントとしてより適切に機能し、Oracle DatabaseにアクセスするプロトコルとしてHTTP(S)を使用する必要があります。

データベース内外で使用可能なOracle XML DB API

すべてのOracle XML DB APIは、サーバー内とデータベース外の両方で実行するアプリケーションで使用可能です。次のものが含まれます。

- XMLTypeに対するJDBCのサポート

- XMLTypeクラス

- Java DOMインプリメンテーション

設計のガイドライン: データベース内外でのJava

JavaでOracle XML DBアプリケーションを作成するアーキテクチャを選択する場合は、次のガイドラインを考慮します。

HTTP(S): JavaサーブレットへのアクセスまたはXMLTypeリソースへの直接アクセス

ダウンストリーム・クライアントがXMLをテキスト表現で処理する場合、HTTP(S)を使用してJavaサーブレットにアクセスするか、またはXMLTypeリソースに直接アクセスする方法が最適です。この方法は、特にJavaプログラムによるXMLノード・ツリーの操作が少ない場合に有効です。

サーバーにJavaを実装すると、UCS-2 Unicode(Java文字列に必要です)で文字データを変換せずに、データをデータベースからネットワークへネイティブに移動できます。多くの場合、データはデータベースのバッファ・キャッシュからHTTP(S)接続に直接コピーされます。データをバッファ・キャッシュから、Oracle Net Servicesで使用されるSQLのシリアライズ・フォーマットに変換し、それをJDBCクライアントに移して、XMLに変換する必要はありません。データベース・サーバー内部では、XMLTypeのロード・オンデマンドおよびLRUキャッシュが最も効率的です。

多くのXMLTypeオブジェクト要素へのアクセス: JDBC XMLTypeサポートの使用

ダウンストリーム・クライアントが、JavaプログラムによってXMLTypeインスタンスの多く、またはほとんどの要素にアクセスするアプリケーションである場合は、最適のパフォーマンスのためJDBC XMLTypeサポートを使用します。また、Javaプログラムのデバッグは、通常、データベース・サーバーの外部で行う方が簡単です。

サーブレットを使用したデータの操作およびXMLとしての迅速な書込み

Oracle XML DBサーブレットは、HTTP(S)を使用してアクセス可能なHTTPストアド・プロシージャをJavaで作成するためのものです。インターネット・アプリケーション全体を開発することを目的としたプラットフォームではありません。その場合、Oracle Application Serverのアプリケーション・サーバーにアプリケーション・サーブレットをデプロイし、JDBCを使用するか、またはjava.net.*や同様のAPIを使用してデータベース内のデータにアクセスし、HTTP(S)を使用してXMLデータを取得する必要があります。

サーブレットは、エンドユーザーのためにHTMLページをフォーマットするのではなく、データベースにアクセスし、データを操作して、そのデータをXMLとして迅速に書き込むアプリケーションに最適です。

JavaでのOracle XML DB HTTPサーブレットの作成

Oracle XML DBは、FTP、HTTP 1.1、WebDAVおよびJavaサーブレットをサポートするプロトコル・サーバーを提供します。Oracle XML DBは、Javaサーブレットのバージョン2.2をサポートしますが、次の例外があります。

- サーブレットのWARファイル(web.xml)はサポートされません。手動で操作する必要があるweb.xml構成パラメータが存在します。たとえば、ロールの作成は、SQL CREATE ROLEコマンドを使用して行う必要があります。

- RequestDispatcherおよび関連付けられたメソッドはサポートされません。

- HTTPServletRequest.getCookies()メソッドはサポートされません。

- 現在、1つのServletContext (および1つのweb-app)のみがサポートされています。

- ステートフル・サーブレット(およびHttpSessionクラスのメソッド)は、サポートされません。サーブレットは、データベース自体の状態を保持する必要があります。

Oracle XML DBサーブレットの構成

Oracle XML DBサーブレットは、Oracle XML DBリポジトリの/xdbconfig.xmlファイルを使用して構成されます。このファイル内の多くのXML要素は、Java 2 Enterprise Edition(J2EE)のJavaサーブレット2.2仕様部分に定義されているものと同じであり、同じセマンティクスを持ちます。表32-1に、Javaサーブレットの仕様でサーブレット・デプロイメント・ディスクリプタに対して定義されたXML要素、およびOracle XML DBがサポートする拡張要素を示します。

表32-1 サーブレット・デプロイメント・ディスクリプタに対して定義されたXML要素

XML要素名

定義元

サポートの有無

説明

コメント

auth-method

Java

非サポート

アクセスに必要なHTTP認証方式を指定します。

--

charset

Oracle

サポート

IANAキャラクタ・セット名を指定します。

ISO8859、UTF-8などです。

charset-mapping

Oracle

サポート

ファイル名の拡張子とキャラクタ・セットの間のマッピングを指定します。

--

context-param

Java

非サポート

Webアプリケーション用のパラメータを指定します。

現在はサポートされていません。

description

Java

サポート

サーブレットまたはWebアプリケーションを説明する文字列です。

サーブレット用にサポートされています。

display-name

Java

サポート

サーブレットまたはWebアプリケーションで表示する文字列です。

サーブレット用にサポートされています。

distributable

Java

非サポート

すべてのインスタンスが同じJava仮想マシンで実行していない場合に、このサーブレットが機能できるかどうかを示します。

Oracle Databaseで実行するすべてのサーブレットは、distributableである必要があります。

errnum

Oracle

サポート

Oracleエラー番号です。

『Oracle Databaseエラー・メッセージ』を参照してください。

error-code

Java

サポート

HTTP(S)エラー・コードです。

RFC 2616で定義されています。

error-page

Java

サポート

エラーが発生した場合のリダイレクト先のURLを定義します。

HTTP(S)エラー、不明なJava例外または不明なOracleエラー・メッセージで指定できます。

exception-type

Java

サポート

エラー・ページにマップされたJava例外のクラス名です。

--

extension

Java

サポート

MIMEタイプやキャラクタ・セットなどに関連付けるために使用するファイル名の拡張子です。

--

facility

Oracle

サポート

エラー・ページをマッピングするためのOracle機能コードです。

ORA、PLSなどです。

form-error-page

Java

非サポート

フォーム・ログインの試行に対するエラー・ページです。

現在はサポートされていません。

form-login-config

Java

非サポート

フォームベースのログインの構成仕様です。

現在はサポートされていません。

form-login-page

Java

非サポート

フォームベースのログイン・ページのURLです。

現在はサポートされていません。

icon

Java

サポート

サーブレットに関連付けられたアイコンのURLです。

サーブレット用にサポートされています。

init-param

Java

サポート

サーブレットの初期化パラメータです。

--

jsp-file

Java

非サポート

サーブレットに使用するJavaServer Pagesファイルです。

サポートされていません。

lang

Oracle

サポート

IANA言語名です。

en-USなどです。

lang-mapping

Oracle

サポート

ファイル名の拡張子と言語コンテンツの間のマッピングを指定します。

--

large-icon

Java

サポート

アイコン表示用の大きいサイズのアイコンです。

--

load-on-startup

Java

サポート

サーブレットの起動時にロードするかどうかを指定します。

--

location

Java

サポート

エラー・ページのURLを指定します。

ローカル・パス名またはHTTP(S) URLを指定できます。

login-config

Java

非サポート

認証方式を指定します。

現在はサポートされていません。

mime-mapping

Java

サポート

コンテンツのファイル名の拡張子とMIMEタイプの間のマッピングを指定します。

--

mime-type

Java

サポート

リソース・コンテンツのMIMEタイプ名です。

text/xml、application/octet-streamなどです。

OracleError

Oracle

サポート

エラー・ページに関連付けるOracleエラーを指定します。

--

param-name

Java

サポート

サーブレットまたはServletContextのパラメータ名です。

サーブレット用にサポートされています。

param-value

Java

サポート

パラメータの値です。

--

realm-name

Java

非サポート

認証に使用するHTTP(S)レルムです。

現在はサポートされていません。

role-link

Java

サポート

特定のユーザーがサーブレットにアクセスするために必要なロールを指定します。

データベース・ロール名を参照します。デフォルトでは、大文字にする必要があります。

role-name

Java

サポート

ロールのサーブレット名です。

データベース・ロールを呼び出すための別の名前です。サーブレットのAPIで使用します。

security-role

Java

非サポート

サーブレットが使用するロールを定義します。

サポートされていません。ロールは、SQLのCREATE ROLEを使用して手動で作成する必要があります。

security-role-ref

Java

サポート

サーブレットとロール間の参照です。

--

servlet

Java

サポート

サーブレットの構成情報です。

--

servlet-class

Java

サポート

Javaサーブレットのクラス名を指定します。

--

servlet-language

Oracle

サポート

サーブレットを作成するプログラミング言語を指定します。

Java、C、PL/SQLのいずれかです。現在、顧客定義のサーブレットには、Javaのみがサポートされています。

servlet-mapping

Java

サポート

サーブレットを関連付けるファイル名のパターンを指定します。

Javaで定義されたすべてのマッピングがサポートされています。

servlet-name

Java

サポート

サーブレットの文字列名です。

サーブレットのAPIで使用します。

servlet-schema

Oracle

サポート

JavaクラスがロードされるOracleスキーマです。指定しない場合、デフォルトのリゾルバ仕様を使用してスキーマが検索されます。

これが指定されない場合、サーブレットをSYSスキーマにロードして、すべてのユーザーがアクセスできるようにするか、またはデフォルトのJavaクラス・リゾルバを変更する必要があります。servlet-schemaの値は、二重引用符で囲まないかぎり大文字になることに注意してください。

session-config

Java

非サポート

HTTPSessionの構成情報です。

HTTPSessionはサポートされません。

session-timeout

Java

非サポート

HTTP(S)セッションのタイムアウトです。

HTTPSessionはサポートされません。

small-icon

Java

サポート

サーブレットに関連付けられた小さいアイコンです。

--

taglib

Java

非サポート

JSPタグ・ライブラリです。

JSPは現在サポートされていません。

taglib-uri

Java

非サポート

web.xmlファイルに相対的なJSPタグ・ライブラリの記述ファイルのURIです。

JSPは現在サポートされていません。

taglib-location

Java

非サポート

タグ・ライブラリが格納されているWebアプリケーションのルートに相対的なパス名です。

JSPは現在サポートされていません。

url-pattern

Java

サポート

サーブレットに関連付けられたURLパターンです。

Javaサーブレット2.2仕様の第10項を参照してください。

web-app

Java

非サポート

Webアプリケーションの構成です。

現在、1つのWebアプリケーションのみがサポートされています。

welcome-file

Java

サポート

ウェルカム・ファイルの名前を指定します。

--

welcome-file-list

Java

サポート

HTTP GETリクエストを使用してフォルダが参照された場合に表示するファイルのリストを定義します。

index.htmlなどです。

注意:

- Javaによって web.xmlファイルに定義されたパラメータ(env-entry、env-entry-name、env-entry-value、env-entry-type、ejb-ref、ejb-ref-type、home、remote、ejb-link、resource-ref、res-ref-name、res-type、res-auth)は、J2EE準拠のEnterprise Java Beanコンテナでのみ使用でき、完全なJ2EE環境をサポートしないJavaサーブレット・コンテナには必要ありません。

- security-constraint、web-resource-collection、web-resource-name、http-method、user-data-constraint、transport-guaranteeおよびauth-constrainの各要素は、リソースにアクセス制御を定義するために使用されます。Oracle XML DBは、アクセス制御リスト(ACL)を使用してこの機能を提供します。ACLは、指定されたリソースへのアクセス権を持つプリンシパルを決定するアクセス制御エントリ(ACE)のリストです。web.xmlファイルを使用したACLの生成は、今後のリリースでサポートされます。

関連項目:
/xdbconfig.xmlファイルの構成の詳細は、第34章「Oracle XML DBの管理」を参照してください。

Oracle XML DBサーブレットに対するHTTPリクエストの処理

Oracle XML DBは、次の手順を実行してHTTPリクエストを処理します。

1. 接続が確立されていない場合、Oracleリスナーは接続を共有サーバー・ディスパッチャに渡します。

2. 新しいHTTPリクエストを受信すると、ディスパッチャは共有サーバーを起動します。

3. HTTPヘッダーは、適切な構造に解析されます。

4. 共有サーバーは、Oracle XML DBセッション・プールが使用可能な場合、そこからデータベース・セッションの割当てを試行します。Oracle XML DBセッション・プールが使用できない場合、新しいセッションを作成します。

5. 新しいデータベース・コールおよび新しいデータベース・トランザクションが開始されます。

6. HTTP(S)に認証ヘッダーが含まれている場合、セッションはそのデータベース・ユーザーとしてSQL*Plusにログインしている場合と同様に認証されます。認証情報が含まれず、リクエストがGETまたはHEADである場合、Oracle XML DBはセッションをANONYMOUSユーザーとして認証しようとします。このデータベース・ユーザーのアカウントがロックされている場合、認証されないアクセスは許可されません。

7. Javaサーブレット2.2の仕様で指定されているとおり、HTTPリクエストのURLがxdbconfig.xmlファイルのサーブレットと一致しているかどうかが確認されます。

8. Oracle XML DBサーブレット・コンテナは、Oracle内部のJava VMで起動されます。指定したサーブレットが初期化されていない場合は、初期化されます。

9. サーブレットは、ServletInputStreamから入力を読み取り、ServletOutputStreamに出力を書き込み、service()メソッドから戻ります。

10. 不明なOracleエラーが発生した場合、セッションはセッション・プールに戻されます。

関連項目:
第28章「プロトコルを使用したリポジトリへのアクセス」

セッション・プールおよびOracle XML DBサーブレット

Oracle Databaseは、データベース・セッションごとに1つのJVMを使用します。セッション・プールから再利用されるセッションは、セッションが最後に使用されてからは、JVM(Java静的変数)内でどのような状態も保持します。

これは、メタデータなど、ユーザー固有でないJava状態をキャッシュする場合に有効ですが、保護ユーザーのデータはJava静的メモリーに格納しないでください。保護ユーザーのデータをJava静的メモリーに格納した場合、アプリケーションによってセキュリティ・ホールが出現する可能性があります。

ネイティブなXMLストリームのサポート

DOMノード・クラスは、write()というOracle固有のメソッドを持ちます。このメソッドは次の引数を取り、voidを戻します。

- java.io.OutputStreamストリーム: XMLテキストの書き込み先Javaストリーム。

- String charEncoding: XMLテキストを書き込むキャラクタ・エンコーディング。NULLの場合、データベース・キャラクタ・セットが使用されます。

- Short indent: ネストしたXML要素のインデントの文字数。

提供されたストリームがデータベース内部で提供されるServletOutputStreamである場合、Javaメソッドwrite()には、ショートカットが実装されます。ノードのコンテンツは、出力ソケットにネイティブなコードのXMLで直接書き込まれます。これによって、JavaオブジェクトまたはUnicode(Java文字列に必要)との間の変換が回避され、パフォーマンスが向上します。

Oracle XML DBサーブレットのAPI

Oracle XML DBサーブレットでサポートされるAPIは、Javaサーブレット2.2仕様で定義されます。現在、Javaサーブレット2.2仕様のJavadocは、http://java.sun.com/products/servlet/2.2/javadoc/index.htmlのサイトで参照できます。

表32-2に、未実装のJavaサーブレット2.2メソッドをリストします。実行時に例外が発生します。

表32-2 未実装のJavaサーブレット2.2メソッド

インタフェース

未実装のメソッド

HttpServletRequest

getSession()、isRequestedSessionIdValid()

HttpSession

all

HttpSessionBindingListener

all

Oracle XML DBサーブレットの例

例32-1に、ファイル・リソース/public/test/foo1.textの内容を出力する単純なサーブレットを示します。

例32-1 Oracle XML DBサーブレット

import javax.servlet.http.*;
import javax.servlet.*;
import java.util.*;
import java.io.*;
import java.util.*;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.sql.DriverManager;
import java.sql.SQLException;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleDriver;
import oracle.jdbc.OraclePreparedStatement;
import oracle.jdbc.OracleResultSet;
import oracle.sql.CLOB;
import oracle.xdb.XMLType;
import oracle.xdb.spi.XDBResource;

public class test extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException,
IOException {
try {
try {
// Get the database connection for the current HTTP session
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
OracleDriver ora = new OracleDriver();
OracleConnection databaseConnection =
(OracleConnection) ora.defaultConnection();
String statementText =
"SELECT XDBURIType('/public/test/foo1.txt').getClob() FROM DUAL";
OraclePreparedStatement statement =
(OraclePreparedStatement)
databaseConnection.prepareStatement(statementText);
OracleResultSet resultSet = null;
CLOB content = null;
// Execute the statement
resultSet = (OracleResultSet) statement.executeQuery();
while (resultSet.next())
{// The statement returns a CLOB.
// Copy content of CLOB to server's output stream.
content = resultSet.getCLOB(1);
Reader reader = content.getCharacterStream();
Writer writer =
new OutputStreamWriter(response.getOutputStream());
int bytesSent = 0;
int n;
char[] buffer = new char[CLOB.MAX_CHUNK_SIZE];
while (-1 != (n = reader.read(buffer)))
{ bytesSent = bytesSent + n;
writer.write(buffer, 0, n); }
writer.flush();
if (content.isOpen()) { content.close(); }}
resultSet.close();
statement.close();
databaseConnection.close();
response.getOutputStream().write('\n'); }
catch (SQLException sql)
{ throw new ServletException(sql); }}
catch (ServletException se )
{ se.printStackTrace(); }
finally
{ System.out.flush(); }}}

サーブレットをインストールするには、サーブレットをコンパイルしてからOracle Databaseにロードします。

% loadjava –grant public –u quine/curry –r test.class

最後に、例32-2に示すようにサーブレットを登録してマップし、URLと関連付けます。

例32-2 Oracle XML DBサーブレットの登録およびマッピング

EXEC DBMS_XDB.addServlet('TestServletFoo', 'Java', 'TestServletFoo',
NULL, NULL, 'test', NULL, NULL, 'XDB');

EXEC DBMS_XDB.addServletMapping('/public/test/foo1.txt', 'TestServletFoo');

COMMIT;

33 ネイティブなOracle XML DB Webサービスの使用

この章の内容は次のとおりです。

- ネイティブなOracle XML DB Webサービスの概要

- Oracle XML DBでのWebサービスの構成と有効化

- Webサービスを使用したOracle XML DBの問合せ

- Webサービスを使用したPL/SQLストアド・プロシージャへのアクセス

ネイティブなOracle XML DB Webサービスの概要

Webサービスは、アプリケーションがインターネットを介して情報をやりとりし、ビジネス・ロジックを実装するサービスにアクセスするための標準的な方法です。Webサービスを使用すると、使用中のアプリケーションからネイティブなOracle XML DBにアクセスできます。あるサービスでは、SQL問合せやXQuery問合せを発行し、その結果をXMLデータとして取得できます。また、別のサービスでは、PL/SQLのあらゆるストアド・ファンクションおよびストアド・プロシージャにアクセスできます。

このサービスを使用する場合は、入力ドキュメントおよび出力ドキュメントのフォーマットをカスタマイズできます。その場合、WSDLはネイティブなデータベースWebサービス・エンジンにより自動的に生成されます。

Oracle XML DBでサポートされているSOAPのバージョンは1.1です。アプリケーションはHTTPメソッドPOSTを使用して、SOAPリクエストをネイティブなOracle XML DBのWebサービスに送信します。ネイティブなOracle XML DB構成ファイルxdbconfig.xmlを使用すると、Oracle XML DBのすべてのWebサービスおよびWSDLドキュメントの格納場所を構成できます。またこの構成ファイルでは、Webサービスに関するセキュリティ設定も構成できます。

入力HTTPヘッダーのAccept-Charsetsフィールドでは、Webサービスの応答に使用するキャラクタ・セットを指定できます。このヘッダー・フィールドを省略すると、応答にはデータベースのキャラクタ・セットが使用されます。入力ドキュメントおよびエラー応答には、データベースのロケール言語が使用されます。

ネイティブなOracle XML DBのWebサービスのエラー処理では、フォルトのSOAPフレームワークを使用します。

関連項目:

- Webサービスの詳細は、http://www.w3.org/2002/ws/を参照してください。

- SOAPの詳細は、W3CのSOAP勧告、http://www.w3.org/TR/2000/NOTE-SOAP-20000508を参照してください。

- Webサービス記述言語(WSDL)の詳細は、http://www.w3.org/TR/wsdlを参照してください。

- SOAPのフォルト処理の詳細は、http://www.w3.org/TR/2003/REC-soap12-part0-20030624/#L11549を参照してください。

- 「xdbconfig.xmlを使用したOracle XML DBの構成」

Oracle XML DBでのWebサービスの構成と有効化

セキュリティ上の理由により、Oracle XML DBに事前に組み込まれているネイティブなWebサービスはありません。ネイティブなOracle XML Webサービスを使用できるようにするには、Oracle XML DB HTTPサーバーを起動し、Webサービス構成を明示的に追加する必要があります。その後、Webサービスの使用を特定のユーザーにのみ許可するため、それらのユーザーに適切なロールを付与する必要があります。

1. Webサービスを構成します。「Oracle XML DBでのWebサービスの構成」を参照してください。

2. 特定のユーザーに適切なロールを付与して、Webサービスを有効化します。「特定のユーザーに対するWebサービスの有効化」を参照してください。

関連項目:
Oracle XML DB HTTPサーバーの詳細は、「HTTP(S)およびOracle XML DBプロトコル・サーバーの使用」を参照してください。

Oracle XML DBでのWebサービスの構成

Oracle XML DBでWebサービスを使用できるようにするには、ユーザーSYSとしてログオンし、例33-2の問合せ出力として示されているサーブレット構成をOracle XML DBの構成ファイルxdbconfig.xmlに追加します。

例33-1に、PL/SQLパッケージDBMS_XDBのプロシージャを使用してサーブレットを追加する方法を示しています。例33-2は、サーブレットが正しく追加されたことを確認する方法を示しています。

例33-1 Webサービス構成サーブレットの追加

DECLARE
SERVLET_NAME VARCHAR2(32) := 'orawsv';
BEGIN
DBMS_XDB.deleteServletMapping(SERVLET_NAME);
DBMS_XDB.deleteServlet(SERVLET_NAME);
DBMS_XDB.addServlet(NAME     => SERVLET_NAME,
LANGUAGE => 'C',
DISPNAME => 'Oracle Query Web Service',
DESCRIPT => 'Servlet for issuing queries as a Web Service',
SCHEMA   => 'XDB');
DBMS_XDB.addServletSecRole(SERVNAME => SERVLET_NAME,
ROLENAME => 'XDB_WEBSERVICES',
ROLELINK => 'XDB_WEBSERVICES');
DBMS_XDB.addServletMapping(PATTERN => '/orawsv/*',
NAME    => SERVLET_NAME);
END;
/

例33-2 Webサービス構成サーブレット追加の検証

XQUERY declare default element namespace "http://xmlns.oracle.com/xdb/xdbconfig.xsd"; (: :)
(: This path is split over two lines for documentation purposes only.
The path should actually be a single long line. :)
for $doc in fn:doc("/xdbconfig.xml")/xdbconfig/sysconfig/protocolconfig/httpconfig/
webappconfig/servletconfig/servlet-list/servlet[servlet-name='orawsv']
return $doc
/

Result Sequence
-------------------------------------------------------------------------
<servlet xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd">
<servlet-name>orawsv</servlet-name>
<servlet-language>C</servlet-language>
<display-name>Oracle Query Web Service</display-name>
<description>Servlet for issuing queries as a Web Service</description>
<servlet-schema>XDB</servlet-schema>
<security-role-ref>
<description/>
<role-name>XDB_WEBSERVICES</role-name>
<role-link>XDB_WEBSERVICES</role-link>
</security-role-ref>
</servlet>

1 item(s) selected.

関連項目:
xdbconfig.xmlを使用したOracle XML DBの構成の詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください。

特定のユーザーに対するWebサービスの有効化

特定のユーザーに対してWebサービスを有効化するには、SYSユーザーとしてログオンし、ロールXDB_WEBSERVICESを目的のユーザーに付与します。このロールはHTTPS経由でのWebサービスを有効化します。Webサービスを使用するために、このロールは必須です。

さらに、ユーザーSYSは、次のいずれかまたは両方のロールをユーザーに付与します。

- XDB_WEBSERVICES_OVER_HTTP: HTTP(HTTPSだけでなく)を介したWebサービスの使用を有効にします。

- XDB_WEBSERVICES_WITH_PUBLIC: PUBLICにアクセス可能なデータベース・オブジェクトに、Webサービスを使用してアクセスできるようにします。

XDB_WEBSERVICES_WITH_PUBLICが付与されていない場合、そのユーザーは、通常使用できるすべてのデータベース・オブジェクトのうちPUBLICオブジェクトを除くすべてに、所有者に関係なくWebサービスを使用してアクセスできます。ユーザーをWebサービスによってPUBLICオブジェクトにアクセス可能にするには、SYSユーザーがそのユーザーにXDB_WEBSERVICES_WITH_PUBLICロールを付与する必要があります。このロールを付与されたユーザーは、データベースにログオンすれば、通常使用できるすべてのPUBLICオブジェクトにアクセスできます。

Webサービスを使用したOracle XML DBの問合せ

データベース問合せに使用するOracle XML DBのWebサービスは、http://host:port/orawsvというURLにあります。ただし、hostおよびportはそれぞれ、使用しているデータベースのホストおよびHTTP(S)ポートのプロパティを表します。このWebサービスは、XML Schemaを使用して入力ドキュメントおよび出力ドキュメントのフォーマットを指定するWSDLドキュメントに関連付けられています。このWSDLドキュメントのURLは、http://host:port/orawsv?wsdlです。

データベース問合せは、例33-3に示されているXML Schemaに準拠したXML文書としてアプリケーションからWebサービスへ送信されます。

例33-3 Webサービスで処理されるデータベース問合せのXML Schema

<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
targetNamespace="http://xmlns.oracle.com/orawsv">
<element name="query">
<complexType>
<sequence>
<element name="query_text">
<complexType>
<simpleContent>
<extension base="string">
<attribute name="type">
<simpleType>
<restriction base="NMTOKEN">
<enumeration value="SQL"/>
<enumeration value="XQUERY"/>
</restriction>
</simpleType>
</attribute>
</extension>
</simpleContent>
</complexType>
</element>
<choice maxOccurs="unbounded">
<element name="bind">
<complexType>
<simpleContent>
<extension base="string">
<attribute name="name" type="string"/>
</extension>
</simpleContent>
</complexType>
</element>
<element name="bindXML" type="any"/>
</choice>
<element name="null_handling" minOccurs="0">
<simpleType>
<restriction base="NMTOKEN">
<enumeration value="DROP_NULLS"/>
<enumeration value="NULL_ATTR"/>
<enumeration value="EMPTY_TAG"/>
</restriction>
</simpleType>
</element>
<element name="max_rows" type="positiveInteger" minOccurs="0"/>
<element name="skip_rows" type="positiveInteger" minOccurs="0"/>
<element name="pretty_print" type="boolean" minOccurs="0"/>
<element name="indentation_width" type="positiveInteger" minOccurs="0"/>
<element name="rowset_tag" type="string" minOccurs="0"/>
<element name="row_tag" type="string" minOccurs="0"/>
<element name="item_tags_for_coll" type="boolean" minOccurs="0"/>
</sequence>
</complexType>
</element>
</schema>

このXML Schemaは、WSDLドキュメントに記述されています。受信する問合せドキュメントの中で重要な部分は次のとおりです。

- query_text: 問合せのテキストです。属性typeには、問合せのタイプとしてSQLまたはXQUERYを指定します。

- bind: スカラー・バインド変数値です。属性nameには変数の名前を指定します。

- bindXML: XMLTypeのバインド変数値です。

- null_handling: 問合せにより戻されたNULL値の処理方法を指定します。

- DROP_NULLS: 出力に何も含めません(要素なし)。これがデフォルトの動作です。

- NULL_ATTR: NULL値出力に空の要素を使用します。要素内では属性xsi:nil = "true"を使用します。

- EMPTY_TAG: NULL値出力に空の要素を使用します。nil属性は使用しません。

- max_rows: 問合せに対して出力する行数の最大値です。デフォルトでは、すべての行が戻されます。

- skip_rows: SOAPメッセージ内に戻されたデータの中に行を取り込む前に、スキップする問合せ出力行の数を指定します。これとmax_rowsをあわせて使用することにより、出力のページ区切りを生成できます。デフォルト値は0(ゼロ)です。

- pretty_print: 出力ドキュメントをフォーマット出力用にフォーマットするかどうかを指定します。デフォルト値はtrueです。この場合ドキュメントはフォーマット出力されます。値がfalseの場合、フォーマット出力は実行されず、出力行は改行文字で改行されません。

- indentation_width: ネストした要素の各行頭のインデント文字数を指定します。デフォルト値は1です。

- rowset_tag: 出力ドキュメントのルート要素名です。

- row_tag: 1行のみの問合せ出力を値に持つ要素名です。

- item_tags_for_coll: collection_name_itemという名前でコレクション要素を生成するかどうかを指定します。ここで、collection_nameはコレクションの名前です。

これらの要素は、PL/SQLパッケージDBMS_XMLGENのプロシージャ内でそれぞれに対応しているパラメータと同じ意味を持っています。

例33-4および例33-5は、単純なSQL問合せの入力および出力を示したものです。

例33-4 問合せWebサービスを使用したSQL問合せの入力XML文書

<?xml version="1.0" ?>
<env:Envelope xmlns:env="http://www.w3.org/2002/06/soap-envelope ">
<env:Body>
<query xmlns="http://xmlns.oracle.com/orawsv">
<query_text type="SQL">
<![CDATA[SELECT * FROM employees WHERE salary = :e]]>
</query_text>
<bind name="e">8300</bind>
<pretty_print>false</pretty_print>
</query>
</env:Body>
</env:Envelope>

例33-4では、問合せテキストは<![CDATA[...]]>で囲まれています。これは、この例の中では必ずしも必要なことではありませんが、問合せには通常<や>などの文字が含まれるため、一般的には適切な方法です。要素bindは、eというバインド変数に値(8300)をバインドするのに使用されます。要素pretty_printでは、出力内容のフォーマット出力が無効になっています。

例33-5 問合せWebサービスを使用したSQL問合せの出力XML文書

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2002/06/soap-envelope">
<soap:Body>
<ROWSET><ROW><EMPLOYEE_ID>206</EMPLOYEE_ID><FIRST_NAME>William</FIRST_NAME><LAST_NAME>G
ietz</LAST_NAME><EMAIL>WGIETZ</EMAIL><PHONE_NUMBER>515.123.8181</PHONE_NUMBER><HIRE_DATE>07-JUN-
94</HIRE_DATE><JOB_ID>AC_ACCOUNT</JOB_ID><SALARY>8300</SALARY><MANAGER_ID>205</MANAGER_ID
><DEPARTMENT_ID>110</DEPARTMENT_ID></ROW></ROWSET>
</soap:Body>
</soap:Envelope>

Webサービスを使用したPL/SQLストアド・プロシージャへのアクセス

PL/SQLストアド・ファンクションおよびストアド・プロシージャへのアクセスに使用するOracle XML DBのWebサービスのURLは、http://host:port/orawsv/dbschema/package/fn_or_procです。またパッケージに含まれていない(スタンドアロン)ファンクションやプロシージャへのアクセスに使用するWebサービスのURLは、http://host:port/orawsv/dbschema/fn_or_procです。ここで、hostおよびportはそれぞれ使用しているデータベースのホストおよびHTTP(S)ポートのプロパティ、fn_or_procはストアド・ファンクションまたはストアド・プロシージャの名前、packageはストアド・ファンクションまたはストアド・プロシージャが含まれているパッケージ、dbschemaはそのパッケージを所有するデータベース・スキーマです。

入力XML文書には、ファンクションまたはプロシージャで必要となる入力内容が含まれます。また出力XML文書には、戻り値、およびOUT変数すべての値も含まれます。

入力ドキュメントおよび出力ドキュメント内のXML要素の名前は、ファンクションまたはプロシージャの変数名に対応しています。生成されたWSDLドキュメントには、正確なXML要素名が表示されます。使用されているネーミング規則は次のとおりです。

- PL/SQLファンクションへの入力を指定するXML要素には、function-nameInputという形式の名前が付けられます。ここで、function-nameはファンクションの名前です(大文字)。

- ファンクションの入力パラメータを指定するXML要素には、param-name-param-type-io-modeという形式の名前が付けられます。ここで、param-nameはパラメータの名前(大文字)、param-typeはそのSQLデータ型であり、io-modeは次のいずれかの入出力モードです。

- IN: INモード

- OUT: OUTモード

- INOUT: IN OUTモード

- PL/SQLファンクションからの出力を指定するXML要素には、Sreturn-type-function-nameOutputという形式の名前が付けられます。ここで、return-typeは戻り値のSQLデータ型(大文字)、function-nameはファンクションの名前(大文字)です。

- ファンクションの出力パラメータを指定するXML要素には、出力パラメータ自体と同じ名前(大文字)が付けられます。戻り値を指定する要素には、RETURNという名前が付けられます。

ファンクションの戻り値は、出力ドキュメントのRETURN要素内にあります。この要素は常にドキュメントの先頭に表示されます。戻り値は、この表示位置によって、RETURNという名前になる可能性のあるOUTパラメータとは明確に区別できます。

ストアド・ファンクションまたはストアド・プロシージャはそれぞれ、生成済WSDLドキュメントを持つ、動的な個別Webサービスに関連付けられます。このWSDLドキュメントのURLは、http://host:port/orawsv/dbschema/package/fn_or_proc?wsdlまたはhttp://host:port/orawsv/dbschema/fn_or_proc?wsdlです。またオプションで、特定のパッケージ内のすべてのストアド・ファンクションおよびストアド・プロシージャで共用するWSDLドキュメントも生成できます。このWSDLドキュメントのURLは、http://host:port/orawsv/dbschema/package?wsdlです。

受信するXML文書および送信するXML文書内のデータ型は、表33-1に従って、ストアド・ファンクションまたはストアド・プロシージャで使用されるSQLデータ型にマップされます。

表33-1 XMLデータ型とSQLデータ型のWebサービスによるマッピング

SQLデータ型

XML Schemaデータ型

CHAR、VARCHAR2、VARCHAR

xsd:string

DATE: 日付は、データベースのフォーマットに従う必要があります。

xsd:date

TIMESTAMP、TIMESTAMP WITH TIMEZONE、TIMESTAMP WITH LOCAL TIMEZONE

xsd:dateTime

INTERVAL YEAR TO MONTH、INTERVAL DAY TO SECOND

xsd:duration

NUMBER、BINARY_DOUBLE、BINARY_FLOAT

xsd:double

PL/SQL BOOLEAN

xsd:boolean

オブジェクト型

complexType

オブジェクト型は、同じ名前の複合型要素としてXMLで表現されます。オブジェクト属性は、その要素の子として表現されます。

Webサービスを使用したPL/SQLファンクションの使用例

この項では、単純なPL/SQLファンクションと、Webサービスを使用したアクセスについて説明します。このファンクションは、部門IDおよび部門名を入力として受け取り、その部門の全従業員の給与合計を戻します。またこのファンクションは、入出力パラメータおよび出力パラメータとしてそれぞれ、部門名およびその部門の従業員数を戻します。部門IDのデフォルト値は20です。この単純な例では、入出力パラメータdept_nameの入力値は実際には使用されません。それは無視され、正しい名前が戻されます。

例33-6は、ファンクションの定義を示したものです。例33-7は、このファンクションの定義から自動的に作成されたWSDLドキュメントです。例33-8は、ストアド・ファンクションを起動する入力ドキュメントです。例33-9は、結果の出力ドキュメントです。

例33-6 Webサービス・アクセスに使用するPL/SQLファンクションの定義

CREATE OR REPLACE PACKAGE salary_calculator AUTHID CURRENT_USER AS
FUNCTION TotalDepartmentSalary (dept_id    IN     NUMBER DEFAULT 20,
dept_name  IN OUT VARCHAR2,
nummembers OUT    NUMBER)
RETURN NUMBER;
END salary_calculator;
/
CREATE OR REPLACE PACKAGE BODY salary_calculator AS
FUNCTION TotalDepartmentSalary (dept_id    IN     NUMBER DEFAULT 20,
dept_name  IN OUT VARCHAR2,
nummembers OUT    NUMBER)
RETURN NUMBER IS
sum_sal NUMBER;
BEGIN
SELECT SUM(salary) INTO sum_sal FROM employees
WHERE department_id = dept_id;
SELECT department_name INTO dept_name FROM departments
WHERE department_name = dept_name;
SELECT count(*) INTO nummembers FROM employees
WHERE department_id = dept_id;
RETURN sum_sal;
END;
END;
/

例33-7 ストアドPL/SQLファンクションに対応するWSDLドキュメント

<definitions name="SALARY_CALCULATOR"
targetNamespace="http://xmlns.oracle.com/orawsv/HR/SALARY_CALCULATOR"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://xmlns.oracle.com/orawsv/HR/SALARY_CALCULATOR"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<types>
<xsd:schema targetNamespace="http://xmlns.oracle.com/orawsv/HR/SALARY_CALCULATOR"
elementFormDefault="qualified">
<xsd:element name="SNUMBER-TOTALDEPARTMENTSALARYInput">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="NUMMEMBERS-NUMBER-OUT">
<xsd:complexType/>
</xsd:element>
<xsd:element name="DEPT_NAME-VARCHAR2-INOUT" type="xsd:string"/>
<xsd:element name="DEPT_ID-NUMBER-IN" type="xsd:double"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="TOTALDEPARTMENTSALARYOutput">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="RETURN" type="xsd:double"/>
<xsd:element name="NUMMEMBERS" type="xsd:double"/>
<xsd:element name="DEPT_NAME" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<message name="TOTALDEPARTMENTSALARYInputMessage">
<part name="parameters" element="tns:SNUMBER-TOTALDEPARTMENTSALARYInput"/>
</message>
<message name="TOTALDEPARTMENTSALARYOutputMessage">
<part name="parameters" element="tns:TOTALDEPARTMENTSALARYOutput"/>
</message>
<portType name="SALARY_CALCULATORPortType">
<operation name="TOTALDEPARTMENTSALARY">
<input message="tns:TOTALDEPARTMENTSALARYInputMessage"/>
<output message="tns:TOTALDEPARTMENTSALARYOutputMessage"/>
</operation>
</portType>
<binding name="SALARY_CALCULATORBinding" type="tns:SALARY_CALCULATORPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="TOTALDEPARTMENTSALARY">
<soap:operation soapAction="TOTALDEPARTMENTSALARY"/>
<input>
<soap:body parts="parameters" use="literal"/>
</input>
<output>
<soap:body parts="parameters" use="literal"/>
</output>
</operation>
</binding>
<service name="SALARY_CALCULATORService">
<documentation>Oracle Web Service</documentation>
<port name="SALARY_CALCULATORPort" binding="tns:SALARY_CALCULATORBinding">
<soap:address location="httpS://example:8088/orawsv/HR/SALARY_CALCULATOR"/>
</port>
</service>
</definitions>

例33-8 Webサービスを使用したPL/SQL問合せの入力XML文書

<?xml version="1.0" ?><soap:Envelope
xmlns:soap="http://www.w3.org/2002/06/soap-envelope"><soap:Body><SNUMBER-
TOTALDEPARTMENTSALARYinput
xmlns="http://xmlns.oracle.com/orawsv/HR/SALARY_CALCULATOR/TOTALDEPARTMENTSALARY">
<DEPT_ID-NUMBER-IN>30</DEPT_ID-NUMBER-IN><DEPT_NAME-VARCHAR2-INOUT>Purchasing
</DEPT_NAME-VARCHAR2-INOUT><NUMMEMBERS-NUMBER-OUT/></SNUMBER-
TOTALDEPARTMENTSALARYinput></soap:Body></soap:Envelope>

例33-9 Webサービスを使用したPL/SQL問合せの出力XML文書

<?xml version="1.0" ?>
<soap:Envelope xmlns:soap="http://www.w3.org/2002/06/soap-envelope">
<soap:Body>
<TOTALDEPARTMENTSALARYOutput
xmlns="http://xmlns.oracle.com/orawsv/HR/SALARY_CALCULATOR/TOTALDEPARTMENTSALARY">
<RETURN>24900</RETURN>
<NUMMEMBERS>6</NUMMEMBERS>
<DEPT_NAME>Purchasing</DEPT_NAME>
</TOTALDEPARTMENTSALARYOutput>
</soap:Body>
</soap:Envelope>

第VI部

Oracle XML DBをサポートするOracleツール

第VI部では、Oracle XML DBとともに使用可能なOracleツールについて説明します。Oracle XML DBの管理、XMLデータのロード、およびXMLデータの交換のためのツールについて説明します。

第VI部に含まれる章は、次のとおりです。

- 第34章「Oracle XML DBの管理」

- 第35章「SQL*Loaderを使用したXMLデータのロード」

- 第36章「XMLType表のエクスポートおよびインポート」

- 第37章「Oracle Streams AQを使用したXMLデータの交換」

34 Oracle XML DBの管理

この章では、Oracle XML DBを管理する方法について説明します。Oracle XML DBのインストール、アップグレードおよび構成に関する情報が含まれます。

この章の内容は次のとおりです。

- Oracle XML DBのインストール

- 既存のOracle XML DBのインストールのアップグレード

- Oracle Enterprise Managerを使用したOracle XML DBの管理

- xdbconfig.xmlを使用したOracle XML DBの構成

関連項目:
XLinkおよびXIncludeを使用するためのOracle XML DBリポジトリ・リソースの構成の詳細は、「XLinkおよびXIncludeのためのリソースの構成」を参照してください。

Oracle XML DBのインストール

Database Configuration Assistant(DBCA)の有無にかかわらず、Oracle XML DBの新規インストールを実行できます。既存のインストールをアップグレードする場合、DBCAを使用せずに手動でOracle XML DBをインストールする必要があります。

注意:
Oracleサポートに問い合せることなく、XMLTypeデータを含むデータベースのOracle XML DBを削除しないでください。

Database Configuration Assistantを使用したOracle XML DBのインストール

Oracle XML DBはシード・データベースの一部であり、デフォルトで、Database Configuration Assistant(DBCA)によってインストールされます。Oracle XML DBのインストールに、他の手順は必要ありません。

ただし、データベースの拡張構成を選択した場合は、Oracle XML DBリポジトリ用のSYSAUX表領域と、FTP、HTTP、HTTPS、WebDAVプロトコルのポート番号を構成できます。

デフォルトでは、DBCAによって次のタスクがインストール中に実行されます。

- Oracle XML DBリポジトリ用の表領域SYSAUXを作成します。

- すべてのプロトコル・アクセスを有効にします。

表領域SYSAUXには、Oracle XML DBリポジトリに格納されるデータが保持されます。次のものを使用して格納されるデータが含まれます。

- SQL(RESOURCE_VIEW、PATH_VIEWなどを使用)

- FTP、HTTP、HTTPSおよびWebDAVなどのプロトコル

この表領域外の表にデータを格納し、このデータに対するREFをこの表領域内の表に格納することにより、Oracle XML DBリポジトリを介してこのデータにアクセスできます。

関連項目:
リポジトリへの非認証アクセス許可の詳細は、「HTTPを使用したOracle XML DBリポジトリへの匿名アクセス」を参照してください。

動的プロトコル登録によるローカル・リスナーへのFTP、HTTPおよびHTTPSサービス

Oracle XML DBのインストールでは、FTP、HTTPおよびHTTPSサービスがローカル・リスナーに動的に登録されます。lsnrctlを使用して、開始、停止および問合せを実行できます。次に例を示します。

- 開始: lsnrctl start

- 停止: lsnrctl stop

- 問合せ: lsnrctl status

FTP、HTTPまたはHTTPSのポート番号の変更

FTP、HTTPおよびHTTPSのポート番号を変更するには、Oracle XML DBリポジトリの/xdbconfig.xmlファイル内の要素<ftp-port>、<http-port>と<http2-port>を更新します。

ポート番号を更新すると、動的プロトコル登録によって更新前のポート番号のFTP、HTTPまたはHTTPSサービスが自動的に停止され、ローカル・リスナーが起動されている場合は、新しいポート番号でFTP、HTTPまたはHTTPSサービスが開始されます。ローカル・リスナーが起動されていない場合は、ポート番号を更新した後、リスナーを再起動します。

関連項目:
プロトコルの構成の詳細は、第28章「プロトコルを使用したリポジトリへのアクセス」 を参照してください。

インストール後

Oracle XML DBでは、動的プロトコル登録を使用して、FTPおよびHTTPリスナー・サービスがローカル・リスナーに設定されます。Oracle XML DBプロトコルにアクセスする場合は、リスナーが起動されていることを確認してください。

注意:
リスナーが標準ポート(例: 1521)以外で起動中の場合、プロトコルを正しいリスナーに登録するには、init.oraファイルにlocal_listenerエントリを含める必要があります。これによって、正しいリスナーを指すTNSNAMEエントリが参照されます。init.oraパラメータの編集後、CREATE SPFILEを使用してSPFILEエントリを再生成する必要があります。

DBCAを使用しない手動でのOracle XML DBのインストール

Oracle XML DBは、catqm SQLスクリプトをディレクトリrdbms/adminでデータベース・ユーザーSYSとして実行することで、手動でインストールできます。スクリプトを実行する前に、データベースをインストールする必要があります。また、Oracle XML DBリポジトリに大量のデータが格納されることが予想される場合は、Oracle XML DB用に個別の表領域を作成することをお薦めします。

catqmの構文と各要素の意味を次に示します。

- xdb_passwordはパスワードです。

- xdb_ts_nameは、Oracle XML DBに使用する表領域です。

- temp_ts_nameは一時表領域です。

- secure_file_for_repoはYESまたはNO(大文字)で、YESはOracle XML DBリポジトリにSecureFile LOBを使用することを意味します。

catqm.sql xdb_password xdb_ts_name temp_ts_name secure_file_for_repos

次に例を示します。

catqm.sql change_on_install SYSAUX TEMP YES

注意:

- SecureFile LOB記憶域は、自動セグメント領域管理を使用する表領域でのみ作成できます。『Oracle Database管理者ガイド』を参照してください。

- SecureFile LOB記憶域を使用するには、データベース互換性が11.0.0.0以上である必要があります。

インストール後

手動でのインストール後、次のタスクを実行します。

1. init.oraファイルに次のディスパッチャ・エントリを追加します。

dispatchers="(PROTOCOL=TCP) (SERVICE=<sid>XDB)"

2. データベースおよびリスナーを再起動して、Oracle XML DBへのプロトコル・アクセスを有効にします。

関連項目:
リポジトリへの非認証アクセス許可の詳細は、「HTTPを使用したOracle XML DBリポジトリへの匿名アクセス」を参照してください。

既存のOracle XML DBのインストールのアップグレード

次の考慮事項は、Oracle Database 11gへのすべてのアップグレードに適用されます。

- 通常どおり、スクリプトcatproc.sqlを実行します。

- アップグレード後の手順として、Oracle XML DB機能が必要である場合、「DBCAを使用しない手動でのOracle XML DBのインストール」で説明されているとおりに、Oracle XML DBを手動でインストールする必要があります。

- ACLセキュリティ: Oracle Database 11gリリース1以前のリリースでは、同じプリンシパルおよび同じ権限のACE間の競合は、先行するACEに子grantがあるかどうかに関係なく、子denyのあるACEを優先させることで解決していました。つまり、ACEの順序は関係ありませんでした。Oracle Database 11gでは、このdeny-trumps-grantの動作も使用できますが、デフォルトの動作ではありません。

関連項目:
ACE間の競合の詳細は、「ACLおよびACEの評価」を参照してください。

ACL文書および構成ファイルの検証

アクセス制御リスト(ACL)の文書は、表XDB$ACLに格納されています。Oracle XML DBの構成ファイルxdbconfig.xmlは、表XDB$CONFIGに格納されています。Oracle Database 11gリリース1以降、これらの表では事後解析(バイナリXML)記憶域モデルを使用します。これは、ACL文書および構成ファイルが、各XML Schemaに対して完全に検証されることを意味します。検証は、既存のACL文書と構成ファイル、および既存の対応するXML Schemaを使用してアップグレード時に行われます。

アップグレード時にACL文書の検証に失敗した場合、その文書は表XDB$INVALID_ACLに移動されます。

アップグレード時に構成ファイルxdbconfig.xmlの検証に失敗した場合、そのファイルは表XDB$INVALID_CONFIGに格納され、デフォルトの構成ファイルが表XDB$CONFIG内でそれを置換し、データベースのXDBコンポーネントは無効としてマークされます。その後、データベースを通常モードで起動し、データベースを使用する前にXDBコンポーネントを修正する必要があります。

XDBコンポーネントを修正するには、無効なファイルを修正して有効にし、PL/SQLプロシージャRecoverUpgradeをコールします。検証後、このプロシージャは修正済のファイルを表XDB$ACLおよび表XDB$CONFIGに移動し、XDBコンポーネントを有効としてマークします。

オプションとして、パラメータuse_defaultをTRUEに設定してプロシージャRecoverUpgradeをコールし、無効なファイルを破棄できます。この場合、有効なファイルは表XDB$ACLおよび表XDB$CONFIGに移動され、残った無効なファイルはすべて削除されます。無効なファイルのかわりにデフォルト・ファイルが使用されます。ACLにはデフォルトのACL文書が使用されます。構成ファイルにはデフォルトのxdbconfig.xmlが使用されます(ここではACEの順序が関係します)。

注意:
古いACLファイルまたは無効な構成ファイルが確実に必要でない場合にのみ、パラメータuse_defaultにTRUEの値を使用します。これらのファイルは削除されます。

Oracle Enterprise Managerを使用したOracle XML DBの管理

Oracle Enterprise ManagerはOracle Database付属のグラフィカル・ツールで、データベース管理タスクの容易な実行を可能にします。このツールを使用して、Oracle XML DBに関連する次のタスクを実行できます。

- Oracle XML DBの構成。Oracle XML DBの構成ファイル、/xdbconfig.xmlのパラメータを表示または編集します。
Oracle Enterprise Managerを使用しないOracle XML DBの構成の詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください。

- Oracle XML DBリポジトリ・リソースおよびそれに関連するアクセス制御リスト(ACL)の検索、作成、編集および削除の取消し。
Oracle Enterprise Managerを使用しないリソースの作成および管理の詳細は、第V部「Oracle XML DBリポジトリ」を参照してください。

- XMLType表およびビューの検索、作成、編集および削除。

- XMLスキーマの検索、作成、登録および削除。
Oracle Enterprise Managerを使用しないXML Schemaの操作の詳細は、第7章「XML Schemaの格納と問合せ: 基本」を参照してください。

- XPath式に基づくファンクション索引の作成。
Oracle Enterprise Managerを使用しないファンクション索引の作成の詳細は、第6章「XMLTypeデータの索引付け」を参照してください。

関連項目:
Oracle Enterprise Managerを使用した、これらのタスクの実行の詳細は、Oracle Enterprise Manager付属のオンライン・ヘルプを参照してください。

xdbconfig.xmlを使用したOracle XML DBの構成

Oracle XML DBは、Oracle XML DBリポジトリにリソースとして格納された構成ファイルの/xdbconfig.xmlを介して内部管理できます。Oracle Enterprise Managerを使用してOracle XML DBを構成するかわりに、Oracle XML DB構成ファイルを使用して直接構成できます。

構成ファイルは実行時に変更できます。構成ファイルを更新すると、このリポジトリ・リソースの新しいバージョンが作成されます。セッションが開始されると、現行のバージョンの構成ファイルがそのセッションにバインドされます。最新のバージョンにセッションをリフレッシュするように明示的にコールしないかぎり、このセッション中は、このバージョンの構成ファイルが使用されます。

Oracle XML DBの構成ファイルxdbconfig.xml

Oracle XML DBの構成ファイルは、Oracle XML DB構成XML Schemaであるhttp://xmlns.oracle.com/xdb/xdbconfig.xsdに準拠するOracle XML DBリポジトリ・リソースの/xdbconfig.xmlで定義および格納されます。Oracle XML DBを構成または再構成するには、/xdbconfig.xmlファイルを更新します。その構造については、次の項で説明します。/xdbconfig.xmlファイルにアクセスするには、管理者権限が必要です。

関連項目:
Oracle XML DB構成XML Schemaの詳細は、「xdbconfig.xsd: Oracle XML DBを構成するためのXML Schema」を参照してください。

<xdbconfig>(最上位要素)

要素<xdbconfig>は、最上位の要素です。その構造は次のとおりです。

<xdbconfig>
<sysconfig> ... </sysconfig>
<userconfig> ... </userconfig>
</xdbconfig>

要素<sysconfig>は、システム固有の組込みパラメータを定義します。要素<userconfig>を使用すると、新しいカスタム・パラメータを格納できます。

<sysconfig>(<xdbconfig>の子)

要素<sysconfig>は、<xdbconfig>の子です。その構造は次のとおりです。

<sysconfig>
general parameters
<protocolconfig> ... </protocolconfig>
</sysconfig>

要素<sysconfig>には、アクセス制御リスト(ACL)の最大存続期間、Oracle XML DBで大/小文字が区別されるかどうかなど、すべてのOracle XML DBに適用されるいくつかの一般的なパラメータが含まれます。子<protocolconfig>には、プロトコル固有のパラメータが含まれます。

<userconfig>(<xdbconfig>の子)

要素<userconfig>は、<xdbconfig>の子です。これには追加する必要のあるパラメータが含まれます。

<protocolconfig>(<sysconfig>の子)

要素<protocolconfig>は、<sysconfig>の子です。その構造は次のとおりです。

<protocolconfig>
<common> ... </common>
<ftpconfig> ... </ftpconfig>
<httpconfig> ... </httpconfig> </protocolconfig>

<common>には、MIMEタイプについての情報など、すべてのプロトコルに適用されるパラメータがOracle Databaseによって格納されます。FTP、HTTPおよびHTTPSプロトコルに固有のパラメータは、要素<ftpconfig>と<httpconfig>にそれぞれ含まれます。

関連項目:
プロトコル構成パラメータのリストは、第28章「プロトコルを使用したリポジトリへのアクセス」の表28-1、表28-2および表28-3を参照してください。

<httpconfig>(<protocolconfig>の子)

要素<httpconfig>は、<protocolconfig>の子です。その構造は次のとおりです。

<httpconfig>
...
<webappconfig>
...
<servletconfig>
...
<servlet-list>
<servlet> ... </servlet>
...
</servlet-list>
</servletconfig>
</webappconfig>
...
<plsql> ... </plsql>
</httpconfig>

要素<httpconfig>には、次の子要素、およびその他の子要素が含まれます。

- <webappconfig>: Webベースのアプリケーションの構成に使用します。これには、アイコン名、アプリケーションの表示名およびサーブレットのリストなど、Webベースのアプリケーション固有のパラメータが含まれます。
要素<servletconfig>は、サーブレットの定義に使用される<webappconfig>の子です。<servlet>を子に持つ子<servlet-list>を含んでいます(「<servlet> (<httpconfig>の子孫)」を参照)。

- <plsql>脚注1 埋込みPL/SQLゲートウェイを構成する際、グローバル構成パラメータを定義するために使用されます。各グローバル・パラメータは、<plsql>の子要素を使用して定義されます。要素名は、グローバル・パラメータ名と同じです。要素のコンテンツは、パラメータ値と同じです。
埋込みPL/SQLゲートウェイの構成方法としては、xdbconfig.xmlファイルを編集するのではなく、PL/SQLパッケージDBMS_EPGのプロシージャを使用する方法をお薦めします。

関連項目:

- プロトコル構成パラメータのリストは、第28章「プロトコルを使用したリポジトリへのアクセス」の表28-1、表28-2および表28-3を参照してください。

- 埋込みPL/SQLゲートウェイの構成と使用の詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

- mod_plsqlの詳細と、PL/SQLゲートウェイの使用に関する概念的な情報は、『Oracle Fusion Middleware Oracle HTTP Server管理者ガイド』を参照してください。

- DBMS_EPGパッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

<servlet>(<httpconfig>の子)

<servlet>の子であるオプションの要素<plsql>は、埋込みPL/SQLゲートウェイ・サーブレットを構成します。ただし、埋込みゲートウェイの構成方法としては、xdbconfig.xmlファイルを編集するのではなく、PL/SQLパッケージDBMS_EPGのプロシージャを使用する方法をお薦めします。

要素<plsql>は、埋込みゲートウェイの構成に必要な、埋込みPL/SQL DAD属性脚注 2 ごとに子要素を持っています。これらの子はすべてオプションです。要素名はDAD属性名と同じです。要素のコンテンツは、DAD属性値と同じです。

要素<servlet>は<httpconfig>の子孫です。「<httpconfig> (<protocolconfig>の子)」を参照してください。Javaサーブレットおよび埋込みPL/SQLゲートウェイ・サーブレットなど、サーブレットの構成に使用します。

関連項目:

- Javaサーブレットの構成の詳細は、第32章「JavaでのOracle XML DBアプリケーションの作成」を参照してください。

- 埋込みPL/SQLゲートウェイの構成と使用の詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

- Oracle Application Expressの詳細は、『Oracle Application Expressアプリケーション・ビルダー・ユーザーズ・ガイド』を参照してください。

- DBMS_EPGパッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

Oracle XML DBの構成ファイルの例

次に、Oracle XML DBの構成ファイルの例を示します。

例34-1 Oracle XML DBの構成ファイル

<xdbconfig xmlns="http://xmlns.oracle.com/xdb/xdbconfig.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/xdb/xdbconfig.xsd
http://xmlns.oracle.com/xdb/xdbconfig.xsd">
<sysconfig>
<acl-max-age>900</acl-max-age>
<acl-cache-size>32</acl-cache-size>
<invalid-pathname-chars>,</invalid-pathname-chars>
<case-sensitive>true</case-sensitive>
<call-timeout>300</call-timeout>
<max-link-queue>65536</max-link-queue>
<max-session-use>100</max-session-use>
<persistent-sessions>false</persistent-sessions>
<default-lock-timeout>3600</default-lock-timeout>
<xdbcore-logfile-path>/sys/log/xdblog.xml</xdbcore-logfile-path>
<xdbcore-log-level>0</xdbcore-log-level>
<resource-view-cache-size>1048576</resource-view-cache-size>

<protocolconfig>
<common>
<extension-mappings>
<mime-mappings>
<mime-mapping>
<extension>au</extension>
<mime-type>audio/basic</mime-type>
</mime-mapping>
<mime-mapping>
<extension>avi</extension>
<mime-type>video/x-msvideo</mime-type>
</mime-mapping>
<mime-mapping>
<extension>bin</extension>
<mime-type>application/octet-stream</mime-type>
</mime-mapping>
</mime-mappings>

<lang-mappings>
<lang-mapping>
<extension>en</extension>
<lang>english</lang>
</lang-mapping>
</lang-mappings>

<charset-mappings>
</charset-mappings>

<encoding-mappings>
<encoding-mapping>
<extension>gzip</extension>
<encoding>zip file</encoding>
</encoding-mapping>
<encoding-mapping>
<extension>tar</extension>
<encoding>tar file</encoding>
</encoding-mapping>
</encoding-mappings>
</extension-mappings>

<session-pool-size>50</session-pool-size>
<session-timeout>6000</session-timeout>
</common>

<ftpconfig>
<ftp-port>2100</ftp-port>
<ftp-listener>local_listener</ftp-listener>
<ftp-protocol>tcp</ftp-protocol>
<logfile-path>/sys/log/ftplog.xml</logfile-path>
<log-level>0</log-level>
<session-timeout>6000</session-timeout>
<buffer-size>8192</buffer-size>
</ftpconfig>

<httpconfig>
<http-port>8080</http-port>
<http-listener>local_listener</http-listener>
<http-protocol>tcp</http-protocol>
<max-http-headers>64</max-http-headers>
<session-timeout>6000</session-timeout>
<server-name>XDB HTTP Server</server-name>
<max-header-size>16384</max-header-size>
<max-request-body>2000000000</max-request-body>
<logfile-path>/sys/log/httplog.xml</logfile-path>
<log-level>0</log-level>
<servlet-realm>Basic realm="XDB"</servlet-realm>
<webappconfig>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
<error-pages>
</error-pages>
<servletconfig>
<servlet-mappings>
<servlet-mapping>
<servlet-pattern>/oradb/*</servlet-pattern>
<servlet-name>DBURIServlet</servlet-name>
</servlet-mapping>
</servlet-mappings>

<servlet-list>
<servlet>
<servlet-name>DBURIServlet</servlet-name>
<display-name>DBURI</display-name>
<servlet-language>C</servlet-language>
<description>Servlet for accessing DBURIs</description>
<security-role-ref>
<role-name>authenticatedUser</role-name>
<role-link>authenticatedUser</role-link>
</security-role-ref>
</servlet>
</servlet-list>
</servletconfig>
</webappconfig>
</httpconfig>
</protocolconfig>
<xdbcore-xobmem-bound>1024</xdbcore-xobmem-bound>
<xdbcore-loadableunit-size>16</xdbcore-loadableunit-size>
</sysconfig>
</xdbconfig>

Oracle XML DB Configuration API

Oracle XML DB構成ファイル(xdbconfig.xml)には、階層内の他のXML Schemaに基づくリソースと同様にアクセスできます。FTP、HTTP(S)、WebDAV、Oracle Enterprise Managerまたはあらゆるリソースおよびドキュメント・オブジェクト・モデル(DOM) API for Java、PL/SQLまたはC (OCI)を使用してアクセスできます。

便宜上、構成へのアクセスには、PL/SQLパッケージDBMS_XDBを使用できます。これにより次の関数およびプロシージャが公開されます。

- cfg_get: 現在のセッションの構成情報を表示します。

- cfg_refresh: 現在の構成ファイルを使用して、セッション構成情報をリフレッシュします。典型的なcfg_refreshの使用例には、次のものがあります。

- 構成の変更後、セッションで最新バージョンの構成情報を取得する必要がある場合。

- セッションの実行が長時間におよび、同時セッションによって構成が変更され、現行のセッションで最新バージョンの構成情報を取得する必要がある場合。

- cfg_update: 構成ファイルを書き込み、構成情報を更新します。COMMITが実行されます。

例34-2では、構成ファイル内のftp-portおよびhttp-portパラメータを更新します。

例34-2 CFG_UPDATEおよびCFG_GETを使用した構成ファイルの更新

DECLARE
v_cfg XMLType;
BEGIN
SELECT updateXML(DBMS_XDB.cfg_get(),
'/xdbconfig/descendant::ftp-port/text()',
'2121',
'/xdbconfig/descendant::http-port/text()',
'19090')
INTO v_cfg FROM DUAL;
DBMS_XDB.cfg_update(v_cfg);
COMMIT;
END;
/

多くのパラメータを更新する場合、FTP、HTTP、HTTPSまたはOracle Enterprise Managerを使用すると、より簡単に構成を更新できます。

関連項目:
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

デフォルトの名前空間のスキーマの場所へのマッピングの構成

Oracle XML DBでは入力XML文書を事前解析して、スキーマに基づくXMLTypeインスタンスを識別します。適切なxsi:schemaLocationまたはxsi:noNamespaceSchemaLocation属性が検出された場合は、指定されたスキーマの場所を示すURLを使用して、登録済スキーマが参照されます。適切なxsi:属性が検出されない場合、そのXML文書は、スキーマに基づかない文書とみなされます。Oracle XML DBは、デフォルトのスキーマの場所のマッピングを構成するメカニズムを提供します。適切なxsi:属性がXML文書に指定されていない場合、デフォルトのスキーマの場所のマッピングが使用されます。Oracle XML DB構成XML Schemaであるxdbconfig.xsdの要素schemaLocation-mappingsを使用して、(namespace, element)の組合せとデフォルトのスキーマの場所との間のマッピングを指定できます。elementの値が空の場合、マッピングは指定した名前空間内のすべてのグローバル要素に適用されます。namespaceの値が空の場合、NULLの名前空間に対応します。

要素schemaLocation-mappingsの定義は、次のとおりです。

<element name="schemaLocation-mappings"
type="xdbc:schemaLocation-mapping-type" minOccurs="0"/>
<complexType name="schemaLocation-mapping-type"><sequence>
<element name="schemaLocation-mapping"
minOccurs="0" maxOccurs="unbounded">
<complexType><sequence>
<element name="namespace" type="string"/>
<element name="element" type="string"/>
<element name="schemaURL" type="string"/>
</sequence></complexType>
</element></sequence>
</complexType>

使用されるスキーマの場所は、Oracle XML DB構成ファイル内の使用される名前空間と文書のルート要素のマッピングによって異なります。たとえば、文書にスキーマの場所を示す適切なxsi:属性がないと想定します。名前空間Nに文書のルート要素Rがあると仮定します。デフォルトのスキーマの場所を識別するアルゴリズムは次のようになります。

1. Oracle XML DB構成ファイルにNおよびRのマッピングが指定されている場合は、対応するスキーマの場所が使用されます。

2. 構成ファイルにNのマッピングが指定されていて、Rのマッピングが指定されていない場合、Nのスキーマの場所が使用されます。

3. ドキュメント・ルートRにいずれの名前空間も指定されていない場合は、Rのスキーマの場所が使用されます。

たとえば、Oracle XML DB構成ファイルに次のマッピングが含まれているとします。

<schemaLocation-mappings>
<schemaLocation-mapping>
<namespace>http://www.oracle.com/example</namespace>
<element>root</element>
<schemaURL>http://www.oracle.com/example/sch.xsd</schemaURL>
</schemaLocation-mapping>
<schemaLocation-mapping>
<namespace>http://www.oracle.com/example2</namespace>
<element></element>
<schemaURL>http://www.oracle.com/example2/sch.xsd</schemaURL>
</schemaLocation-mapping>
<schemaLocation-mapping>
<namespace></namespace>
<element>specialRoot</element>
<schemaURL>http://www.oracle.com/example3/sch.xsd</schemaURL>
</schemaLocation-mapping>
</schemaLocation-mappings>

次のスキーマの場所が使用されます。

- ルート要素 = root

- 名前空間 = http://www.oracle.com/example

- スキーマURL = http://www.oracle.com/example/sch.xsd

このマッピングは、インスタンス・ドキュメントによる指定が次の場合に使用されます。

<root xmlns="http://www.oracle.com/example">

- ルート要素 = null (名前空間内の任意のグローバル要素)

- 名前空間 = http://www.oracle.com/example2

- スキーマURL = http://www.oracle.com/example2/sch.xsd

このマッピングは、インスタンス・ドキュメントによる指定が次の場合に使用されます。

<root xmlns="http://www.oracle.example2">

- ルート要素 = specialRoot

- 名前空間 = null (NULLの名前空間)

- スキーマURL = http://www.oracle.com/example3/sch.xsd

このマッピングは、インスタンス・ドキュメントによる指定が次の場合に使用されます。

<specialRoot>

注意:
この機能はXMLがサーバー上で解析される場合にサーバー側でのみ使用できます。XMLがクライアント側で解析される場合は、適切なxsi:属性も必要になります。

XMLファイル拡張子の構成

Oracle XML DBリポジトリは、特定のファイルをそのファイル拡張子に基づいてXML文書として処理します。このようなファイルがリポジトリに挿入されると、Oracle XML DBはそのファイルを事前解析し、スキーマの場所を識別(またはデフォルトのマッピングがある場合はそれを使用)して、文書を適切なデフォルト表に挿入します。デフォルトでは、xml、xsd、xsl、xltなどの拡張子がXMLファイル拡張子とみなされます。さらに、Oracle XML DBは、各アプリケーションに対して、その他のファイル拡張子をXMLファイル拡張子として指定できるメカニズムを提供します。xml-extensions要素は、構成スキーマのhttp://xmlns.oracle.com/xdb/xdbconfig.xsdで次のように定義されます。

<element name="xml-extensions"
type="xdbc:xml-extension-type" minOccurs="0"/>

<complexType name="xml-extension-type"><sequence>
<element name="extension" type="xdbc:exttype"
minOccurs="0" maxOccurs="unbounded">
</element></sequence>
</complexType>

たとえば、Oracle XML DB構成ファイルxdbconfig.xmlの次のフラグメントは、拡張子vsd、vmlおよびsvglを持つファイルをXMLファイルとして処理することを指定しています。

<xml-extensions>
<extension>vsd</extension>
<extension>vml</extension>
<extension>svgl</extension>
</xml-extensions>

パッケージDBMS_XDB_ADMIN

表34-1は、Oracle XML DBおよびOracle XML DBリポジトリの管理および構成用のDBMS_XDB_ADMIN PL/SQLプロシージャを示しています。

表34-1 DBMS_XDB_ADMIN管理プロシージャ

ファンクションおよびプロシージャ

説明

moveXDB_tablespace

データベース・スキーマXDBを指定した表領域に移動します。

rebuildHierarchicalIndex

階層リポジトリ索引を再構築します。これには、特にmoveXDB_tablespaceの起動後では、時間がかかる可能性があります。

注意:
デフォルトの汎用データベースで、データベース・スキーマXDBが表領域SYSAUXにある場合、データベースの完全エクスポートを実行する前に、DBMS_XDB_ADMIN.moveXDB_tablespaceを使用する必要があります。データベースの完全エクスポートでは、SYSTEMまたはSYSAUX表領域からはデータはエクスポートされません。

注意:
Oracle Database 11gリリース2 (11.2.0.3)以前は、これらのプロシージャはPL/SQLパッケージDBMS_XDBに付属していました。パッケージDBMS_XDB内のこれらの2つのプロシージャはりリース11.2.0.3の時点では非推奨です。

関連項目:
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

脚注の凡例

脚注1: 埋込みPL/SQLゲートウェイの構成に使用される<plsql>要素には、2つの異なるものがあります。1つは<httpconfig>の子で、グローバル・パラメータを定義します。もう1つは<servlet>の子で、DAD属性を定義します。
脚注 2:  DADは、データベース・アクセス記述子の略語です。DAD属性は、このような記述子を定義するパラメータです。

35 SQL*Loaderを使用したXMLデータのロード

この章では、SQL*Loaderを使用してXMLデータをOracle XML DBにロードする方法を説明します。

この章の内容は次のとおりです。

- Oracle DatabaseへのXMLTypeデータのロードの概要

- SQL*Loaderを使用したXMLTypeデータのロード

- Oracle Databaseへの大規模なXML文書のロード

関連項目:
第3章「Oracle XML DBの使用」

Oracle DatabaseへのXMLTypeデータのロードの概要

Oracle9iリリース1(9.0.1)以上のExport/Import UtilityおよびSQL*Loaderでは、列の型としてXMLTypeがサポートされています。Oracle Database 10g以降は、SQL*LoaderはXMLType表のロードもサポートしています。XMLTypeデータは、SQL*Loaderを使用して、格納方式(構造化記憶域、非構造化記憶域またはバイナリXML記憶域)に関係なく、従来の方式またはダイレクト・パス方式でロードできます。

注意:
XMLデータの構造化記憶域の場合、データにXML Schema型の継承(拡張または制限)が含まれている場合、SQL*Loaderはダイレクト・パス・ロードをサポートしません。
つまり、他のcomplexType要素(ベース型)を拡張または制限するXML SchemaにcomplexType要素が含まれている場合は、SQLタイプのいくつかは他のSQLタイプによって定義されます。この場合、オブジェクト・リレーショナル記憶域では、ダイレクト・パス・ロードはサポートされません。

関連項目:
第36章「XMLType表のエクスポートおよびインポート」および『Oracle Databaseユーティリティ』

ユーザー・データのエクスポート時に、Oracle XML DBリポジトリの情報はエクスポートされません。つまり、リソースまたはすべての情報のいずれもエクスポートされません。

SQL*Loaderを使用したXMLTypeデータのロード

XML列とは、XMLType型であると宣言された列です。

SQL*Loaderは、XMLType列および表をオブジェクト・リレーショナル列および表と同様に処理します。次の項で説明するプライマリ・データ・ファイルまたはLOBFILE値からのLOBデータのロード方法は、XMLTypeデータがLOBとして格納されている場合は、XMLType列および表のロードにも適用されます。

関連項目:
『Oracle Databaseユーティリティ』

注意:
LOBフィールドにはSQL文字列を指定できません。これは、LOBFILE_specを指定する場合も同じです。

XMLTypeデータは、制御ファイルまたはLOBファイルに存在する場合があります。この場合は、LOBファイルの名前が制御ファイルに表示されます。

XMLTypeデータは非常に大きいデータであるため、SQL*Loaderでは、LOBデータをプライマリ・データ・ファイル(残りのデータを持つインライン)またはLOBファイルのいずれかから、そのデータの格納方法に関係なくロードできます(基礎となる記憶域はオブジェクト・リレーショナルのままです)。

SQL*Loaderを使用したLOB内のXMLTypeデータのロード

プライマリ・データ・ファイルから内部LOB(バイナリ・ラージ・オブジェクト(BLOB)、キャラクタ・ラージ・オブジェクト(CLOB)および各国語キャラクタ・ラージ・オブジェクト(NCLOB))、またはXMLType列および表をロードするには、次の標準SQL*Loader形式を使用できます。

- 事前にサイズが決まっているフィールド

- デリミタ付きフィールド

- Length-Value Pairフィールド

これらの各形式の詳細は、次の項および『Oracle Databaseユーティリティ』を参照してください。

事前にサイズが決まっているフィールドのLOBデータのロード

これはLOBをロードする、最も高速で概念的に単純な形式です。

注意:
ロードするLOBデータはサイズが均等ではないため、サイズが小さいデータ・フィールドに空白を埋め込み、すべてのLOBを同じサイズにできます。

デリミタ付きフィールドのLOBデータのロード

この形式で、同じ列(データ・ファイルのフィールド)で異なるサイズのLOBを、問題なく処理します。ただし、このような柔軟性によって、SQL*Loaderでデリミタ文字列を探してデータをスキャンする必要があるため、パフォーマンスに影響します。

単一文字のデリミタで、文字列のデリミタを指定する場合は、データ・ファイルのキャラクタ・セットに注意してください。データ・ファイルのキャラクタ・セットが制御ファイルのキャラクタ・セットと異なる場合は、デリミタを16進文字列の表記法で指定できます('hexadecimal string')。デリミタを実際に16進数文字列で指定する場合は、入力データ・ファイルのキャラクタ・セット中の有効な文字で指定する必要があります。一方、16進数文字列で指定しない場合、デリミタは、クライアント(制御ファイル)のキャラクタ・セットで指定してください。この場合、デリミタは、SQL*Loaderによってデータ・ファイル内で検索される前に、データ・ファイルのキャラクタ・セットに変換されます。

LOBFILEからのLOBデータを含んだXML列のロード

LOBデータは、非常に長いデータであるため、プライマリ・データ・ファイルではなく、LOBFILEからロードすることが有効です。LOBFILEでは、LOBデータのインスタンスは、フィールド(事前に決められたサイズ、デリミタ付き、Length-Value Pair)内にあるとみなされますが、これらのフィールドは、レコードに編成されていません(LOBFILEにはレコードの概念がありません)。そのため、レコードを扱うことによって発生するオーバーヘッドを回避できます。このようなデータの編成方法は、LOBのロードにとって理想的です。

LOBFILEのLOBはメモリーに収まる必要はありません。SQL*Loaderは、LOBFILEを64KBのチャンクで読み取ります。

LOBFILEのデータ・フィールドは、次のいずれかの型であり、どれもXML列のロードに使用できます。

- ファイルの内容全体を読み取る単一のLOBフィールド

- サイズが決められたフィールド(固定長フィールド)

- デリミタ付きフィールド(TERMINATED BYまたはENCLOSED BY)
PRESERVE BLANKS句は、LOBFILEから読み取るフィールドには使用できません。

- Length-Value Pairフィールド(可変長フィールド)。
この型のフィールドからデータをロードするには、VARRAY、またはVARCHARまたはVARCHAR2 SQL*Loaderデータ型を使用します。

LOBFILEの指定

LOBFILEを静的に指定(ファイルにファイル名を指定)するか、または動的に指定(FILLERフィールドをファイル名のソースとして使用)できます。いずれの場合も、LOBFILEの終わりに到達するとファイルがクローズされ、そのファイルからさらにデータを読み取る場合は、空のフィールドからデータを読み取ることになります。

同じLOBFILEを、2つの異なるフィールドのソースとして指定しないでください。指定すると、通常、2つのフィールドで、データが別々に読み取られます。

SQL*Loaderによる制御ファイルからのXMLTypeデータの直接ロード

XMLTypeデータは制御ファイルから直接ロードできます。SQL*Loaderは、XMLTypeデータを他のスカラー型と同様に処理します。たとえば、NUMBER列に続いてXMLType列がオブジェクト・リレーショナル形式で格納されている表について考えてみます。この表に使用される制御ファイルには、NUMBER列の値とそれに続くXMLTypeインスタンスの値が含まれます。

SQL*Loaderは、サイズが非常に大きいXMLTypeインスタンスに対応できます。このようなデータをLOBファイルからロードするオプションもあります。

Oracle Databaseへの大規模なXML文書のロード

SQL*Loaderを使用すると、大量のXMLデータをOracle Databaseにロードできます。次の手順を実行します。

1. データ・ファイル(filelist.datなど)、つまりロードするXML文書の場所を特定します。

2. データ・ファイルにリストされているファイルを処理するコマンドを使用して、制御ファイル(load_data.ctlなど)を作成します。

3. SQL*Loaderシェル・コマンドsqlldrを起動し、この制御ファイル名を渡します。

これは例35-2、例35-1、例35-3で説明しています。ファイルfilelist.datには、2002年の発注書を含むXMLファイルがリストされます。

例35-1 データ・ファイルfilelist.dat: ロードするXMLファイルのリスト

2002/Jan/AMCEWEN-20021009123335370PDT.xm
2002/Jan/AWALSH-2002100912333570PDT.xml
2002/Jan/CJOHNSON-20021009123335170PDT.xml
2002/Jan/LSMITH-20021009123335500PDT.xml
2002/Jan/PTUCKER-20021009123335430PDT.xml
2002/Jan/SBELL-20021009123335280PDT.xml
2002/Jan/SKING-20021009123335560PDT.xml
2002/Jan/SMCCAIN-20021009123335470PDT.xml
2002/Jan/TFOX-20021009123335520PDT.xml
2002/Jan/VJONES-20021009123335350PDT.xml
2002/Jan/WSMITH-20021009123335450PDT.xml
2002/Feb/AMCEWEN-20021009123335600PDT.xml
2002/Feb/AMCEWEN-20021009123335701PDT.xml
2002/Feb/DAUSTIN-20021009123335811PDT.xml
2002/Feb/EABEL-20021009123335791PDT.xml
2002/Feb/PTUCKER-20021009123335721PDT.xml
2002/Feb/PTUCKER-20021009123335821PDT.xml
2002/Feb/SBELL-20021009123335771PDT.xml
2002/Feb/SMCCAIN-20021009123335681PDT.xml
2002/Feb/WSMITH-20021009123335650PDT.xml
2002/Feb/WSMITH-20021009123335741PDT.xml
2002/Feb/WSMITH-20021009123335751PDT.xml
...

例35-2 発注書XML文書のロードに使用する制御ファイルload_datra.ctl

load data
infile 'filelist.dat'
append
into table PURCHASEORDER
xmltype(XMLDATA)
(
filename filler char(120),
XMLDATA  lobfile(filename) terminated by eof
)

例35-3 シェル・コマンドsqlldrを使用したXMLデータのロード

sqlldr load_data.ctl

ダイレクト・パス・ロードを使用する場合は、かわりに次のコマンドを使用します。

sqlldr load_data.ctl direct=y

関連項目:

- 第3章「Oracle XML DBの使用」の「SQL*Loaderを使用した大規模なXMLファイルのロード」

- シェル・コマンドsqlldrの詳細は、『Oracle Databaseユーティリティ』を参照してください。

36 XMLType表のエクスポートおよびインポート

この章では、Oracle XML DBで使用するために、Oracle Data Pumpを使用してXMLType表をエクスポートおよびインポートする方法を説明します。

注意:
元のエクスポート・ユーティリティおよびインポート・ユーティリティでは、Oracle Database 11gリリース2(11.2)より前のデータベース・リリースにデータを移行できます。

この章では、次の項目について説明します。

- Oracle Data Pumpの概要

- Oracle XML DBにおけるエクスポート/インポートのサポート

- XML Schemaに基づくXMLType表のエクスポート

- 階層対応(リポジトリ)表のエクスポート

- トランスポータブル表領域のエクスポートおよびインポート

- リポジトリ・リソースおよびフォルダリング・サポート

- エクスポート/インポートの構文および例

Oracle Data Pumpの概要

Oracle Data Pumpテクノロジにより、1つのデータベースから他のデータベースへのデータおよびメタデータの高速移動が可能になります。Oracle Data Pumpには、expdpおよびimpdpという2つのコマンドライン・クライアントがあり、それぞれデータ・ポンプ・エクスポート・ユーティリティおよびデータ・ポンプ・インポート・ユーティリティを起動します。expdpおよびimpdpクライアントは、PL/SQLパッケージDBMS_DATAPUMP で提供されているプロシージャを使用して、コマンドラインに入力されたパラメータを渡してエクスポートおよびインポートのコマンドを実行します。これらのパラメータにより、完全なデータベースまたはデータベースのサブセットの、データおよびメタデータのエクスポートとインポートが可能になります。

データ・ポンプ・エクスポート・ユーティリティおよびインポート・ユーティリティ(それぞれコマンドexpdpおよびimpdpにより起動)は、元のエクスポート・ユーティリティ(exp)およびインポート・ユーティリティ(imp)と外観は似ていますが、完全に別のものです。

関連項目:
元のエクスポート・ユーティリティおよびインポート・ユーティリティを使用する場合の詳細は、『Oracle Databaseユーティリティ』を参照してください。

データ・ポンプ・エクスポート・ユーティリティ(expdpで起動)は、ダンプ・ファイル・セットと呼ばれるオペレーティング・システムのファイル・セットにデータおよびメタデータをアンロードします。ダンプ・ファイル・セットは、データ・ポンプ・インポート・ユーティリティ(impdpで起動)でのみインポートできます。

Oracle XML DBにおけるエクスポート/インポートのサポート

Oracle XML DBは、XMLデータを格納するXMLType表および列のエクスポートおよびインポートをサポートします。

XMLType記憶域形式(構造化、非構造化またはバイナリXML)に関係なく、このデータをエクスポートおよびインポートできます。ただし、データ・ポンプはテキスト形式のXMLデータまたはバイナリXMLデータのみをエクスポートまたはインポートします。このため、XMLTypeの構造化記憶域に使用される、基礎となるオブジェクト・リレーショナル表および列はエクスポートされません。それらの表および列は、バイナリ形式に変換され、自己記述的なバイナリXMLデータとしてエクスポートされます。CLOBインスタンス(非構造化記憶域)として格納されているXMLTypeデータはテキスト形式でエクスポートされます。

注意:
Oracle Data Pump for Oracle Database 11gリリース1(11.1)は、XML Schema、XML Schemaに基づくXMLType列またはバイナリXMLデータをリリース11.1より前のバージョンにエクスポートする機能をサポートしていません。

エクスポート形式に関係なく、ダンプ・ファイルの形式はCLOBまたは自己記述的なバイナリXMLにトークン・マップ・プリアンブルを加えたもののいずれかになります。Oracle Data Pumpがこのデータをダンプ・ファイルに格納する方法は、エクスポート・パラメータdata_optionsの値に依存します(このパラメータに対して唯一有効な値は、xml_clobsです)。エクスポート・コマンドラインでこの値を指定すると、XMLTypeデータがすべてダンプ・ファイルにテキスト形式で格納されます。expdpコマンドでxml_clobsパラメータを指定しない場合、表内のXMLType列の形式によってダンプ・ファイル内のデータの形式が決定されます。表36-1は、表内のXMLType列とそれに対応するダンプ・ファイルの形式を示しています。

表36-1 表内のXMLType列の形式とそれに対応するダンプ・ファイルの形式

XMLType列の記憶域モデル

XMLデータのダンプ・ファイル・フォーマット

非構造化記憶域

テキスト

構造化記憶域、バイナリXML記憶域またはハイブリッド記憶域(非構造化記憶域および構造化記憶域の混合)

自己記述的なバイナリXML

XMLTypeデータはXMLデータとしてエクスポートおよびインポートされるため、ソース・データベースおよびターゲット・データベースはそのデータに対して異なるXMLType記憶域モデルを使用できます。つまり、ある方式でXMLTypeデータが格納されたデータベースからデータをエクスポートし、それとは異なる方式でXMLTypeデータが格納されたデータベースへインポートできます。

注意:
外部表を使用してインポートする場合、XMLType記憶域モデルを使用しているかどうかにかかわらず、オプションappendを指定して、同じダンプ・ファイルからXMLType表または列に複数回インポートしないでください。そのようなことを行うと、一意性制約違反エラーが発生します。
外部表を使用したインポートの詳細は、『Oracle Databaseユーティリティ』を参照してください。

XML Schemaに基づくXMLType表のエクスポート

XML Schemaに基づくかどうかにかかわらず、XMLType表をエクスポートできます。表がXML Schemaに基づいている場合、表のデータを定義するために使用されたXML Schemaに依存します。構造化記憶域の場合、このXML Schemaに、データを格納するために使用されたSQLオブジェクト型への依存関係があることもあります。そのため、XML Schemaに基づくXMLType表を持つユーザーをエクスポートすると、次もエクスポートされます。

- SQLオブジェクト型(構造化記憶域が使用されている場合)

- XML Schema

- XML表

階層対応(リポジトリ)表のエクスポート

次のガイドラインは、階層対応表(Oracle XML DBリポジトリ・データの基礎となる表)のエクスポートに適用されます。

- 階層対応表の行レベルのセキュリティ(RLS)ポリシーおよびパス索引トリガーはエクスポートされません。これらの表のインポート時には階層対応していません。

- これらの表の非表示列ACLOIDおよびOWNERIDはエクスポートされません。インポートされたデータベースではこれらの列の値が異なる場合があるため、それらの値を再初期化する必要があります。

関連項目:
RLSポリシーおよびパス索引トリガーの詳細は、「リポジトリ・リソースおよびデータベース表のセキュリティ」を参照してください。

トランスポータブル表領域のエクスポートおよびインポート

トランスポータブル表領域機能を使用して、XML Schemaに基づくか基づかないかにかかわらず、Oracleデータベース間で表領域セットを移動できます。トランスポータブル表領域モードを使用してエクスポートをすると、指定された表領域セット内の表のメタデータ(および依存オブジェクト)のみがアンロードされます。その後、表領域のデータ・ファイルを他のOracleデータベースにコピーし、トランスポータブル表領域のインポートを実行できます。一般的に、ここでは、表領域の作成および表領域メタデータの再作成のみが行われるため、非常に高速に処理されます。

expdpのTRANSPORT_TABLESPACESパラメータを使用して、オブジェクトのメタデータがソース・データベースからターゲット・データベースへエクスポートされる対象となる表領域名のリストを指定します。

トランスポータブル表領域をエクスポートして、それをリリース・レベルの低いデータベースにインポートすることはできません。ターゲット・データベースのリリース・レベルは、ソース・データベースと同じかそれよりも高いレベルである必要があります。

エクスポート時には、Oracle XML DBリポジトリ階層情報が失われます(「階層対応(リポジトリ)表のエクスポート」を参照)。インポート時、インポートされるデータにより参照されているXML Schemaもすべてインポートされます。

リポジトリ・リソースおよびフォルダリング・サポート

Oracle XML DBでは、従来のリレーショナル・データベース構造ではなく、階層構造のデータベースにコンテンツを格納するフォルダリング・メカニズムがサポートされます。フォルダリングを使用すると、表名や列名などではなく、パス名およびURIを使用してデータ(リポジトリ・ソース)を参照できます。expdpまたはimpdpを使用する場合、このフォルダリング・メカニズムは完全にはサポートされません。

ただし、登録されたXML Schemaに基づくリソースの場合、データを格納するXMLType表はエクスポートおよびインポートできます。エクスポート中、XMLデータのみがエクスポートされ、Oracle XML DB Foldering階層内の関係は失われます。

データベースの全体エクスポート

Oracle XML DBは、Oracle XML DBリポジトリ用のメタデータ(およびXML Schemaに関連しないデータ)をデータベース・スキーマ(ユーザー・アカウント)XDBに格納します。Oracle Databaseはリポジトリ構造をエクスポートしないため、データベースの全体エクスポートの実行時に、これらのメタデータ表および構造はエクスポートされません。データベースの全体エクスポート時にデータベース・スキーマ(ユーザー)XDB全体がスキップされ、ユーザーXDBが所有するすべてのデータベース・オブジェクトはエクスポートされません。

異なるキャラクタ・セットでのエクスポートおよびインポート

XMLデータは、他のデータベース・オブジェクトの場合と同様に、エクスポート側サーバーのキャラクタ・セットでエクスポートされます。インポート中、このデータはインポート側サーバーのキャラクタ・セットに変換されます。

エクスポート/インポートの構文および例

Oracle Data Pumpを使用したエクスポートおよびインポートは『Oracle Databaseユーティリティ』 で説明されています。この項では、XMLTypeデータにコマンドexpdpおよびimpdpを使用する場合のその他のガイドラインおよび例を示します。Oracle Data Pumpは、CLOBとして格納されているXMLTypeデータを持つ表に関しては、他のすべての表と同じ方法で表のエクスポートおよびインポートを行います。

ここに示す例では、コマンドライン・コマンドexpdpおよびimpdpを使用します。このようなコマンドをユーザー名およびコマンド・パラメータとともに発行すると、パスワードの入力を要求されます。この例では、この入力要求は示されていません。

表モード・エクスポート/インポートの実行

XMLType表は、それを定義するために使用されたXML Schemaに依存します。同様に、XML Schemaはそれ用に作成または指定されたSQLオブジェクト型に依存します。XMLType表をインポートするには、そのXML SchemaおよびSQLオブジェクト型が必要です。TABLEモード・エクスポートを使用すると、表関連のメタデータおよびデータのみがエクスポートされます。これらのデータを正常にインポートできるようにするには、XML Schemaとオブジェクト型の両方が作成済であることを確認する必要があります。

この項に示す例では、次のようなデータベースを使用していることを前提としています。

- サンプル・スキーマを持つデータベース

- 非構造化記憶域形式(CLOB)であるXMLType列を持つ表foo

- READおよびWRITE権限がサンプル・スキーマに対して与えられているディレクトリ・オブジェクトdpump_dir

例36-1は、TABLESパラメータを使用して指定した表モード・エクスポートを示しています。これにより表fooがfoo.dmpダンプ・ファイルにエクスポートされます。

例36-1 表モードでのXMLTypeデータのエクスポート

expdp system directory=dpump_dir dumpfile=foo.dmp tables=foo

注意:
表モードでは、expdpコマンドでスキーマ接頭辞を指定しないと、エクスポート側のスキーマがデフォルトで使用されます。

例36-2は表モード・インポートを示しています。これにより、表fooがfoo.dmpダンプ・ファイルからインポートされます。

例36-2 表モードでのXMLTypeデータのインポート

impdp system tables=foo directory=dpump_dir dumpfile=foo.dmp table_exists_action=append

このインポートの際にfooという名前の表がすでに存在している場合は、既存の表の最後の行にtable_exists_actionパラメータが追加されます。APPENDを使用すると、データは常に新しい領域にロードされます。たとえ利用可能でも既存の領域は再利用されません。このため、ロード後にはデータの圧縮が必要になることがあります。

関連項目:
Oracle Data Pumpおよびそのコマンドライン・クライアントexpdpおよびimpdpの詳細は、『Oracle Databaseユーティリティ』を参照してください。

スキーマ・モード・エクスポート/インポートの実行

スキーマ・モード・エクスポートを実行する際には、ロールEXP_FULL_DATABASEが割り当てられている場合、データベース・スキーマ、データベース・スキーマ定義、およびそのデータベース・スキーマのシステム権限をエクスポートできます。

この項に示す例では、次のようなデータベースを使用していることを前提としています。

- ユーザーx4aが表po2を作成済。

- ユーザーx4aが登録されたXML Schema、ipoを持っており、そのXML SchemaがOrdered Collection Table(OCT)、item_oct2およびsitem_nt2を作成済。

ユーザーx4aは、例36-3に示すようにして表po2を作成します。

例36-3 表po2の作成

CREATE TABLE po2 (po XMLType)
XMLTYPE COLUMN po
XMLSCHEMA "ipo.xsd"
ELEMENT "purchaseOrder"
VARRAY po.XMLDATA."items"."item"
STORE AS TABLE item_oct2 ((PRIMARY KEY(NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
NESTED TABLE po.XMLDATA."shippedItems"."item" STORE AS sitem_nt2;

その後、例36-4に示すように表po2がデータが移入され、エクスポートされます。

例36-4 スキーマ・モードでのXMLTypeデータのエクスポート

expdp x4a directory=tkxm_xmldir dumpfile=x4a.dmp

例36-4では、次のものすべてがエクスポートされます。

- XML Schema、ipoの登録時に生成されたすべてのデータ型

- XML Schema、ipo

- XML Schema、ipoの登録時に生成された表po2およびOrdered Collection Table(OCT)、item_oct2およびsitem_nt2

- これらすべての表にあるすべてのデータ

例36-5 スキーマ・モードでのXMLTypeデータのインポート

impdp x4a directory=tkxm_xmldir dumpfile=x4a.dmp

例36-5は、x4a.dmp内のすべてのデータをユーザーx4aがすでに存在する他のデータベースにインポートします。

例36-6は例36-5と同じ動作をしますが、ユーザーx4aからユーザーquineへのデータベース・スキーマの再マップも行います。

例36-6 スキーマ・モードでのXMLTypeデータのインポート、スキーマの再マップ

impdp x4a directory=tkxm_xmldir dumpfile=x4a.dmp remap_schema=x4a:quine

例36-6は、x4a.dmp内のすべてのデータ(ユーザーx4aのデータベース・スキーマからエクスポートしたデータ)を、データベース・スキーマquineにインポートします。スキーマを再マップするには、ユーザーx4aがローカル・データベース上でIMP_FULL_DATABASEロールを、ソース・データベース上でEXP_FULL_DATABASEロールを付与されている必要があります。REMAP_SCHEMAは、すべてのオブジェクトをソース・スキーマからターゲット・スキーマにロードします。

37 Oracle Streams AQを使用したXMLデータの交換

Oracle Streamsアドバンスト・キューイング(AQ)には、次のデータベース統合化メッセージ・キューイング機能があります。

- メッセージを使用して、2つ以上のアプリケーションの非同期通信を可能にし、その管理を行います。

- ポイント・ツー・ポイント通信モデルおよびパブリッシュ・サブスクライブ通信モデルをサポートします。

Oracle Databaseとメッセージ・キューイングの統合により、メッセージ・キューイングにOracle Databaseの整合性、信頼性、リカバリ能力、スケーラビリティ、パフォーマンスおよびセキュリティ機能が追加されます。また、メッセージ・フローからのインテリジェント機能の抽出が容易になります。

この章では、AQを使用してXMLデータを交換する方法を説明します。内容は次のとおりです。

- AQとXMLの相互補完

- Oracle StreamsおよびAQ

- オブジェクト型のXMLType属性

- Internet Data Access Presentation(iDAP)

- iDAPアーキテクチャ

- XMLおよびOracle Streamsアドバンスト・キューイングを使用する場合のガイドライン

AQとXMLの相互補完

XMLは、企業間通信の標準フォーマットとして登場しました。XMLは、ビジネス・アプリケーション間で通信されるデータを表現するだけでなく、ビジネス・ロジックの表現にも使用されています。

Oracle Databaseでは、AQによって、ネイティブなXMLメッセージがサポートされます。AQ操作をXMLベースのInternet-Data-Access-Presentation (iDAP)形式で定義できます。iDAPは拡張可能なメッセージの起動プロトコルです。これはインターネット標準に基づいて構築され、転送メカニズムとしてHTTP(S)および電子メール・プロトコルを使用します。XMLがiDAP用のデータ表示用の言語です。

AQおよびXMLメッセージ・ペイロード

図37-1に、AQを使用して3つのアプリケーションと通信するOracle Databaseを示します。メッセージ・ペイロードはXMLデータです。この使用例においてAQが実行する一般的なタスクは、次のとおりです。

- サブスクリプション・ルールを使用したメッセージ・フロー

- メッセージ管理

- メッセージからのビジネス・インテリジェンスの抽出

- メッセージ変換

XMLメッセージは、AQを使用してアプリケーション間で非同期に渡されます。

- 企業内業務。典型的な使用例には、販売注文の遂行およびサプライチェーンの管理などがあります。

- 企業間業務処理。複数の統合ハブが、インターネットを介して通信できます。使用例には、旅行の予約、メーカーとサプライヤ間の調整、銀行間での資金の移動、保険請求の清算などがあります。
Oracleは、このアプローチを企業アプリケーション統合製品で使用します。XMLメッセージは、アプリケーションからAQハブへ送信されます。このハブは、メッセージを必要とするすべてのアプリケーションに対してメッセージ・サーバーとして機能します。このハブ・アンド・スポーク・アーキテクチャを介して、XMLメッセージを、疎結合された複数のアプリケーションへ非同期に送信できます。

図37-1に、AQを使用して、次のアプリケーションを介して配送したXMLペイロード・メッセージを示します。

- iDAPを使用し、HTTPおよびHTTPS接続を介したAQ操作を行うWebベースのアプリケーション

- Net*接続を介してXMLメッセージを伝播するために、AQを使用するアプリケーション

- AQを使用して、HTTP、HTTPSまたはSMTPを介してインターネットまたはXMLメッセージを直接データベースへ伝播するアプリケーション

図37-1は、AQクライアントが、OCI、JavaまたはPL/SQLを使用してデータにアクセスできることも示しています。

図37-1 Oracle Streamsアドバンスト・キューイングおよびXMLメッセージ・ペイロード

AQを使用するメリット

AQを使用すると、異なるアプリケーション間での通信を柔軟に構成できます。 統合されたソリューションの管理、構成およびビジネス・ニーズの変化に伴う変更が容易になります。複雑な業務トランザクションを実行するための、複数のアプリケーションの協調、調整、同期化が可能になります。

AQが提供するメッセージ管理では、異なるアプリケーション間のメッセージ・フローを管理できます。AQは、監査や追跡目的、およびビジネス・インテリジェンスの抽出のためにもメッセージを保持できます。

AQは、メッセージにアクセスするためのSQLビューを提供します。これらのビューを使用して、動向を分析できます。

Oracle StreamsおよびAQ

Oracle Streams(Streams)を使用すると、ストリーム内のデータおよびイベントを共有できます。ストリームは、この情報をデータベース内またはデータベース間で伝播できます。ストリームは、指定された情報を指定された宛先にルーティングします。これによって、イベントを取得および管理し、他のデータベースおよびアプリケーションとイベントを共有するための従来のソリューションより、機能性と柔軟性が向上します。

Streamsを使用すると、あるソリューションを使用したために別のソリューションが使用できなくなるということがなくなります。Streamsを使用すると、分散した企業とアプリケーション、データ・ウェアハウスおよび高可用性ソリューションを構築および操作できます。Oracle Streamsのすべての機能は同時に使用できます。

Streamsを使用して、次の操作を実行できます。

- データベースでの変更の取得。バックグラウンドの取得プロセスが表、データベース・スキーマまたはデータベース全体に加えられた変更を取得するように構成できます。取得プロセスでは、REDOログから変更が取得され、取得された各変更が論理変更レコード(LCR)にフォーマットされます。REDOログに変更が生成されたデータベースをソース・データベースと呼びます。

- キューへのイベントのエンキュー。Streamsキューには、LCRおよびユーザー・メッセージという2つのタイプのイベントをステージングできます。取得プロセスでは、LCRイベントが、指定したキューにエンキューされます。そのキューは、LCRイベントを同じデータベース内で共有するか、または他のデータベースと共有できます。また、ユーザー・アプリケーションを使用してユーザー・イベントを明示的にエンキューすることもできます。明示的にエンキューされたこれらのイベントは、LCRまたはユーザー・メッセージになります。

- あるキューから別のキューへのイベントの伝播。これらのキューは、同じデータベース内または異なるデータベース内に存在できます。

- イベントのデキュー。バックグラウンドの適用プロセスによって、イベントをデキューできます。また、ユーザー・アプリケーションを使用してイベントを明示的にデキューすることもできます。

- データベースでのイベントの適用。適用プロセスがキュー内のすべてのイベントまたは指定したイベントのみを適用するように構成できます。また、適用プロセスが、ユーザー独自のPL/SQLサブプログラムをコールしてイベントを処理するように構成することもできます。
LCRイベントが適用され、他のタイプのイベントが処理されるデータベースを宛先データベースと呼びます。構成によっては、ソース・データベースと宛先データベースが同じ場合もあります。

Streamsメッセージ・キューイング

Streamsを使用すると、ユーザー・アプリケーションは次の操作を実行できます。

- 様々な型のメッセージのエンキュー

- 使用可能なメッセージの伝播

- 宛先データベースでのメッセージのデキュー

Streamsでは、SYS.AnyData型のメッセージをステージングする新しいタイプのキューが導入されています。ほぼすべての型のメッセージをSYS.AnyDataラッパーでラップし、SYS.AnyDataキューにステージングできます。Streamsは、Advanced Queuing (AQ)と相互に作用します。これによって、マルチ・コンシューマ・キュー、パブリッシュとサブスクライブ、コンテンツ・ベースのルーティング、インターネット伝播、変換、他のメッセージ・サブシステムへのゲートウェイなど、メッセージ・キューイング・システムのすべての標準機能がサポートされます。

関連項目:
『Oracle Streams概要および管理』およびその付録Aの「LCRのXML Schema」を参照してください。

オブジェクト型のXMLType属性

XMLType属性を持つOracleオブジェクト型を使用するキューを作成できます。これらのキューは、XML文書であるメッセージを転送および格納するために使用できます。XMLTypeを使用すると、次の操作を実行できます。

- 任意の型のメッセージをキューに格納する。

- 文書をCLOB値として内部的に格納する。

- 複数の型のペイロードをキューに格納する。

- XMLExistsなどのSQL/XML関数を使用してXMLType列を問い合せる。

- サブスクライバ・ルールまたはデキュー条件にその演算子を指定する。

Internet Data Access Presentation(iDAP)

SOAPを使用して、インターネット上でAQにアクセスできます。Internet Data Access Presentation (iDAP)は、AQ操作に対するSOAP仕様です。iDAPによって、SOAPリクエストの本体にXMLメッセージ構造が定義されます。iDAPによって構造化されたメッセージは、HTTP(S)またはSMTPなどの転送プロトコルを使用してインターネット上で転送されます。

iDAPは、Content-Typeのtext/xmlを使用して、SOAPリクエストの本体を指定します。XMLは、iDAPリクエストおよび応答メッセージの表示方法を次のとおり定義します。

- すべてのリクエスト・タグおよびレスポンス・タグは、SOAP名前空間で有効です。

- AQ操作は、iDAP名前空間で有効です。

- 送信者は、SOAP本体のiDAP要素および属性に名前空間を含めます。

- 受信者は、適切な名前空間を含むiDAPメッセージを処理します。不適切な名前空間を持つリクエストの場合、リクエストが無効であるというエラーを戻します。

- SOAP名前空間の値は、http://schemas.xmlsoap.org/soap/envelope/です。

- iDAP名前空間の値は、http://ns.oracle.com/AQ/schemas/accessです。

関連項目:
『Oracle Streamsアドバンスト・キューイング・ユーザーズ・ガイド』

iDAPアーキテクチャ

図37-2に、HTTPまたはHTTPSメッセージを送信するために必要な次のコンポーネントを示します。

- iDAP形式に準拠したXMLメッセージをAQサーブレットに送信するクライアント・プログラム。これには、Webブラウザなど任意のHTTPクライアントが含まれます。

- Apache JServ、Tomcatなど、受信したXMLメッセージを解析するためのAQサーブレットをホストするWebサーバーまたはサーブレット・コンテナ。

- Oracle ServerまたはOracle Database。Oracle Streams AQサーブレットは、Oracle Databaseに接続し、キューに対して操作を実行します。

図37-2 HTTPまたはHTTPSを使用してAQ操作を実行するためのiDAPアーキテクチャ

XMLTypeキュー・ペイロード

XMLType 属性を含むペイロードを持つキューを作成できます。これらのペイロードは、XML文書を含むメッセージの転送および格納に使用できます。XMLType属性を持つOracleオブジェクトを定義すると、次の操作を実行できます。

- 複数の型のXML文書を同じキュー内に格納します。この文書は、CLOBインスタンスとして内部的に格納されます。

- XMLExistsやXMLQueryなどのSQL/XML関数を使用して、XMLType属性を持つメッセージを選択的にデキューします。

- 変換を定義して、OracleオブジェクトをXMLTypeに変換します。

- XMLExistsやXMLQueryなどのSQL/XML関数を使用して、メッセージ内容を問い合せるルールベースのサブスクライバを定義します。

BooksOnlineのアプリケーションの海外向け出荷サイトでは、注文がSYS.XMLTypeを使用して表現されると想定します。注文入力サイトでは、注文がOracleオブジェクトのORDER_TYPとして表現されます。

例37-1では、海外向け出荷用のキュー表およびキューを作成します。

例37-1 キュー表およびキューの作成

BEGIN
DBMS_AQADM.create_queue_table(
queue_table        => 'OS_orders_pr_mqtab',
comment            => 'Overseas Shipping MultiConsumer Orders queue table',
multiple_consumers => TRUE,
queue_payload_type => 'SYS.XMLtype',
compatible         => '8.1');
END;
/

BEGIN
DBMS_AQADM.create_queue(queue_name   => 'OS_bookedorders_que',
queue_table  => 'OS_orders_pr_mqtab');
END;
/

海外向け出荷サイトの注文の表現は、注文入力サイトでの注文の表現と異なるため、メッセージは注文入力サイトから海外向け出荷サイトに送信される前に変換される必要があります。例37-2では変換を作成し、例37-3でそれを適用します。

例37-2 メッセージ・データをXMLに変換するための変換の作成

CREATE OR REPLACE FUNCTION convert_to_order_xml(input_order ORDER_TYP)
RETURN XMLType AS
new_order XMLType;
BEGIN
SELECT sys_xmlgen(input_order) INTO new_order FROM DUAL;
RETURN new_order;
END convert_to_order_xml;
/

BEGIN
SYS.DBMS_TRANSFORM.create_transformation(
schema =>         'OE',
name   =>         'OE2XML',
from_schema =>    'OE',
from_type =>      'ORDER_TYP',
to_schema =>      'SYS',
to_type =>        'XMLTYPE',
transformation => 'convert_to_order_xml(source.user_data)');
END;
/

例37-3 メッセージを海外に送信する前の変換の適用

-- Add a rule-based subscriber for overseas shipping to the booked-orders
-- queues with transformation.
DECLARE
subscriber SYS.AQ$_AGENT;
BEGIN
subscriber := SYS.AQ$_AGENT('Overseas_Shipping',
'OS.OS_bookedorders_que',
NULL);
DBMS_AQADM.add_subscriber(
queue_name     => 'OS_bookedorders_que',
subscriber     => subscriber,
rule           => 'XMLSerialize(CONTENT XMLQuery(''//orderregion''' ||
'PASSING tab.user_data RETURNING CONTENT)' ||
' AS VARCHAR2(1000)) = ''INTERNATIONAL''',
transformation => 'OE.OE2XML');
END;
/

注文入力アプリケーションによって使用される型から、海外向け出荷によって使用される型への変換の定義の詳細は、『Oracle Streamsアドバンスト・キューイング・ユーザーズ・ガイド』を参照してください。

例37-4では、別の国(この場合はカナダ)の顧客の注文を処理するアプリケーションで、メッセージをどのようにデキューできるかを示しています。

例37-4 XMLTypeおよびAQ: メッセージのデキュー

-- Create procedure to enqueue into single-consumer queues.
CREATE OR REPLACE PROCEDURE get_canada_orders AS
deq_msgid             RAW(16);
dopt                  DBMS_AQ.dequeue_options_t;
mprop                 DBMS_AQ.message_properties_t;
deq_order_data        SYS.XMLType;
deq_order_data_text   CLOB;
no_messages           EXCEPTION;
PRAGMA EXCEPTION_INIT (no_messages, -25228);
new_orders            BOOLEAN := TRUE;
BEGIN
dopt.wait := 1;
-- Specify dequeue condition to select orders for Canada.
dopt.deq_condition := 'XMLSerialize(CONTENT ' ||
'XMLQuery(''/ORDER_TYP/CUSTOMER/COUNTRY/text()''' ||
' PASSING tab.user_data RETURNING CONTENT)' ||
' AS VARCHAR2(1000))=''CANADA''';
dopt.consumer_name := 'Overseas_Shipping';
WHILE (new_orders) LOOP
BEGIN
DBMS_AQ.dequeue(queue_name         => 'OS.OS_bookedorders_que',
dequeue_options    => dopt,
message_properties => mprop,
payload            => deq_order_data,
msgid              => deq_msgid);
COMMIT;
SELECT XMLSerialize(DOCUMENT deq_order_data AS CLOB)
INTO deq_order_data_text FROM DUAL;
DBMS_OUTPUT.put_line('Order for Canada - Order: ' || deq_order_data_text);
EXCEPTION
WHEN no_messages THEN
DBMS_OUTPUT.put_line (' ---- NO MORE ORDERS  ---- ');
new_orders := FALSE;
END;
END LOOP;
END;
/

XMLおよびOracle Streamsアドバンスト・キューイングを使用する場合のガイドライン

この項では、XMLおよびOracle Streamsアドバンスト・キューイングを使用する場合のガイドラインについて説明します。

多くのPDFファイルを持つOracle Streams AQ XMLメッセージを1つのレコードとして格納する方法

Oracle Streamsアドバンスト・キューイングを使用して、企業間でXML文書を交換できます。受信または送信される各メッセージには、XMLヘッダー、XMLアタッチメント(XMLデータ・ストリーム)、DTDおよびPDFファイルが含まれ、データをqueuetableのようなデータベース表に格納できます。メッセージは、1つのレコードまたは1つのピースとしてOracleキュー表にエンキューできます。または、メッセージを複数のレコード(XMLデータ・ストリームに対するCLOB型としての1つのレコード、PDFファイルに対するRAWとしての1つのレコードなど)としてエンキューできます。メッセージのデキューもできます。

次の方法で可能です。

- CLOB、RAWなどの属性を持つオブジェクト型を定義し、これを単一メッセージとして格納します。

- AQメッセージ・グループ化機能を使用して、該当するメッセージを複数のメッセージに格納します。この場合、メッセージのプロパティは1つのグループに対応付けられます。メッセージ・グループ化機能を使用するには、すべてのメッセージのペイロード型が同じである必要があります。

ペイロードを指定するには、最初に、次の例のようにオブジェクト型を作成します。

CREATE TYPE mypayload_type as OBJECT (xmlDataStream CLOB, dtd CLOB, pdf BLOB);

次に、このオブジェクト型を単一のメッセージとして格納します。

メッセージをエンキューした後の新しい受信者の追加

キュー表を使用して、メッセージ割当てをサポートできます。たとえば、他の企業は、メッセージを特定の企業に送信するときに、これらのメッセージを処理するために誰が割り当てられるかは認識していません。ただし、そのメッセージが人事部(HR)宛てであることは認識しています。そのため、すべてのメッセージは人事部管理者へ送信されます。この時点で、メッセージはキュー表にエンキューされます。このメッセージの受信者は人事部管理者のみであり、その他のすべての人事部社員はこのキューのサブスクライバとして事前定義されています。

メッセージがエンキューされた後に受信者のリストを変更することはできません。受信者のリストを指定しない場合、サブスクライバはそのキューをサブスクライブし、メッセージをデキューできます。この場合は、新しい受信者がそのキューのサブスクライバである必要があります。それ以外の場合は、メッセージをデキューし、そのメッセージを新しい受信者が再度エンキューする必要があります。

XMLメッセージのエンキューおよびデキュー

Oracle Streams AQは、オブジェクトのエンキューおよびデキューをサポートします。これらのオブジェクトは、メタデータ属性に加えて、XML文書を含むXMLType型の属性を持つことができます。詳細および例は、『Oracle Streamsアドバンスト・キューイング・ユーザーズ・ガイド』を参照してください。

XMLコンテンツを持つメッセージのOracle Streams AQキューからの解析

XMLコンテンツを持つメッセージをOracle Streams AQキューから解析し、ODS(Operational Data Store)にある表およびフィールドを更新できます。

Oracle Streams AQと同時に、Oracle XML Parser for JavaおよびJavaストアド・プロシージャを使用すると、特定のXMLデータをターゲットにする問合せに基づいて、AQエンキューまたはAQデキューの回数やJMSヘッダー情報などのメタデータを取得できます。この方法は、Oracle Text XML検索とともに使用できます。

関連項目:
第12章「XMLデータの全文検索」

XML文書が処理されるまでのリスナー停止の回避

クライアントからのXMLメッセージの受信後、すぐにメッセージを処理する必要がある場合があります。しかし、各XML文書は処理数秒かかります。PL/SQLでは、XML文書を処理するために、1つのプロシージャがリスナーの開始、メッセージのデキュー、別のプロシージャのコールを行います。リスナーはXML文書が処理されるまで停止し、その間メッセージがキューに蓄積されます。

メッセージを受信後、かわりにPL/SQLパッケージDBMS_JOBを使用してジョブを送信できます。ジョブは、異なるデータベース・セッションで非同期に起動されます。

メッセージがキューに入れられると非同期に起動されるPL/SQLコールバックを登録できます。PL/SQLコールバックは、 Oracle Streams AQ通知フレームワークの一部です。

AQでのHTTPSの使用

HTTPSを使用してXMLメッセージをサプライヤに送信し、レスポンスを受信するために、Oracle Streams AQのインターネット・アクセス機能を使用できます。XMLを使用して、確実なトランザクション処理でHTTPを介してメッセージをエンキューまたはデキューできます。

関連項目:
『Oracle Streamsアドバンスト・キューイング・ユーザーズ・ガイド』

Oracle Streams AQメッセージ・ペイロードへのXMLの格納

SYS.XMLTypeが含まれるADTをペイロードとして使用する以外にも、XMLをOracle Streams AQメッセージ・ペイロードにネイティブに格納することができます。ペイロードとXMLType属性を持つキューを作成できます。

iDAPとSOAPの比較

iDAPは、AQ操作に対するSOAP仕様です。iDAPは、Oracle Streams AQ操作に対するXML仕様です。SOAPは、サービスを起動するための共通のメカニズムを定義します。iDAPは、AQ操作を実行するためのメカニズムを定義します。

iDAPには、SOAPが定義していない、次の主要なプロパティが含まれます。

- トランザクション動作。AQ操作をトランザクションとして実行できます。トランザクションは、複数のiDAPリクエストにまたがることができます。

- すべてのiDAP操作は、許可済ユーザーおよび認証済ユーザーのみが実行できます。

第VII部

付録

第(不明な手順番号)部では、一連の付録として参考資料を提供します。

- 付録A「Oracleが提供するXML Schemaおよび例」

- 付録B「Oracle XML DBの制限」

A Oracleが提供するXML Schemaおよび例

この付録には、RESOURCE_VIEWおよびPATH_VIEWの定義と構造、およびOracle XML DB提供のXML Schemaが含まれています。また、様々な例で使用されている発注書XML Schemaの完全なリストと、XMLコンテンツをOracle XML DBにロードするためのCの例も含まれています。

この付録の内容は次のとおりです。

- XDBResource.xsd: Oracle XML DBリソースのためのXML Schema

- XDBResConfig.xsd: リソース構成のためのXML Schema

- acl.xsd: ACLのXML Schema

- xdbconfig.xsd: Oracle XML DBを構成するためのXML Schema

- xdiff.xsd: スキーマをインプレース拡張と比較するためのXML Schema

- 発注書XML Schema

- XSLスタイルシートの例: PurchaseOrder.xsl

- C(OCI)を使用したXMLデータのロード

- XMLコンテキスト(OCI)の初期化および終了

XDBResource.xsd: Oracle XML DBリソースのためのXML Schema

この項では、Oracle XML DBリソースを表すために使用される、Oracle XML DBが提供するXML Schema XDBResource.xsdの完全なリストを示します。

XDBResource.xsd

<schema xdb:schemaURL="http://xmlns.oracle.com/xdb/XDBResource.xsd"
targetNamespace="http://xmlns.oracle.com/xdb/XDBResource.xsd"
version="1.0" xdb:numProps="72" elementFormDefault="qualified"
xdb:flags="23" xdb:mapStringToNCHAR="false" xdb:mapUnboundedStringToLob="false"
xdb:storeVarrayAsTable="false" xdb:schemaOwner="XDB">
<simpleType name="OracleUserName">
<restriction base="string">
<minLength value="1" fixed="false"/>
<maxLength value="4000" fixed="false"/>
</restriction>
</simpleType>
<simpleType name="ResMetaStr">
<restriction base="string">
<minLength value="1" fixed="false"/>
<maxLength value="128" fixed="false"/>
</restriction>
</simpleType>
<simpleType name="SchElemType">
<restriction base="string">
<minLength value="1" fixed="false"/>
<maxLength value="4000" fixed="false"/>
</restriction>
</simpleType>
<simpleType name="GUID">
<restriction base="hexBinary">
<minLength value="8" fixed="false"/>
<maxLength value="32" fixed="false"/>
</restriction>
</simpleType>
<simpleType name="LocksRaw">
<restriction base="hexBinary">
<minLength value="0" fixed="false"/>
<maxLength value="2000" fixed="false"/>
</restriction>
</simpleType>
<simpleType name="lockModeType">
<restriction base="string">
<enumeration value="exclusive" fixed="false"/>
<enumeration value="shared" fixed="false"/>
</restriction>
</simpleType>
<simpleType name="lockTypeType">
<restriction base="string">
<enumeration value="read-write" fixed="false"/>
<enumeration value="write" fixed="false"/>
<enumeration value="read" fixed="false"/>
</restriction>
</simpleType>
<simpleType name="lockDepthType">
<restriction base="string">
<enumeration value="0" fixed="false"/>
<enumeration value="infinity" fixed="false"/>
</restriction>
</simpleType>
<complexType name="lockType" abstract="false" mixed="false">
<sequence minOccurs="1" maxOccurs="1">
<element xdb:propNumber="768" name="LockOwner" type="string" xdb:memType="1"
xdb:system="false" xdb:mutable="true" xdb:JavaType="String" xdb:global="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="769" name="Mode" type="xdb:lockModeType" xdb:memType="1"
xdb:system="false" xdb:mutable="true" xdb:JavaType="String" xdb:global="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="770" name="Type" type="xdb:lockTypeType" xdb:memType="1"
xdb:system="false" xdb:mutable="true" xdb:JavaType="String" xdb:global="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="771" name="Depth" type="xdb:lockDepthType" xdb:memType="1"
xdb:system="false" xdb:mutable="true" xdb:JavaType="String" xdb:global="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="772" name="Expiry" type="dateTime" xdb:memType="180"
xdb:system="false" xdb:mutable="true" xdb:JavaType="TimeStamp" xdb:global="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="0" maxOccurs="1"/>
<choice minOccurs="0" maxOccurs="unbounded">
<element xdb:propNumber="773" name="Token" type="string" xdb:memType="1"
xdb:system="false" xdb:mutable="true" xdb:JavaType="String" xdb:global="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="0" maxOccurs="1"/>
<element xdb:propNumber="774" name="NodeId" type="string" xdb:memType="1"
xdb:system="false" xdb:mutable="true" xdb:JavaType="String" xdb:global="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="0" maxOccurs="1"/>
</choice>
</sequence>
</complexType>
<complexType name="locksType" abstract="false" mixed="false">
<sequence minOccurs="1" maxOccurs="1">
<element xdb:propNumber="767" name="Lock" type="xdb:lockType" xdb:memType="258"
xdb:system="false" xdb:mutable="true" xdb:JavaType="XMLType" xdb:global="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
minOccurs="0" maxOccurs="2147483647"/>
</sequence>
</complexType>
<complexType name="ResContentsType" abstract="false" mixed="false">
<sequence minOccurs="1" maxOccurs="1">
<any xdb:propNumber="736" name="ContentsAny" xdb:memType="258" xdb:system="false"
xdb:mutable="false" xdb:JavaType="XMLType" minOccurs="0" maxOccurs="1"/>
</sequence>
</complexType>
<complexType name="ResAclType" abstract="false" mixed="false">
<sequence minOccurs="1" maxOccurs="1">
<any xdb:propNumber="737" name="ACLAny" xdb:memType="258" xdb:system="false"
xdb:mutable="false" xdb:JavaType="XMLType" minOccurs="0" maxOccurs="1"/>
</sequence>
</complexType>
<complexType name="AttrCopyType" abstract="false" mixed="false">
<sequence minOccurs="1" maxOccurs="1">
<any xdb:propNumber="748" name="AttrCopyAny" xdb:memType="258" xdb:system="false"
xdb:mutable="false" xdb:JavaType="XMLType" minOccurs="0" maxOccurs="65535"/>
</sequence>
</complexType>
<complexType name="RCListType" abstract="false" mixed="false">
<sequence minOccurs="1" maxOccurs="1">
<element xdb:propNumber="755" name="OID" type="hexBinary" xdb:memByteLength="22"
xdb:memType="23" xdb:system="false" xdb:mutable="false" xdb:SQLName="OID"
xdb:SQLType="RAW" xdb:JavaType="byteArray" xdb:global="false"
xdb:SQLCollType="XDB$OID_LIST_T" xdb:SQLCollSchema="XDB" xdb:hidden="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="65535"/>
</sequence>
</complexType>
<complexType name="ResourceType" abstract="false" mixed="false">
<sequence minOccurs="1" maxOccurs="1">
<element xdb:propNumber="709" name="CreationDate" type="dateTime" xdb:memType="180"
xdb:system="false" xdb:mutable="false" xdb:SQLName="CREATIONDATE"
xdb:SQLType="TIMESTAMP" xdb:JavaType="TimeStamp" xdb:global="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="710" name="ModificationDate" type="dateTime"
xdb:memType="180" xdb:system="false" xdb:mutable="false"
xdb:SQLName="MODIFICATIONDATE" xdb:SQLType="TIMESTAMP" xdb:JavaType="TimeStamp"
xdb:global="false" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="true" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="711" name="Author" type="xdb:ResMetaStr" xdb:memType="1"
xdb:system="false" xdb:mutable="false" xdb:SQLName="AUTHOR" xdb:SQLType="VARCHAR2"
xdb:JavaType="String" xdb:global="false" nillable="false" abstract="false"
xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="0"
maxOccurs="1"/>
<element xdb:propNumber="712" name="DisplayName" type="xdb:ResMetaStr"
xdb:memType="1" xdb:system="false" xdb:mutable="false" xdb:SQLName="DISPNAME"
xdb:SQLType="VARCHAR2" xdb:JavaType="String" xdb:global="false" nillable="false"
abstract="false" xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="1"
maxOccurs="1"/>
<element xdb:propNumber="713" name="Comment" type="xdb:ResMetaStr" xdb:memType="1"
xdb:system="false" xdb:mutable="false" xdb:SQLName="RESCOMMENT"
xdb:SQLType="VARCHAR2" xdb:JavaType="String" xdb:global="false" nillable="false"
abstract="false" xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="1"
maxOccurs="1"/>
<element xdb:propNumber="714" name="Language" type="xdb:ResMetaStr" xdb:memType="1"
xdb:system="false" xdb:mutable="false" xdb:SQLName="LANGUAGE"
xdb:SQLType="VARCHAR2" xdb:JavaType="String" default="en" xdb:global="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="false" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="715" name="CharacterSet" type="xdb:ResMetaStr"
xdb:memType="1" xdb:system="false" xdb:mutable="false" xdb:SQLName="CHARSET"
xdb:SQLType="VARCHAR2" xdb:JavaType="String" xdb:global="false" nillable="false"
abstract="false" xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="0"
maxOccurs="1"/>
<element xdb:propNumber="716" name="ContentType" type="xdb:ResMetaStr"
xdb:memType="1" xdb:system="false" xdb:mutable="false" xdb:SQLName="CONTYPE"
xdb:SQLType="VARCHAR2" xdb:JavaType="String" xdb:global="false" nillable="false"
abstract="false" xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="0"
maxOccurs="1"/>
<element xdb:propNumber="717" name="RefCount" type="nonNegativeInteger"
xdb:memByteLength="4" xdb:memType="68" xdb:system="false" xdb:mutable="true"
xdb:SQLName="REFCOUNT" xdb:SQLType="RAW" xdb:JavaType="long" xdb:global="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="718" name="LockBuf" type="xdb:LocksRaw" xdb:memType="23"
xdb:system="false" xdb:mutable="true" xdb:SQLName="LOCKS" xdb:SQLType="RAW"
xdb:JavaType="byteArray" xdb:global="false" nillable="false" abstract="false"
xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="0"
maxOccurs="1"/>
<element xdb:propNumber="732" name="ACL" type="xdb:ResAclType" xdb:memType="258"
xdb:system="false" xdb:mutable="false" xdb:JavaType="XMLType" xdb:global="false"
xdb:hidden="false" xdb:transient="generated" xdb:baseProp="false" nillable="false"
abstract="false" xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:JavaClassname="oracle.xdb.ResAclTypeBean"
xdb:beanClassname="oracle.xdb.ResAclTypeBean" xdb:numCols="0" minOccurs="0"
maxOccurs="1"/>
<element xdb:propNumber="719" name="ACLOID" type="hexBinary" xdb:memType="23"
xdb:system="false" xdb:mutable="false" xdb:SQLName="ACLOID" xdb:SQLType="RAW"
xdb:JavaType="byteArray" xdb:global="false" xdb:hidden="true" xdb:baseProp="true"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="720" name="Owner" type="xdb:OracleUserName" xdb:memType="1"
xdb:system="false" xdb:mutable="false" xdb:JavaType="String" xdb:global="false"
xdb:hidden="false" xdb:transient="generated" xdb:baseProp="false" nillable="false"
abstract="false" xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="0" minOccurs="0"
maxOccurs="1"/>
<element xdb:propNumber="721" name="OwnerID" type="xdb:GUID" xdb:memType="23"
xdb:system="false" xdb:mutable="false" xdb:SQLName="OWNERID" xdb:SQLType="RAW"
xdb:JavaType="byteArray" xdb:global="false" xdb:hidden="true" xdb:baseProp="true"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="722" name="Creator" type="xdb:OracleUserName"
xdb:memType="1" xdb:system="false" xdb:mutable="false" xdb:JavaType="String"
xdb:global="false" xdb:hidden="false" xdb:transient="generated"
xdb:baseProp="false" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="false" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:numCols="0" minOccurs="0" maxOccurs="1"/>
<element xdb:propNumber="723" name="CreatorID" type="xdb:GUID" xdb:memType="23"
xdb:system="false" xdb:mutable="false" xdb:SQLName="CREATORID" xdb:SQLType="RAW"
xdb:JavaType="byteArray" xdb:global="false" xdb:hidden="true" xdb:baseProp="true"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="724" name="LastModifier" type="xdb:OracleUserName"
xdb:memType="1" xdb:system="false" xdb:mutable="false" xdb:JavaType="String"
xdb:global="false" xdb:hidden="false" xdb:transient="generated"
xdb:baseProp="false" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="false" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:numCols="0" minOccurs="0" maxOccurs="1"/>
<element xdb:propNumber="725" name="LastModifierID" type="xdb:GUID" xdb:memType="23"
xdb:system="false" xdb:mutable="false" xdb:SQLName="LASTMODIFIERID"
xdb:SQLType="RAW" xdb:JavaType="byteArray" xdb:global="false" xdb:hidden="true"
xdb:baseProp="true" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="true" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="726" name="SchemaElement" type="xdb:SchElemType"
xdb:memType="1" xdb:system="false" xdb:mutable="false" xdb:JavaType="String"
xdb:global="false" xdb:hidden="false" xdb:transient="generated"
xdb:baseProp="false" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="false" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:numCols="0" minOccurs="0" maxOccurs="1"/>
<element xdb:propNumber="727" name="ElNum" type="nonNegativeInteger"
xdb:memByteLength="4" xdb:memType="3" xdb:system="false" xdb:mutable="false"
xdb:SQLName="ELNUM" xdb:SQLType="INTEGER" xdb:JavaType="long" xdb:global="false"
xdb:hidden="true" xdb:baseProp="true" nillable="false" abstract="false"
xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="true"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="1"
maxOccurs="1"/>
<element xdb:propNumber="728" name="SchOID" type="hexBinary" xdb:memType="23"
xdb:system="false" xdb:mutable="false" xdb:SQLName="SCHOID" xdb:SQLType="RAW"
xdb:JavaType="byteArray" xdb:global="false" xdb:hidden="true" xdb:baseProp="true"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="733" name="Contents" type="xdb:ResContentsType"
xdb:memType="258" xdb:system="false" xdb:mutable="false" xdb:JavaType="XMLType"
xdb:global="false" xdb:hidden="false" xdb:transient="manifested"
xdb:baseProp="false" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="false" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:JavaClassname="oracle.xdb.ResContentsTypeBean"
xdb:beanClassname="oracle.xdb.ResContentsTypeBean" xdb:numCols="0" minOccurs="0"
maxOccurs="1"/>
<element xdb:propNumber="729" name="XMLRef" type="REF" xdb:memType="110"
xdb:system="false" xdb:mutable="true" xdb:SQLName="XMLREF" xdb:SQLType="REF"
xdb:JavaType="Reference" xdb:global="false" xdb:hidden="true" xdb:baseProp="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="false" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="0" maxOccurs="1"/>
<element xdb:propNumber="730" name="XMLLob" type="hexBinary" xdb:memType="113"
xdb:system="false" xdb:mutable="true" xdb:SQLName="XMLLOB" xdb:SQLType="BLOB"
xdb:JavaType="String" xdb:global="false" xdb:hidden="true" xdb:baseProp="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="false" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="0" maxOccurs="1"/>
<element xdb:propNumber="731" name="Flags" type="nonNegativeInteger"
xdb:memByteLength="4" xdb:memType="3" xdb:system="false" xdb:mutable="true"
xdb:SQLName="FLAGS" xdb:SQLType="RAW" xdb:JavaType="long" xdb:global="false"
xdb:hidden="true" xdb:baseProp="true" nillable="false" abstract="false"
xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="true"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="1"
maxOccurs="1"/>
<element xdb:propNumber="740" name="VCRUID" type="xdb:GUID" xdb:memType="23"
xdb:system="false" xdb:mutable="false" xdb:SQLName="VCRUID" xdb:SQLType="RAW"
xdb:JavaType="byteArray" xdb:global="false" nillable="false" abstract="false"
xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="1"
maxOccurs="1"/>
<element xdb:propNumber="741" name="Parents" type="hexBinary" xdb:memType="23"
xdb:system="false" xdb:mutable="false" xdb:SQLName="PARENTS" xdb:SQLType="RAW"
xdb:JavaType="Reference" xdb:global="false"
xdb:SQLCollType="XDB$PREDECESSOR_LIST_T" xdb:SQLCollSchema="XDB" nillable="false"
abstract="false" xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="0" minOccurs="0"
maxOccurs="1000"/>
<element xdb:propNumber="745" name="SBResExtra" type="REF" xdb:memType="110"
xdb:system="false" xdb:mutable="true" xdb:SQLName="SBRESEXTRA" xdb:SQLType="REF"
xdb:JavaType="Reference" xdb:global="false"
xdb:SQLCollType="XDB$XMLTYPE_REF_LIST_T" xdb:SQLCollSchema="XDB" xdb:hidden="true"
xdb:baseProp="false" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="false" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="0"
maxOccurs="2147483647"/>
<element xdb:propNumber="746" name="Snapshot" type="hexBinary" xdb:memType="23"
xdb:system="false" xdb:mutable="true" xdb:SQLName="SNAPSHOT" xdb:SQLType="RAW"
xdb:JavaType="byteArray" xdb:global="false" xdb:hidden="true" xdb:baseProp="true"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="747" name="AttrCopy" type="xdb:AttrCopyType"
xdb:memType="258" xdb:system="false" xdb:mutable="true" xdb:SQLName="ATTRCOPY"
xdb:SQLType="BLOB" xdb:JavaType="XMLType" xdb:global="false" xdb:hidden="true"
xdb:baseProp="true" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="false" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:numCols="0" minOccurs="0" maxOccurs="1"/>
<element xdb:propNumber="749" name="CtsCopy" type="hexBinary" xdb:memType="113"
xdb:system="false" xdb:mutable="true" xdb:SQLName="CTSCOPY" xdb:SQLType="BLOB"
xdb:JavaType="String" xdb:global="false" xdb:hidden="true" xdb:baseProp="false"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="false" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="0" maxOccurs="1"/>
<element xdb:propNumber="750" name="NodeNum" type="hexBinary" xdb:memType="23"
xdb:system="false" xdb:mutable="true" xdb:SQLName="NODENUM" xdb:SQLType="RAW"
xdb:JavaType="byteArray" xdb:global="false" xdb:hidden="true" xdb:baseProp="true"
nillable="false" abstract="false" xdb:SQLInline="true" xdb:JavaInline="false"
xdb:MemInline="true" xdb:maintainDOM="false" xdb:defaultTableSchema="XDB"
xdb:numCols="1" minOccurs="1" maxOccurs="1"/>
<element xdb:propNumber="751" name="ContentSize" type="integer"
xdb:memByteLength="8" xdb:memType="3" xdb:system="false" xdb:mutable="false"
xdb:JavaType="long" xdb:global="false" xdb:hidden="true" xdb:transient="generated"
xdb:baseProp="false" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="true" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="0" maxOccurs="1"/>
<element xdb:propNumber="752" name="SizeOnDisk" type="nonNegativeInteger"
xdb:memByteLength="8" xdb:memType="3" xdb:system="false" xdb:mutable="false"
xdb:SQLName="SIZEONDISK" xdb:SQLType="INTEGER" xdb:JavaType="long"
xdb:global="false" xdb:hidden="true" xdb:baseProp="true" nillable="false"
abstract="false" xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="true"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="0"
maxOccurs="1"/>
<element xdb:propNumber="754" name="RCList" type="xdb:RCListType" xdb:memType="258"
xdb:system="false" xdb:mutable="false" xdb:SQLName="RCLIST"
xdb:SQLType="XDB$RCLIST_T" xdb:SQLSchema="XDB" xdb:JavaType="XMLType"
xdb:global="true" xdb:hidden="true" xdb:baseProp="true" nillable="false"
abstract="false" xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTable="00" xdb:defaultTableSchema="XDB"
xdb:JavaClassname="oracle.xdb.RCListBean"
xdb:beanClassname="oracle.xdb.RCListBean" xdb:numCols="1" minOccurs="0"
maxOccurs="1"/>
<element xdb:propNumber="762" name="Branch" type="string" xdb:memType="1"
xdb:system="false" xdb:mutable="false" xdb:SQLName="BRANCH" xdb:SQLType="VARCHAR2"
xdb:JavaType="String" xdb:global="false" xdb:hidden="false"
xdb:transient="generated" xdb:baseProp="false" nillable="false" abstract="false"
xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="0"
maxOccurs="1"/>
<element xdb:propNumber="763" name="CheckedOutBy" type="xdb:OracleUserName"
xdb:memType="1" xdb:system="false" xdb:mutable="false" xdb:JavaType="String"
xdb:global="false" xdb:hidden="false" xdb:transient="generated"
xdb:baseProp="false" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="false" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:numCols="0" minOccurs="0" maxOccurs="1"/>
<element xdb:propNumber="764" name="CheckedOutByID" type="xdb:GUID" xdb:memType="23"
xdb:system="false" xdb:mutable="false" xdb:SQLName="CHECKEDOUTBYID"
xdb:SQLType="RAW" xdb:JavaType="byteArray" xdb:global="false" xdb:hidden="true"
xdb:baseProp="true" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="true" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="0" maxOccurs="1"/>
<element xdb:propNumber="765" name="BaseVersion" type="hexBinary" xdb:memType="23"
xdb:system="false" xdb:mutable="false" xdb:SQLName="BASEVERSION" xdb:SQLType="RAW"
xdb:JavaType="byteArray" xdb:global="false" xdb:hidden="false"
xdb:baseProp="false" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="true" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="0" maxOccurs="1"/>
<element xdb:propNumber="766" name="Locks" type="xdb:locksType" xdb:memType="258"
xdb:system="false" xdb:mutable="true" xdb:JavaType="XMLType" xdb:global="false"
xdb:hidden="true" xdb:transient="generated" nillable="false" abstract="false"
xdb:SQLInline="true" xdb:JavaInline="false" xdb:MemInline="false"
xdb:maintainDOM="false" xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="0"
maxOccurs="1"/>
<any xdb:propNumber="735" name="ResExtra" xdb:memType="258" xdb:system="false"
xdb:mutable="false" xdb:SQLName="RESEXTRA" xdb:SQLType="CLOB"
xdb:JavaType="XMLType" namespace="##other" minOccurs="0" maxOccurs="65535"/>
</sequence>
<attribute xdb:propNumber="705" name="Hidden" type="boolean" xdb:memByteLength="1"
xdb:memType="252" xdb:system="false" xdb:mutable="false" xdb:JavaType="boolean"
default="false" xdb:hidden="false" xdb:transient="generated"
xdb:baseProp="false"/>
<attribute xdb:propNumber="706" name="Invalid" type="boolean" xdb:memByteLength="1"
xdb:memType="252" xdb:system="false" xdb:mutable="false" xdb:JavaType="boolean"
default="false" xdb:hidden="false" xdb:transient="generated"
xdb:baseProp="false"/>
<attribute xdb:propNumber="707" name="VersionID" type="integer" xdb:memByteLength="4"
xdb:memType="3" xdb:system="false" xdb:mutable="false" xdb:SQLName="VERSIONID"
xdb:SQLType="INTEGER" xdb:JavaType="long"/>
<attribute xdb:propNumber="708" name="ActivityID" type="integer" xdb:memByteLength="4"
xdb:memType="3" xdb:system="false" xdb:mutable="false" xdb:SQLName="ACTIVITYID"
xdb:SQLType="INTEGER" xdb:JavaType="long"/>
<attribute xdb:propNumber="738" name="Container" type="boolean" xdb:memByteLength="1"
xdb:memType="252" xdb:system="false" xdb:mutable="false" xdb:JavaType="boolean"
default="false" xdb:hidden="false" xdb:transient="generated"
xdb:baseProp="false"/>
<attribute xdb:propNumber="739" name="CustomRslv" type="boolean" xdb:memByteLength="1"
xdb:memType="252" xdb:system="false" xdb:mutable="false" xdb:JavaType="boolean"
default="false" xdb:hidden="false" xdb:transient="generated"
xdb:baseProp="false"/>
<attribute xdb:propNumber="742" name="VersionHistory" type="boolean"
xdb:memByteLength="1" xdb:memType="252" xdb:system="false" xdb:mutable="false"
xdb:JavaType="boolean" default="false" xdb:hidden="false"
xdb:transient="generated" xdb:baseProp="false"/>
<attribute xdb:propNumber="743" name="StickyRef" type="boolean" xdb:memByteLength="1"
xdb:memType="252" xdb:system="false" xdb:mutable="false" xdb:JavaType="boolean"
default="false" xdb:hidden="false" xdb:transient="generated"
xdb:baseProp="false"/>
<attribute xdb:propNumber="744" name="HierSchmResource" type="boolean"
xdb:memByteLength="1" xdb:memType="252" xdb:system="false" xdb:mutable="false"
xdb:JavaType="boolean" default="false" xdb:hidden="true" xdb:transient="generated"
xdb:baseProp="false"/>
<attribute xdb:propNumber="753" name="SizeAccurate" type="boolean"
xdb:memByteLength="1" xdb:memType="252" xdb:system="false" xdb:mutable="false"
xdb:JavaType="boolean" default="false" xdb:hidden="true" xdb:transient="generated"
xdb:baseProp="false"/>
<attribute xdb:propNumber="756" name="IsVersionable" type="boolean"
xdb:memByteLength="1" xdb:memType="252" xdb:system="false" xdb:mutable="false"
xdb:JavaType="boolean" default="false" xdb:hidden="true" xdb:transient="generated"
xdb:baseProp="false"/>
<attribute xdb:propNumber="757" name="IsCheckedOut" type="boolean"
xdb:memByteLength="1" xdb:memType="252" xdb:system="false" xdb:mutable="false"
xdb:JavaType="boolean" default="false" xdb:hidden="true" xdb:transient="generated"
xdb:baseProp="false"/>
<attribute xdb:propNumber="758" name="IsVersion" type="boolean" xdb:memByteLength="1"
xdb:memType="252" xdb:system="false" xdb:mutable="false" xdb:JavaType="boolean"
default="false" xdb:hidden="true" xdb:transient="generated" xdb:baseProp="false"/>
<attribute xdb:propNumber="759" name="IsVCR" type="boolean" xdb:memByteLength="1"
xdb:memType="252" xdb:system="false" xdb:mutable="false" xdb:JavaType="boolean"
default="false" xdb:hidden="true" xdb:transient="generated" xdb:baseProp="false"/>
<attribute xdb:propNumber="760" name="IsVersionHistory" type="boolean"
xdb:memByteLength="1" xdb:memType="252" xdb:system="false" xdb:mutable="false"
xdb:JavaType="boolean" default="false" xdb:hidden="true" xdb:transient="generated"
xdb:baseProp="false"/>
<attribute xdb:propNumber="761" name="IsWorkspace" type="boolean"
xdb:memByteLength="1" xdb:memType="252" xdb:system="false" xdb:mutable="false"
xdb:JavaType="boolean" default="false" xdb:hidden="true" xdb:transient="generated"
xdb:baseProp="false"/>
<attribute xdb:propNumber="776" name="HasUnresolvedLinks" type="boolean"
xdb:memByteLength="1" xdb:memType="252" xdb:system="false" xdb:mutable="false"
xdb:JavaType="boolean" default="false" xdb:hidden="false"
xdb:transient="generated" xdb:baseProp="false"/>
</complexType>
<element xdb:propNumber="734" name="Resource" type="xdb:ResourceType" xdb:memType="258"
xdb:system="false" xdb:mutable="false" xdb:SQLName="RESOURCE"
xdb:SQLType="XDB$RESOURCE_T" xdb:SQLSchema="XDB" xdb:JavaType="XMLType"
xdb:global="true" nillable="false" abstract="false" xdb:SQLInline="false"
xdb:JavaInline="false" xdb:MemInline="false" xdb:maintainDOM="false"
xdb:defaultTable="XDB$RESOURCE" xdb:defaultTableSchema="XDB"
xdb:JavaClassname="oracle.xdb.ResourceBean"
xdb:beanClassname="oracle.xdb.ResourceBean" xdb:numCols="33" minOccurs="1"
maxOccurs="1"/>
<element xdb:propNumber="775" name="Locks" type="xdb:locksType" xdb:memType="258"
xdb:system="false" xdb:mutable="true" xdb:JavaType="XMLType" xdb:global="false"
xdb:hidden="false" nillable="false" abstract="false" xdb:SQLInline="true"
xdb:JavaInline="false" xdb:MemInline="false" xdb:maintainDOM="false"
xdb:defaultTableSchema="XDB" xdb:numCols="1" minOccurs="0" maxOccurs="1"/>
</schema>

XDBResConfig.xsd: リソース構成のためのXML Schema

この項では、リポジトリ・リソースの構成に使用される、Oracle XML DBで提供するXML Schemaについて説明します。これは、パス/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBResConfig.xsdにあるOracle XML DBリポジトリでアクセス可能です。

XDBResConfig.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
xmlns:rescfg="http://xmlns.oracle.com/xdb/XDBResConfig.xsd"
targetNamespace="http://xmlns.oracle.com/xdb/XDBResConfig.xsd"
elementFormDefault="qualified" version="1.0">
<annotation>
<documentation>
This XML schema declares the schema of an XDB resource configuration,
which includes default ACL, event listeners and user configuration.
It lists all XDB repository events that will be supported.

Future extension can be added to support user-defined events and
XML events.
</documentation>
</annotation>
<simpleType name="language">
<restriction base="string">
<enumeration value="Java"/>
<enumeration value="C"/>
<enumeration value="PL/SQL"/>
</restriction>
</simpleType>
<complexType name="existsNode">
<all>
<element name="XPath" type="string"/>
<element name="namespace" type="string" minOccurs="0"/>
</all>
</complexType>
<!-- listener pre-condition element  -->
<complexType name="condition">
<all>
<element name="existsNode" type="rescfg:existsNode" minOccurs="0"/>
</all>
</complexType>
<complexType name="events">
<all>
<element name="Render" type="string" minOccurs="0"/>
<element name="Pre-Create" type="string" minOccurs="0"/>
<element name="Post-Create" type="string" minOccurs="0"/>
<element name="Pre-Delete" type="string" minOccurs="0"/>
<element name="Post-Delete" type="string" minOccurs="0"/>
<element name="Pre-Update" type="string" minOccurs="0"/>
<element name="Post-Update" type="string" minOccurs="0"/>
<element name="Pre-Lock" type="string" minOccurs="0"/>
<element name="Post-Lock" type="string" minOccurs="0"/>
<element name="Pre-Unlock" type="string" minOccurs="0"/>
<element name="Post-Unlock" type="string" minOccurs="0"/>
<element name="Pre-LinkIn" type="string" minOccurs="0"/>
<element name="Post-LinkIn" type="string" minOccurs="0"/>
<element name="Pre-LinkTo" type="string" minOccurs="0"/>
<element name="Post-LinkTo" type="string" minOccurs="0"/>
<element name="Pre-UnlinkIn" type="string" minOccurs="0"/>
<element name="Post-UnlinkIn" type="string" minOccurs="0"/>
<element name="Pre-UnlinkFrom" type="string" minOccurs="0"/>
<element name="Post-UnlinkFrom" type="string" minOccurs="0"/>
<element name="Pre-CheckIn" type="string" minOccurs="0"/>
<element name="Post-CheckIn" type="string" minOccurs="0"/>
<element name="Pre-CheckOut" type="string" minOccurs="0"/>
<element name="Post-CheckOut" type="string" minOccurs="0"/>
<element name="Pre-UncheckOut" type="string" minOccurs="0"/>
<element name="Post-UncheckOut" type="string" minOccurs="0"/>
<element name="Pre-VersionControl" type="string" minOccurs="0"/>
<element name="Post-VersionControl" type="string" minOccurs="0"/>
<element name="Pre-Open" type="string" minOccurs="0"/>
<element name="Post-Open" type="string" minOccurs="0"/>
<element name="Pre-InconsistentUpdate" type="string" minOccurs="0"/>
<element name="Post-InconsistentUpdate" type="string" minOccurs="0"/>
</all>
</complexType>
<!-- event listener element  -->
<complexType name="event-listener">
<all>
<element name="description" type="string" minOccurs="0"/>
<element name="schema" type="string" minOccurs="0"/>
<element name="source" type="string"/>
<element name="language" type="rescfg:language" minOccurs="0"/>
<element name="pre-condition" type="rescfg:condition" minOccurs="0"/>
<element name="events" type="rescfg:events" minOccurs="0"/>
</all>
</complexType>
<complexType name="event-listeners">
<sequence>
<element name="listener" type="rescfg:event-listener" maxOccurs="unbounded"/>
</sequence>
<attribute name="default-schema" type="string" use="optional"/>
<attribute name="default-language" type="rescfg:language" use="optional"/>
<attribute name="set-invoker" type="boolean" default="false"/>
</complexType>
<complexType name="defaultPath">
<all>
<element name="pre-condition" type="rescfg:condition" minOccurs="0"/>
<element name="path" type="string" minOccurs="0"/>
<element name="resolvedpath" type="string"/>
<element name="oid" type="hexBinary"/>
</all>
</complexType>
<complexType name="defaultACL">
<sequence>
<element name="ACL" type="rescfg:defaultPath" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="defaultConfig">
<sequence>
<element name="configuration" type="rescfg:defaultPath" maxOccurs="unbounded"/>
</sequence>
</complexType>
<simpleType name="link-type">
<restriction base="string">
<enumeration value="None"/>
<enumeration value="Hard"/>
<enumeration value="Weak"/>
<enumeration value="Symbolic"/>
</restriction>
</simpleType>
<simpleType name="path-format">
<restriction base="string">
<enumeration value="OID"/>
<enumeration value="Named"/>
</restriction>
</simpleType>
<simpleType name="link-metadata">
<restriction base="string">
<enumeration value="None"/>
<enumeration value="Attributes"/>
<enumeration value="All"/>
</restriction>
</simpleType>
<simpleType name="unresolved-link">
<restriction base="string">
<enumeration value="Error"/>
<enumeration value="SymLink"/>
<enumeration value="Skip"/>
</restriction>
</simpleType>
<simpleType name="conflict-rule">
<restriction base="string">
<enumeration value="Error"/>
<enumeration value="Overwrite"/>
<enumeration value="Syspath"/>
</restriction>
</simpleType>
<simpleType name="section-type">
<restriction base="string">
<enumeration value="None"/>
<enumeration value="Fragment"/>
<enumeration value="Document"/>
</restriction>
</simpleType>
<!-- XLinkConfig complex type -->
<complexType name="xlink-config">
<sequence>
<element name="LinkType" type="rescfg:link-type"/>
<element name="PathFormat" type="rescfg:path-format" default="OID" minOccurs="0"/>
<element name="LinkMetadata" type="rescfg:link-metadata" default="None" minOccurs="0"/>
<element name="pre-condition" type="rescfg:condition" minOccurs="0"/>
</sequence>
<attribute name="UnresolvedLink" type="rescfg:unresolved-link" default="Error"/>
</complexType>
<!-- XIncludeConfig element -->
<complexType name="xinclude-config">
<sequence>
<element name="LinkType" type="rescfg:link-type"/>
<element name="PathFormat" type="rescfg:path-format" default="OID" minOccurs="0"/>
<element name="ConflictRule" type="rescfg:conflict-rule" default="Error" minOccurs="0"/>
</sequence>
<attribute name="UnresolvedLink" type="rescfg:unresolved-link" default="Error"/>
</complexType>
<!-- SectionConfig element -->
<complexType name="section-config">
<sequence>
<element name="Section" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="sectionPath" type="string"/>
<element name="documentPath" type="string" minOccurs="0"/>
<element name="namespace" type="string" minOccurs="0"/>
</sequence>
<attribute name="type" type="rescfg:section-type" default="None"/>
</complexType>
</element>
</sequence>
</complexType>
<!-- ContentFormat element -->
<simpleType name="content-format">
<restriction base="string">
<enumeration value="text"/>
<enumeration value="binary"/>
</restriction>
</simpleType>
<!-- resource configuration element  -->
<complexType name="ResConfig">
<all>
<element name="defaultChildConfig" type="rescfg:defaultConfig" minOccurs="0"/>
<element name="defaultChildACL" type="rescfg:defaultACL" minOccurs="0"/>
<element name="event-listeners" type="rescfg:event-listeners" minOccurs="0"/>
<element name="XLinkConfig" type="rescfg:xlink-config" minOccurs="0"/>
<element name="XIncludeConfig" type="rescfg:xinclude-config" minOccurs="0"/>
<element name="SectionConfig" type="rescfg:section-config" minOccurs="0"/>
<element name="ContentFormat" type="rescfg:content-format" minOccurs="0"/>
<!-- application data -->
<element name="applicationData" minOccurs="0">
<complexType>
<sequence>
<any namespace="##other" processContents="lax" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
</all>
<attribute name="enable" type="boolean" default="true"/>
<attribute name="copy-on-inconsistent-update" type="boolean" use="optional"/>
</complexType>
<element name="ResConfig" type="rescfg:ResConfig" xdb:defaultTable="XDB$RESCONFIG"/>
</schema>

acl.xsd: ACLのXML Schema

この項では、アクセス制御リスト(ACL)を表すために使用される、Oracle Databaseが提供するXML Schemaについて説明します。

acl.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://xmlns.oracle.com/xdb/acl.xsd" version="1.0"
xmlns:xdb="http://xmlns.oracle.com/xdb"
xmlns:xdbacl="http://xmlns.oracle.com/xdb/acl.xsd"
elementFormDefault="qualified">
<annotation>
<documentation>
This XML schema describes the structure of XDB ACL documents.

Note : The "systemPrivileges" element below lists all supported
system privileges and their aggregations.
See dav.xsd for description of DAV privileges
Note : The elements and attributes marked "hidden" are for
internal use only.
</documentation>
<appinfo>
<xdb:systemPrivileges>
<xdbacl:all>
<xdbacl:read-properties/>
<xdbacl:read-contents/>
<xdbacl:read-acl/>
<xdbacl:update/>
<xdbacl:link/>
<xdbacl:unlink/>
<xdbacl:unlink-from/>
<xdbacl:write-acl-ref/>
<xdbacl:update-acl/>
<xdbacl:link-to/>
<xdbacl:resolve/>
<xdbacl:write-config/>
</xdbacl:all>
</xdb:systemPrivileges>
</appinfo>
</annotation>
<!-- privilegeNameType (this is an emptycontent type) -->
<complexType name = "privilegeNameType"/>
<!-- privilegeName element
All system and user privileges are in the substitutionGroup
of this element.
-->
<element name = "privilegeName" type="xdbacl:privilegeNameType"
xdb:defaultTable=""/>
<!-- all system privileges in the XDB ACL namespace -->
<element name = "read-properties" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
<element name = "read-contents" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
<element name = "read-acl" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
<element name = "update" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
<element name = "link" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
<element name = "unlink" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
<element name = "unlink-from" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
<element name = "write-acl-ref" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
<element name = "update-acl" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
<element name = "link-to" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
<element name = "resolve" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
<element name = "all" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
<!-- privilege element -->
<element name = "privilege" xdb:defaultTable="">
<complexType>
<sequence>
<any maxOccurs="unbounded" processContents="lax"/>
</sequence>
</complexType>
</element>
<!-- ace element -->
<element name = "ace" xdb:defaultTable="">
<complexType>
<sequence>
<element name = "grant" type = "boolean"/>
<choice>
<element name="invert" xdb:transient="generated">
<complexType>
<sequence>
<element name="principal" type="string"
xdb:transient="generated" />
</sequence>
</complexType>
</element>
<element name="principal" type="string" xdb:transient="generated"/>
</choice>
<element ref="xdbacl:privilege" minOccurs="1"/>
<!-- "any" contain all app info for an ACE e.g.reason for creation -->
<any minOccurs="0" maxOccurs="unbounded" namespace="##other"
processContents="lax"/>
<!-- HIDDEN ELEMENTS -->
<choice minOccurs="0">
<element name = "principalID" type = "hexBinary"
xdb:baseProp="true" xdb:hidden="true"/>
<element name = "principalString" type = "string"
xdb:baseProp="true" xdb:hidden="true"/>
</choice>
<element name = "flags" type = "unsignedInt" minOccurs="0"
xdb:baseProp="true" xdb:hidden="true"/>
</sequence>
<attribute name = "collection" type = "boolean"
xdb:transient="generated" use="optional"/>
<attribute name = "principalFormat"
xdb:transient="generated" use="optional">
<simpleType>
<restriction base="string">
<enumeration value="ShortName"/>
<enumeration value="DistinguishedName"/>
<enumeration value="GUID"/>
<enumeration value="XSName"/>
<enumeration value="ApplicationName"/>
</restriction>
</simpleType>
</attribute>
<attribute name = "start_date" type = "dateTime" use = "optional"/>
<attribute name = "end_date" type = "dateTime" use = "optional"/>
</complexType>
</element>
<!-- acl element -->
<complexType name="inheritanceType">
<attribute name="type" type="string" use="required"/>
<attribute name="href" type="string" use="required"/>
</complexType>
<complexType name="aclType">
<sequence>
<element name = "schemaURL" type = "string" minOccurs="0"
xdb:transient="generated"/>
<element name = "elementName" type = "string" minOccurs="0"
xdb:transient="generated"/>
<element name = "security-class" type = "QName" minOccurs="0"/>
<choice minOccurs="0">
<element name="extends-from" type="xdbacl:inheritanceType"/>
<element name="constrained-with" type="xdbacl:inheritanceType"/>
</choice>
<element ref = "xdbacl:ace" minOccurs="0" maxOccurs = "unbounded"/>
<!-- this "any" contains all application specific info for an ACL,
e.g., reason for creation  -->
<any minOccurs="0" maxOccurs="unbounded" namespace="##other"
processContents="lax"/>
<!-- HIDDEN ELEMENTS -->
<element name = "schemaOID" type = "hexBinary" minOccurs="0"
xdb:baseProp="true" xdb:hidden="true"/>
<element name = "elementNum" type = "unsignedInt" minOccurs="0"
xdb:baseProp="true" xdb:hidden="true"/>
</sequence>
<attribute name = "shared" type = "boolean" default="true"/>
<attribute name = "description" type = "string"/>
</complexType>
<complexType name="rule-based-acl">
<complexContent>
<extension base="xdbacl:aclType">
<sequence>
<element name = "param" minOccurs="0" maxOccurs="unbounded">
<complexType>
<simpleContent>
<extension base="string">
<attribute name = "name" type = "string" use = "required"/>
</extension>
</simpleContent>
</complexType>
</element>
</sequence>
</extension>
</complexContent>
</complexType>
<element name = "acl" type="xdbacl:aclType" xdb:defaultTable = "XDB$ACL"/>
<element name = "write-config" type="xdbacl:privilegeNameType"
substitutionGroup="xdbacl:privilegeName" xdb:defaultTable=""/>
</schema>

xdbconfig.xsd: Oracle XML DBを構成するためのXML Schema

ファイルxdbconfig.xsdには、Oracle XML DBを構成するために使用される、Oracle XML DBで提供するXML Schemaが含まれます。

注意:
ここでは、要素patternの属性valueの値は、説明のために分割されています。実際には、この値は分割されない(改行文字なし)、1つの長い文字列です。

xdbconfig.xsd

<schema targetNamespace="http://xmlns.oracle.com/xdb/xdbconfig.xsd"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xdbc="http://xmlns.oracle.com/xdb/xdbconfig.xsd"
xmlns:xdb="http://xmlns.oracle.com/xdb"
version="1.0" elementFormDefault="qualified">
<element name="xdbconfig" xdb:defaultTable="XDB$CONFIG">
<complexType>
<sequence>

<!-- predefined XDB properties - these should NOT be changed -->
<element name="sysconfig">
<complexType>
<sequence>

<!-- generic XDB properties -->
<element name="acl-max-age" type="unsignedInt" default="15"/>
<element name="acl-cache-size" type="unsignedInt" default="32"/>
<element name="invalid-pathname-chars" type="string" default=""/>
<element name="case-sensitive" type="boolean" default="true"/>
<element name="call-timeout"   type="unsignedInt" default="300"/>
<element name="max-link-queue" type="unsignedInt" default="65536"/>
<element name="max-session-use" type="unsignedInt" default="100"/>
<element name="persistent-sessions" type="boolean" default="false"/>
<element name="default-lock-timeout" type="unsignedInt"
default="3600"/>
<element name="xdbcore-logfile-path" type="string"
default="/sys/log/xdblog.xml"/>
<element name="xdbcore-log-level" type="unsignedInt"
default="0"/>
<element name="resource-view-cache-size" type="unsignedInt"
default="1048576"/>
<element name="case-sensitive-index-clause" type="string"
minOccurs="0"/>

<!-- protocol specific properties -->
<element name="protocolconfig">
<complexType>
<sequence>

<!-- these apply to all protocols -->
<element name="common">
<complexType>
<sequence>
<element name="extension-mappings">
<complexType>
<sequence>
<element name="mime-mappings"
type="xdbc:mime-mapping-type"/>
<element name="lang-mappings"
type="xdbc:lang-mapping-type"/>
<element name="charset-mappings"
type="xdbc:charset-mapping-type"/>
<element name="encoding-mappings"
type="xdbc:encoding-mapping-type"/>
<element name="xml-extensions"
type="xdbc:xml-extension-type"
minOccurs="0"/>
</sequence>
</complexType>
</element>
<element name="session-pool-size" type="unsignedInt"
default="50"/>
<element name="session-timeout" type="unsignedInt"
default="6000"/>
</sequence>
</complexType>
</element>

<!-- FTP specific -->
<element name="ftpconfig">
<complexType>
<sequence>
<element name="ftp-port" type="unsignedShort"
default="2100"/>
<element name="ftp-listener" type="string"/>
<element name="ftp-protocol" type="string"/>
<element name="logfile-path" type="string"
default="/sys/log/ftplog.xml"/>
<element name="log-level" type="unsignedInt"
default="0"/>
<element name="session-timeout"  type="unsignedInt"
default="6000"/>
<element name="buffer-size" default="8192">
<simpleType>
<restriction base="unsignedInt">
<minInclusive value="1024"/>       <!-- 1KB -->
<maxInclusive value="1048496"/>    <!-- 1MB -->
</restriction>
</simpleType>
</element>
<element name="ftp-welcome-message" type="string"
minOccurs="0" maxOccurs="1"/>
</sequence>
</complexType>
</element>

<!-- HTTP specific -->
<element name="httpconfig">
<complexType>
<sequence>
<element name="http-port" type="unsignedShort"
default="8080"/>
<element name="http-listener" type="string"/>
<element name="http-protocol" type="string"/>
<element name="max-http-headers" type="unsignedInt"
default="64"/>
<element name="max-header-size" type="unsignedInt"
default="4096"/>
<element name="max-request-body" type="unsignedInt"
default="2000000000" minOccurs="1"/>
<element name="session-timeout"  type="unsignedInt"
default="6000"/>
<element name="server-name" type="string"/>
<element name="logfile-path" type="string"
default="/sys/log/httplog.xml"/>
<element name="log-level" type="unsignedInt"
default="0"/>
<element name="servlet-realm" type="string"
minOccurs="0"/>
<element name="webappconfig">
<complexType>
<sequence>
<element name="welcome-file-list"
type="xdbc:welcome-file-type"/>
<element name="error-pages"
type="xdbc:error-page-type"/>
<element name="servletconfig"
type="xdbc:servlet-config-type"/>
</sequence>
</complexType>
</element>
<element name="default-url-charset" type="string"
minOccurs="0"/>
<element name="http2-port" type="unsignedShort"
minOccurs="0"/>
<element name="http2-protocol" type="string"
default="tcp" minOccurs="0"/>
<element name="plsql" minOccurs="0">
<complexType>
<sequence>
<element name="log-level"
type="unsignedInt" minOccurs="0"/>
<element name="max-parameters"
type="unsignedInt" minOccurs="0"/>
</sequence>
</complexType>
</element>
<element name="allow-repository-anonymous-access"
minOccurs="0" default="false" type="boolean"/>
<element name="authentication" minOccurs="0"
maxOccurs="1">
<complexType>
<sequence>
<element name="allow-mechanism" minOccurs="1"
maxOccurs="unbounded">
<simpleType>
<restriction base="string">
<enumeration value="digest"/>
<enumeration value="basic" />
<enumeration value="custom"/>
</restriction>
</simpleType>
</element>
<element name="digest-auth" minOccurs="0"
maxOccurs="1">
<complexType>
<sequence>
<element name="nonce-timeout"
type="unsignedInt"
minOccurs="1" maxOccurs="1"
default="300"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
<element name="http-host" type="string" minOccurs="0"/>
<element name="http2-host" type="string" minOccurs="0"/>
<element name="custom-authentication"
type="xdbc:custom-authentication-type"
minOccurs="0"/>
<element name="realm" type="string" minOccurs="0"/>
<element name="respond-with-server-info" type="boolean"
default="true" minOccurs="0"/>
<element name="expire" type="xdbc:expire-type"
minOccurs="0"/>
</sequence>
</complexType>
</element>
<element name="nfsconfig" minOccurs="0">
<complexType>
<sequence>
<element name="nfs-port" type="unsignedShort"
default="2049"/>
<element name="nfs-listener" type="string"/>
<element name="nfs-protocol" type="string"/>
<element name="logfile-path" type="string"
default="/sys/log/nfslog.xml"/>
<element name="log-level" type="unsignedInt"
default="0"/>
<element name="nfs-exports"
type="xdbc:nfs-exports-type"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
<element name="schemaLocation-mappings"
type="xdbc:schemaLocation-mapping-type" minOccurs="0"/>
<element name="xdbcore-xobmem-bound" type="unsignedInt"
default="1024" minOccurs="0"/>
<element name="xdbcore-loadableunit-size" type="unsignedInt"
default="16" minOccurs="0"/>
<element name="folder-hard-links" type="boolean" default="false"
minOccurs="0"/>
<element name="non-folder-hard-links" type="boolean" default="true"
minOccurs="0"/>
<element name="copy-on-inconsistent-update" type="boolean"
default="false" minOccurs="0"/>
<element name="rollback-on-sync-error" type="boolean"
default="false" minOccurs="0"/>
<element name="acl-evaluation-method" default="deny-trumps-grant"
minOccurs="0">
<simpleType>
<restriction base="string">
<enumeration value="deny-trumps-grant"/>
<enumeration value="ace-order"/>
</restriction>
</simpleType>
</element>
<element name="default-workspace" type="string" minOccurs="0"/>
<element name="num_job_queue_processes" type="unsignedInt"
minOccurs="0"/>
<element name="allow-authentication-trust" type="boolean"
default="false" minOccurs="0"/>
<element name="custom-authentication-trust"
type="xdbc:custom-authentication-trust-type"
minOccurs="0"/>
<element name="default-type-mappings" minOccurs="0">
<simpleType>
<restriction base="string">
<enumeration value="pre-11.2"/>
<enumeration value="post-11.2"/>
</restriction>
</simpleType>
</element>
<element name="localApplicationGroupStore" type="boolean"
default="true" minOccurs="0"/>
</sequence>
</complexType>
</element>

<!-- users can add any properties they want here -->
<element name="userconfig" minOccurs="0">
<complexType>
<sequence>
<any maxOccurs="unbounded" namespace="##other"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
<complexType name="welcome-file-type">
<sequence>
<element name="welcome-file" minOccurs="0" maxOccurs="unbounded">
<simpleType>
<restriction base="string">
<pattern value="[^/]*"/>
</restriction>
</simpleType>
</element>
</sequence>
</complexType>

<!-- customized error pages -->
<complexType name="error-page-type">
<sequence>
<element name="error-page" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<choice>
<element name="error-code">
<simpleType>
<restriction base="positiveInteger">
<minInclusive value="100"/>
<maxInclusive value="999"/>
</restriction>
</simpleType>
</element>

<!-- Fully qualified classname of a Java exception type -->
<element name="exception-type" type="string"/>
<element name="OracleError">
<complexType>
<sequence>
<element name="facility" type="string" default="ORA"/>
<element name="errnum" type="unsignedInt"/>
</sequence>
</complexType>
</element>
</choice>
<element name="location" type="anyURI"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>

<!-- parameter for a servlet: name, value pair and a description  -->
<complexType name="param">
<sequence>
<element name="param-name" type="string"/>
<element name="param-value" type="string"/>
<element name="description" type="string"/>
</sequence>
</complexType>
<complexType name="servlet-config-type">
<sequence>
<element name="servlet-mappings">
<complexType>
<sequence>
<element name="servlet-mapping" minOccurs="0"
maxOccurs="unbounded">
<complexType>
<sequence>
<element name="servlet-pattern" type="string"/>
<element name="servlet-name" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
<element name="servlet-list">
<complexType>
<sequence>
<element name="servlet" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="servlet-name" type="string"/>
<element name="servlet-language">
<simpleType>
<restriction base="string">
<enumeration value="C"/>
<enumeration value="Java"/>
<enumeration value="PL/SQL"/>
</restriction>
</simpleType>
</element>
<element name="icon" type="string" minOccurs="0"/>
<element name="display-name" type="string"/>
<element name="description" type="string" minOccurs="0"/>
<choice>
<element name="servlet-class" type="string" minOccurs="0"/>
<element name="jsp-file" type="string" minOccurs="0"/>
<element name="plsql" type="xdbc:plsql-servlet-config"
minOccurs="0"/>
</choice>
<element name="servlet-schema" type="string" minOccurs="0"/>
<element name="init-param" minOccurs="0"
maxOccurs="unbounded" type="xdbc:param"/>
<element name="load-on-startup" type="string" minOccurs="0"/>
<element name="security-role-ref" minOccurs="0"
maxOccurs="unbounded">
<complexType>
<sequence>
<element name="description" type="string" minOccurs="0"/>
<element name="role-name" type="string"/>
<element name="role-link" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<complexType name="lang-mapping-type">
<sequence>
<element name="lang-mapping" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="extension" type="xdbc:exttype"/>
<element name="lang" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<complexType name="charset-mapping-type">
<sequence>
<element name="charset-mapping" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="extension" type="xdbc:exttype"/>
<element name="charset" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<complexType name="encoding-mapping-type">
<sequence>
<element name="encoding-mapping" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="extension" type="xdbc:exttype"/>
<element name="encoding" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<complexType name="mime-mapping-type">
<sequence>
<element name="mime-mapping" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="extension" type="xdbc:exttype"/>
<element name="mime-type" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<complexType name="xml-extension-type">
<sequence>
<element name="extension" type="xdbc:exttype"
minOccurs="0" maxOccurs="unbounded">
</element>
</sequence>
</complexType>
<complexType name="schemaLocation-mapping-type">
<sequence>
<element name="schemaLocation-mapping"
minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="namespace" type="string"/>
<element name="element" type="string"/>
<element name="schemaURL" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<complexType name="plsql-servlet-config">
<sequence>
<element name="database-username" type="string" minOccurs="0"/>
<element name="authentication-mode" minOccurs="0">
<simpleType>
<restriction base="string">
<enumeration value="Basic"/>
<enumeration value="SingleSignOn"/>
<enumeration value="GlobalOwa"/>
<enumeration value="CustomOwa"/>
<enumeration value="PerPackageOwa"/>
</restriction>
</simpleType>
</element>
<element name="session-cookie-name" type="string" minOccurs="0"/>
<element name="session-state-management" minOccurs="0">
<simpleType>
<restriction base="string">
<enumeration value="StatelessWithResetPackageState"/>
<enumeration value="StatelessWithFastResetPackageState"/>
<enumeration value="StatelessWithPreservePackageState"/>
</restriction>
</simpleType>
</element>
<element name="max-requests-per-session" type="unsignedInt" minOccurs="0"/>
<element name="default-page" type="string" minOccurs="0"/>
<element name="document-table-name" type="string" minOccurs="0"/>
<element name="document-path" type="string" minOccurs="0"/>
<element name="document-procedure" type="string" minOccurs="0"/>
<element name="upload-as-long-raw" type="string" minOccurs="0"
maxOccurs="unbounded"/>
<element name="path-alias" type="string" minOccurs="0"/>
<element name="path-alias-procedure" type="string" minOccurs="0"/>
<element name="exclusion-list" type="string" minOccurs="0"
maxOccurs="unbounded"/>
<element name="cgi-environment-list" type="string" minOccurs="0"
maxOccurs="unbounded"/>
<element name="compatibility-mode" type="unsignedInt" minOccurs="0"/>
<element name="nls-language" type="string" minOccurs="0"/>
<element name="fetch-buffer-size" type="unsignedInt" minOccurs="0"/>
<element name="error-style" minOccurs="0">
<simpleType>
<restriction base="string">
<enumeration value="ApacheStyle"/>
<enumeration value="ModplsqlStyle"/>
<enumeration value="DebugStyle"/>
</restriction>
</simpleType>
</element>
<element name="transfer-mode" minOccurs="0">
<simpleType>
<restriction base="string">
<enumeration value="Char"/>
<enumeration value="Raw"/>
</restriction>
</simpleType>
</element>
<element name="before-procedure" type="string" minOccurs="0"/>
<element name="after-procedure" type="string" minOccurs="0"/>
<element name="bind-bucket-lengths" type="unsignedInt" minOccurs="0"
maxOccurs="unbounded"/>
<element name="bind-bucket-widths" type="unsignedInt" minOccurs="0"
maxOccurs="unbounded"/>
<element name="always-describe-procedure" minOccurs="0">
<simpleType>
<restriction base="string">
<enumeration value="On"/>
<enumeration value="Off"/>
</restriction>
</simpleType>
</element>
<element name="info-logging" minOccurs="0">
<simpleType>
<restriction base="string">
<enumeration value="InfoDebug"/>
</restriction>
</simpleType>
</element>
<element name="owa-debug-enable" minOccurs="0">
<simpleType>
<restriction base="string">
<enumeration value="On"/>
<enumeration value="Off"/>
</restriction>
</simpleType>
</element>
<element name="request-validation-function" type="string" minOccurs="0"/>
<element name="input-filter-enable" minOccurs="0">
<simpleType>
<restriction base="string">
<enumeration value="On"/>
<enumeration value="Off"/>
</restriction>
</simpleType>
</element>
<element name="database-edition" type="string" minOccurs="0"/>
</sequence>
</complexType>
<simpleType name="exttype">
<restriction base="string">
<pattern value="[^\*\./]*"/>
</restriction>
</simpleType>
<simpleType name="ipaddress">
<restriction base="string">
<maxLength value="40" />
</restriction>
</simpleType>
<complexType name="nfs-exports-type">
<sequence>
<element name="nfs-export" minOccurs="1" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="nfs-clientgroup">
<complexType>
<sequence>
<element name="nfs-client" minOccurs="1" maxOccurs="unbounded">
<complexType>
<sequence>
<choice>
<element name="nfs-client-subnet"
type="xdbc:ipaddress"/>
<element name="nfs-client-dnsname" type="string"/>
<element name="nfs-client-address"
type="xdbc:ipaddress"/>
</choice>
<element name="nfs-client-netmask"
type="xdbc:ipaddress"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
<element name="nfs-export-paths">
<complexType>
<sequence>
<element name="nfs-export-path" minOccurs="1"
maxOccurs="unbounded">
<complexType>
<sequence>
<element name="path" type="string"/>
<element name="mode">
<simpleType>
<restriction base="string">
<enumeration value="read-write"/>
<enumeration value="read-only"/>
</restriction>
</simpleType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<complexType name="custom-authentication-type">
<sequence>
<element name="custom-authentication-mappings">
<complexType>
<sequence>
<element name="custom-authentication-mapping" minOccurs="0"
maxOccurs="unbounded">
<complexType>
<sequence>
<element name="authentication-pattern" type="string"/>
<element name="authentication-name" type="string"/>
<element name="authentication-trust-name" type="string"
minOccurs="0"/>
<element name="user-prefix" type="string" minOccurs="0"/>
<element name="on-deny" minOccurs="0">
<simpleType><restriction base="string">
<enumeration value="next-custom"/>
<enumeration value="basic"/>
</restriction></simpleType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
<element name="custom-authentication-list">
<complexType>
<sequence>
<element name="authentication" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="authentication-name" type="string"/>
<element name="authentication-description" type="string"
minOccurs="0"/>
<element name="authentication-implement-schema" type="string"/>
<element name="authentication-implement-method" type="string"/>
<element name="authentication-implement-language">
<simpleType>
<restriction base="string">
<enumeration value="PL/SQL"/>
</restriction>
</simpleType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
<element name="custom-authentication-trust"
type="xdbc:custom-authentication-trust-type" minOccurs="0"/>
</sequence>
</complexType>
<complexType name="custom-authentication-trust-type">
<sequence>
<element name="trust-scheme"  minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="trust-scheme-name" type="string"/>
<element name="requireParsingSchema" type="boolean" default="true"
minOccurs="0"/>
<element name="allowRegistration" type="boolean" default="true"
minOccurs="0"/>
<element name="trust-scheme-description" type="string" minOccurs="0"/>
<element name="trusted-session-user" type="string"  minOccurs="1"
maxOccurs="unbounded"/>
<element name="trusted-parsing-schema" type="string" minOccurs="0"
maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<complexType name="expire-type">
<sequence>
<element name="expire-mapping" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="expire-pattern" type="string"/>
<element name="expire-default">
<simpleType>
<restriction base="string">
<pattern value=
"(now|modification)(\s(plus))?(\s(([1]\s(year))|
([0-9]*\s(years))))?(\s(([1]\s(month))|([0-9]*\s(months))))?(\s(([1]\s(week))|
([0-9]*\s(weeks))))?(\s(([1]\s(day))|([0-9]*\s(days))))?(\s(([1]\s(hour))|
([0-9]*\s(hours))))?(\s(([1]\s(minute))|
([0-9]*\s(minutes))))?(\s(([1]\s(second))|([0-9]*\s(seconds))))?"/>Foot 1
</restriction>
</simpleType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</schema>

xdiff.xsd: スキーマをインプレース拡張と比較するためのXML Schema

xdiff.xsdは、Oracle XML DBが提供するXML Schemaで、プロシージャDBMS_XMLSCHEMA.inPlaceEvolveに対するdiffXMLパラメータとして指定されたドキュメントは、このスキーマに準拠している必要があります。

xdiff.xsd

<schema targetNamespace="http://xmlns.oracle.com/xdb/xdiff.xsd"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://xmlns.oracle.com/xdb/xdiff.xsd"
version="1.0" elementFormDefault="qualified"
attributeFormDefault="qualified">
<annotation>
<documentation xml:lang="en">
Defines the structure of XML documents that capture the difference
between two XML documents. Changes that are not supported by Oracle
XmlDiff may not be expressible in this schema.

'oracle-xmldiff' PI:

We use 'oracle-xmldiff' PI to describe certain aspects of the diff.
This should be the first element of top level xdiff element.

operations-in-docorder:
Can be either 'true' or 'false'.
If true, the operations in the diff document refer to the
elements of the input doc in the same order as document order. Output of
global algorithm meets this requirement while local does not.

output-model: output models for representing the diff. Can be either
'Snapshot' or 'Current'.

Snapshot model:
Each operation uses Xpaths as if no operations
have been applied to the input document. (like UNIX diff)
Default and works for both Xmldiff and XmlPatch.
For XmlPatch to handle this model, "operations-in-docorder" must be
true and the Xpaths must be simple. (see XmlDif C API documentation).

Current model :
Each operation uses Xpaths as if all operations till the previous one
have been applied to the input document. Not implemented for Xmldiff.
Works with XmlPatch.

<!-- Example:
<?oracle-xmldiff operations-in-docorder="true" output-model=
"snapshot" diff-algorithm="global"?>
-->
</documentation>
</annotation>
<!-- Enumerate the supported node types -->
<simpleType name="xdiff-nodetype">
<restriction base="string">
<enumeration value="element"/>
<enumeration value="attribute"/>
<enumeration value="text"/>
<enumeration value="cdata"/>
<enumeration value="entity-reference"/>
<enumeration value="entity"/>
<enumeration value="processing-instruction"/>
<enumeration value="notation"/>
<enumeration value="comment"/>
</restriction>
</simpleType>

<element name="xdiff">
<complexType>
<choice minOccurs="0" maxOccurs="unbounded">
<element name="append-node">
<complexType>
<sequence>
<element name="content" type="anyType"/>
</sequence>
<attribute name="node-type" type="xd:xdiff-nodetype"/>
<attribute name="xpath" type="string"/>
<attribute name="parent-xpath" type="string"/>
<attribute name="attr-local" type="string"/>
<attribute name="attr-uri" type="string"/>
</complexType>
</element>

<element name="insert-node-before">
<complexType>
<sequence>
<element name="content" type="anyType"/>
</sequence>
<attribute name="xpath" type="string"/>
<attribute name="node-type" type="xd:xdiff-nodetype"/>

</complexType>
</element>

<element name="delete-node">
<complexType>
<attribute name="node-type" type="xd:xdiff-nodetype"/>
<attribute name="xpath" type="string"/>
<attribute name="parent-xpath" type="string"/>
<attribute name="attr-local" type="string"/>
<attribute name="attr-uri" type="string"/>
</complexType>
</element>
<element name="update-node">
<complexType>
<sequence>
<element name="content" type="anyType"/>
</sequence>
<attribute name="node-type" type="xd:xdiff-nodetype"/>
<attribute name="parent-xpath" type="string"/>
<attribute name="xpath" type="string"/>
<attribute name="attr-local" type="string"/>
<attribute name="attr-uri" type="string"/>
</complexType>
</element>
<element name="rename-node">
<complexType>
<sequence>
<element name="content" type="anyType"/>
</sequence>
<attribute name="xpath" type="string"/>
<attribute name="node-type" type="xd:xdiff-nodetype"/>
</complexType>
</element>
</choice>
<attribute name="xdiff-version" type="string"/>
</complexType>
</element>
</schema>

発注書XML Schema

この項では、特に第3章の様々な例で使用されている注釈付き発注書XML Schemaの完全なリストを示します。例A-2は、例A-1を変更したものです。この変更版は第10章のXML Schema拡張処理で使用されています。

例A-1は、例3-10に示されている注釈付き発注書XML Schemaの完全なリストです。

例A-1 注釈付き発注書XML SchemaのpurchaseOrder.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
version="1.0"
xdb:storeVarrayAsTable="true">
<xs:element name="PurchaseOrder" type="PurchaseOrderType" xdb:defaultTable="PURCHASEORDER"/>
<xs:complexType name="PurchaseOrderType" xdb:SQLType="PURCHASEORDER_T">
<xs:sequence>
<xs:element name="Reference" type="ReferenceType" minOccurs="1" xdb:SQLName="REFERENCE"/>
<xs:element name="Actions" type="ActionsType" xdb:SQLName="ACTIONS"/>
<xs:element name="Reject" type="RejectionType" minOccurs="0" xdb:SQLName="REJECTION"/>
<xs:element name="Requestor" type="RequestorType" xdb:SQLName="REQUESTOR"/>
<xs:element name="User" type="UserType" minOccurs="1" xdb:SQLName="USERID"/>
<xs:element name="CostCenter" type="CostCenterType" xdb:SQLName="COST_CENTER"/>
<xs:element name="ShippingInstructions" type="ShippingInstructionsType"
xdb:SQLName="SHIPPING_INSTRUCTIONS"/>
<xs:element name="SpecialInstructions" type="SpecialInstructionsType"
xdb:SQLName="SPECIAL_INSTRUCTIONS"/>
<xs:element name="LineItems" type="LineItemsType" xdb:SQLName="LINEITEMS"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemsType" xdb:SQLType="LINEITEMS_T">
<xs:sequence>
<xs:element name="LineItem" type="LineItemType" maxOccurs="unbounded"
xdb:SQLName="LINEITEM" xdb:SQLCollType="LINEITEM_V"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemType" xdb:SQLType="LINEITEM_T">
<xs:sequence>
<xs:element name="Description" type="DescriptionType"
xdb:SQLName="DESCRIPTION"/>
<xs:element name="Part" type="PartType" xdb:SQLName="PART"/>
</xs:sequence>
<xs:attribute name="ItemNumber" type="xs:integer" xdb:SQLName="ITEMNUMBER"
xdb:SQLType="NUMBER"/>
</xs:complexType>
<xs:complexType name="PartType" xdb:SQLType="PART_T">
<xs:attribute name="Id" xdb:SQLName="PART_NUMBER" xdb:SQLType="VARCHAR2">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="10"/>
<xs:maxLength value="14"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Quantity" type="moneyType" xdb:SQLName="QUANTITY"/>
<xs:attribute name="UnitPrice" type="quantityType" xdb:SQLName="UNITPRICE"/>
</xs:complexType>
<xs:simpleType name="ReferenceType">
<xs:restriction base="xs:string">
<xs:minLength value="18"/>
<xs:maxLength value="30"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="ActionsType" xdb:SQLType="ACTIONS_T">
<xs:sequence>
<xs:element name="Action" maxOccurs="4" xdb:SQLName="ACTION" xdb:SQLCollType="ACTION_V">
<xs:complexType xdb:SQLType="actioN_t">
<xs:sequence>
<xs:element name="User" type="UserType" xdb:SQLName="ACTIONED_BY"/>
<xs:element name="Date" type="DateType" minOccurs="0" xdb:SQLName="DATE_ACTIONED"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RejectionType" xdb:SQLType="REJECTION_T">
<xs:all>
<xs:element name="User" type="UserType" minOccurs="0" xdb:SQLName="REJECTED_BY"/>
<xs:element name="Date" type="DateType" minOccurs="0" xdb:SQLName="DATE_REJECTED"/>
<xs:element name="Comments" type="CommentsType" minOccurs="0" xdb:SQLName="REASON_REJECTED"/>
</xs:all>
</xs:complexType>
<xs:complexType name="ShippingInstructionsType" xdb:SQLType="SHIPPING_INSTRUCTIONS_T">
<xs:sequence>
<xs:element name="name" type="NameType" minOccurs="0" xdb:SQLName="SHIP_TO_NAME"/>
<xs:element name="address" type="AddressType" minOccurs="0" xdb:SQLName="SHIP_TO_ADDRESS"/>
<xs:element name="telephone" type="TelephoneType" minOccurs="0" xdb:SQLName="SHIP_TO_PHONE"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="moneyType">
<xs:restriction base="xs:decimal">
<xs:fractionDigits value="2"/>
<xs:totalDigits value="12"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="quantityType">
<xs:restriction base="xs:decimal">
<xs:fractionDigits value="4"/>
<xs:totalDigits value="8"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="RequestorType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="128"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CostCenterType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="4"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="VendorType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PurchaseOrderNumberType">
<xs:restriction base="xs:integer"/>
</xs:simpleType>
<xs:simpleType name="SpecialInstructionsType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="2048"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NameType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AddressType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TelephoneType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="24"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="DateType">
<xs:restriction base="xs:date"/>
</xs:simpleType>
<xs:simpleType name="CommentsType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="2048"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="DescriptionType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

例A-2は、例10-1に示されている、修正された注釈付き発注書XML Schemaの完全なリストです。太字は、例A-1のスキーマ内のものに追加されたものか、あるいは大幅に異なるものを示しています。

例A-2 修正された発注書XML Schema

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"
version="1.0">
<xs:element
name="PurchaseOrder" type="PurchaseOrderType"
xdb:defaultTable="PURCHASEORDER"
xdb:columnProps=
"CONSTRAINT purchaseorder_pkey PRIMARY KEY (XMLDATA.reference),
CONSTRAINT valid_email_address FOREIGN KEY (XMLDATA.userid)
REFERENCES hr.employees (EMAIL)"
xdb:tableProps=
"VARRAY XMLDATA.ACTIONS.ACTION STORE AS TABLE ACTION_TABLE
((CONSTRAINT action_pkey PRIMARY KEY (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
VARRAY XMLDATA.LINEITEMS.LINEITEM STORE AS TABLE LINEITEM_TABLE
((constraint LINEITEM_PKEY primary key (NESTED_TABLE_ID, SYS_NC_ARRAY_INDEX$)))
lob (XMLDATA.NOTES) STORE AS (ENABLE STORAGE IN ROW STORAGE(INITIAL 4K NEXT 32K))"/>
<xs:complexType name="PurchaseOrderType" xdb:SQLType="PURCHASEORDER_T">
<xs:sequence>
<xs:element name="Actions" type="ActionsType" xdb:SQLName="ACTIONS"/>
<xs:element name="Reject" type="RejectionType" minOccurs="0" xdb:SQLName="REJECTION"/>
<xs:element name="Requestor" type="RequestorType" xdb:SQLName="REQUESTOR"/>
<xs:element name="User" type="UserType" xdb:SQLName="USERID"/>
<xs:element name="CostCenter" type="CostCenterType" xdb:SQLName="COST_CENTER"/>
<xs:element name="BillingAddress" type="AddressType" minOccurs="0"
xdb:SQLName="BILLING_ADDRESS"/>
<xs:element name="ShippingInstructions" type="ShippingInstructionsType"
xdb:SQLName="SHIPPING_INSTRUCTIONS"/>
<xs:element name="SpecialInstructions" type="SpecialInstructionsType"
xdb:SQLName="SPECIAL_INSTRUCTIONS"/>
<xs:element name="LineItems" type="LineItemsType" xdb:SQLName="LINEITEMS"/>
<xs:element name="Notes" type="NotesType" minOccurs="0" xdb:SQLType="CLOB"
xdb:SQLName="NOTES"/>
</xs:sequence>
<xs:attribute name="Reference" type="ReferenceType" use="required" xdb:SQLName="REFERENCE"/>
<xs:attribute name="DateCreated" type="xs:dateTime" use="required"
xdb:SQLType="TIMESTAMP WITH TIME ZONE"/>
</xs:complexType>
<xs:complexType name="LineItemsType" xdb:SQLType="LINEITEMS_T">
<xs:sequence>
<xs:element name="LineItem" type="LineItemType" maxOccurs="unbounded" xdb:SQLName="LINEITEM"
xdb:SQLCollType="LINEITEM_V"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="LineItemType" xdb:SQLType="LINEITEM_T">
<xs:sequence>
<xs:element name="Part" type="PartType" xdb:SQLName="PART"/>
<xs:element name="Quantity" type="quantityType"/>
</xs:sequence>
<xs:attribute name="ItemNumber" type="xs:integer" xdb:SQLName="ITEMNUMBER"
xdb:SQLType="NUMBER"/>
</xs:complexType>
<xs:complexType name="PartType" xdb:SQLType="PART_T">
<xs:simpleContent>
<xs:extension base="UPCCodeType">
<xs:attribute name="Description" type="DescriptionType" use="required"
xdb:SQLName="DESCRIPTION"/>
<xs:attribute name="UnitCost" type="moneyType" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="ReferenceType">
<xs:restriction base="xs:string">
<xs:minLength value="18"/>
<xs:maxLength value="30"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="ActionsType" xdb:SQLType="ACTIONS_T">
<xs:sequence>
<xs:element name="Action" maxOccurs="4" xdb:SQLName="ACTION" xdb:SQLCollType="ACTION_V">
<xs:complexType xdb:SQLType="ACTION_T">
<xs:sequence>
<xs:element name="User" type="UserType" xdb:SQLName="ACTIONED_BY"/>
<xs:element name="Date" type="DateType" minOccurs="0" xdb:SQLName="DATE_ACTIONED"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RejectionType" xdb:SQLType="REJECTION_T">
<xs:all>
<xs:element name="User" type="UserType" minOccurs="0" xdb:SQLName="REJECTED_BY"/>
<xs:element name="Date" type="DateType" minOccurs="0" xdb:SQLName="DATE_REJECTED"/>
<xs:element name="Comments" type="CommentsType" minOccurs="0" xdb:SQLName="REASON_REJECTED"/>
</xs:all>
</xs:complexType>
<xs:complexType name="ShippingInstructionsType" xdb:SQLType="SHIPPING_INSTRUCTIONS_T">
<xs:sequence>
<xs:element name="name" type="NameType" minOccurs="0" xdb:SQLName="SHIP_TO_NAME"/>
<xs:choice>
<xs:element name="address" type="AddressType" minOccurs="0"/>
<xs:element name="fullAddress" type="FullAddressType" minOccurs="0"
xdb:SQLName="SHIP_TO_ADDRESS"/>
</xs:choice>
<xs:element name="telephone" type="TelephoneType" minOccurs="0" xdb:SQLName="SHIP_TO_PHONE"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="moneyType">
<xs:restriction base="xs:decimal">
<xs:fractionDigits value="2"/>
<xs:totalDigits value="12"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="quantityType">
<xs:restriction base="xs:decimal">
<xs:fractionDigits value="4"/>
<xs:totalDigits value="8"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UserType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="RequestorType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="128"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CostCenterType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="4"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="VendorType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PurchaseOrderNumberType">
<xs:restriction base="xs:integer"/>
</xs:simpleType>
<xs:simpleType name="SpecialInstructionsType">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="2048"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NameType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="FullAddressType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TelephoneType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="24"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="DateType">
<xs:restriction base="xs:date"/>
</xs:simpleType>
<xs:simpleType name="CommentsType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="2048"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="DescriptionType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="256"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="AddressType" xdb:SQLType="ADDRESS_T">
<xs:sequence>
<xs:element name="StreetLine1" type="StreetType"/>
<xs:element name="StreetLine2" type="StreetType" minOccurs="0"/>
<xs:element name="City" type="CityType"/>
<xs:choice>
<xs:sequence>
<xs:element name="State" type="StateType"/>
<xs:element name="ZipCode" type="ZipCodeType"/>
</xs:sequence>
<xs:sequence>
<xs:element name="Province" type="ProvinceType"/>
<xs:element name="PostCode" type="PostCodeType"/>
</xs:sequence>
<xs:sequence>
<xs:element name="County" type="CountyType"/>
<xs:element name="Postcode" type="PostCodeType"/>
</xs:sequence>
</xs:choice>
<xs:element name="Country" type="CountryType"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="StreetType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="128"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CityType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="64"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="StateType">
<xs:restriction base="xs:string">
<xs:minLength value="2"/>
<xs:maxLength value="2"/>
<xs:enumeration value="AK"/>
<xs:enumeration value="AL"/>
<xs:enumeration value="AR"/>
<xs:enumeration value="AS"/>
<xs:enumeration value="AZ"/>
<xs:enumeration value="CA"/>
<xs:enumeration value="CO"/>
<xs:enumeration value="CT"/>
<xs:enumeration value="DC"/>
<xs:enumeration value="DE"/>
<xs:enumeration value="FL"/>
<xs:enumeration value="FM"/>
<xs:enumeration value="GA"/>
<xs:enumeration value="GU"/>
<xs:enumeration value="HI"/>
<xs:enumeration value="IA"/>
<xs:enumeration value="ID"/>
<xs:enumeration value="IL"/>
<xs:enumeration value="IN"/>
<xs:enumeration value="KS"/>
<xs:enumeration value="KY"/>
<xs:enumeration value="LA"/>
<xs:enumeration value="MA"/>
<xs:enumeration value="MD"/>
<xs:enumeration value="ME"/>
<xs:enumeration value="MH"/>
<xs:enumeration value="MI"/>
<xs:enumeration value="MN"/>
<xs:enumeration value="MO"/>
<xs:enumeration value="MP"/>
<xs:enumeration value="MQ"/>
<xs:enumeration value="MS"/>
<xs:enumeration value="MT"/>
<xs:enumeration value="NC"/>
<xs:enumeration value="ND"/>
<xs:enumeration value="NE"/>
<xs:enumeration value="NH"/>
<xs:enumeration value="NJ"/>
<xs:enumeration value="NM"/>
<xs:enumeration value="NV"/>
<xs:enumeration value="NY"/>
<xs:enumeration value="OH"/>
<xs:enumeration value="OK"/>
<xs:enumeration value="OR"/>
<xs:enumeration value="PA"/>
<xs:enumeration value="PR"/>
<xs:enumeration value="PW"/>
<xs:enumeration value="RI"/>
<xs:enumeration value="SC"/>
<xs:enumeration value="SD"/>
<xs:enumeration value="TN"/>
<xs:enumeration value="TX"/>
<xs:enumeration value="UM"/>
<xs:enumeration value="UT"/>
<xs:enumeration value="VA"/>
<xs:enumeration value="VI"/>
<xs:enumeration value="VT"/>
<xs:enumeration value="WA"/>
<xs:enumeration value="WI"/>
<xs:enumeration value="WV"/>
<xs:enumeration value="WY"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ZipCodeType">
<xs:restriction base="xs:string">
<xs:pattern value="\d{5}"/>
<xs:pattern value="\d{5}-\d{4}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CountryType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="64"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CountyType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="32"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PostCodeType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="12"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ProvinceType">
<xs:restriction base="xs:string">
<xs:minLength value="2"/>
<xs:maxLength value="2"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NotesType">
<xs:restriction base="xs:string">
<xs:maxLength value="32767"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="UPCCodeType">
<xs:restriction base="xs:string">
<xs:minLength value="11"/>
<xs:maxLength value="14"/>
<xs:pattern value="\d{11}"/>
<xs:pattern value="\d{12}"/>
<xs:pattern value="\d{13}"/>
<xs:pattern value="\d{14}"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

XSLスタイルシートの例: PurchaseOrder.xsl

例A-3は、XSLTスタイルシートPurchaseOrder.xslを示しています。このスタイルシートの例は、第3章「Oracle XML DBの使用」の例で使用されています。

例A-3 PurchaseOrder.xslスタイルシート

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xdb="http://xmlns.oracle.com/xdb"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:template match="/">
<html>
<head/>
<body bgcolor="#003333" text="#FFFFCC" link="#FFCC00"
vlink="#66CC99" alink="#669999">
<FONT FACE="Arial, Helvetica, sans-serif">
<xsl:for-each select="PurchaseOrder"/>
<xsl:for-each select="PurchaseOrder">
<center>
<span style="font-family:Arial; font-weight:bold">
<FONT COLOR="#FF0000">
<B>Purchase Order </B>
</FONT>
</span>
</center>
<br/>
<center>
<xsl:for-each select="Reference">
<span style="font-family:Arial; font-weight:bold">
<xsl:apply-templates/>
</span>
</xsl:for-each>
</center>
</xsl:for-each>
<P>
<xsl:for-each select="PurchaseOrder">
<br/>
</xsl:for-each>
<P/>
<P>
<xsl:for-each select="PurchaseOrder">
<br/>
</xsl:for-each>
</P>
</P>
<xsl:for-each select="PurchaseOrder"/>
<xsl:for-each select="PurchaseOrder">
<table border="0" width="100%" BGCOLOR="#000000">
<tbody>
<tr>
<td WIDTH="296">
<P>
<B>
<FONT SIZE="+1" COLOR="#FF0000"
FACE="Arial, Helvetica, sans-serif">Internal
</FONT>
</B>
</P>
<table border="0" width="98%" BGCOLOR="#000099">
<tbody>
<tr>
<td WIDTH="49%">
<B>
<FONT COLOR="#FFFF00">Actions</FONT>
</B>
</td>
<td WIDTH="51%">
<xsl:for-each select="Actions">
<xsl:for-each select="Action">
<table border="1" WIDTH="143">
<xsl:if test="position()=1">
<thead>
<tr>
<td HEIGHT="21">
<FONT
COLOR="#FFFF00">User</FONT>
</td>
<td HEIGHT="21">
<FONT
COLOR="#FFFF00">Date</FONT>
</td>
</tr>
</thead>
</xsl:if>
<tbody>
<tr>
<td>
<xsl:for-each select="User">
<xsl:apply-templates/>
</xsl:for-each>
</td>
<td>
<xsl:for-each select="Date">
<xsl:apply-templates/>
</xsl:for-each>
</td>
</tr>
</tbody>
</table>
</xsl:for-each>
</xsl:for-each>
</td>
</tr>
<tr>
<td WIDTH="49%">
<B>
<FONT COLOR="#FFFF00">Requestor</FONT>
</B>
</td>
<td WIDTH="51%">
<xsl:for-each select="Requestor">
<xsl:apply-templates/>
</xsl:for-each>
</td>
</tr>
<tr>
<td WIDTH="49%">
<B>
<FONT COLOR="#FFFF00">User</FONT>
</B>
</td>
<td WIDTH="51%">
<xsl:for-each select="User">
<xsl:apply-templates/>
</xsl:for-each>
</td>
</tr>
<tr>
<td WIDTH="49%">
<B>
<FONT COLOR="#FFFF00">Cost Center</FONT>
</B>
</td>
<td WIDTH="51%">
<xsl:for-each select="CostCenter">
<xsl:apply-templates/>
</xsl:for-each>
</td>
</tr>
</tbody>
</table>
</td>
<td width="93"/>
<td valign="top" WIDTH="340">
<B>
<FONT COLOR="#FF0000">
<FONT SIZE="+1">Ship To</FONT>
</FONT>
</B>
<xsl:for-each select="ShippingInstructions">
<xsl:if test="position()=1"/>
</xsl:for-each>
<xsl:for-each select="ShippingInstructions">
<xsl:if test="position()=1">
<table border="0" BGCOLOR="#999900">
<tbody>
<tr>
<td WIDTH="126" HEIGHT="24">
<B>Name</B>
</td>
<xsl:for-each
select="../ShippingInstructions">
<td WIDTH="218" HEIGHT="24">
<xsl:for-each select="name">
<xsl:apply-templates/>
</xsl:for-each>
</td>
</xsl:for-each>
</tr>
<tr>
<td WIDTH="126" HEIGHT="34">
<B>Address</B>
</td>
<xsl:for-each
select="../ShippingInstructions">
<td WIDTH="218" HEIGHT="34">
<xsl:for-each select="address">
<span style="white-space:pre">
<xsl:apply-templates/>
</span>
</xsl:for-each>
</td>
</xsl:for-each>
</tr>
<tr>
<td WIDTH="126" HEIGHT="32">
<B>Telephone</B>
</td>
<xsl:for-each
select="../ShippingInstructions">
<td WIDTH="218" HEIGHT="32">
<xsl:for-each select="telephone">
<xsl:apply-templates/>
</xsl:for-each>
</td>
</xsl:for-each>
</tr>
</tbody>
</table>
</xsl:if>
</xsl:for-each>
</td>
</tr>
</tbody>
</table>
<br/>
<B>
<FONT COLOR="#FF0000" SIZE="+1">Items:</FONT>
</B>
<br/>
<br/>
<table border="0">
<xsl:for-each select="LineItems">
<xsl:for-each select="LineItem">
<xsl:if test="position()=1">
<thead>
<tr bgcolor="#C0C0C0">
<td>
<FONT COLOR="#FF0000">
<B>ItemNumber</B>
</FONT>
</td>
<td>
<FONT COLOR="#FF0000">
<B>Description</B>
</FONT>
</td>
<td>
<FONT COLOR="#FF0000">
<B>PartId</B>
</FONT>
</td>
<td>
<FONT COLOR="#FF0000">
<B>Quantity</B>
</FONT>
</td>
<td>
<FONT COLOR="#FF0000">
<B>Unit Price</B>
</FONT>
</td>
<td>
<FONT COLOR="#FF0000">
<B>Total Price</B>
</FONT>
</td>
</tr>
</thead>
</xsl:if>
<tbody>
<tr bgcolor="#DADADA">
<td>
<FONT COLOR="#000000">
<xsl:for-each select="@ItemNumber">
<xsl:value-of select="."/>
</xsl:for-each>
</FONT>
</td>
<td>
<FONT COLOR="#000000">
<xsl:for-each select="Description">
<xsl:apply-templates/>
</xsl:for-each>
</FONT>
</td>
<td>
<FONT COLOR="#000000">
<xsl:for-each select="Part">
<xsl:for-each select="@Id">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:for-each>
</FONT>
</td>
<td>
<FONT COLOR="#000000">
<xsl:for-each select="Part">
<xsl:for-each select="@Quantity">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:for-each>
</FONT>
</td>
<td>
<FONT COLOR="#000000">
<xsl:for-each select="Part">
<xsl:for-each select="@UnitPrice">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:for-each>
</FONT>
</td>
<td>
<FONT FACE="Arial, Helvetica, sans-serif"
COLOR="#000000">
<xsl:for-each select="Part">
<xsl:value-of select="@Quantity*@UnitPrice"/>
</xsl:for-each>
</FONT>
</td>
</tr>
</tbody>
</xsl:for-each>
</xsl:for-each>
</table>
</xsl:for-each>
</FONT>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

C(OCI)を使用したXMLデータのロード

例A-4は、XMLデータをXMLType表に挿入するCプログラムです。一部は第3章「Oracle XML DBの使用」の「Cを使用したXMLコンテンツのロード」に示されています。

例A-4 Cを使用したXMLType表へのXMLデータの挿入

#include "stdio.h"
#include <xml.h>
#include <stdlib.h>
#include <string.h>
#include <ocixmldb.h>
OCIEnv *envhp;
OCIError *errhp;
OCISvcCtx *svchp;
OCIStmt *stmthp;
OCIServer *srvhp;
OCIDuration dur;
OCISession *sesshp;
oratext *username = "QUINE";
oratext *password = "************";      /* Replace with real password */
oratext *filename = "AMCEWEN-20021009123336171PDT.xml";
oratext *schemaloc = "http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd";

/* Execute a SQL statement that binds XML data */
sword exec_bind_xml(OCISvcCtx *svchp, OCIError *errhp, OCIStmt *stmthp,
void *xml,        OCIType *xmltdo, OraText *sqlstmt)
{
OCIBind *bndhp1 = (OCIBind *) 0;
sword  status = 0;
OCIInd ind = OCI_IND_NOTNULL;
OCIInd *indp = &ind;
if(status = OCIStmtPrepare(stmthp, errhp, (OraText *)sqlstmt,
(ub4)strlen((const char *)sqlstmt),
(ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT))
return OCI_ERROR;
if(status = OCIBindByPos(stmthp, &bndhp1, errhp, (ub4) 1, (dvoid *) 0,
(sb4) 0, SQLT_NTY, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, (ub4) 0, (ub4 *) 0, (ub4) OCI_DEFAULT))
return OCI_ERROR;
if(status = OCIBindObject(bndhp1, errhp, (CONST OCIType *) xmltdo,
(dvoid **) &xml, (ub4 *) 0,
(dvoid **) &indp, (ub4 *) 0))
return OCI_ERROR;
if(status = OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0,
(CONST OCISnapshot*) 0, (OCISnapshot*) 0,
(ub4) OCI_DEFAULT))
return OCI_ERROR;
return OCI_SUCCESS;
}

/* Initialize OCI handles, and connect  */
sword init_oci_connect()
{
sword status;
if (OCIEnvCreate((OCIEnv **) &(envhp), (ub4) OCI_OBJECT,
(dvoid *) 0, (dvoid * (*)(dvoid *,size_t)) 0,
(dvoid * (*)(dvoid *, dvoid *, size_t)) 0,
(void (*)(dvoid *, dvoid *)) 0, (size_t) 0, (dvoid **) 0))
{
printf("FAILED: OCIEnvCreate()\n");
return OCI_ERROR;
}
/* Allocate error handle */
if (OCIHandleAlloc((dvoid *) envhp, (dvoid **) &(errhp),
(ub4) OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0))
{
printf("FAILED: OCIHandleAlloc() on errhp\n");
return OCI_ERROR;
}
/* Allocate server handle */
if (status = OCIHandleAlloc((dvoid *) envhp, (dvoid **) &srvhp,
(ub4) OCI_HTYPE_SERVER, (size_t) 0, (dvoid **) 0))
{
printf("FAILED: OCIHandleAlloc() on srvhp\n");
return OCI_ERROR;
}
/* Allocate service context handle */
if (status = OCIHandleAlloc((dvoid *) envhp,
(dvoid **) &(svchp), (ub4) OCI_HTYPE_SVCCTX,
(size_t) 0, (dvoid **) 0))
{
printf("FAILED: OCIHandleAlloc() on svchp\n");
return OCI_ERROR;
}
/* Allocate session handle */
if (status = OCIHandleAlloc((dvoid *) envhp, (dvoid **) &sesshp ,
(ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0))
{
printf("FAILED: OCIHandleAlloc() on sesshp\n");
return OCI_ERROR;
}
/* Allocate statement handle */
if (OCIHandleAlloc((dvoid *)envhp, (dvoid **) &stmthp,
(ub4)OCI_HTYPE_STMT, (CONST size_t) 0, (dvoid **) 0))
{
printf("FAILED: OCIHandleAlloc() on stmthp\n");
return status;
}
if (status = OCIServerAttach((OCIServer *) srvhp, (OCIError *) errhp,
(CONST oratext *)"", 0, (ub4) OCI_DEFAULT))
{
printf("FAILED: OCIServerAttach() on srvhp\n");
return OCI_ERROR;
}
/* Set server attribute to service context */
if (status = OCIAttrSet((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX,
(dvoid *) srvhp, (ub4) 0, (ub4) OCI_ATTR_SERVER,
(OCIError *) errhp))
{
printf("FAILED: OCIAttrSet() on svchp\n");
return OCI_ERROR;
}
/* Set user attribute to session */
if (status = OCIAttrSet((dvoid *)sesshp, (ub4) OCI_HTYPE_SESSION,
(dvoid *)username,
(ub4) strlen((const char *)username),
(ub4) OCI_ATTR_USERNAME, (OCIError *) errhp))
{
printf("FAILED: OCIAttrSet() on authp for user\n");
return OCI_ERROR;
}
/* Set password attribute to session */
if (status = OCIAttrSet((dvoid *) sesshp, (ub4) OCI_HTYPE_SESSION,
(dvoid *)password,
(ub4) strlen((const char *)password),
(ub4) OCI_ATTR_PASSWORD, (OCIError *) errhp))
{
printf("FAILED: OCIAttrSet() on authp for password\n");
return OCI_ERROR;
}
/* Begin a session  */
if (status = OCISessionBegin((OCISvcCtx *) svchp,
(OCIError *) errhp,
(OCISession *) sesshp, (ub4) OCI_CRED_RDBMS,
(ub4) OCI_STMT_CACHE))
{
printf("FAILED: OCISessionBegin(). Make sure database is up and the username/password is valid. \n");
return OCI_ERROR;
}
/* Set session attribute to service context */
if (status = OCIAttrSet((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX,
(dvoid *)sesshp, (ub4) 0, (ub4) OCI_ATTR_SESSION,
(OCIError *) errhp))
{
printf("FAILED: OCIAttrSet() on svchp\n");
return OCI_ERROR;
}
}

/* Free OCI handles, and disconnect                       */
void free_oci()
{
sword  status = 0;

/* End the session */
if (status = OCISessionEnd((OCISvcCtx *)svchp, (OCIError *)errhp,
(OCISession *)sesshp, (ub4) OCI_DEFAULT))
{
if (envhp)
OCIHandleFree((dvoid *)envhp, OCI_HTYPE_ENV);
return;
}
/* Detach from the server */
if (status = OCIServerDetach((OCIServer *)srvhp, (OCIError *)errhp,
(ub4)OCI_DEFAULT))
{
if (envhp)
OCIHandleFree((dvoid *)envhp, OCI_HTYPE_ENV);
return;
}
/* Free the handles */
if (stmthp) OCIHandleFree((dvoid *)stmthp, (ub4) OCI_HTYPE_STMT);
if (sesshp) OCIHandleFree((dvoid *)sesshp, (ub4) OCI_HTYPE_SESSION);
if (svchp) OCIHandleFree((dvoid *)svchp, (ub4) OCI_HTYPE_SVCCTX);
if (srvhp) OCIHandleFree((dvoid *)srvhp, (ub4) OCI_HTYPE_SERVER);
if (errhp) OCIHandleFree((dvoid *)errhp, (ub4) OCI_HTYPE_ERROR);
if (envhp) OCIHandleFree((dvoid *)envhp, (ub4) OCI_HTYPE_ENV);
return;
}

void main()
{
OCIType *xmltdo;
xmldocnode  *doc;
ocixmldbparam params[1];
xmlerr       err;
xmlctx  *xctx;
oratext *ins_stmt;
sword    status;
xmlnode *root;
oratext buf[10000];

/* Initialize envhp, svchp, errhp, dur, stmthp */
init_oci_connect();

/* Get an XML context */
params[0].name_ocixmldbparam = XCTXINIT_OCIDUR;
params[0].value_ocixmldbparam = &dur;
xctx = OCIXmlDbInitXmlCtx(envhp, svchp, errhp, params, 1);
if (!(doc = XmlLoadDom(xctx, &err, "file", filename,
"schema_location", schemaloc, NULL)))
{
printf("Parse failed.\n");
return;
}
else
printf("Parse succeeded.\n");
root = XmlDomGetDocElem(xctx, doc);
printf("The xml document is :\n");
XmlSaveDom(xctx, &err, (xmlnode *)doc, "buffer", buf, "buffer_length", 10000, NULL);
printf("%s\n", buf);

/* Insert the document into my_table */
ins_stmt = (oratext *)"insert into purchaseorder values (:1)";
status = OCITypeByName(envhp, errhp, svchp, (const text *) "SYS",
(ub4) strlen((const char *)"SYS"), (const text *) "XMLTYPE",
(ub4) strlen((const char *)"XMLTYPE"), (CONST text *) 0,
(ub4) 0, OCI_DURATION_SESSION, OCI_TYPEGET_HEADER,
(OCIType **) &xmltdo);
if (status == OCI_SUCCESS)
{
status = exec_bind_xml(svchp, errhp, stmthp, (void *)doc,
xmltdo, ins_stmt);
}
if (status == OCI_SUCCESS)
printf ("Insert successful\n");
else
printf ("Insert failed\n");

/* Free XML instances */
if (doc) XmlFreeDocument((xmlctx *)xctx, (xmldocnode *)doc);

/* Free XML CTX */
OCIXmlDbFreeXmlCtx(xctx);
free_oci();
}

XMLコンテキスト(OCI)の初期化および終了

例A-5では、OCI関数のOCIXmlDbInitXmlCtx()およびOCIXmlDbFreeXmlCtx()を使用して、XMLコンテキストを初期化および終了する方法を示します。C DOM APIを使用してXML文書を構成し、データベース内に保存します。

例A-5の一部は第16章「C API for XMLの使用」の「XMLコンテキストの初期化および終了」に示されています。これはデータベース・スキーマCAPIUSERでmy_table表を作成するため、次のSQLコードを最初に実行したことを前提としています。

CONNECT CAPIUSER
Enter password: <password>

Connected.

CREATE TABLE my_table OF XMLType;

例A-5 OCIXmlDbInitXmlCtx()およびOCIXmlDbFreeXmlCtx()の使用

#ifndef S_ORACLE
#include <s.h>
#endif
#ifndef ORATYPES_ORACLE
#include <oratypes.h>
#endif
#ifndef XML_ORACLE
#include <xml.h>
#endif
#ifndef OCIXML_ORACLE
#include <ocixml.h>
#endif
#ifndef OCI_ORACLE
#include <oci.h>
#endif
#include <string.h>

typedef struct test_ctx {
OCIEnv *envhp;
OCIError *errhp;
OCISvcCtx *svchp;
OCIStmt *stmthp;
OCIServer *srvhp;
OCIDuration dur;
OCISession *sesshp;
oratext *username;
oratext *password;
} test_ctx;

/* Helper function 1: execute a sql statement which binds xml data */
STATICF sword exec_bind_xml(OCISvcCtx *svchp,
OCIError *errhp,
OCIStmt *stmthp,
void *xml,
OCIType *xmltdo,
OraText *sqlstmt);

/* Helper function 2: Initialize OCI handles and connect */
STATICF sword init_oci_handles(test_ctx *ctx);

/* Helper function 3: Free OCI handles and disconnect */
STATICF sword free_oci_handles(test_ctx *ctx);

void main()
{
test_ctx temp_ctx;
test_ctx *ctx = &temp_ctx;
OCIType *xmltdo = (OCIType *) 0;
xmldocnode *doc = (xmldocnode *)0;
ocixmldbparam params[1];
xmlnode *quux, *foo, *foo_data, *top;
xmlerr err;
sword status = 0;
xmlctx *xctx;

oratext ins_stmt[] = "insert into my_table values (:1)";
oratext tlpxml_test_sch[] = "<TOP/>";
ctx->username = (oratext *)"CAPIUSER";
ctx->password = (oratext *)"************";   /* Replace with real password */

/* Initialize envhp, svchp, errhp, dur, stmthp */
init_oci_handles(ctx);

/* Get an xml context */
params[0].name_ocixmldbparam = XCTXINIT_OCIDUR;
params[0].value_ocixmldbparam = &ctx->dur;
xctx = OCIXmlDbInitXmlCtx(ctx->envhp, ctx->svchp, ctx->errhp, params, 1);

/* Start processing - first, check that this DOM supports XML 1.0 */
printf("\n\nSupports XML 1.0? : %s\n",
XmlHasFeature(xctx, (oratext *) "xml", (oratext *) "1.0") ?
"YES" : "NO");

/* Parse a document */
if (!(doc = XmlLoadDom(xctx, &err, "buffer", tlpxml_test_sch,
"buffer_length", sizeof(tlpxml_test_sch)-1,
"validate", TRUE, NULL)))
{
printf("Parse failed, code %d\n", err);
}
else
{
/* Get the document element */
top = (xmlnode *)XmlDomGetDocElem(xctx, doc);

/* Print out the top element */
printf("\n\nOriginal top element is :\n");
XmlSaveDom(xctx, &err, top, "stdio", stdout, NULL);

/* Print out the document-note that the changes are reflected here */
printf("\n\nOriginal document is :\n");
XmlSaveDom(xctx, &err, (xmlnode *)doc, "stdio", stdout, NULL);

/* Create some elements and add them to the document */
quux = (xmlnode *) XmlDomCreateElem(xctx ,doc, (oratext *) "QUUX");
foo = (xmlnode *) XmlDomCreateElem(xctx, doc, (oratext *) "FOO");
foo_data = (xmlnode *) XmlDomCreateText(xctx, doc, (oratext *) "data");
foo_data = XmlDomAppendChild(xctx, (xmlnode *) foo, (xmlnode *) foo_data);
foo = XmlDomAppendChild(xctx, quux, foo);
quux = XmlDomAppendChild(xctx, top, quux);

/* Print out the top element */
printf("\n\nNow the top element is :\n");
XmlSaveDom(xctx, &err, top, "stdio", stdout, NULL);

/* Print out the document. Note that the changes are reflected here */
printf("\n\nNow the document is :\n");
XmlSaveDom(xctx, &err, (xmlnode *)doc, "stdio", stdout, NULL);

/* Insert the document into my_table */
status = OCITypeByName(ctx->envhp, ctx->errhp, ctx->svchp,
(const text *) "SYS", (ub4) strlen((char *)"SYS"),
(const text *) "XMLTYPE",
(ub4) strlen((char *)"XMLTYPE"), (CONST text *) 0,
(ub4) 0, OCI_DURATION_SESSION, OCI_TYPEGET_HEADER,
(OCIType **) &xmltdo);
if (status == OCI_SUCCESS)
{
exec_bind_xml(ctx->svchp, ctx->errhp, ctx->stmthp, (void *)doc, xmltdo,
ins_stmt);
}
}
/* Free xml ctx */
OCIXmlDbFreeXmlCtx(xctx);

/* Free envhp, svchp, errhp, stmthp */
free_oci_handles(ctx);
}

/* Helper function 1: execute a SQL statement that binds xml data */
STATICF sword exec_bind_xml(OCISvcCtx *svchp,
OCIError *errhp,
OCIStmt *stmthp,
void *xml,
OCIType *xmltdo,
OraText *sqlstmt)
{
OCIBind *bndhp1 = (OCIBind *) 0;
sword status = 0;
OCIInd ind = OCI_IND_NOTNULL;
OCIInd *indp = &ind;
if(status = OCIStmtPrepare(stmthp, errhp, (OraText *)sqlstmt,
(ub4)strlen((char *)sqlstmt),
(ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) {
printf("Failed OCIStmtPrepare\n");
return OCI_ERROR;
}
if(status = OCIBindByPos(stmthp, &bndhp1, errhp, (ub4) 1, (dvoid *) 0,
(sb4) 0, SQLT_NTY, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, (ub4) 0, (ub4 *) 0, (ub4) OCI_DEFAULT)) {
printf("Failed OCIBindByPos\n");
return OCI_ERROR;
}
if(status = OCIBindObject(bndhp1, errhp, (CONST OCIType *) xmltdo, (dvoid **)
&xml,
(ub4 *) 0, (dvoid **) &indp, (ub4 *) 0)) {
printf("Failed OCIBindObject\n");
return OCI_ERROR;
}
if(status = OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0,
(CONST OCISnapshot*) 0, (OCISnapshot*) 0,
(ub4) OCI_DEFAULT)) {
printf("Failed OCIStmtExecute\n");
return OCI_ERROR;
}
return OCI_SUCCESS;
}

/* Helper function 2: Initialize OCI handles and connect */
STATICF sword init_oci_handles(test_ctx *ctx)
{
sword status;
ctx->dur = OCI_DURATION_SESSION;
if (OCIEnvCreate((OCIEnv **) &(ctx->envhp), (ub4) OCI_OBJECT,
(dvoid *) 0, (dvoid * (*)(dvoid *,size_t)) 0,
(dvoid * (*)(dvoid *, dvoid *, size_t)) 0,
(void (*)(dvoid *, dvoid *)) 0, (size_t) 0, (dvoid **) 0))
{
printf("FAILED: OCIEnvCreate()\n");
return OCI_ERROR;
}
/* Allocate error handle */
if (OCIHandleAlloc((dvoid *) ctx->envhp, (dvoid **) &(ctx->errhp),
(ub4) OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0))
{
printf("FAILED: OCIHandleAlloc() on errhp\n");
return OCI_ERROR;
}
/* Allocate server handle */
if (status = OCIHandleAlloc((dvoid *) ctx->envhp, (dvoid **) &ctx->srvhp,
(ub4) OCI_HTYPE_SERVER, (size_t) 0, (dvoid **) 0))
{
printf("FAILED: OCIHandleAlloc() on srvhp\n");
return OCI_ERROR;
}
/* Allocate service context handle */
if (status = OCIHandleAlloc((dvoid *) ctx->envhp,
(dvoid **) &(ctx->svchp), (ub4) OCI_HTYPE_SVCCTX,
(size_t) 0, (dvoid **) 0))
{
printf("FAILED: OCIHandleAlloc() on svchp\n");
return OCI_ERROR;
}
/* Allocate session handle */
if (status = OCIHandleAlloc((dvoid *) ctx->envhp, (dvoid **) &ctx->sesshp ,
(ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0))
{
printf("FAILED: OCIHandleAlloc() on sesshp\n");
return OCI_ERROR;
}
/* Allocate statement handle */
if (OCIHandleAlloc((dvoid *)ctx->envhp, (dvoid **) &ctx->stmthp,
(ub4)OCI_HTYPE_STMT, (CONST size_t) 0, (dvoid **) 0))
{
printf("FAILED: OCIHandleAlloc() on stmthp\n");
return status;
}
if (status = OCIServerAttach((OCIServer *) ctx->srvhp, (OCIError *) ctx->errhp,
(CONST oratext *)"", 0, (ub4) OCI_DEFAULT))
{
printf("FAILED: OCIServerAttach() on srvhp\n");
return OCI_ERROR;
}
/* Set server attribute to service context */
if (status = OCIAttrSet((dvoid *) ctx->svchp, (ub4) OCI_HTYPE_SVCCTX,
(dvoid *) ctx->srvhp, (ub4) 0, (ub4) OCI_ATTR_SERVER,
(OCIError *) ctx->errhp))
{
printf("FAILED: OCIAttrSet() on svchp\n");
return OCI_ERROR;
}
/* Set user attribute to session */
if (status = OCIAttrSet((dvoid *)ctx->sesshp, (ub4) OCI_HTYPE_SESSION,
(dvoid *)ctx->username,
(ub4) strlen((char *)ctx->username),
(ub4) OCI_ATTR_USERNAME, (OCIError *) ctx->errhp))
{
printf("FAILED: OCIAttrSet() on authp for user\n");
return OCI_ERROR;
}
/* Set password attribute to session */
if (status = OCIAttrSet((dvoid *) ctx->sesshp, (ub4) OCI_HTYPE_SESSION,
(dvoid *)ctx->password,
(ub4) strlen((char *)ctx->password),
(ub4) OCI_ATTR_PASSWORD, (OCIError *) ctx->errhp))
{
printf("FAILED: OCIAttrSet() on authp for password\n");
return OCI_ERROR;
}
/* Begin a session  */
if (status = OCISessionBegin((OCISvcCtx *) ctx->svchp,
(OCIError *) ctx->errhp,
(OCISession *) ctx->sesshp, (ub4) OCI_CRED_RDBMS,
(ub4) OCI_STMT_CACHE))
{
printf("FAILED: OCISessionBegin(). Make sure database is up and the \
username/password is valid. \n");
return OCI_ERROR;
}
/* Set session attribute to service context */
if (status = OCIAttrSet((dvoid *) ctx->svchp, (ub4) OCI_HTYPE_SVCCTX,
(dvoid *)ctx->sesshp, (ub4) 0, (ub4) OCI_ATTR_SESSION,
(OCIError *) ctx->errhp))
{
printf("FAILED: OCIAttrSet() on svchp\n");
return OCI_ERROR;
}
return status;
}

/* Helper function 3: Free OCI handles and disconnect */
STATICF sword free_oci_handles(test_ctx *ctx)
{
sword  status = 0;
/* End the session */
if (status = OCISessionEnd((OCISvcCtx *)ctx->svchp, (OCIError *)ctx->errhp,
(OCISession *)ctx->sesshp, (ub4) OCI_DEFAULT))
{
if (ctx->envhp)
OCIHandleFree((dvoid *)ctx->envhp, OCI_HTYPE_ENV);
return status;
}
/* Detach from the server */
if (status = OCIServerDetach((OCIServer *)ctx->srvhp, (OCIError *)ctx->errhp,
(ub4)OCI_DEFAULT))
{
if (ctx->envhp)
OCIHandleFree((dvoid *)ctx->envhp, OCI_HTYPE_ENV);
return status;
}
/* Free the handles */
if (ctx->stmthp) OCIHandleFree((dvoid *)ctx->stmthp, (ub4) OCI_HTYPE_STMT);
if (ctx->sesshp) OCIHandleFree((dvoid *)ctx->sesshp, (ub4) OCI_HTYPE_SESSION);
if (ctx->svchp)  OCIHandleFree((dvoid *)ctx->svchp,  (ub4) OCI_HTYPE_SVCCTX);
if (ctx->srvhp)  OCIHandleFree((dvoid *)ctx->srvhp,  (ub4) OCI_HTYPE_SERVER);
if (ctx->errhp)  OCIHandleFree((dvoid *)ctx->errhp,  (ub4) OCI_HTYPE_ERROR);
if (ctx->envhp)  OCIHandleFree((dvoid *)ctx->envhp,  (ub4) OCI_HTYPE_ENV);
return status;
}

脚注の凡例

脚注 1: ここでは、属性valueの値は、説明のために分割されています。実際には、この値は改行されない1つの長い文字列です。

B Oracle XML DBの制限

この付録では、Oracle XML DBに関する制限事項について説明します。

- 一部のXMLType関数でのThin JDBCドライバの未サポート – XMLTypeメソッドの、ストリーム引数を持つcreateXML()、extract()、transform()およびexistsNode()は、OCIドライバでのみ機能します。Thin JDBCドライバでは、すべてのoracle.xdb.XMLType関数がサポートされているわけではありません。oracle.xdb.XMLTypeクラスとOCIドライバを使用しない場合、パフォーマンスのメリットを失う可能性があります。

- NCHAR、NVARCHARおよびNCLOBの未サポート: Oracle XML DBは、次の操作のためにSQLデータ型NCHAR、NVARCHARおよびNCLOBを使用することをサポートしていません。

- XML ShemaでSQLType注釈を使用して、XML要素または属性をこれらのデータ型にマップ

- SQL/XML関数XMLElement、XMLAttributesおよびXMLForestを使用して、これらのデータ型からXMLデータを生成

- SQL/XML関数XMLQueryおよびXMLTable内で、これらのデータ型を持つ列を含む表に対してXQuery関数ora:view(非推奨)、fn:doc、およびfn:collectionを使用

マルチバイト文字を含むXMLデータを処理、格納または生成する場合、データベース・キャラクタ・セットとしてAL32UTF8を使用することを強くお薦めします。

- XML識別子の長さ制限: Oracle XML DBでは、4000文字以下のXML識別子のみをサポートしています。

- リポジトリ・ファイルのサイズ制限: Oracle XML DBリポジトリの最大ファイルサイズは4GBです。このため、様々な種類のファイル・データに次のような制限があります。

- 任意のLOBが4GBということは、データベース・キャラクタ・セットAL32UTF8に格納されるCLOBは2GBということです。

- エンコードされたバイナリXMLデータが4GBということは、一般に、エンコードされる前の外部XMLデータは4GBを超えているということです。

- オブジェクト・リレーショナル形式で格納されたXMLデータについては、不確定です。

- リポジトリ全体のリソース構成ファイルの制限: リポジトリ全体の構成では、125を超えるリソース構成ファイルを作成することはできません。

- 再帰的フォルダの削除: 再帰的削除のオプションを使用して、50レベルを超えるネストされたフォルダを削除することはできません。

- ハイブリッド列圧縮の非サポート: Oracle Exadata Storage Server Softwarでのみ利用可能なハイブリッド列圧縮は、オブジェクト・リレーショナル形式で格納されているXMLType列、またはXMLType表とともには使用できません(使用されている記憶域モデルは問いません)。XMLTypeは、基本圧縮およびOLTPの圧縮のみをサポートしています。

- XMLTypeの列レベル暗号化の非サポート – XMLTypeの列レベルの暗号化はサポートされていません。表領域レベルの暗号化は、すべてのXMLType表領域モデルでサポートされています。

- XMLTypeでのパラレルDMLの未サポート: XMLTypeデータのDML操作は常にシリアルで実行されます。XMLTypeではパラレルDMLはサポートされません(XMLTypeでサポートされるのは、パラレル問合せとDDLです)。

- XMLTypeへのデータベース・リンクを介したアクセスの非サポート: リモートのXMLType表または列へのアクセスはサポートされていません。

- 一部の機能の利用にOracle JVMが必要: 通常、Oracle XML DBの動作はOracle JVM(Java仮想マシン)がインストールされているかどうかに依存しません。ただし、JavaサーブレットまたはPL/SQLパッケージDBMS_XMLSAVEまたはDBMS_XMLQUERYを使用する場合は、Oracle JVMをインストールする必要があります。

- エディショニング・ビューとXMLTypeの非互換性: エディショング・ビューは、オブジェクト・リレーショナル形式で格納されているXMLTypeデータと互換性がありません。永続オブジェクト・タイプを含むデータベース・スキーマでは有効化できません。

関連項目:

- Oracle XML DBでのXQueryサポートの詳細は、「Oracle XML DBでのXQueryサポート」

- Oracle Exadata Storage Serverの詳細は、『Oracle Exadata Storage Server Softwareユーザーズ・ガイド』

索引
A B C D E F G H I J L M N O P Q R S T U V W X

A

アクセス制御エントリ(ACE)

定義, 27.1.3

アクセス制御リスト(ACL)

子

定義, 27.4.4

制約継承

定義, 27.4.4

定義, 27.1.4 拡張継承

定義, 27.4.4

概要, 1.2.3.1 親

定義, 27.4.4

システム, 27.4.1 アカウントXDB, 2.1, 3.18.1, 3.18.7.1, 25.6, 26.2, 27.4, 36.6.1, 36.6.1 ACE

「アクセス制御エントリ」を参照

ACL

「アクセス制御リスト」を参照

ACLOIDリソース・プロパティ

定義, 27.4

Oracle XML DBの管理, 34 Advanced Queuing(AQ)

IDAP, 37.4

メッセージ機能, 37.1.1

ポイント・ツー・ポイント・サポート, 37

パブリッシュ・サブスクライブ・サポート, 37

XMLTypeキュー・ペイロード, 37.5.1

集約権限

定義, 27.1.2

注釈

XML Schema, 3.7.3, 7.9

取得のための問合せ, 7.10

匿名ユーザー, リポジトリへのアクセス, 28.2.1 appendChildXML SQL関数, 4.2.11 基本権限

定義, 27.1.2

XML Schema属性データ型

SQLへのマッピング, 7.12.2

属性

コンテナ, 21.3.2

xdb:columnProps, 7.9.3

xdb:defaultSchema, 7.3.7

xdb:defaultTable, 7.9.1, 7.9.3

xdb:defaultTableSchema, 7.9.3

xdb:maintainDOM, 7.6.2, 7.9.1, 7.9.3, 7.9.3

xdb:maintainOrder, 7.9.3

xdb:mapUnboundedStringToLob, 7.9.3

xdb:maxOccurs, 7.9.3

xdb:SQLCollSchema, 7.9.3

xdb:SQLCollType, 7.9.1, 7.9.3

xdb:SQLInline, 7.9.3, 9.3, 9.3

xdb:SQLName, 7.9.1, 7.9.3

xdb:SQLSchema, 7.9.3, 7.9.3

xdb:SQLType, 7.9.1, 7.9.3, 7.9.3, 9.7

xdb:srclang, 7.9.3

xdb:storeVarrayAsTable, 7.9.1, 7.9.3

xdb:tableProps, 7.9.3

xdb:translate, 7.9.3

xsi:noNamespaceSchemaLocation, 7.1, 19.3.1.1

authenticatedUserロール

DBuriサーブレットのセキュリティ, 20.9.3

B

下位互換のXML Schema拡張

定義, 10.3.1

バイナリXML

定義, 1.3.3

Schemaデータ型

SQLへのマッピング, 7.12.4

ブートストラップACL

定義, 27.4.1

Bツリー索引, 1.3.3

C

XML用のC API, 16

CharacterDataインタフェース, 13.2.10

CheckInイベント, リポジトリ, 30.2

CheckOutイベント, リポジトリ, 30.2

子ACL

定義, 27.4.4

循環依存

XML Schema, 9.9

CLASSPATH Java変数

設定, 31.3.1

XMLデータのCLOB記憶域

定義, 1.3.3

closeContext PL/SQLプロシージャ, 14.2 コレクション

表外, 9.4

大規模な文書のロードおよび取得, 9.11

XML

定義, 7.8.1.3

collection属性(SQL), 7.12.5 columnProps属性, 7.9.3 複合的なXLinkリンク

定義, 23.2.2

「拡張XLinkリンク」も参照

complexType

循環の処理, 9.9.2

継承の処理, 9.8.1

マッピング

anyおよびanyAttribute宣言, 9.8.3

フラグメントからLOB, 9.7

XML Schemaデータ型からSQL, 7.12.5

Oracle XML DBの制限および拡張, 9.8 リソース・パス名の構成要素

定義, 21.2.1

複合XML文書, 23.3

定義, 23.1

圧縮

オンライン・トランザクション処理(OLTP)

CREATE TABLEの使用, 7.8.1.3

XML Schema注釈の使用, 7.9.4.6

XMLTypeのサポート, 1.3.3, B Oracle XML DBの構成

プロトコル・サーバー, 28.2.1

リポジトリ, 22

サーブレット, 32.4

DBMS_XDB APIの使用, 34.4.1.8

Oracle Enterprise Managerの使用, 34.3

xdbconfig.xml構成ファイル, 34.4

制約継承, ACL

定義, 27.4.4

XMLTypeデータに対する制約, 7.8.2

繰返しXML要素, 9.2

contains SQL関数, 6.2.2 contains XPath関数(Oracle), 12.5 リソースのコンテンツ

定義, 21.2.1

Content Repository API for Java

「JJCR」を参照

コンテンツ管理アプリケーション

定義, 23.1

Contents要素, 21.3 コピーに基づくXML Schemaの拡張, 10.2 copyEvolve PL/SQLプロシージャ, 10 COST_XML_QUERY_REWRITEオプティマイザ・ヒント, 5.10.1 コストベースのXML問合せのリライト

定義, 5.10.1

Createイベント, リポジトリ, 30.2 CREATE TABLE文

バイナリXMLのためのエンコード・オプション, 7.8.1.1

ロギング, 7.3.6

記憶域オプション, 7.8.1

XMLType, 3.2

CLOBとしての記憶域, 7.8.1.2

CREATE TYPE文

ロギング, 7.3.6

createResource PL/SQL関数, 3.4.6 createXML() XMLTypeメソッド, 13.1.1.3, 15.2.1 XMLType表の作成, 3.2

ネストしたコレクション, 3.7.7

記憶域オプション, 7.8.1

XML Schemaに基づく, 3.7.7, 7.8

CTXCAT索引, 12.4.5.1 CTXRULE索引, 12.4.5.1 循環依存

XML Schema, 9.9

D

データベース・ロール

定義, 27.1.1, 27.1.1, 27.1.1

データベース・ユーザー

定義, 27.1.1

データ中心の使用, XMLデータ

定義, 1.3.3

XML Schema日時データ型

SQLへのマッピング, 7.12.4

DAV: WebDAV名前空間, 27.3 DBMS_METADATA PL/SQLパッケージ, 20.3.1

参照ドキュメント, 1.2.1, 1.2.1

DBMS_XDB PL/SQLパッケージ, 26.1

参照ドキュメント, 1.2.1, 1.2.1

DBMS_XDB_ADMIN PL/SQLパッケージ

参照ドキュメント, 1.2.1

DBMS_XDB_VERSION PL/SQLパッケージ, 24

参照ドキュメント, 1.2.1

DBMS_XDBT PL/SQLパッケージ, 1.2.1 DBMS_XDBZ PL/SQLパッケージ, 29.7

disable_hierarchyプロシージャ, 27.7.1

enable_hierarchyプロシージャ, 27.7

is_hierarchy_enabledファンクション, 29.7

purgeLDAPCacheプロシージャ, 27.6

参照ドキュメント, 1.2.1

DBMS_XEVENT PL/SQLパッケージ

参照ドキュメント, 1.2.1

DBMS_XMLDOM PL/SQLパッケージ, 13.2

例, 13.2.12

参照ドキュメント, 1.2.1

DBMS_XMLGEN PL/SQLパッケージ, 18.3

参照ドキュメント, 1.2.1

DBMS_XMLINDEX PL/SQLパッケージ

modifyParameterプロシージャ, 6.4.17.1

参照ドキュメント, 1.2.1

registerParameterプロシージャ, 6.4.17.1

DBMS_XMLPARSER PL/SQLパッケージ, 13.3

参照ドキュメント, 1.2.1

DBMS_XMLQUERY PL/SQLパッケージ

Oracle Java Virtual Machineへの依存性, B

DBMS_XMLSAVE PL/SQLパッケージ, 14.1

Oracle Java Virtual Machineへの依存性, B

DBMS_XMLSCHEMA PL/SQLパッケージ, 7.3

copyEvolveプロシージャ, 10

deleteSchemaプロシージャ, 7.3.13

generateSchemaおよびgenerateSchemas関数, 9.1

inPlaceEvolveプロシージャ, 10

マッピングのタイプ, 7.12

purgeSchemaプロシージャ, 7.3.13.1

参照ドキュメント, 1.2.1

registerSchemaプロシージャ, 7.3.1, 9.10.3

enableHierarchyパラメータ, 29.2

DBMS_XMLSTORE PL/SQLパッケージ, 14

参照ドキュメント, 1.2.1

DBMS_XSLPROCESSOR PL/SQLパッケージ, 13.4

参照ドキュメント, 1.2.1

DBUri

定義, 20.3

sys_DburiGen SQL関数を使用した生成, 20.8

行の識別, 20.6.4.2

ターゲット列の指定, 20.6.4.3

列のテキスト値の取出し, 20.6.4.4

表全体の取出し, 20.6.4

セキュリティ, 20.9.3

サーブレット, インストール, 20.9.2

DBURI参照, 20.6

HTTPアクセス, 20.9

DBUriServlet

定義, 20.9

DBURIType

定義, 20.3

デバッグ

XML Schema登録, 7.3.6

デフォルトの表

XML Schema登録時の作成, 7.3.8

defaultSchema属性, 7.3.7 defaultTable属性, 7.9.1, 7.9.3 defaultTableSchema属性, 7.9.3 Deleteイベント, リポジトリ, 30.2 deleteSchema PL/SQLプロシージャ, 7.3.13 deleteXML PL/SQL関数, 14.1 deleteXML SQL関数, 4.2.12 削除

リソース, 25.3.2

DBMS_XMLSCHEMAを使用したXML Schema, 7.3.13

depth SQL関数, 25.2.4 XML Schema派生データ型

SQLへのマッピング, 7.12.4

ディレクトリ

「フォルダ」を参照。

disable_hierarchy PL/SQLプロシージャ, 27.7.1 ドキュメント(DOM)

定義, 13.2.8

ドキュメント・リンク

定義, 21.3.3.1, 23.2.1

関連情報の取得, 23.6

ドキュメントの場所を示すヒント

定義, 3.7.6

ドキュメント・オブジェクト・モデル

「DOM」を参照

ドキュメント・タイプ定義

「DTD」を参照

ドキュメント・ビュー・シリアライズ, JCR

定義, 31.2.3

DOCUMENT_LINKSパブリック・ビュー, 23.6 ドキュメント中心の使用, XMLデータ

定義, 1.3.3

文書が相互に関連する再帰的な問合せ

定義, 9.10, 9.10

DOM

定義, 13.1

SAXとの違い, 13.2.1.3

ドキュメント

定義, 13.2.8

再現性, 7.6, 7.6

XML Schemaマッピング, 13.2.5.1

SYS_XDBPD$オブジェクト属性, 7.6.2

updateXML SQL関数の使用, 4.2.3.3

Java API for XMLType, 15.1 NamedNodeMapオブジェクト, 13.2.10 NodeListオブジェクト, 13.2.10 概要, 13.2.1 PL/SQL API for XMLType, 13.2 DOM再現性

定義, 7.6.1

DTD

定義, 7.2.2

Oracle XML DBでのサポート, 7.2.2

Oracle XML DBの使用, 7.2

動的型チェック

XQuery言語, 5.11

E

ノードの有効テキスト値

定義, 6.4.4.2

XML Schema要素データ型

SQLへのマッピング, 7.12.3

要素

Contents, リソース索引, 21.3

XDBBinary, 21.4.1.3

enable_hierarchy PL/SQLプロシージャ, 27.7, 27.7 enableHierarchyパラメータ, DBMS_XMLSCHEMA.registerSchema, 29.2 Enterprise Manager

Oracle XML DBの管理, 34.3

エンティティ, XML

バイナリXML記憶域を使用したDTDの使用, 7.2

equals_path SQL関数, 5.10.5.1, 25.2.2 XMLType表の同一レベル・パーティション化

定義, 9.5

イベント

リポジトリ, 30

構成, 30.5

事前定義, 30.2

イベント・ハンドラ, リポジトリ

定義, 30.1.3

イベント・リスナー, リポジトリ

定義, 30.1.3

拡張, XML Schema, 10 existsNode Oracle SQL関数(非推奨), はじめに 拡張XLinkリンク

定義, 23.2.2

拡張継承, ACL

定義, 27.4.4

extract Oracle SQL関数(非推奨), はじめに XMLからのデータの抽出, 4.1.3 extractValue Oracle SQL関数(非推奨), はじめに

F

再現性

DOM, 7.6

XML Schemaマッピング, 13.2.5.1

SYS_XDBPD$オブジェクト属性, 7.6.2

updateXML SQL関数の使用, 4.2.3.3

FLWOR XQuery式, 5.2.3 fn:available

サポート, 5.14.2.1

fn:collection

パフォーマンス向上のために回避, 5.10.5

サポート, 5.14.2

fn:doc

パフォーマンス向上のために回避, 5.10.5

サポート, 5.14.2

fn:id

サポート, 5.14.2

fn:idref

サポート, 5.14.2

fn:matches

サポート, 5.14.2

fn:replace

サポート, 5.14.2

fn:tokenize

サポート, 5.14.2

フォルダ

定義, 21.2.1, 21.2.1

フォルダ・リンク

定義, 21.3.3.1

フォルダsys, リポジトリ, 21.1 フォルダリング, 21.1 フォルダ限定の問合せ

定義, 3.18.13.2

フラグメント, XML

定義, 3.11.6

SQL操作, 3.11.6

フラグメント, XML

LOBへのマッピング, 9.7

freeDocument PL/SQLプロシージャ, 13.2.12 DOMdocumentインスタンスの解放, 13.2.12 FROMリストの順序

XMLTableのPASSING句, 5.9.4

FTP

構成パラメータ, 28.2.1

デフォルト表の作成, 7.3.8

プロトコル・サーバー, 機能, 28.3

完全修飾されたXML SchemaのURL, 9.6 機能上の評価

定義, 3.15

ファンクション索引, 6.2.4.1 関数

PL/SQL

createResource, 3.4.6

deleteXML, 14.1

generateSchemaおよびgenerateSchemas, 9.1

insertXML, 14.1

is_hierarchy_enabled, 29.7

updateXML, 14.1

SQL

appendChildXML, 4.2.11

contains, 6.2.2

deleteXML, 4.2.12

depth, 25.2.4

equals_path, 5.10.5.1, 25.2.2

existsNode(非推奨), はじめに

extract(非推奨), はじめに

extractValue(非推奨), はじめに

insertChildXML, 4.2.6

insertChildXMLafter, 4.2.8

insertChildXMLbefore, 4.2.7

insertXMLafter, 4.2.10

insertXMLbefore, 4.2.9

path, 25.2.3

sys_DburiGen, 20.8

sys_XMLAgg, 18.5

sys_XMLGen, 18.4

under_path, 25.2.1

updateXML, 4.2.3

XMLデータの更新, 4.2

XMLAgg, 18.2.4

XMLAttributes, 18.2.1

XMLCast, 4.1.2.2

XMLCDATA, 18.2.11

XMLColAttVal, 18.2.10

XMLComment, 18.2.6

XMLConcat, 18.2.3

XMLElement, 18.2.1

XMLExists, 4.1.2.1

XMLForest, 18.2.2

XMLIsValid, 3.9.1.2.1, 11.3

XMLParse, 18.2.8

XMLPI, 18.2.5

XMLQuery, 5.3, 5.3.1

XMLRoot, 18.2.9

XMLSequence(非推奨), はじめに

XMLSerialize, 18.2.7

XMLTable, 5.3, 5.3.2

XMLtransform, 11.1.1

XPath

ora:instanceof(非推奨), はじめに

ora:instanceof-only(非推奨), はじめに, はじめに

G

gatherRepositoryStats PL/SQLプロシージャ, 26.2

generateSchemaおよびgenerateSchemas PL/SQL関数, 9.1

XMLの生成, 18

DBMS_XMLGEN PL/SQLパッケージ, 18.3

DBMS_XMLSCHEMA PL/SQLパッケージ, 9.1

generateSchemaおよびgenerateSchemas PL/SQL関数, 9.1

SQL関数, 18.1

sys_XMLAgg SQL関数, 18.5

sys_XMLGen SQL関数, 18.4

XML Schema, 9.1

XMLAgg SQL関数, 18.2.4

XMLAttributes SQL関数, 18.2.1

XMLCDATA SQL関数, 18.2.11

XMLColAttVal SQL関数, 18.2.10

XMLComment SQL関数, 18.2.6

XMLConcat SQL関数, 18.2.3

XMLElement SQL関数, 18.2.1

XMLForest SQL関数, 18.2.2

XMLParse SQL関数, 18.2.8

XMLPI SQL関数, 18.2.5

XMLRoot SQL関数, 18.2.9

XMLSerialize SQL関数, 18.2.7

getBLOBVal() Oracle XMLTypeメソッド(非推奨), はじめに getCLOB() XMLTypeメソッド, 15.3 getCLOBVal() Oracle XMLTypeメソッド(非推奨), はじめに getNamespace() Oracle XMLTypeメソッド(非推奨), はじめに getNumberVal() XMLTypeメソッド, 4.1.1 getObject() XMLTypeメソッド, 15.2.1.2 getOPAQUE() XMLTypeメソッド, 15.2.1.2 getRootElement() Oracle XMLTypeメソッド(非推奨), はじめに getSchemaURL() XMLTypeメソッド, 7.4 getStringVal() Oracle XMLTypeメソッド(非推奨), はじめに JCRリポジトリ・オブジェクトの取得, 31.3.2 グローバルXML Schema

定義, 7.5.2

完全修飾されたURLを使用して上書き, 9.6

ACL内で宣言した権限

定義, 27.4.4

ACLに定義した権限

定義, 27.4.4

XMLIndex構造化コンポーネント内のグループ

定義, 6.4.7

H

ハード・リンク

定義, 21.3.3.2

JCR, 31.2.6

リポジトリの階層索引, 3.18.14 階層対応表

定義, 27.7

HTTP

DBURI参照へのアクセス, 20.9

JavaサーブレットまたはXMLTypeへのアクセス, 32.2.1

リポジトリ・リソースへのアクセス, 21.4.1.2

構成パラメータ, WebDAV, 28.2.1

デフォルト表の作成, 7.3.8

パフォーマンスの向上, 28.1.1

Oracle XML DBサーブレット, 32.5

プロトコル・サーバー, 機能, 28.4

リクエスト, 32.5

サーブレット, 32.3

URIFACTORY, 20.9.4

URI参照を使用したポインタの格納, 20.3

HTTPUri

定義, 20.3

HTTPURIType

定義, 20.3

ハイブリッド列圧縮, B ハイブリッド記憶域

定義, 6.2.1

XMLデータのハイブリッド記憶域

定義, 1.3.3

I

IDAP

アーキテクチャ, 37.5

インターネットを介した転送, 37.4

インポート/エクスポート・ユーティリティ

XML DB, 36.6

索引

リポジトリの階層索引, 3.18.14

索引付け

CTXCAT, 12.4.5.1

CTXRULE, 12.4.5.1

ファンクション, 6.2.4.1

XMLTypeのオプション, 3.1.2

Oracle Text, 1.4.4, 6.5, 12

XMLType, 6.2

索引構成表, 3.7.4 継承

XML Schema, complexTypesでの制限, 9.8.1

インプレースXML Schemaの拡張, 10.3 inPlaceEvolve PL/SQLプロシージャ, 10 insertChildXML SQL関数, 4.2.6 insertChildXMLafter SQL関数, 4.2.8 insertChildXMLbefore SQL関数, 4.2.7 insertXML PL/SQL関数, 14.1 insertXML() XMLTypeメソッド, 15.3 insertXMLafter SQL関数, 4.2.10 insertXMLbefore SQL関数, 4.2.9 Oracle XML DBのインストール, 34.1 インスタンス・ドキュメント

定義, 1.3.2

ルート要素(名前空間)の指定, 7.1

Internet Data Access Presentation(IDAP)

AQに対するSOAP仕様, 37.4

インターネット・プロトコル・バージョン6

FTP, 28.3.1.6

HTTP(S), 28.4.1.4

IPv6

FTP, 28.3.1.6

HTTP(S), 28.4.1.4

is_hierarchy_enabled PL/SQL関数, 29.7 isSchemaBased() XMLTypeメソッド, 7.4 isSchemaValid() XMLTypeメソッド, 7.4 IsSchemaValid() XMLTypeメソッド, 11.3 isSchemaValidated() XMLTypeメソッド, 7.4, 11.3

J

Java

接続, シックおよびシン, 15.4

DOM API for XMLType, 15.1

Oracle XML DBアプリケーション, 32.1

oracle.xml.parser.v2, 15.1

Java Content Repository API

「JJCR」を参照

JCR

コンプライアンス・レベル, サポート, 31.3.6

ドキュメント・ビュー・シリアライズ

定義, 31.2.3

ファイルとフォルダ, 公開, 31.2.1 getPath() Javaメソッド, 31.2.6 ハード・リンク, 31.2.6 ロギング, 31.3.5 Oracle XML DBリポジトリへのアクセス, 31.2 概要, 31.1.1 制限事項, Oracle XML DB Content Connector, 31.3.7 弱いリンク, 31.2.6 XML Schema, 31.4 JCRノード型

XML Schemaデータ型からのマッピング, 31.4.3

XML Schemaのグローバルな要素宣言からのマッピング, 31.4.3.4

nt:file, 31.2

nt:folder, 31.2

Oracleの拡張機能, 31.2.2

jcr:content, 31.2.5 jcr:dataプロパティ, 31.2.3 JDBC

XML文書へのアクセス, 15.2.1.2

ドライバ, OCIおよびThin, 15.2.2

大規模なXML文書のロード, 15.3

XML文書の操作, 15.2.2

JSR-170

「JCR 1.0」を参照

L

大規模ノードの処理, 13.2.13

XMLの遅延ロード(実体化の遅延), 13.1.1.1

リンク

ドキュメント

定義, 21.3.3.1

フォルダ

定義, 21.3.3.1

ハード

定義, 21.3.3.2

リポジトリ

定義, 21.3.3.1

弱い

定義, 21.3.3.2

リンク名

定義, 21.2.1

LinkInイベント, リポジトリ, 30.2 リンク, リポジトリ

定義, 3.18.13.1

リンク・プロパティ文書

定義, 3.18.13.1

LinkToイベント, リポジトリ, 30.2 ロード

コレクションでの大規模な文書, 9.11

JDBCを使用した大規模なXML文書のロード, 15.3 XMLデータのロード, 遅延, 13.1.1.1 LOBロケータ, 24.4 LOB

XMLフラグメントのマッピング, 9.7

ローカルXML Schema

定義, 7.5.1

完全修飾されたURLを使用して指定, 9.6

Lockイベント, リポジトリ, 30.2

M

maintainDOM属性, 7.6.2, 7.9.1, 7.9.3, 7.9.3

maintainOrder属性, 7.9.3

実体化, 遅延, 13.1.1.1

マッピング

complexType anyおよびanyAttributes宣言, 9.8.3

SQLへのcomplexType

表外に格納, 9.3

SQLType属性を使用したオーバーライド, 7.12.3.1 simpleContentからオブジェクト型, 9.8.2 XML Schema complexTypeデータ型のSQLへのマッピング, 7.12.5 XML Schemaデータ型のSQLデータ型へのマッピング, 7.12 XML SchemaのSQLへのマッピング

simpleType, 7.12.4

mapUnboundedStringToLob属性, 7.9.3 matches XQuery関数(Oracle), 5.7.2 maxOccurs属性, 7.9.3 メタデータ

定義, 29.1

システム定義

定義, 1.2.3

ユーザー定義

定義, 1.2.3

メソッド

XMLType

createXML(), 13.1.1.3, 15.2.1

getBLOBVal()(非推奨), はじめに

getCLOB(), 15.3

getCLOBVal()(非推奨), はじめに

getNamespace()(非推奨), はじめに

getNumberVal(), 4.1.1

getObject(), 15.2.1.2

getOPAQUE(), 15.2.1.2

getRootElement()(非推奨), はじめに

getSchemaURL(), 7.4

getStringVal()(非推奨), はじめに

insertXML(), 15.3

isSchemaBased(), 7.4

isSchemaValid(), 7.4

IsSchemaValid(), 11.3

isSchemaValidated(), 7.4, 11.3

schemaValidate(), 7.4

setObject(), 15.2.2

setSchemaValidated(), 7.4, 11.3

writeToStream(), 21.4.1.5

XML Schema, 7.4

MIME

DBUriサーブレットによるオーバーライド, 20.9.1

mix:referenceable, 31.2.3 混合XMLコンテンツ

定義, 1.3.3

モデル, XML Schema

定義, 10.3.1.1.4

modifyParameter PL/SQLプロシージャ, 6.4.17.1

N

NamedNodeMapオブジェクト(DOM), 13.2.10

名前空間

接頭辞

ocjr, 31.2.2

XML SchemaのURL, 7.1 XQuery, 5.5, 5.9.5 SQLオブジェクトの命名, 7.9 リポジトリ・リソースへのナビゲーショナル・アクセス, 21.4 ネストしたXML

DBMS_XMLGENを使用した生成, 18.3.3

XMLElementを使用した生成, 18.2.1.3

NESTED_TABLE_ID疑似列, 3.7.7 newDOMDocument()関数, 13.2.9 NodeListオブジェクト(DOM), 13.2.10 ノード, 大規模(DBMS_XMLDOM), 13.2.13 ノード, 大規模(Java), 15.6 noNamespaceSchemaLocation属性, 7.1, 19.3.1.1 XML Schemaに基づかないビュー

定義, 19.1

nt:file JCRノード型, 31.2 nt:folder, 31.2 nt:folder JCRノード型, 31.2 XML Schema数値データ型

SQLへのマッピング, 7.12.4

O

オブジェクト属性

collection(SQL), 7.12.5

XMLFormat, 18.4.2

REF, 9.3, 9.9.2

sys_DburiGen SQL関数

送信, 20.8.1

SYS_XDBPD$, 7.6.2 XMLType, AQ, 37.5.1 オブジェクト識別子

定義, 27.4

XDB$ACL表のOBJECT_ID列, 27.4 オブジェクトベースのXMLデータの永続性

定義, 1.3.3

XMLデータのオブジェクト・リレーショナル記憶域

定義, 1.3.3

出現インジケータ

定義, 5.2.2

OCI API for XML, 16 ocjr名前空間接頭辞, 31.2.2 OCT

定義, 3.7.4

ODP.NET, 17 OID

「オブジェクト識別子」を参照

ojcr:folder, 31.2.3 演算子

「関数, SQL」を参照

オプティマイザ・ヒント

COST_XML_QUERY_REWRITE, 5.10.1

リポジトリ問合せの最適化, 26.2 ora:contains XPath関数(Oracle), 12.5

ポリシー

定義, 12.5.4

ora:defaultTable XQueryプラグマ, 5.8, 5.10.5.2 ora:instanceof Oracle XPath関数(非推奨), はじめに ora:instanceof-only Oracle XPath関数(非推奨), はじめに, はじめに ora:invalid_path XQueryプラグマ, 5.8 ora:matches XQuery関数(Oracle), 5.7.2 ora:replace XQuery関数(Oracle), 5.7.3 ora:sqrt XQuery関数(Oracle), 5.7.4 ora:tokenize XQuery関数(Oracle), 5.7.5 ora:view_on_null XQueryプラグマ, 5.8 ora:xq_proc XQueryプラグマ, 5.8, 6.4.9 ora:xq_qry XQueryプラグマ, 5.8 Oracle ASMファイル

アクセス, 21.4.2

FTPを使用, 28.3.1.4

Oracle ASM仮想フォルダ, 21.3.1.3 Oracle Data Provider for .NET, , 17 Oracle Enterprise Manager

Oracle XML DBの管理, 34.3

JCRノード型に対するOracle拡張関数, 31.2.2 Oracle Internet Directory, 27.8 Oracle Net Services, 1.2 Oracle Text

contains SQL関数およびXMLType, 6.2.2

索引, 1.4.4, 6.5, 12

リソースの検索, 25.6

検索, CLOB内のXML, 1.4.4

Oracle XML DB

アクセス・モデル, 2.3.2

アドバンスト・キューイング, 1.4.4

アーキテクチャ, 1.2

機能 1.3

インストール, 34.1

Javaアプリケーション, 32.1

概要, 1.1

リポジトリ

「リポジトリ」を参照

アップグレード, 34.2 バージョニング, 24 用途, 2.2 Oracle XML DB Content Connector, 31

使用方法, 31.3

ロギングAPI, 31.3.5

概要, 31.1.2

制限, 31.3.7

ファイルをアップロードするサンプル・コード, 31.3.3

「JCR」も参照

OracleRepository, 31.3.2 oracle.xdb.XMLType Javaクラス, 15.1, 15.4.1.1 oracle.xml.parser.v2 Javaパッケージ, 15.1 XMLIndexの順序索引

定義, 6.4.4

Ordered Collection

定義, 3.7.4

Ordered Collection Table(OCT)

定義, 3.7.4

Ordered Collections in Tables(OCT)

VARRAYのデフォルトの格納, 7.12.5

表外に格納, 9.3

コレクション, 9.4

XPathリライト, 9.3.1

P

親ACL

定義, 27.4.4

XMLデータの部分更新

定義, 4.2.2

XMLデータの部分検証

定義, 3.9.1.1

XMLType表のパーティション化, 9.5

バイナリXML, 3.3

XMLTableのPASSING句

FROMリストの順序, 5.9.4

リソース・パス名のパス要素

定義, 21.2.1

XMLIndexのパス索引

定義, 6.4.4

パス名

定義, 21.2.1

解決, 21.3.2

path SQL関数, 25.2.3 XMLIndexのパス表, 6.4.4 PATH_VIEW, 25 パスベースのリポジトリ・リソースへのアクセス, 21.4 パス索引トリガー

定義, 27.7

PD(位置指定ディスクリプタ), 7.6.2 XMLデータの永続性モデル, 1.3.3 PL/SQL関数

「関数, PL/SQL」を参照

PL/SQLパッケージ

DBMS_METADATA, 20.3.1

参照ドキュメント, 1.2.1, 1.2.1

DBMS_XDB, 26.1

参照ドキュメント, 1.2.1, 1.2.1

DBMS_XDB_ADMIN

参照ドキュメント, 1.2.1

DBMS_XDB_VERSION, 24

参照ドキュメント, 1.2.1

DBMS_XDBT, 1.2.1 DBMS_XDBZ, 27.7, 29.7

参照ドキュメント, 1.2.1

DBMS_XEVENT

参照ドキュメント, 1.2.1

DBMS_XMLDOM, 13.2

参照ドキュメント, 1.2.1

DBMS_XMLGEN, 18.3

参照ドキュメント, 1.2.1

DBMS_XMLINDEX

参照ドキュメント, 1.2.1

DBMS_XMLPARSER, 13.3

参照ドキュメント, 1.2.1

DBMS_XMLQUERY

Oracle Java Virtual Machineへの依存性, B

DBMS_XMLSAVE, 14.1

Oracle Java Virtual Machineへの依存性, B

DBMS_XMLSCHEMA

参照ドキュメント, 1.2.1

「DBMS_XMLSCHEMA PL/SQLパッケージ」を参照

DBMS_XMLSTORE, 14

参照ドキュメント, 1.2.1

DBMS_XSLPROCESSOR, 13.4

参照ドキュメント, 1.2.1

XMLType, 13.1 PL/SQLプロシージャ

「プロシージャ, PL/SQL」を参照

ポイント・ツー・ポイント

AQでのサポート, 37

ora:contains XPath関数のポリシー(Oracle)

定義, 12.5.4

ポート

構成

FTP, 28.2.1

HTTP, 28.2.1

HTTPS, 28.2.2

位置指定ディスクリプタ(PD), 7.6.2 XMLデータの事後解析の永続性

定義, 1.3.3

プラグマ

XQuery

Oracle, 5.8

事前定義のACL, 27.4.1 プリファレンス

Oracle Textの索引付け

定義, 12.4.5.1

フォーマット出力, 18.2.7

マニュアルの例, はじめに

SQL/XML関数により実行されない, 3.16.1

Webサービス出力, 33.3

XML Schema基本データ型

SQLへのマッピング, 7.12.4

プリンシパル

定義, 27.1.1, 27.1.1

プライベート(ローカル)XML Schema, 定義, 7.5 権限

定義, 27.1.2

プロシージャ

PL/SQL

closeContext, 14.2

copyEvolve, 10

disable_hierarchy, 27.7.1

enable_hierarchy, 27.7, 27.7

freeDocument, 13.2.12

gatherRepositoryStats, 26.2

inPlaceEvolve, 10

modifyParameter, 6.4.17.1

processXSL, 13.4.3

purgeLDAPCache, 27.6

registerParameter, 6.4.17.1

registerSchema, 7.3.1

setKeyColumn, 14.2

setUpdateColumn, 14.2

processXSL PL/SQLプロシージャ, 13.4.3 プロトコル・サーバー, 28.1

アーキテクチャ, 28.1.1

構成パラメータ, 28.2.1

イベントベース・ロギング, 28.2.5

FTP, 28.3

構成パラメータ, 28.2.1

HTTP, 28.4

構成パラメータ, 28.2.1

WebDAV, 28.5

構成パラメータ, 28.2.1

プロトコル, リポジトリ・リソースへのアクセス, 21.4.1 パブリック(グローバル)XML Schema, 定義, 7.5 パブリッシュ・サブスクライブ

AQでのサポート, 37

発注書のXML文書

全文の例で使用, 12.7.1

発注書のXML Schema, 3.6.4.1

注釈付き, 3.7.5, A.6

グラフィカル表現, 3.6.4.2

修正された, 10.2.1, A.6

purgeLDAPCache PL/SQLプロシージャ, 27.6 purgeSchema PL/SQLプロシージャ, 7.3.13.1

Q

修飾されたXML SchemaのURL, 9.6

問合せベースのアクセス

RESOURCE_VIEWおよびPATH_VIEWの使用, 25.1

SQLの使用, 21.5

XMLTypeデータの問合せ

選択, 4.1

一時データ, 4.1.3

R

ra:use_text_index Oracle XQueryプラグマ, 12.5.5.2

再帰的スキーマのサポート, 9.10

REFオブジェクト属性, 9.3, 9.9.2

REGISTER_NT_AS_IOTオプション, XML Schema登録, 3.7.4, 3.7.4, 7.3.1

登録されたXML Schema, リスト, 7.3.12

XML Schemaの登録, 7.3.1

デバッグ, 7.3.6

デフォルト表, 作成, 7.3.8

SQLオブジェクト型, 作成, 7.3.7

JCR用XML Schemaの登録, 31.4.1 registerParameter PL/SQLプロシージャ, 6.4.17.1 registerSchema PL/SQLプロシージャ, 7.3.1 XMLIndex索引の名前変更, 6.4.5 Renderイベント, リポジトリ, 30.2 replace XQuery関数(Oracle), 5.7.3 リポジトリ, 21.2

匿名ユーザー・アクセス, 28.2.1

JCRを使用したアクセス, 31.2

データ記憶域, 21.3.1

イベント, 30

構成, 30.5

事前定義, 30.2

イベント・ハンドラ

定義, 30.1.3

イベント・リスナー

定義, 30.1.3

階層索引, 3.18.14 リソース

「リソース」を参照

Xqueryの使用, 5.9.2 リポジトリ・リンク

定義, 21.3.3.1

リポジトリ・オブジェクト, 31.3.2 RESID

定義, 24.2

リソース

アクセス, 21.1.1

プロトコルの使用, 28.2.3

定義, 1.2.3, 29.1 削除, 21.3.3.2

空でないコンテナ, 25.3.2.1

DELETEの使用, 25.3.2

DBMS_XDBを使用した管理, 26.2, 34.5 操作に必要な権限, 27.2 検索, Oracle Textの使用, 25.6 ACLでのプロパティの設定, 27.5 同時操作, 25.4 更新, 25.3.3 リソース構成ファイル

定義, 22.1

リソース構成リスト

定義, 22.1

リソース・コンテンツ

定義, 21.2.1

リソース・ドキュメント

定義, 3.18.7.1

リソースID

定義, 24.2

リソース名

定義, 21.2.1

リソース・バージョン

定義, 24.1

RESOURCE_VIEW

説明, 25

resource-view-cache-size構成パラメータ, 25.5 コレクションでの大規模な文書の取得, 9.11 リライト

XPath(XPath), 8

XQuery, 5.10

ロール

authenticatedUser, DBuriサーブレット, 20.9.3

データベース

定義, 27.1.1

XDB_SET_INVOKER, 30.5.1 XDBADMIN, 7.5.2, 22.1, 27.4.1, 30.5 ルート・フォルダ, リポジトリ, 21.1 ルートXML Schema

定義, 7.3.5

ルールベースのXML問合せのリライト

定義, 5.10.1

S

スカラー値

sys_XMLGenを使用したXML文書の変換, 18.4.2

スキーマの拡張

「XML Schemaの拡張」を参照

スキーマのスキーマ(XML Schema)

定義, 1.3.2

スキーマの場所を示すヒント

定義, 3.7.6

schemaValidate() XMLTypeメソッド, 7.4 検索, CLOBインスタンス, 1.4.4 セキュリティ

DBUri, 20.9.3

半構造化XMLデータ

定義, 1.3.3

サーブレット

リポジトリ・データへのアクセス, 21.6

API, 32.8

構成, 32.4

セッション・プーリング, 32.6, 32.6

作成, 32.9

Java, 32.3

XML操作, 32.2.3 セッション・プーリング, 32.6

プロトコル・サーバー, 28.1.1

setKeyColumn PL/SQLプロシージャ, 14.2 setObject() XMLTypeメソッド, 15.2.2 setSchemaValidated() XMLTypeメソッド, 7.4, 11.3 setUpdateColumn PL/SQLプロシージャ, 14.2 単純XLinkリンク

定義, 23.2.2

simpleContent

オブジェクト型へのマッピング, 9.8.2

XML Schema simpleTypeデータ型

SQLへのマッピング, 7.12.4

SOAP, 33.1

アドバンスト・キューイングを介したアクセス, 1.2

IDAP, 37.4

SQL関数

「関数, SQL」を参照

SQL関数

「関数, SQL」を参照

SQLオブジェクト型

XML Schema登録時の作成, 7.3.7

SQL演算子

「関数, SQL」を参照

SQL*Loader, 35.2 SQL*Plus

XQUERYコマンド, 5.12

SQLCollSchema属性, 7.9.3 SQLCollType属性, 7.9.1, 7.9.3 SQLInline属性, 7.9.3, 9.3, 9.3 SQLJ, 15.4.1.1 SQLName属性, 7.9.1, 7.9.3 SQLSchema属性, 7.9.3, 7.9.3 SQLType属性, 7.9.1, 7.9.3, 7.9.3, 9.7 SQL/XML生成関数

定義, 1.3.5

SQL/XMLパブリッシング関数

定義, 1.3.5, 18.2

SQL/XML問合せおよびアクセス関数

定義, 1.3.5

SQL/XML標準

XMLデータの生成, 18.2

XMLデータの問合せ

XMLExistsおよびXMLCast, 4.1.2

XMLQueryおよびXMLTable, 5.3

sqrt XQuery関数(Oracle), 5.7.4 srclang属性, 7.9.3 標準のメタデータ, 31.2.4 静的型チェック

XQuery言語, 5.11

記憶域

表外, 9.3

コレクション, 9.4

XMLType, CREATE TABLE, 7.8.1.2 XMLTypeの記憶域モデル, 1.3.3 storeVarrayAsTable属性, 7.9.1, 7.9.3 XML Schema文字列データ型

SQLへのマッピング, 7.12.4

VARCHAR2またはCLOBへのマッピング, 7.12.4.2

XMLデータの構造化記憶域

定義, 1.3.3

構造化XMLIndexコンポーネント

定義, 6.4.2

XMLインスタンス・ドキュメントの更新用スタイルシート, 10.2.5 sysフォルダ, リポジトリ, 21.1 sys_DburiGen SQL関数, 20.8

データベース参照の挿入, 20.8.2

オブジェクトのURLの取得, 20.8.2.2, 20.8.2.2

テキスト・ノード・テストの使用, 20.8.1

SYS_NC_ARRAY_INDEX$列, 3.7.7 SYS_XDBPD$オブジェクト属性, 7.6.2 sys_XMLAgg SQL関数, 18.5 sys_XMLGen SQL関数, 18.4

XMLTypeインスタンスの変換, 18.4.2

オブジェクト・ビュー, 18.4.2

XMLFormatオブジェクト属性, 18.4.2

XMLGenFormatTypeオブジェクト, 18.4.2

SYSAUX表領域, 34.1.1 システムACL

定義, 27.4.1

システムACL, 27.4.1 システム定義メタデータ

定義, 1.2.3

T

tableProps属性, 7.9.3

表

索引構成, 3.7.4

表領域

SYSAUX, 34.1.1

ノードのテキスト値, 有効

定義, 6.4.4.2

テキスト・ベースのXMLデータの永続性

定義, 1.3.3

サード・パーティのXLinkリンク

定義, 23.2.2

tokenize XQuery関数(Oracle), 5.7.5 translate属性, 7.9.3 トリガー, パス索引

定義, 27.7

型チェック, 静的および動的

XQuery言語, 5.11

U

ユーザー定義型

要素の生成, 18.2.1.3

UncheckOutイベント, リポジトリ, 30.2 under_path SQL関数, 25.2.1 均一なアクセス制御メカニズム

定義, 27.7

属性の親要素の一意制約, 9.2 UnLinkInイベント, リポジトリ, 30.2 Unlockイベント, リポジトリ, 30.2 未解決のXLinkリンクおよびXIncludeリンク, 23.7.1 XMLデータの非構造化記憶域

定義, 1.3.3

非構造化XMLIndexコンポーネント

定義, 6.4.2

Updateイベント, リポジトリ, 30.2 updateXML PL/SQL関数, 14.1 updateXML SQL関数, 4.2.3

NULL値のマッピング, 4.2.3.1

リポジトリ・リソースの更新, 25.3.3 XMLデータの更新

部分更新

定義, 4.2.2

同じノードの複数回の更新, 4.2.3.2 SQL関数の使用, 4.2

最適化, 4.2.4

Oracle XML DBのアップグレード, 34.2 URIFACTORY PL/SQLパッケージ

DBURI参照を処理するための構成, 20.9.4

URITypeのサブタイプの作成, 20.7

URI参照

データベースおよびセッション, 20.6.3

DBURI参照, 20.6

DBURI参照へのHTTPアクセス, 20.9

URIFACTORY PL/SQLパッケージ, 20.7

URITypeの例, 20.4

URIType

例, 20.4

ユーザー

定義, 27.1.1

ユーザーXDB, 2.1, 3.18.1, 3.18.7.1, 25.6, 26.2, 27.4, 36.6.1, 36.6.1 ユーザー定義メタデータ, 31.2.5

定義, 1.2.3

V

検証

例, 11.4

IsSchemaValid() XMLTypeメソッド, 11.3

isSchemaValidated() XMLTypeメソッド, 11.3

setSchemaValidated() XMLTypeメソッド, 11.3

XMLIsValid SQL関数, 11.3

CHECK制約として使用, 3.9.1.2.1

XMLデータの検証, 部分

定義, 3.9.1.1

XMLIndexの値索引

定義, 6.4.4

VARRAY, LOB内

定義, 3.7.4

VARRAY, 表内

定義, 3.7.4

VCR

「バージョン管理されたリソース」を参照

バージョン・リソース

定義, 24.1

リソースのバージョン・シリーズ

定義, 24.2

バージョン対応リソース

定義, 24.1

VersionControlイベント, リポジトリ, 30.2 バージョン管理されたリソース

定義, 24.1

バージョニング, 1.2.3.1, 24 ビュー

RESOURCEおよびPATH, 25

W

弱いリンク

定義, 21.3.3.2

削除, 23.7.1

JCR, 31.2.6

Webサービス, 33.1

フォーマット出力, 33.3

WebDAVプロトコル・サーバー, 28.5 Webフォルダ

Windows 2000での作成, 28.5.3

整形式のXML文書

定義, 3.9

writeToStream() XMLTypeメソッド, 21.4.1.5 WSDL

ストアドPL/SQLへのアクセスに使用するWebサービス, 33.4

データベース問合せに使用するWebサービス, 33.3

X

XDBデータベース・スキーマ(ユーザー・アカウント), 2.1, 3.18.1, 3.18.7.1, 25.6, 26.2, 27.4, 36.6.1, 36.6.1

xdb名前空間, 27.3

XDB$ACL表, 27.4

xdb:columnProps属性, 7.9.3

xdb:defaultSchema属性, 7.3.7

xdb:defaultTable属性, 7.9.1, 7.9.3

xdb:defaultTableSchema属性, 7.9.3

xdb:maintainDOM属性, 7.6.2, 7.9.1, 7.9.3, 7.9.3

xdb:maintainOrder属性, 7.9.3

xdb:mapUnboundedStringToLob属性, 7.9.3

xdb:maxOccurs属性, 7.9.3

xdb:SQLCollSchema属性, 7.9.3

xdb:SQLCollType属性, 7.9.1, 7.9.3

xdb:SQLInline属性, 7.9.3, 9.3, 9.3

xdb:SQLName属性, 7.9.1, 7.9.3

xdb:SQLSchema属性, 7.9.3, 7.9.3

xdb:SQLType属性, 7.9.1, 7.9.3, 7.9.3, 9.7

xdb:srclang属性, 7.9.3

xdb:storeVarrayAsTable属性, 7.9.1, 7.9.3

xdb:tableProps属性, 7.9.3

xdb:translate属性, 7.9.3

XDB_SET_INVOKERロール, 30.5.1

XDBADMINロール, 7.5.2, 22.1, 27.4.1, 27.4.1, 30.5

XDBBinary要素, 21.4.1.3

定義, 21.2.1

xdbconfig.xml構成ファイル, 34.4 xdbcoreパラメータ, 9.11.1 xdbcore-loadableunit-size構成パラメータ, 9.11, 25.5 xdbcore-xobmem-bound構成パラメータ, 9.11, 25.5 XDBUri, 20.3.1

定義, 20.3, 20.5

XDBURIType

定義, 20.3

コンストラクタを使用した複合ドキュメントの展開(XInclude), 23.5.1, 23.5.1

XInclude, 23, 23

定義, 23.1

未解決リンク, 23.7.1

XLink, 23, 23

複合的なリンク

定義, 23.2.2

定義, 23.1 拡張リンク

定義, 23.2.2

リンク・タイプ, 23.2.2 単純リンク

定義, 23.2.2

サード・パーティのリンク

定義, 23.2.2

未解決リンク, 23.7.1 XML属性

「属性」を参照

XML診断能力モード, 5.10.4 XMLエンティティ

バイナリXML記憶域を使用したDTDの使用, 7.2

XMLフラグメント

定義, 3.11.6

LOBへのマッピング, 9.7

SQL操作, 3.11.6

XMLインスタンス・ドキュメント

定義, 1.3.2

XMLオブジェクト(XOB), 2.4.2 XML問合せのリライト

定義, 5.10

コストベース, 5.10.1

ルールベース, 5.10.1

XML Schema

注釈, 3.7.3, 7.9

取得のための問合せ, 7.10

循環依存, 9.9 complexTypeの宣言, 9.8.1, 9.9.2 循環依存, 9.9 定義, 1.3.2, 7.1 削除, 7.3.13 拡張, 10

下位互換性, 定義, 10.3.1

登録可能なXML Schema, 7.3.5 オブジェクト・リレーショナル型からの生成, 9.1 継承, complexTypeの制限, 9.8.1 ローカルおよびグローバル, 7.5 管理および格納, 7.3.5 SQLオブジェクト型へのマッピング, 13.2.5 Oracle XML DBを使用した登録, 7.3.1

JCRで使用, 31.4.1

登録後に更新, 10 URL, 9.6 使用, JCRで, 31.4 Oracle XML DBの使用, 7.2 W3C勧告, 3.6, 7 XMLTypeメソッド, 7.4 XMLスキーマ

定義, はじめに

XML Schemaデータ型

JCRノード型へのマッピング, 31.4.3

SQLデータ型へのマッピング, 7.12

XML Schema定義

定義, 1.3.2

XML Schemaの拡張

コピーに基づく, 10.2

インプレース, 10.3

XML Schemaに基づく表および列, 作成, 7.8 XML Schemaに基づくビュー

定義, 19.1

XML_DB_EVENTSパラメータ, 30.5 XMLAgg SQL関数, 18.2.4 XMLAttributes SQL関数, 18.2.1 XMLCast SQL関数, 4.1.2.2 XMLCDATA SQL関数, 18.2.11 XMLColAttVal SQL関数, 18.2.10 XMLComment SQL関数, 18.2.6 XMLConcat SQL関数, 18.2.3 XMLElement SQL関数, 18.2.1 XMLExists SQL関数, 4.1.2.1 XMLEXTRAオブジェクト列, 9.9.2.1 XMLForest SQL関数, 18.2.2 XMLFormat

XMLAgg, 18.2.4, 18.5

XMLFormatオブジェクト型

sys_XMLGen

XMLFormatTypeオブジェクト, 18.4.2

XMLGenFormatTypeオブジェクト, 18.4.2 XMLIndex

索引の作成, 6.4.5

索引の削除, 6.4.5

順序索引

定義, 6.4.4

パス索引

定義, 6.4.4

パス表, 6.4.4 索引の名前変更, 6.4.5 構造化コンポーネント

定義, 6.4.2

非構造化コンポーネント

定義, 6.4.2

値索引

定義, 6.4.4

XMLIsValid SQL関数, 3.9.1.2.1, 11.3 XMLOptimizationCheck SQL*Plus設定, 5.10.4 XMLOptimizationCheck SQL*Plusシステム変数, はじめに, 5.10.4 XMLParse SQL関数, 18.2.8 XMLPI SQL関数, 18.2.5 XMLQuery SQL関数, 5.3, 5.3.1 XMLRoot SQL関数, 18.2.9 XMLSequence Oracle SQL関数(非推奨), はじめに XMLSerialize SQL関数, 18.2.7 XMLTable SQL関数, 5.3, 5.3.2

XMLフラグメントの分割, 3.11.6

複数レベルのXMLデータの分割, 3.12.2

PASSING句およびFROMリストの順序, 5.9.4

XMLtransform SQL関数, 11.1.1 XMLType

抽象データ型として, 1.3.3

メリット, 3.1.2

コンストラクタ, 3.4.1

contains SQL関数, 6.2.2

CREATE TABLE文, 7.8.1.2

DBMS_XMLDOM PL/SQL API, 13.2

DBMS_XMLPARSER PL/SQL API, 13.3

DBMS_XSLPROCESSOR PL/SQL API, 13.4

定義, 1.3.1

データの抽出, 4.1.3

列の索引付け, 6.2

インスタンス, PL/SQL API, 13.1

データのロード, 35.1

SQL*Loaderを使用したロード, 35.2

メソッド

createXML(), 13.1.1.3, 15.2.1

getCLOB(), 15.3

getNumberVal(), 4.1.1

getObject(), 15.2.1.2

getOPAQUE(), 15.2.1.2

getSchemaURL(), 7.4

insertXML(), 15.3

isSchemaBased(), 7.4

isSchemaValid(), 7.4

IsSchemaValid(), 11.3

isSchemaValidated(), 7.4, 11.3

schemaValidate(), 7.4

setObject(), 15.2.2

setSchemaValidated(), 7.4, 11.3

writeToStream(), 21.4.1.5

XML Schema, 7.4

PL/SQLパッケージ, 13.1 問合せ, 4.1 一時データの問合せ, 4.1.3 XMLType列の問合せ, 4.1.3 キュー・ペイロード, 37.5.1 記憶域モデル, 1.3.3 表, JDBCを使用した問合せ, 15.2.1.2 表, ビュー, 列, 7.8 ビュー, PL/SQL DOM APIを使用したアクセス, 13.2.6 XOB, 2.4.2 XPath言語

関数

ora:contains(Oracle), 5.7.1, 12.5

構文, 4.1.1 「XQuery言語」も参照 XPathリライト, 8, 8

定義, 5.10

単一の要素および属性の索引, 6.3.1

表外に格納, 9.3.1

XQuery

拡張式, 5.8

プラグマ

Oracle, 5.8

プラグマ, Oracle

ora:use_text_index, 12.5.5.2

XQUERYコマンド, SQL*Plus, 5.12 XQuery関数および演算子

サポート, 5.14.2

XQuery言語, 5

式, 5.2.2

FLWOR, 5.2.3

リライト, 5.10

関数

ora:contains(Oracle), 5.7.1, 12.5

ora:matches(Oracle), 5.7.2

ora:replace(Oracle), 5.7.3

ora:sqrt(Oracle), 5.7.4

ora:tokenize(Oracle), 5.7.5

項目

定義, 5.2.1

名前空間, 5.5, 5.9.5 最適化, 5.10 リレーショナル・データに関する最適化, 5.10.2 Oracle拡張関数, 5.7 Oracle XML DBのサポート, 5.14 パフォーマンス, 5.10 事前定義の名前空間および接頭辞, 5.5 参照透過性

定義, 5.2.1

順序

定義, 5.2.1

SQL*Plus XQUERYコマンド, 5.12 チューニング, 5.10 型チェック, 静的および動的, 5.11 順序付けられていないモード

定義, 5.2.1

Oracle XML DBリポジトリの使用, 5.9.2 XMLTypeリレーショナル・データの使用, 5.9.4

最適化, 5.10.3

XMLQueryおよびXMLTable SQL関数, 5.3

例, 5.9

XSD

定義, 1.3.2

xsi:noNamespaceSchemaLocation属性, 7.1, 19.3.1.1 XSLスタイルシート

定義, 13.4

XSLT

スタイルシート

XMLインスタンス・ドキュメントの更新用, 10.2.5

DBUriサーブレットの使用, 3.19.1, 3.20

Oracle XML DBの使用, 3.17

DBMS_XSLPROCESSORパッケージの使用, 13.4.3

オラクル社の法律上の注意点について

コピーライトについて

Copyright © 1994-2014, Oracle and/or its affiliates.All rights reserved.

商標と登録商標について

OracleおよびJavaはOracle Corporationおよびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

ライセンス制約の保証と結果的に生じる損害の免責

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

保証免責

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

制限付権利

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs.No other rights are granted to the U.S. Government.

危険な用途への使用について

このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション（人的傷害を発生させる可能性があるアプリケーションを含む）への用途を目的として開発されていません。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性（redundancy）、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

第三者のコンテンツ、製品、サービスに対する免責事項

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても一切の責任を負いかねます。

ドラフトのアルファ版およびベータ版ドキュメントについて

このドキュメントが試作版の場合:

このドキュメントは試作版であり、デモおよび暫定使用のみを目的としたものです。このソフトウェアを使用するハードウェアに限定するものではありません。オラクル社およびその関連会社は、このドキュメントに関して一切の責任を負わず、いかなる保証もいたしません。また、このドキュメントを使用したことによって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。