Oracle® XML DB

開発者ガイド

12cリリース1 (12.1)

B71282-04(原本部品番号:E41152-15)

2016年12月

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

Oracle XML DB開発者ガイド, 12cリリース1 (12.1)

B71282-04

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

原本著者:  Drew Adams

原本協力者: Oracle XML DBの開発、製品管理および品質保証チーム

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

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

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

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 Corporationとの間の契約に別段の定めがある場合を除いて、Oracle Corporationおよびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。適用されるお客様とOracle Corporationとの間の契約に定めがある場合を除いて、Oracle Corporationおよびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても一切の責任を負いかねます。

目次

例一覧

図一覧

表一覧

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

はじめに

- 対象読者

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

- 関連ドキュメント

- 表記規則

- コード例

- 標準データベース・スキーマ

- XMLデータのフォーマット出力

- 実行計画

- 大/小文字の区別に関する注意

- 構文の説明

『Oracle XML DB開発者ガイド』の今回のリリースにおける変更点

- Oracle Database 12cリリース1 (12.1.0.2)でのOracle Databaseの変更

- 新機能

- JSONのサポート

- レルム構成のためのPL/SQLサブプログラム

- Oracle Database 12cリリース1 (12.1.0.1)でのOracle XML DBの変更

- 新機能

- Oracle XML DBは必須(削除不可)

- XQuery Updateのサポート

- XQuery Full Textのサポート

- 新しいXQuery拡張式プラグマ

- レプリケーションおよびローリング・アップグレードのサポート

- Oracle GoldenGateおよびOracle Data Guard SQL ApplyによるXMLTypeのサポート

- ローリング・アップグレードでOracle XML DBリポジトリをサポート

- XMLTypeに対するパラレルDMLのサポート

- XMLIndexの改善

- XMLIndex索引の同期化の向上

- XMLIndexのハッシュ・パーティション化のサポート

- PL/SQLパッケージDBMS_XDBの分割

- Digestアクセス認証によるリポジトリへのアクセス

- DBFSのサポート

- XQuery API for Java (XQJ)のサポート

- 非推奨となった機能

- サポート対象外機能

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

- 非推奨となった機能

- その他の変更

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

- 新機能

- XMLTypeのデフォルト記憶域モデル

- バイナリXMLのデフォルトLOB記憶域

- リポジトリの問合せパフォーマンスを高めるXQueryプラグマora:defaultTable

- XML診断能力モード: SQL*Plusのシステム変数XMLOptimizationCheck

- 非推奨となった機能

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

- 新機能

- XMLType表および列のパーティション化

- アクセス制御の拡張

- リポジトリの読取りおよび書込みパフォーマンスの拡張

- バイナリXMLのパフォーマンス拡張およびパーティション化

- XMLIndexの機能強化

- コストベースのXPathリライト

- オブジェクト・リレーショナル記憶域の新しいデフォルトの型マッピング

- 非推奨となった機能

- Oracle Database 11gリリース1 (11.1)でのOracle XML DBの変更

- 新機能

- バイナリXML

- XMLIndex

- XMLType OCTでのIOTに代わるヒープ記憶域の使用

- XML Schema注釈xdb:storeVarrayAsTableのデフォルト値をtrueに変更

- リポジトリのイベント

- Content Repository API for Javaのサポート(JCR: JSR-170)

- リポジトリ・リソースの新しいリンク・タイプ

- WebDAV権限と新規Oracle XML DB権限のサポート

- Webサービス

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

- 再帰的なXML Schemaのサポート

- XLinkおよびXIncludeのサポート

- XML変換のサポート

- 大規模なXMLノードのサポート

- 統合Java API

- Oracle Data PumpによるXMLTypeサポート

- Oracle Streamsおよびロジカル・スタンバイによるXMLTypeのサポート

- Oracle XML Developer's Kit Pull-Parser API(XMLイベント、JSR-173)

- XQueryの標準準拠

- PL/SQLを使用した、ネットワーク・サービスへのファイングレイン・アクセス

- SQL/XML標準準拠とパフォーマンスの拡張

- XML-Updateのパフォーマンス拡張

- XQueryおよびSQL/XMLパフォーマンスの拡張

- XSLTパフォーマンス拡張機能

第I部 Oracle XML DBの基礎

1 Oracle XML DBの概要

- 1.1 Oracle XML DBの概要

- 1.2 Oracle XML DBのメリット

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

- 1.2.1.1 XML操作のためのデータベース機能

- 1.2.1.2 データベースでデータをXMLとして格納する場合のメリット

- 1.2.2 データの双対性: XMLおよびリレーショナル

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

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

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

- 1.4 Oracle XML DBの機能

- 1.4.1 XMLTypeデータ型

- 1.4.2 XMLType記憶域モデル

- 1.4.3 XML Schemaのサポート

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

- 1.4.5 XMLに関連する静的データ・ディクショナリ・ビュー

- 1.4.6 SQL/XML標準関数

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

- 1.4.8 Oracle XML DBリポジトリ: 概要

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

- 1.6 Oracle XML DBの技術サポート

- 1.7 Oracle XML DBの例

- 1.8 OTNでのOracle XML DBの事例およびデモ

2 Oracle XML DBを使用する前に

- 2.1 Oracle XML DBのインストール

- 2.2 Oracle XML DBのユースケース

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

- 2.3.1 XMLデータ記憶域

- 2.3.2 XMLデータの構造

- 2.3.3 アプリケーションの実装に使用する言語

- 2.3.4 XMLの処理オプション

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

- 2.3.6 Oracle XML DBとその他のデータベース・オプションおよび機能との連携

3 Oracle XML DBの使用方法の概要

- 3.1 XMLType表および列の作成

- 3.2 バイナリXMLとして格納されたXMLTypeデータでの仮想列の作成

- 3.3 バイナリXMLとして格納されたXMLTypeデータが含まれる表のパーティション化

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

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

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

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

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

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

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

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

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

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

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

- 3.6.1 例で使用されているXML文書PurchaseOrder

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

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

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

- 3.6.5 XMLEXISTS、XMLCASTおよびXMLQUERYを使用したXML文書の検索

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

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

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

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

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

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

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

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

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

第II部 Oracle XML DBでのXMLデータの操作

4 XQueryとOracle XML DB

- 4.1 XQuery言語の概要

- 4.1.1 XQuery式に含まれるXPath式

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

- 4.1.2.1 XQueryとシーケンス

- 4.1.2.2 参照が透過的なXQuery

- 4.1.2.3 データに対するXQuery Updateの副次的な影響

- 4.1.2.4 XQuery Updateのスナップショット

- 4.1.2.4.1 スナップショット・セマンティクスを使用しないOracle XML Update関数(非推奨)

- 4.1.2.5 XQuery Full Textの全文検索機能

- 4.1.3 XQuery式

- 4.1.4 FLWOR式

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

- 4.2.1 XQueryの用途

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

- 4.3 SQL/XML関数XMLQUERY、XMLTABLE、XMLExistsおよびXMLCast

- 4.3.1 Oracle XML DBのXMLQUERY SQL/XML関数

- 4.3.2 Oracle XML DBのXMLTABLE SQL/XML関数

- 4.3.2.1 SQL/XML関数XMLTABLEのコールのチェーン

- 4.3.3 Oracle XML DBのXMLEXISTS SQL/XML関数

- 4.3.4 ノードを検索するためのXMLExistsの使用

- 4.3.5 Oracle XML DBのXMLCAST SQL/XML関数

- 4.3.6 XMLフラグメントのスカラー値を抽出するためのXMLCASTの使用

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

- 4.5 Oracle XQuery拡張関数

- 4.5.1 ora:contains XQuery関数

- 4.5.2 ora:sqrt XQuery関数

- 4.5.3 ora:tokenize XQuery関数

- 4.5.4 ora:matches XQuery関数(非推奨)

- 4.5.5 ora:replace XQuery関数(非推奨)

- 4.6 Oracle XQuery拡張式プラグマ

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

- 4.8 Oracle XML DBでのXQueryサポート

- 4.8.1 XQueryとSQLのサポート

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

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

- 4.8.1.3 XQueryのオプション機能

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

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

- 4.8.3 XQuery Full Textのサポート

- 4.8.3.1 XQuery Full Text、XML Schemaに基づくデータ、およびプラグマora:no_schema

- 4.8.3.2 XMLExistsでのXQuery Full Textの使用制限

- 4.8.3.3 サポートされているXQuery Full TextのFTSelection演算子

- 4.8.3.4 サポートされているXQuery Full TextのMatchオプション

- 4.8.3.5 サポート対象外のXQuery Full Text機能

- 4.8.3.6 XQuery Full Textのエラー

5 XMLデータの問合せと更新

- 5.1 Oracle XML DBでのXQueryの使用

- 5.1.1 XQueryシーケンスには任意のXQuery型のデータを含めることが可能

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

- 5.1.3 XQueryとURIスキームoradbを使用したリレーショナル・データの問合せ

- 5.1.4 XQueryを使用したXMLTypeデータの問合せ

- 5.1.5 XQueryでの名前空間の使用

- 5.2 SQLおよびPL/SQLを使用したXMLデータの問合せ

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

- 5.4 XQueryとXQJを使用したデータベース・データへのアクセス

- 5.5 XQueryをPL/SQL、JDBCおよびODP.NETとともに使用したデータベース・データへのアクセス

- 5.6 XMLデータの更新

- 5.6.1 XML文書全体の更新

- 5.6.2 XMLノードの置換

- 5.6.2.1 XMLデータのNULL値への更新

- 5.6.3 XML子ノードの挿入

- 5.6.4 XMLノードの削除

- 5.6.5 変更されたXMLデータのXMLビューの作成

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

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

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

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

- 5.7.4 XQueryの最適化の診断: XMLOptimizationCheck

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

- 5.7.5.1 fn:docとfn:collectionにかわるEQUALS_PATHおよびUNDER_PATHの使用

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

6 XMLTypeデータの索引

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

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

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

- 6.2.2 XMLデータのためのOracle Text索引

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

- 6.2.4 XMLTypeに対するファンクション索引の非推奨化

- 6.3 XMLIndex

- 6.3.1 XMLIndexの利点

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

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

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

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

- 6.3.3.3 パーティション交換とXMLIndex

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

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

- 6.3.4.2 XMLIndexパス表のVALUE列

- 6.3.4.3 VALUE列に対する2次索引

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

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

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

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

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

- 6.3.7.1 XMLIndex構造化コンポーネントでの名前空間とStorage句の使用

- 6.3.7.2 XMLIndex索引への構造化コンポーネントの追加

- 6.3.7.3 XMLIndex構造化コンポーネントでの非ブロック・モードによるALTER INDEXの使用

- 6.3.7.4 構造化XMLIndexコンポーネントのデータ型の変更

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

- 6.3.7.6 構造化XMLIndexコンポーネントのリレーショナル表への索引付け

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

- 6.3.9 XMLIndexの使用の無効化

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

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

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

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

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

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

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

- 6.3.14.1 エラーORA-08181が発生した場合のXMLIndex索引の同期化

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

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

- 6.3.17 CREATE INDEXおよびALTER INDEXのPARAMETERS句

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

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

- 6.3.17.3 XMLIndex_parameters_clauseの使用

- 6.3.17.4 XMLIndex_parameterの使用

- 6.3.17.5 PATHS句の使用

- 6.3.17.6 create_index_paths_clauseおよびalter_index_paths_clauseの使用

- 6.3.17.7 pikey_clause、path_id_clauseおよびorder_key_clauseの使用

- 6.3.17.8 value_clauseの使用

- 6.3.17.9 async_clauseの使用

- 6.3.17.10 groups_clauseおよびalter_index_group_clauseの使用

- 6.3.17.11 XMLIndex_xmltable_clauseの使用

- 6.3.17.12 column_clauseの使用

- 6.4 全文問合せ用のXMLデータの索引付け

- 6.4.1 XML検索索引の作成と使用

- 6.4.2 XML検索索引を取得できない場合の対処方法

- 6.4.3 プラグマora:no_schema: XQuery Full TextでのXML Schemaに基づくデータの使用

- 6.4.4 プラグマora:use_xmltext_idx: XML検索索引の強制的な使用

- 6.4.5 Oracle Text索引の使用からXML検索索引への移行

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

- 6.5.1 繰り返し使用しないテキスト・ノードまたは属性値の索引付け

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

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

- 7.1 XSL変換とOracle XML DB

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

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

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

- 7.2 XMLTypeインスタンスの検証

- 7.2.1 XML Schemaの部分検証と全体検証

- 7.2.1.1 部分検証

- 7.2.1.2 全体検証

- 7.2.1.2.1 XML Schemaの全体検証による処理時間とメモリーの消費

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

第III部 XMLデータに対するリレーショナル・データ

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

- 8.1 XMLデータの生成の概要

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

- 8.2.1 XMLELEMENTおよびXMLATTRIBUTES SQL/XML関数

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

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

- 8.2.1.3 XMLElementの例

- 8.2.2 XMLFOREST SQL/XML関数

- 8.2.3 XMLCONCAT SQL/XML関数

- 8.2.4 XMLAGG SQL/XML関数

- 8.2.5 XMLPI SQL/XML関数

- 8.2.6 XMLCOMMENT SQL/XML関数

- 8.2.7 XMLSERIALIZE SQL/XML関数

- 8.2.8 XMLPARSE SQL/XML関数

- 8.2.9 XMLROOT Oracle SQL関数

- 8.2.10 XMLCOLATTVAL Oracle SQL関数

- 8.2.11 XMLCDATA Oracle SQL関数

- 8.3 DBMS_XMLGENを使用したXMLデータの生成

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

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

- 8.3.3 DBMS_XMLGENの例

- 8.4 SYS_XMLAGG Oracle SQL関数

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

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

9 XMLデータのリレーショナル・ビュー

- 9.1 XMLデータのリレーショナル・ビューの作成および使用の概要

- 9.2 XMLのリレーショナル・ビューの作成: XML文書ごとに1行

- 9.3 XMLのリレーショナル・ビューの作成: XMLノードの列へのマップ

- 9.4 リレーショナル・ビューを使用して公開されたバイナリXMLデータの索引付け

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

10 XMLTypeビュー

- 10.1 XMLTypeビューの概要

- 10.2 XMLTypeビューのCREATE VIEW: 構文

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

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

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

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

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

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

- 10.4.2.1.1 手順1: XMLType従業員ビューに対応するオブジェクト型の作成

- 10.4.2.1.2 手順2: XML Schema emp_complex.xsdの作成および登録

- 10.4.2.1.3 手順3a: オブジェクト型emp_tを使用したXMLTypeビューemp_xmlの作成

- 10.4.2.1.4 手順3b: オブジェクト・ビューemp_vを使用したXMLTypeビューemp_xmlの作成

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

- 10.4.2.2.1 手順1: XMLType部門ビューに対応するオブジェクト型の作成

- 10.4.2.2.2 手順2: XML Schema dept_complex.xsdの登録

- 10.4.2.2.3 手順3a: オブジェクト型dept_tを使用したXMLTypeビューdept_xmlの作成

- 10.4.2.2.4 手順3b: リレーショナル・データを直接使用したXMLTypeビューdept_xmlの作成

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

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

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

第IV部 XMLType API

11 PL/SQL API for XMLType

- 11.1 Overview of PL/SQL API for XMLTypeの概要

- 11.1.1 PL/SQL API for XMLType: 機能

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

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

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

- 11.1.2 PL/SQL API for XMLType: リファレンス

- 11.2 PL/SQL DOM API for XMLType (DBMS_XMLDOM)

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

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

- 11.2.1.2 W3CのDOM勧告のサポート

- 11.2.1.3 DOMとSAXの違い

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

- 11.2.2.1 XML Schemaのサポート

- 11.2.2.2 DOMのパフォーマンスの向上

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

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

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

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

- 11.2.6 XMLTypeビューによる既存データのXMLとしてのラップ

- 11.2.7 Oracle XML DBによってサポートされるDBMS_XMLDOMメソッド

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

- 11.2.9 PL/SQL関数NEWDOMDOCUMENTおよびDOMDOCUMENTのノード

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

- 11.2.11 PL/SQL DOM API for XMLType (DBMS_XMLDOM)の使用方法の概要

- 11.2.12 PL/SQL DOM API for XMLType - 例

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

- 11.2.14 大規模ノード処理のGet-Pushモデル

- 11.2.15 大規模ノード処理のGet-Pullモデル

- 11.2.16 大規模ノード処理のSet-Pullモデル

- 11.2.17 大規模ノード処理のSet-Pushモデル

- 11.2.18 大規模ノード処理のバイナリ・ストリームか文字ストリームかの判断

- 11.3 PL/SQL Parser API for XMLType(DBMS_XMLPARSER)

- 11.4 PL/SQL XSLT Processor for XMLType(DBMS_XSLPROCESSOR)

- 11.4.1 PL/SQL XSLT Processor for XMLType: 機能

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

12 PL/SQLパッケージDBMS_XMLSTORE

- 12.1 DBMS_XMLSTOREパッケージの使用

- 12.2 DBMS_XMLSTOREを使用したXML文書の挿入

- 12.3 DBMS_XMLSTOREを使用したXMLデータの更新

- 12.4 DBMS_XMLSTOREを使用したXMLデータの削除

13 Java DOM API for XMLType

- 13.1 Java DOM API for XMLTypeの概要

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

- 13.2.1 JDBCを使用したOracle XML DB内のXML文書へのアクセス

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

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

- 13.5 Java DOM API for XMLTypeの機能

- 13.6 Thick接続を使用したJava DOM APIに対するMS Windows Javaセキュリティ・マネージャの権限

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

- 13.8 Java (JDBCまたはSQLJ)でのXMLTypeインスタンス表現

- 13.9 Java DOM API for XMLTypeのクラス

- 13.10 非推奨またはサポート外になったXMLTypeのクラスとメソッドのJava DOM API

- 13.11 Java DOM API for XMLTypeの使用

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

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

- 13.12.1.1 Get-Pullモデル

- 13.12.1.2 Get-Pushモデル

- 13.12.1.3 Set-Pullモデル

- 13.12.1.4 Set-Pushモデル

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

14 C API for XML

- 14.1 C API for XMLの概要

- 14.2 OCIを使用したデータベースに格納されているXMLTypeデータへのアクセス

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

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

- 14.4.1 OCIXmlDbInitXmlCtx()の構文

- 14.4.2 OCIXmlDbFreeXmlCtx()の構文

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

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

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

- 14.8 Cでの一般的なXMLType操作

15 Oracle XML DBおよびOracle Data Provider for .NET

- 15.1 Oracle XML DBとODP.NET XML

- 15.2 ODP.NETとのXMLTypeデータの使用

第V部 XML Schemaとオブジェクト・リレーショナルXMLType

16 XMLType記憶域および索引付けの選択

- 16.1 XMLType記憶域モデルと索引付けの方法の選択に関する概要

- 16.2 XMLTypeのユースケースの範囲: データ中心からドキュメント中心

- 16.3 XMLTypeとして格納されるXMLデータの一般的なユースケース

- 16.3.1 XMLTypeのユースケース: XMLフラグメントの更新または問合せがない

- 16.3.2 XMLTypeのユースケース: 異なるXML Schemaを持つ多様なソースからのデータ統合

- 16.3.3 XMLTypeのユースケース: ETLのステージを経たXMLデータ

- 16.3.4 XMLTypeのユースケース: 半構造化XMLデータ

- 16.3.5 XMLTypeのユースケース: ビジネス・インテリジェンス問合せ

- 16.3.6 XMLTypeのユースケース: 全文検索を伴うXML問合せ

- 16.4 XMLType記憶域モデルについての考慮事項

- 16.5 XMLTypeの索引付けについての考慮事項

- 16.6 XMLType記憶域オプション: 相対的なメリット

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

- 17.1 XML Schemaの概要

- 17.1.1 XML Schema for Schemas

- 17.1.2 XML Schemaの機能

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

- 17.1.4 XML名前空間とXML Schema

- 17.1.5 XML Schemaの編集の概要

- 17.2 Oracle XML DBにおけるXML Schemaの使用方法の概要

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

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

- 17.2.3 DOM再現性

- 17.2.4 XMLTypeのXML Schema関連メソッド

- 17.3 Oracle XML DBへのXML Schemaの登録

- 17.3.1 XML Schemaの登録操作

- 17.3.2 Oracle XML DBへのXML Schemaの登録

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

- 17.3.4 グローバル要素のデフォルト表

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

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

- 17.3.6.1 ローカルXML Schema

- 17.3.6.2 グローバルXML Schema

- 17.3.7 完全修飾されたXML Schema URL

- 17.3.8 XML Schemaの削除

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

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

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

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

- 17.4.1.2 XML Schemaに基づくデータのオブジェクト・リレーショナル記憶域

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

- 17.5.1 属性noNamespaceSchemaLocationおよびschemaLocation

- 17.5.2 XML Schemaおよび複数の名前空間

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

18 XML Schemaの格納と問合せ: オブジェクト・リレーショナル記憶域

- 18.1 XML文書のオブジェクト・リレーショナル記憶域

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

- 18.1.2 オブジェクト・リレーショナル記憶域に対してXML Schema登録時に作成されるSQL型

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

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

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

- 18.1.6 SYS_XDBPD$とオブジェクト・リレーショナル記憶域のDOM再現性

- 18.2 OracleでのXML Schemaの注釈

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

- 18.2.2 XML Schema注釈の例

- 18.2.3 DBMS_XMLSCHEMA_ANNOTATEを使用したXML Schemaの注釈付け

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

- 18.2.5 オブジェクト・リレーショナル記憶域に対するXML Schema注釈のガイドライン

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

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

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

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

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

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

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

- 18.2.6.1 あるXML Schemaから別のXML Schemaに適用可能な注釈

- 18.3 DBMS_XMLSCHEMAを使用したXML Schemaデータ型のSQLデータ型へのマッピング

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

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

- 18.3.2.1 属性を宣言する際に実行できるXML Schema内のSQLType値のオーバーライド

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

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

- 18.3.4 XML Schema simpleTypeのSQLへのマッピング

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

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

- 18.3.4.3 XML SchemaのタイムゾーンのSQLへのマッピング方法

- 18.3.4.3.1 値の最後にZを使用したUTCタイムゾーンの指定

- 18.3.5 XML Schema complexTypeのSQLへのマッピング

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

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

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

- 18.4.2 simpleContentに基づくcomplexTypeのオブジェクト型へのマッピング

- 18.4.3 anyおよびanyAttribute宣言のオブジェクト型属性へのマッピング

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

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

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

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

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

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

- 18.8 XMLTypeデータの表外記憶域

- 18.8.1 表外に格納するための注釈属性xdb:SQLInlineのfalse設定

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

- 18.9 複雑または大規模なXML Schemaの操作の考慮事項

- 18.9.1 XML Schema間での循環依存

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

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

- 18.9.1.3 XML Schema間での循環参照

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

- 18.9.2.1 一般的な表外の要素間で共有されるdefaultTable

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

- 18.9.2.3 DOCID列の作成の無効化

- 18.9.3 ラージ・オブジェクト(LOB)にマップできるXMLフラグメント

- 18.9.4 ORA-01792およびORA-04031: 大規模XML Schemaに関する問題

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

- 18.9.5.1 構成パラメータxdbcore-loadableunit-sizeおよびxdbcore-xobmem-boundのガイドライン

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

19 オブジェクト・リレーショナル記憶域のXPathリライト

- 19.1 オブジェクト・リレーショナル記憶域のXPathリライトの概要

- 19.2 リライトされる一般的なXPath式

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

- 19.4 XPath問合せを解析および最適化する実行計画を使用する場合のガイドライン

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

- 19.4.2 ガイドライン: 実行計画で認識するためのオブジェクト・リレーショナル表の名前付け

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

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

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

20 XML Schemaの拡張

- 20.1 XML Schemaの拡張の概要

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

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

- 20.2.2 COPYEVOLVEパラメータおよびエラー

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

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

- 20.2.4.1 最上位要素名の変更

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

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

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

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

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

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

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

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

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

- 20.3.1.1 下位互換性の制約

- 20.3.1.1.1 ディスク上のデータ・レイアウトの変更

- 20.3.1.1.2 XML Schema構造体の再順序付け

- 20.3.1.1.3 コレクションから非コレクションへの変更

- 20.3.1.1.4 複合型要素内のモデルの変更

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

- 20.3.1.2.1 xdb名前空間の属性の変更

- 20.3.1.2.2 非コレクションからコレクションへの変更

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

- 20.3.3 インプレースXMLスキーマの進化の使用に関するガイドライン

- 20.3.4 inPlaceEvolveパラメータ

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

- 20.3.5.1 diffXMLの操作と例

第VI部 Oracle XML DBリポジトリ

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

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

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

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

- 21.1.3 データベース・スキーマ(ユーザー・アカウント) XDBおよびOracle XML DBリポジトリ

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

- 21.2.1 リポジトリの用語

- 21.2.2 事前定義されたリポジトリのファイルおよびフォルダ

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

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

- 21.3.1.1 生成された表の名前

- 21.3.1.2 リポジトリ・リソース用のオブジェクト・リレーショナル記憶域の定義方法

- 21.3.1.3 Oracle ASM仮想フォルダ

- 21.3.2 Oracle XML DBリポジトリへの文書の格納方法

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

- 21.3.4 リポジトリのパス名の解決

- 21.3.5 リンク・タイプ

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

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

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

- 21.3.5.4 複数のハード・リンクを回避する方法およびタイミング

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

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

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

- 21.4.1.2 Oracle XML DBへのプロトコル・アクセスの概要

- 21.4.1.3 Oracle XML DBリソースの取得

- 21.4.1.4 Oracle XML DBリソースの格納

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

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

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

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

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

- 21.8 SQLを使用したリポジトリ・リソースのコンテンツへのアクセス

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

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

- 21.10 リポジトリの文書のコンテンツの更新

- 21.10.1 インターネット・プロトコルを使用したリポジトリのコンテンツの更新

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

- 21.10.2.1 リソース・ドキュメントの更新によるリポジトリ内の文書の更新

- 21.10.2.2 デフォルト表の更新によるリポジトリ内のXML Schemaに基づく文書の更新

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

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

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

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

- 22.2 リソースの構成

- 22.3 共通の構成パラメータ

- 22.3.1 構成要素ResConfig

- 22.3.2 構成要素defaultChildConfigおよびconfiguration

- 22.3.3 構成要素applicationData

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

- 23.1 XLinkおよびXIncludeの概要

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

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

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

- 23.3 XInclude: 複合ドキュメント

- 23.4 Oracle XML DBのXLinkサポート

- 23.5 Oracle XML DBのXIncludeサポート

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

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

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

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

- 23.6 DOCUMENT_LINKSビューを使用したXLinkリンクおよびXIncludeリンクの調査

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

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

- 23.7 XLinkおよびXIncludeのリポジトリ・リソースの構成

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

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

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

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

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

- 23.7.6 XLinkおよびXIncludeの構成例

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

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

- 24.1 Oracle XML DBのRESOURCE_VIEWとPATH_VIEWの概要

- 24.1.1 RESOURCE_VIEWの定義および構造

- 24.1.2 PATH_VIEWの定義および構造

- 24.1.3 RESOURCE_VIEWとPATH_VIEWとの違い

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

- 24.2 RESOURCE_VIEWおよびPATH_VIEWを使用するOracle SQL関数

- 24.2.1 UNDER_PATH SQL関数

- 24.2.2 EQUALS_PATH SQL関数

- 24.2.3 PATH SQL関数

- 24.2.4 DEPTH SQL関数

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

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

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

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

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

- 24.7 Oracle XML DBリポジトリ操作のパフォーマンス・ガイドライン

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

25 リソース・バージョン

- 25.1 Oracle XML DBリポジトリ・リソースのバージョニングの概要

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

- 25.3 リソース・バージョンおよびリソースID

- 25.4 リソース・バージョンおよびACL

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

26 Oracle XML DBリポジトリへのPL/SQLアクセス

- 26.1 DBMS_XDB_REPOS: リポジトリ・リソースのアクセスと管理

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

- 26.3 DBMS_XDB_CONFIG: 構成管理

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

- 27.1 アクセス制御の概念

- 27.1.1 認証と認可

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

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

- 27.1.2.2 プリンシパルDAV::owner

- 27.1.3 権限

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

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

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

- 27.3 権限

- 27.3.1 基本権限

- 27.3.2 集約権限

- 27.4 ACLおよびACE

- 27.4.1 システムACL

- 27.4.2 ACLおよびACEの評価

- 27.4.3 ACL検証

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

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

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

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

- 27.5.3 リソースのACLの設定

- 27.5.4 ACLの削除

- 27.5.5 ACLの更新

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

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

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

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

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

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

- 27.6 ACLキャッシング

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

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

- 27.8 Oracle XML DBのLDAPとの統合

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

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

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

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

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

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

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

- 28.2.2.2 TCPS Dispatcherの有効化

- 28.2.3 リスナー・ステータスを使用したポート構成の確認

- 28.2.4 データベース統合後のプロトコル・ポート・パラメータの構成

- 28.2.5 HTTPの認証メカニズムの構成および管理

- 28.2.5.1 Digest認証のnonce

- 28.2.6 Oracle XML DBリポジトリおよびファイルシステムのリソース

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

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

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

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

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

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

- 28.3.1.3 FTP Quoteメソッド

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

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

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

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

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

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

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

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

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

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

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

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

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

- 28.4.1.5 URL有効期限の制御

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

- 28.4.1.7 HTTP(S)によるJavaサーブレットの使用

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

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

- 28.4.1.10 URL内の非ASCII文字

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

- 28.4.1.11.1 HTTP(S)リクエストのキャラクタ・セット

- 28.4.1.11.2 HTTP(S)レスポンスのキャラクタ・セット

- 28.5 WebDAVとOracle XML DB

- 28.5.1 Oracle XML DB WebDAVの機能

- 28.5.1.1 Oracle XML DBによってサポートされないWebDAV機能

- 28.5.1.2 Oracle XML DBによってサポートされるWebDAVクライアント・メソッド

- 28.5.2 WebDAVとMicrosoft Windows XP SP2

- 28.5.3 Oracle XML DBリポジトリで使用するためのMicrosoft WindowsでのWebフォルダの作成

- 28.5.3.1 ファイルをOracle XML DBリポジトリにコピーする際のWindows ExplorerでのWebDAVの使用

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

- 29.1 メタデータとXMLの概要

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

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

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

- 29.2 XML Schemaを使用したリソース・メタデータの定義

- 29.3 リソース・メタデータの追加、変更および削除

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

- 30.5.1 構成要素event-listeners

- 30.5.2 構成要素listener

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

31 Oracle XML DB Content Connector

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

- 31.2 Oracle XML DB Content Connectorについて

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

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

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

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

- 31.3.4 JCRにマップされたシステム定義のメタデータ

- 31.3.5 JCRにマップされたユーザー定義のメタデータ

- 31.3.6 JCRとリポジトリのハード・リンクと弱いリンク

- 31.4 Oracle XML DB Content ConnectorのCLASSPATH

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

- 31.6 Oracle XML DB Content Connectorを使用してリポジトリにファイルをアップロードするためのJavaコード

- 31.7 追加のJCRコード例

- 31.8 Oracle XML DB Content Connectorでの標準JavaロギングAPIの使用

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

- 31.10 Oracle XML DB Content Connectorの制限

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

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

- 31.10.3 ファイルとフォルダの状態

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

- 31.10.5 変更の保存順

- 31.10.6 未定義のプロパティ

- 31.10.7 ノード型nt:baseは抽象

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

- 31.10.9 jcr:xmltextノードは保存時に結合される

- 31.10.10 ノード型mix:referenceable

- 31.10.11 JCRと併用するための全文索引

- 31.11 XML SchemaとJCR

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

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

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

- 31.11.3.1 JCRおよびXML Schemaの組込み単純型

- 31.11.3.2 JCRとXML Schemaで定義される単純型

- 31.11.3.3 JCRとXML Schemaで定義される複合型

- 31.11.3.4 JCRおよびグローバルXML要素宣言

32 JavaでのOracle XML DBアプリケーションのガイドライン

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

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

- 32.3 JDBC XMLTypeサポートを使用した多数のXMLTypeオブジェクト要素へのアクセス

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

- 32.5 Oracle XML DBのJavaサーブレットのサポートの制限

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

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

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

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

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

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

33 URIを使用したデータ・アクセス

- 33.1 Oracle XML DB URIの機能の概要

- 33.2 URIとURL

- 33.3 URITypeとそのサブタイプ

- 33.3.1 DBUriおよびXDBUriの概要

- 33.3.2 URIType PL/SQLメソッド

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

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

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

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

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

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

- 33.5.1 XDBUri URIの構文

- 33.5.2 XDBUriの使用: 例

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

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

- 33.6.2 DBUri URIの構文

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

- 33.6.4 DBUriの使用 - 例

- 33.6.4.1 DBUriを使用した表のターゲット化

- 33.6.4.2 DBUriを使用した表内の行のターゲット化

- 33.6.4.3 DBUriを使用した列のターゲット化

- 33.6.4.4 DBUriを使用した列のテキスト値の取得

- 33.6.4.5 DBUriを使用したコレクションのターゲット化

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

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

- 33.8 SYS_DBURIGEN SQL関数

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

- 33.8.2 SQL関数SYS_DBURIGENの使用: 例

- 33.8.2.1 SYS__DBURIGENを使用したデータベース参照の挿入

- 33.8.2.2 SYS__DBURIGENを使用して部分的な結果を戻す方法

- 33.8.2.3 SYS_DBURIGENを使用して挿入されたオブジェクトのURLを戻す方法

- 33.9 DBUriServlet

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

- 33.9.2 DBUriServletのカスタマイズ

- 33.9.3 DBUriServletセキュリティのロールの使用

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

- 33.9.5 DBUriサーブレットを使用した、Webブラウザからの表またはビューへのアクセス

34 ネイティブなOracle XML DB Webサービス

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

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

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

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

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

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

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

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

35 Oracle XML DBの管理

- 35.1 既存のOracle XML DBのインストールのアップグレードまたはダウングレード

- 35.1.1 データベースのインストール、アップグレードおよびダウングレードに関する認証の考慮事項

- 35.1.1.1 データベースのインストールに関する認証の考慮事項

- 35.1.1.2 データベースのアップグレードに関する認証の考慮事項

- 35.1.1.3 データベースのダウングレードに関する認証の考慮事項

- 35.1.2 Oracle XML DBの自動インストール

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

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

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

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

- 35.3.1.1 要素xdbconfig (最上位)

- 35.3.1.2 要素sysconfig (xdbconfigの子)

- 35.3.1.3 要素userconfig (xdbconfigの子)

- 35.3.1.4 要素protocolconfig (sysconfigの子)

- 35.3.1.5 要素httpconfig (protocolconfigの子)

- 35.3.1.6 要素servlet (httpconfigの子孫)

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

- 35.3.1.8 Oracle XML DB Configuration API

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

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

- 35.4 Oracle XML DBとデータベース統合

- 35.5 パッケージDBMS_XDB_ADMIN

36 XMLデータのロード方法

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

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

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

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

- 36.2.1.2 デリミタ付きフィールドを使用したLOBデータのロード

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

- 36.2.1.4 LOBFILEの指定

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

- 36.2.3 SQL*Loaderを使用した大規模なXML文書のロード

37 Oracle XML DBデータのエクスポートとインポート

- 37.1 XMLType表のエクスポートおよびインポートの概要

- 37.2 Oracle XML DBリポジトリのエクスポート/インポートの制限事項

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

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

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

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

- 38.1 XMLおよびOracle Streamsアドバンスト・キューイング

- 38.1.1 Oracle Streamsアドバンスト・キューイングおよびXMLメッセージ・ペイロード

- 38.1.2 Oracle Streamsアドバンスト・キューイングを使用するメリット

- 38.2 Oracle Streamsおよびアドバンスト・キューイング

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

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

- 38.4 Internet Data Access Presentation (iDAP): AQ用のSOAP

- 38.5 iDAPアーキテクチャ

- 38.5.1 XMLTypeキュー・ペイロード

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

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

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

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

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

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

- 38.6.6 AQでのHTTPSの使用

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

- 38.6.8 iDAPとSOAP

第VIII部 JSON

39 Oracle DatabaseのJSON

- 39.1 JSONの概要

- 39.1.1 JSON構文およびJSON構文が表すデータの概要

- 39.1.2 XMLと比較したJSONの概要

- 39.2 Oracle DatabaseにおけるJSONの概要

- 39.2.1 Oracle DatabaseでJSONを使用する前に

- 39.3 JSON: Oracle Databaseのキャラクタ・セットおよび文字エンコーディング

- 39.3.1 JSONデータ内のUnicode文字のエスケープ

- 39.4 Oracle JSONパス式の概要

- 39.4.1 Oracle JSONパス式の構文

- 39.4.1.1 Oracle JSONパス式の基本的な構文

- 39.4.1.2 Oracle JSONパス式の構文の緩和

- 39.5 JSONデータで使用するためのOracle SQL関数および条件

- 39.5.1 JSON用のOracle SQL関数および条件で使用される句

- 39.5.1.1 JSON用のOracle SQL関数のRETURNING句

- 39.5.1.2 Oracle SQL関数JSON_QUERYおよびJSON_TABLEのラッパー句

- 39.5.1.3 JSON用のOracle SQL関数および条件のエラー句

- 39.5.2 Oracle SQL条件IS JSONおよびIS NOT JSON

- 39.5.2.1 列にJSONデータが含まれることを確認するためのチェック制約の使用

- 39.5.2.2 列にJSONデータが必然的に含まれるかどうかの確認

- 39.5.2.3 JSONオブジェクトの一意フィールドと重複フィールド

- 39.5.2.4 厳密なJSON構文と緩慢なJSON構文について

- 39.5.2.5 厳密なOracle JSON構文と緩慢なOracle JSON構文の指定

- 39.5.3 Oracle SQL条件JSON_EXISTS

- 39.5.3.1 JSON_TABLEとしてのJSON_EXISTS

- 39.5.4 Oracle SQL関数JSON_VALUE

- 39.5.4.1 Oracle SQL関数JSON_VALUEとブール型のJSON値の使用

- 39.5.4.2 JSONのnull値に適用されるOracle SQL関数JSON_VALUE

- 39.5.4.3 JSON_TABLEとしてのJSON_VALUE

- 39.5.5 Oracle SQL関数JSON_QUERY

- 39.5.5.1 JSON_TABLEとしてのJSON_QUERY

- 39.5.6 Oracle SQL関数JSON_TABLE

- 39.5.6.1 JSON_TABLEによる他のOracle SQL関数の汎化

- 39.5.6.2 JSON_TABLEとJSON配列の使用

- 39.6 JSONデータに対する単純なドット表記法アクセス

- 39.7 JSONデータの索引

- 39.7.1 JSONデータに対して関数ベースの索引が選択されるかどうかを確認する方法

- 39.7.2 Oracle SQL条件JSON_EXISTSのビットマップ索引の作成

- 39.7.3 JSON_VALUE関数ベースの索引の作成

- 39.7.4 JSON_VALUE関数ベースの索引とJSON_TABLE問合せの使用

- 39.7.5 JSON_VALUEの索引付けおよび問合せに関するデータ型の考慮事項

- 39.7.6 コンポジットBツリー索引を使用した複数のJSONフィールドの索引付け

- 39.8 JSONデータの全文検索

- 39.9 外部JSONデータのロード

- 39.10 JSONデータのレプリケーション

- 39.11 JSONに対するOracle Databaseのサポート

付録

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

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

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

- A.3 acl.xsd: ACLのXML Schema

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

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

- A.6 発注書XML Schema

- A.7 XSLTスタイルシートの例、PurchaseOrder.xsl

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

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

B Oracle XML DBの制限

C XMLデータを更新するための非推奨の関数

- C.1 XMLデータを更新するためのOracle関数のXQuery Updateへの移行

- C.2 XMLデータを更新するための非推奨のOracle SQL関数

- C.2.1 非推奨のOracle SQL関数を使用したXML要素の挿入

- C.3 UPDATEXML (非推奨のOracle SQL関数)

- C.3.1 非推奨のOracle SQL関数UPDATEXMLおよびNULL値

- C.3.2 UPDATEXMLを使用した同じXMLノードの複数回の更新(非推奨)

- C.3.3 UPDATEXML使用時のDOM再現性のガイドライン(非推奨)

- C.4 XMLデータを変更する非推奨のOracle SQL関数の最適化

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

- C.6 INSERTCHILDXML (非推奨のOracle SQL関数)

- C.7 INSERTCHILDXMLBEFORE (非推奨のOracle SQL関数)

- C.8 INSERTCHILDXMLAFTER (非推奨のOracle SQL関数)

- C.9 INSERTXMLBEFORE (非推奨のOracle SQL関数)

- C.10 INSERTXMLAFTER (非推奨のOracle SQL関数)

- C.11 APPENDCHILDXML (非推奨のOracle SQL関数)

- C.12 DELETEXML (非推奨のOracle SQL関数)

D 非推奨となったXML変換の構造体

- D.1 XML変換(非推奨)

- D.1.1 変換のためのXML SchemaとXMLインスタンス・ドキュメントの変更(非推奨)

- D.1.1.1 XML Schema内での変換可能な要素の指示(非推奨)

- D.1.1.2 XMLインスタンス・ドキュメント内での変換言語属性の指示(非推奨)

- D.1.2 XML文書を変換可能にする方法(非推奨)

- D.1.3 変換済のドキュメントに対する操作(非推奨)

- D.2 PL/SQLパッケージDBMS_XMLTRANSLATIONS (非推奨)

- D.2.1 DBMS_XMLTRANSLATIONSメソッド(非推奨)

E XQueryを使用しないXMLデータの全文検索

- E.1 XMLデータのOracle固有の全文検索の概要

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

- E.1.2 XMLデータの検索

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

- E.2 全文検索の例について

- E.2.1 全文に必要なロールと権限の例

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

- E.3 SQL関数CONTAINSおよびXPath関数ora:containsの概要

- E.3.1 SQL関数CONTAINSの概要

- E.3.2 XPath関数ora:containsの概要

- E.3.3 SQL関数CONTAINSとXPath関数ora:containsの比較

- E.4 SQL関数CONTAINS

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

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

- E.4.1.2 text_query: $を使用した全文ステミング

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

- E.4.2 SQL関数SCORE

- E.4.3 CONTAINS検索の有効範囲

- E.4.3.1 構造体演算子WITHINの使用

- E.4.3.1.1 ネストされたWITHINの使用

- E.4.3.1.2 WITHIN属性の使用

- E.4.3.1.3 WITHINおよびANDの使用

- E.4.3.1.4 セクションの定義

- E.4.3.2 構造体演算子INPATHの使用

- E.4.3.2.1 テキスト・パスの使用

- E.4.3.2.2 Text PathとXPathの比較

- E.4.3.2.3 ネストされたINPATHの使用

- E.4.3.3 構造体演算子HASPATHの使用

- E.4.4 CONTAINS結果の投影

- E.4.5 CONTEXT索引

- E.4.5.1 CONTEXT索引の使用

- E.4.5.1.1 XMLType表でのCONTEXT索引の使用

- E.4.5.1.2 CONTEXT索引のメンテナンス

- E.4.5.1.3 CONTEXT索引付けのためのロールおよび権限

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

- E.4.5.3 CONTEXT索引プリファレンス

- E.4.5.3.1 検索で大/小文字を区別する方法

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

- E.4.5.4.1 セクション・グループ・タイプの選択

- E.4.5.4.2 セクション・グループの選択

- E.5 ora:contains XQuery関数

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

- E.5.2 ora:contains問合せの有効範囲

- E.5.3 ora:contains結果の投影

- E.5.4 ora:contains問合せでのポリシーの使用

- E.5.4.1 ポリシーの例: 提供されているストップリスト

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

- E.5.4.2.1 ポリシーの例: ユーザー定義レクサー

- E.5.4.3 ポリシーのデフォルト

- E.5.5 ora:containsのパフォーマンスの改善

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

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

- E.6 Text Path BNFの仕様

- E.7 全文XMLのサポートの例

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

- E.7.2 XQueryを使用しない全部検索例の表

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

索引

例一覧

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

- 3-2 XMLType表の作成

- 3-3 XMLType表内のXML属性の仮想列の作成

- 3-4 XMLType列内のXML属性の仮想列の作成

- 3-5 XMLType列を持つリレーショナル表のパーティション化

- 3-6 XMLType表のパーティション化

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

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

- 3-9 仮想列を使用したバイナリXML列の制約: 一意性

- 3-10 仮想列を使用したバイナリXML列の制約: 外部キー

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

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

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

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

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

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

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

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

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

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

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

- 3-22 XMLType表とリレーショナル表のデータの結合

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

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

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

- 3-26 テキスト・ノードの更新

- 3-27 XQuery Updateを使用した要素全体の置換

- 3-28 XQuery Updateを使用したテキスト・ノード値の変更

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

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

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

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

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

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

- 4-1 XMLTableコールのチェーン

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

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

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

- 4-5 XQuery式の静的型チェック: XML Schemaベースのデータ

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

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

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

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

- 5-5 XMLQueryを使用したXMLとしてのリレーショナル・データの問合せ

- 5-6 ネストされたFLWOR式を使用したXMLとしてのリレーショナル・データの問合せ

- 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でのRETURNING SEQUENCE BY REFの使用

- 5-13 連鎖XMLTABLEでの参照によるアクセスの使用

- 5-14 XMLTABLEを使用したXMLコレクション要素のリレーショナル・データへの分解

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

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

- 5-17 XMLTYPEデータの問合せ

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

- 5-19 SQLを使用したXMLデータの抽出およびリレーショナル表への挿入

- 5-20 PL/SQLを使用したXMLデータの抽出および表への挿入

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

- 5-22 XMLQUERYを使用したフラグメントの抽出

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

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

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

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

- 5-27 SQL UPDATEを使用したXMLTypeデータの更新

- 5-28 SQL UPDATEおよびXQuery Updateを使用したXMLTypeデータの更新

- 5-29 複数のテキスト・ノードと属性ノードの更新

- 5-30 コレクション内で選択されたノードの更新

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

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

- 5-33 NULL更新: 要素および属性

- 5-34 NULL更新: テキスト・ノード

- 5-35 コレクションへの要素の挿入

- 5-36 名前空間を使用する要素の挿入

- 5-37 要素の前への要素の挿入

- 5-38 最後の子要素としての要素の挿入

- 5-39 要素の削除

- 5-40 更新されたXMLデータを使用したビューの作成

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

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

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

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

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

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

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

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

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

- 6-3 XMLIndex構造化コンポーネントを持つ表のパーティション交換

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

- 6-5 XMLIndex索引の作成

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

- 6-21 DBMS_XMLINDEX.PROCESS_PENDINGを使用したXMLデータの索引付け

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

- 6-38 XML検索索引の作成

- 6-39 XQuery Full Text問合せ

- 6-40 XQuery Full Text問合せの実行計画

- 6-41 XML Schemaに基づくデータを使用したXQuery Full Text問合せ: エラーORA-18177

- 6-42 XML Schemaに基づくデータでのXQueryプラグマora:no_schemaの使用

- 6-43 XQueryプラグマora:use_xmltext_idxを使用した全文問合せ

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

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

- 7-1 XSLTスタイルシートの例: PurchaseOrder.xsl

- 7-2 XML Schemaの登録およびXMLデータの挿入

- 7-3 SQL関数XMLTRANSFORMを使用してXSLスタイルシートを適用

- 7-4 一時XSLスタイルシートでのXMLTypeメソッドTRANSFORM()の使用

- 7-5 XMLTRANSFORMを使用して、XDBURITypeで取得したXSLスタイルシートを適用

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

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

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

- 7-9 SQLでメソッドISSCHEMAVALID()を使用したXMLの検証

- 7-10 PL/SQLでメソッドISSCHEMAVALID()を使用したXMLの検証

- 7-11 トリガー内でメソッドSCHEMAVALIDATE()を使用したXMLの検証

- 7-12 CHECK制約内でXMLISVALIDを使用したXMLの妥当性のチェック

- 8-1 XMLELEMENT: 日付のフォーマット

- 8-2 XMLELEMENT: 各従業員の要素の生成

- 8-3 XMLELEMENT: ネストされたXMLの生成

- 8-4 XMLELEMENT: IDおよびname属性を持つ従業員要素の生成

- 8-5 XMLELEMENT: 生成されたXMLデータにおける文字がエスケープされない

- 8-6 XMLELEMENTと名前空間を使用したXML Schemaに基づく文書の作成

- 8-7 XMLELEMENT: ユーザー定義のデータ型インスタンスからの要素の生成

- 8-8 XMLFOREST: 属性と子要素を持つ要素の生成

- 8-9 XMLFOREST: ユーザー定義のデータ型インスタンスからの要素の生成

- 8-10 XMLCONCAT: 順序で使用されるXMLTypeインスタンスの連結

- 8-11 XMLCONCAT: XML要素の連結

- 8-12 XMLAGG: 子の従業員要素を含む部門要素の生成

- 8-13 XMLAGG: GROUP BYを使用した複数の部門要素の生成

- 8-14 XMLAGG: ネストされた要素の生成

- 8-15 SQL/XML関数XMLPIの使用

- 8-16 SQL/XML関数XMLCOMMENTの使用

- 8-17 SQL/XML関数XMLSERIALIZEの使用

- 8-18 SQL/XML関数XMLPARSEの使用

- 8-19 Oracle SQL関数XMLRootの使用

- 8-20 XMLCOLATTVAL: 属性と子要素を持つ要素の生成

- 8-21 Oracle SQL関数XMLCDATAの使用

- 8-22 DBMS_XMLGEN: 単純なXMLの生成

- 8-23 DBMS_XMLGEN: ページ区切りを使用した単純なXMLの生成(フェッチ)

- 8-24 DBMS_XMLGEN: オブジェクト型を使用したXMLの生成

- 8-25 DBMS_XMLGEN: ユーザー定義のデータ型インスタンスを使用したXMLの生成

- 8-26 DBMS_XMLGEN: XML発注書の生成

- 8-27 DBMS_XMLGEN: REFカーソルからの新規コンテキスト・ハンドルの生成

- 8-28 DBMS_XMLGEN: NULL処理の指定

- 8-29 DBMS_XMLGEN: 階層問合せを使用した再帰XMLの生成

- 8-30 DBMS_XMLGEN: SETBINDVALUE()を使用した問合せ変数のバインド

- 8-31 XMLAGG ORDER BY句の使用

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

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

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

- 9-3 リレーショナル・ビューの列に対応するXMLIndex索引

- 9-4 PL/SQL関数getSIDXDefFromViewによって戻されたXMLTable式

- 9-5 XMLデータのマスター・リレーショナル・ビューの問合せ

- 9-6 XMLデータのマスターおよび詳細リレーショナル・ビューの問合せ

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

- 10-1 XMLELEMENTを使用したXMLTypeビューの作成

- 10-2 XML Schema emp_simple.xsdの登録

- 10-3 SQL/XMLパブリッシング関数を使用したXMLTypeビューの作成

- 10-4 XMLTypeビューの問合せ

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

- 10-6 ターゲットの名前空間が存在しないXML Schema

- 10-7 ターゲットの名前空間が存在しないXML Schemaのビューの作成

- 10-8 XML Schemaに基づくXMLTypeビューでのSQL/XML関数の使用

- 10-9 XML Schemaに基づくXMLTypeビューに対応するオブジェクト型の作成

- 10-10 XML Schema emp_complex.xsdの作成および登録

- 10-11 オブジェクト型emp_tを使用したXMLTypeビューemp_xmlの作成

- 10-12 オブジェクト・ビューの作成と、そのオブジェクト・ビューへのXMLTypeビューの作成

- 10-13 オブジェクト型の作成

- 10-14 XML Schema dept_complex.xsdの登録

- 10-15 オブジェクト型dept_tを使用したXMLTypeビューdept_xmlの作成

- 10-16 リレーショナル・データを直接使用したXMLTypeビューdept_xmlの作成

- 10-17 XMLType表の行の制限によるXMLTypeビューの作成

- 10-18 XMLType表の変換によるXMLTypeビューの作成

- 10-19 暗黙的に更新可能なXMLTypeビューの識別およびその更新

- 11-1 DOM文書の作成および操作

- 11-2 要素ノードの作成および関連情報の取得

- 11-3 ユーザー定義サブタイプSYS.util_BinaryOutputStream()の作成

- 11-4 ユーザー定義ストリームによるノード値の取得

- 11-5 バイナリ・データのGet-Pull

- 11-6 文字データのGet-Pull

- 11-7 バイナリ・データのSet-Pull

- 11-8 バイナリ・データのSet-Push

- 11-9 XML文書の解析

- 11-10 XSLスタイルシートを使用したXML文書の変換

- 12-1 指定した列でのデータの挿入

- 12-2 キー列を使用したデータの更新

- 12-3 DBMS_XMLSTORE.DELETEXMLの例

- 13-1 JDBCを使用したXMLType表の問合せ

- 13-2 getStringVal()およびgetCLOB()を使用したXMLTypeデータの選択

- 13-3 getObject()を使用してXMLTypeデータを戻す方法

- 13-4 出力パラメータを使用してXMLTypeデータを戻す方法

- 13-5 SQL UPDATEとコンストラクタXMLTypeを使用したXMLTypeデータの更新

- 13-6 SQL UPDATEとsetObject()を使用したXMLTypeデータの更新

- 13-7 JDBCを使用したXMLTypeデータに関するメタデータの取得

- 13-8 JDBCを使用したXMLType列の要素の更新

- 13-9 更新済の発注書

- 13-10 JDBCを使用したXMLType列の操作

- 13-11 JavaメソッドinsertXML()

- 13-12 JavaメソッドgetCLOB()

- 13-13 Java DOM APIの権限を付与するポリシー・ファイル

- 13-14 Java DOM APIを使用したDOMオブジェクトの作成

- 13-15 バイナリXMLでのJava DOM APIの使用

- 14-1 OCIXMLDBINITXMLCTX()およびOCIXMLDBFREEXMLCTX()の使用

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

- 14-3 Oracle XML DB Pull Parserの使用

- 14-4 DOMを使用した発注部品のカウント

- 15-1 .NETへのXMLTypeデータの取出し

- 17-1 DBMS_XMLSCHEMA.REGISTERSCHEMAを使用したXML Schemaの登録

- 17-2 XML Schemaの登録時のオブジェクトの作成

- 17-3 ローカルXML Schemaの登録

- 17-4 グローバルXML Schemaの登録

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

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

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

- 17-8 デフォルト記憶域でのオブジェクト・リレーショナル形式のXMLType表の作成

- 17-9 XMLType表および列に対するオブジェクト・リレーショナル記憶域オプションの指定

- 17-10 STORE ALL VARRAYS ASの使用

- 18-1 XMLType表を格納するためのSQLオブジェクト型

- 18-2 グローバル要素PurchaseOrderのデフォルト表

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

- 18-4 注釈付きXML Schemaの登録

- 18-5 DBMS_XMLSCHEMA_ANNOTATEの使用

- 18-6 登録されたXML Schemaを取得するビューUSER_XML_SCHEMASの問合せ

- 18-7 登録されたXML Schemaからのメタデータの問合せ

- 18-8 属性SQLTypeを使用したXML Schemaデータ型のSQLデータ型へのマッピング

- 18-9 XML Schemaでの継承: complexTypeの拡張としてのcomplexContent

- 18-10 XML Schemaでの継承: complexTypeの制限

- 18-11 XML SchemaのcomplexType: simpleContentへのcomplexTypeのマッピング

- 18-12 XML Schema: any/anyAttributeへのcomplexTypeのマッピング

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

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

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

- 18-16 XML Schemaの登録時のパーティション化情報の指定

- 18-17 表の作成時のパーティション化情報の指定

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

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

- 18-20 表外に格納するためのSQLInLineのfalse設定

- 18-21 生成されたXMLType表および型

- 18-22 表外の表の問合せ

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

- 18-24 生成された表外のコレクション型

- 18-25 REF値の中間表名の変更

- 18-26 表外のコレクションのXPathリライト

- 18-27 REFへの索引を使用した表外のコレクションのXPathリライト

- 18-28 循環依存を使用したXML Schema

- 18-29 XML Schema: complexType間での循環

- 18-30 XML Schema: complexType間での循環、自己参照

- 18-31 存在しないXML Schemaを含むXML Schema

- 18-32 FORCEオプションを使用したXML Schema xm40.xsdの登録

- 18-33 循環するXML Schemaを使用した表作成の試行

- 18-34 FORCEオプションを使用したXML Schema xm40a.xsdの登録

- 18-35 再帰的XML Schema

- 18-36 表外の表

- 18-37 デフォルト表の無効な共有

- 18-38 Oracle XML DBのXML Schema: LOBへのcomplexTypeのXMLフラグメントのマッピング

- 19-1 XPathリライト

- 19-2 表外の表のXPathリライト

- 19-3 表外の表での索引の使用

- 19-4 XPathリライトを実行しない場合に生成される実行計画

- 19-5 実行計画の分析による列と索引の対応の特定

- 19-6 DBMS_XMLSTORAGE_MANAGE.XPATH2TABCOLMAPPINGの使用

- 19-7 述語でターゲットとなっている列に対する索引の作成

- 19-8 述語でターゲットとなっている列に対するファンクション索引の作成

- 19-9 索引が選択されていることを示す実行計画

- 19-10 述語でターゲットとなっている列に対するファンクション索引の作成

- 19-11 コレクション要素の選択の実行計画

- 19-12 Ordered Collection Tableに直接アクセスするための索引の作成

- 20-1 修正された発注書XML Schema

- 20-2 evolvePurchaseOrder.xsl: インスタンス・ドキュメントを更新するXSLTスタイルシート

- 20-3 修正されたXML SchemaおよびXSLTスタイルシートのロード

- 20-4 DBMS_XMLSCHEMA.COPYEVOLVEを使用したXML Schemaの更新

- 20-5 1つの複合型の2つの複合型への分割

- 20-6 diffXMLパラメータ・ドキュメント

- 21-1 PATH_VIEWへの問合せによるリンク・タイプの特定

- 21-2 リソースのOIDパスの取得

- 21-3 OIDパスを使用した弱いリンクの作成

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

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

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

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

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

- 21-9 リソースでUPDATEとXQuery Updateを使用したテキスト・ドキュメントの更新

- 21-10 リソースでUPDATEとXQuery Updateを使用したXMLノードの更新

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

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

- 21-13 リポジトリに格納されたXSLTスタイルシートへのパスの判別

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

- 21-15 パス内のフォルダのコンテンツのリスト

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

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

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

- 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 あるパスの下にないパスの判別

- 24-4 複数のcorrelationを使用したパスの判別

- 24-5 3レベルのリソースの相対パス名

- 24-6 UNDER_PATHを使用したリソース・メタデータの抽出

- 24-7 関数PATHとDEPTHのPATH_VIEWでの使用

- 24-8 リンクおよびリソース情報のPATH_VIEWからの抽出

- 24-9 特定の深さまでの、あるパス以下のすべてのリポジトリ・パス

- 24-10 EQUALS_PATHを使用したリポジトリ・パスの特定

- 24-11 指定したリソースのリソースIDの取得

- 24-12 RESIDからのリソースのパス名の取得

- 24-13 指定したパスの下にあるフォルダ

- 24-14 RESOURCE_VIEWのXMLType表への結合

- 24-15 リソースの削除

- 24-16 リソースへのリンクの削除

- 24-17 空でないフォルダの削除

- 24-18 リソースの更新

- 24-19 PATH_VIEW内のパスの更新

- 24-20 属性に基づいたリソースの更新

- 24-21 フォルダ内のリソースの検索

- 24-22 リソースのコピー

- 24-23 「Paper」を含むすべてのリソースの検索

- 24-24 特定のパスの下にあり、「Paper」を含むすべてのリソースの検索

- 25-1 リポジトリ・リソースの作成

- 25-2 バージョン管理されたリソースの作成

- 25-3 リソースIDの参照によるリソース・コンテンツの取出し

- 25-4 バージョン管理されたリソースのチェックアウト

- 25-5 リソース・コンテンツの更新

- 25-6 バージョン管理されたリソースのチェックイン

- 25-7 XDBURITYPEおよびCREATEOIDPATHを使用したリソース・バージョン・コンテンツの取出し

- 25-8 GETCONTENTSCLOBBYRESIDを使用したリソース・バージョン・コンテンツの取出し

- 25-9 GETRESOURCEBYRESIDを使用したリソース・バージョン・メタデータの取出し

- 25-10 UNCHECKOUTを使用したチェックアウトのキャンセル

- 26-1 DBMS_XDB_REPOSを使用したリソースの管理

- 26-2 DBMS_XDB_REPOS.GETACLDOCUMENTの使用

- 26-3 DBMS_XDB_REPOS.SETACLの使用

- 26-4 DBMS_XDB_REPOS.CHANGEPRIVILEGESの使用

- 26-5 DBMS_XDB_REPOS.GETPRIVILEGESの使用

- 26-6 DBMS_XDB_CONFIG.CFG_GETの使用

- 26-7 DBMS_XDB_CONFIG.CFG_UPDATEの使用

- 27-1 権限を付与する単純なアクセス制御エントリ(ACE)

- 27-2 権限を付与する単純なアクセス制御リスト(ACL)

- 27-3 要素invertを使用したプリンシパル・セットの補完

- 27-4 CREATERESOURCEを使用したACLの作成

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

- 27-6 リソースのACLの設定

- 27-7 ACLの削除

- 27-8 アクセス制御リストの更新(置換)

- 27-9 アクセス制御リストへのACEの追加

- 27-10 アクセス制御リストからのACEの削除

- 27-11 リソースのACL文書の取得

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

- 27-13 あるリソースに対してユーザーが特定の権限を所有しているかどうかの確認

- 27-14 ACLCheckPrivilegesを使用したユーザー権限の確認

- 27-15 特定のリソースを保護するACLのパスの取得

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

- 27-17 LDAPユーザーを参照するACL

- 27-18 LDAPグループを参照するACL

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

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

- 28-3 Oracle ASMフォルダのナビゲート

- 28-4 FTP proxyメソッドによる、Oracle ASMファイルのデータベース間転送

- 28-5 IPv6を使用したFTP接続

- 28-6 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スキーマ

- 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 HTTPURIType PL/SQLメソッドGETCONTENTTYPE()

- 33-2 URI列の作成と問合せ

- 33-3 各種の方法で作成された様々な種類のURIの使用

- 33-4 XDBUriを使用した、URIによるリポジトリ・リソースへのアクセス

- 33-5 XMLCASTおよびXMLQUERYでのPL/SQLメソッドGETXMLの使用

- 33-6 DBUriを使用した完全な表のターゲット化

- 33-7 DBUriを使用した表内の個別行のターゲット化

- 33-8 DBUriを使用した特定の列のターゲット化

- 33-9 DBUriを使用した、特定の属性値を持つオブジェクト列のターゲット化

- 33-10 DBUriを使用したノードのテキスト値のみの取出し

- 33-11 DBUriを使用したコレクションのターゲット化

- 33-12 URIFACTORY: ECOMプロトコルの登録

- 33-13 SYS_DBURIGEN: 列をターゲットとするDBUriの生成

- 33-14 SYS_DBURIGENへの単一の引数を持つ列の送信

- 33-15 SYS_DBURIGENを使用したデータベース参照の挿入

- 33-16 旅行体験記の表の作成

- 33-17 最初の20文字のみを戻す関数

- 33-18 SYS_DBURIGENで使用するための旅行体験記ビューの作成

- 33-19 RETURNING句でのSYS_DBURIGENの使用によるURLの取得

- 33-20 DBUriServletのインストール先の変更

- 33-21 サーブレット・アクセスのデータベース・ロールへの制限

- 33-22 DBUri接頭辞用のハンドラの登録

- 34-1 Webサービス構成サーブレットの追加

- 34-2 Webサービス構成サーブレット追加の検証

- 34-3 Webサービスで処理されるデータベース問合せのXML Schema

- 34-4 問合せWebサービスを使用したSQL問合せの入力XML文書

- 34-5 問合せWebサービスを使用したSQL問合せの出力XML文書

- 34-6 Webサービス・アクセスに使用するPL/SQLファンクションの定義

- 34-7 ストアドPL/SQLファンクションに対応するWSDLドキュメント

- 34-8 Webサービスを使用したPL/SQL問合せの入力XML文書

- 34-9 Webサービスを使用したPL/SQL問合せの出力XML文書

- 35-1 Oracle XML DBの構成ファイル

- 35-2 CFG_UPDATEおよびCFG_GETを使用した構成ファイルの更新

- 36-1 データ・ファイルfilelist.dat: ロードするXMLファイルのリスト

- 36-2 発注書XML文書のロードに使用する制御ファイルload_datra.ctl

- 36-3 シェル・コマンドsqlldrを使用したXMLデータのロード

- 37-1 表モードでのXMLTypeデータのエクスポート

- 37-2 表モードでのXMLTypeデータのインポート

- 37-3 表po2の作成

- 37-4 スキーマ・モードでのXMLTypeデータのエクスポート

- 37-5 スキーマ・モードでのXMLTypeデータのインポート

- 37-6 スキーマ・モードでのXMLTypeデータのインポート、スキーマの再マップ

- 38-1 キュー表およびキューの作成

- 38-2 メッセージ・データをXMLに変換するための変換の作成

- 38-3 メッセージを海外に送信する前の変換の適用

- 38-4 XMLTypeおよびAQ: メッセージのデキュー

- 39-1 A JSONオブジェクト(JavaScriptのオブジェクト・リテラルの表現)

- 39-2 JSONデータの単純なSQL問合せ

- 39-3 JSONデータが整形式であることを確認するためのチェック制約でのIS JSONの使用

- 39-4 JSON列のあるリレーショナル表へのデータの挿入

- 39-5 JSONデータが厳密な整形式(標準)であることを確認するためのチェック制約でのIS JSONの使用

- 39-6 JSON_TABLEを使用して表されたJSON_EXISTS

- 39-7 JSON_VALUE: SQLでJSONのブール値を戻す2通りの方法

- 39-8 JSON_TABLEを使用して表されたJSON_VALUE

- 39-9 JSON_QUERYを使用したJSON値の選択

- 39-10 JSON_TABLEを使用して表されたJSON_QUERY

- 39-11 JSONデータに複数回アクセスすることによるデータの抽出

- 39-12 JSON_TABLEの使用によって複数回の解析が不要なデータの抽出

- 39-13 JSON配列全体のJSONデータとしての投影

- 39-14 JSON配列の要素の投影

- 39-15 JSON配列の要素と他のデータの投影

- 39-16 JSON_TABLE: NESTEDを使用した配列要素の投影

- 39-17 JSONデータを介したリレーショナル・ビューの定義

- 39-18 JSONドット表記法の問合せとJSON_VALUEの比較

- 39-19 JSONドット表記法の問合せとJSON_QUERYの比較

- 39-20 JSON_EXISTSのビットマップ索引の作成

- 39-21 JSON_VALUEのビットマップ索引の作成

- 39-22 JSONオブジェクト・フィールドに対する関数ベースの索引の作成: JSON_VALUE

- 39-23 JSONオブジェクト・フィールドに対する関数ベースの索引の作成: ドット表記法

- 39-24 JSON_VALUE関数ベースの索引とJSON_TABLE問合せの使用

- 39-25 JSON_VALUE問合せと明示的なRETURNING NUMBER

- 39-26 JSON_VALUE問合せと明示的な数値変換

- 39-27 JSON_VALUE問合せと暗黙的な数値変換

- 39-28 JSONオブジェクト・フィールドの仮想列の作成

- 39-29 JSONオブジェクト・フィールドのコンポジットBツリー索引の作成

- 39-30 コンポジット索引を使用して索引が付けられたJSONデータを問い合せる2通りの方法

- 39-31 JSON検索索引の作成

- 39-32 JSONデータの全文問合せ

- 39-33 JSONデータの非定型問合せ

- 39-34 JSON検索索引が使用されていることを示す実行計画

- 39-35 データベース・ディレクトリ・オブジェクトの作成

- 39-36 データベース・ディレクトリ・オブジェクトの作成

- 39-37 外部表の作成およびJSONダンプ・ファイルからの入力

- 39-38 外部表からリレーショナル表へのJSONデータのコピー

- A-1 注釈の付いていない発注書XML Schema

- A-2 注釈付きの発注書XML Schema

- A-3 改訂された発注書XML Schema

- A-4 XSLTスタイルシートPurchaseOrder.xsl

- A-5 Cを使用したXMLType表へのXMLデータの挿入

- A-6 OCIXmlDbInitXmlCtx()およびOCIXmlDbFreeXmlCtx()の使用

- C-1 UPDATEおよびUPDATEXMLを使用したXMLTYPEの更新(非推奨)

- C-2 UPDATEXMLを使用した、複数のテキスト・ノードと属性値の更新(非推奨)

- C-3 UPDATEXMLを使用した、コレクション内で選択されたノードの更新(非推奨)

- C-4 UPDATEXMLを使用したNULL更新(非推奨): 要素および属性

- C-5 UPDATEXMLを使用したNULL更新(非推奨): テキスト・ノード

- C-6 UPDATEXML式内のXPath式

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

- C-8 UPDATEXMLを使用したビューの作成(非推奨)

- C-9 INSERTCHILDXMLを使用したコレクションへの挿入(非推奨)

- C-10 名前空間を使用する要素の挿入

- C-11 INSERTXMLBEFOREを使用した要素の前への挿入(非推奨)

- C-12 APPENDCHILDXMLを使用した最後の子としての挿入(非推奨)

- C-13 DELETEXMLを使用した要素の削除(非推奨)

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

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

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

- D-4 変換後のドキュメント

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

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

- D-7 言語情報のないドキュメントの挿入

- D-8 リポジトリに挿入された後のドキュメント

- D-9 言語情報を持つドキュメントの挿入

- D-10 挿入後のドキュメント

- E-1 Oracle SQL関数CONTAINSを使用した単純な問合せ

- E-2 CONTAINSおよびWITHINを使用した問合せの制限

- E-3 CONTAINSおよびINPATHを使用した問合せの制限

- E-4 複雑な任意のテキスト問合せを使用したora:contains

- E-5 単純なブール演算子を使用したCONTAINS問合せ

- E-6 複雑なブールを使用したCONTAINS問合せ

- E-7 ステミングを使用したCONTAINS問合せ

- E-8 複雑な問合せ式を使用したCONTAINS問合せ

- E-9 SCOREを使用した単純なCONTAINS問合せ

- E-10 WITHIN

- E-11 ネストしたWITHIN

- E-12 WITHIN (属性の場合)

- E-13 WITHINおよびAND: あるコメント・セクション内の2つのワード

- E-14 WITHINおよびAND: 同じコメント内の2つのワード

- E-15 WITHINおよびAND: カッコなし

- E-16 WITHINおよびAND: 演算子優先順位を示すカッコ

- E-17 全文述語内の構造: INPATH

- E-18 全文述語内の構造: INPATH

- E-19 複雑なパス式を使用したINPATH(1)

- E-20 複雑なパス式を使用したINPATH(2)

- E-21 ネストしたINPATH

- E-22 リライト済のネストしたINPATH

- E-23 単純HASPATH

- E-24 HASPATH等価

- E-25 HASPATHと他の演算子の組合せ

- E-26 CONTAINS問合せの結果の範囲指定

- E-27 ora:containsを使用したCONTAINS問合せ結果の投影

- E-28 表PURCHASE_ORDERSの単純なCONTEXT索引

- E-29 パス・セクション・グループを使用したXMLType表の単純なCONTEXT索引

- E-30 XMLType列の単純なCONTEXT索引

- E-31 XMLType表の単純なCONTEXT索引

- E-32 XMLType表のCONTAINS問合せ

- E-33 CONTAINS: デフォルトの大/小文字を区別しない一致

- E-34 大/小文字混合のプリファレンスの作成

- E-35 PURCHASE_ORDERS表のCONTEXT索引、大/小文字混合

- E-36 CONTAINS: 大/小文字混合の(正確な)一致

- E-37 パス・セクション・グループを使用したpurchase_orders表の単純なCONTEXT索引

- E-38 XMLQueryおよびXMLExistsでのora:containsの使用

- E-39 ora:containsで使用するポリシーの作成

- E-40 ora:containsを使用したストップワードの検索

- E-41 ora:containsおよびポリシーmy_nostopwords_policyを使用したストップワードの検索

- E-42 ora:contains、デフォルトの大/小文字の区別

- E-43 大/小文字混合のプリファレンスの作成

- E-44 大/小文字混合の(大/小文字が区別されない)ポリシーの作成

- E-45 ora:contains、大/小文字の区別(1)

- E-46 ora:contains、大/小文字の区別(2)

- E-47 大規模な表のora:contains

- E-48 IDのBツリー索引

- E-49 大規模な表のora:contains (追加の述語を使用)

- E-50 ora:containsでの"electric"の検索

- E-51 XQueryプラグマora:use_text_indexをora:containsとともに使用する

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

- E-53 表PURCHASE_ORDERSの作成

- E-54 表PURCHASE_ORDERS_XMLTYPEの作成

- E-55 表PURCHASE_ORDERS_XMLTYPE_TABLEの作成

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

図一覧

- 1-1 Oracle XML DBのメリット

- 1-2 データとコンテンツの統合: 一般的なXMLアーキテクチャ

- 1-3 XMLType記憶域

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

- 2-1 XMLデータに対するOracle XML DBの記憶域オプション

- 3-1 Windows Explorerを使用したリポジトリへのコンテンツのロード

- 4-1 XMLQUERYの構文

- 4-2 XMLTABLEの構文

- 4-3 XMLExistsの構文

- 4-4 XMLCastの構文

- 6-1 XMLのユースケースとXML索引付け

- 7-1 XMLTRANSFORMの構文

- 7-2 XMLTRANSFORMの使用

- 7-3 DBUriサーブレットを使用したPurchaseOrderのデータベースXSL変換

- 7-4 DBUriサーブレットを使用したDepartments表のデータベースXSL変換

- 8-1 XMLELEMENTの構文

- 8-2 XMLAttributes句の構文(XMLATTRIBUTES)

- 8-3 XMLFORESTの構文

- 8-4 XMLCONCATの構文

- 8-5 XMLAGGの構文

- 8-6 XMLPIの構文

- 8-7 XMLCommentの構文

- 8-8 XMLSerializeの構文

- 8-9 XMLParseの構文

- 8-10 XMLRootの構文

- 8-11 XMLCOLATTVALの構文

- 8-12 XMLCDATAの構文

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

- 8-14 SYS_XMLAGGの構文

- 10-1 XMLTypeビューの作成の句: 構文

- 11-1 PL/SQL DOM API for XMLTypeの使用

- 11-2 PL/SQL Parser API for XMLTypeの使用

- 11-3 PL/SQL XSLT Processor for XMLTypeの使用

- 13-1 Java DOM API for XMLTypeの使用

- 16-1 XMLのユースケースとXMLType記憶域モデル

- 17-1 XML Schema Purchase-OrderのXMLSpyによるグラフィカル表現

- 17-2 XMLSpyにおけるOracle XML DB Schema注釈のサポート

- 17-3 XMLType表の作成: CREATE TABLEの構文

- 17-4 XMLType表の作成: XMLType_tableの構文

- 17-5 XMLType表の作成: table_propertiesの構文

- 17-6 XMLType表の作成: XMLType_virtual_columnsの構文

- 17-7 Oracle XML DBによるXML Schemaに基づくXMLType表のマッピング方法

- 18-1 simpleTypeのマッピング: XML文字列からSQLのVARCHAR2またはCLOB

- 18-2 表外に格納するためのSQLへのcomplexTypeのマッピング

- 18-3 同じXML Schemaの異なるcomplexType間での相互参照

- 18-4 XML Schema内での複合型の自己参照

- 18-5 XML Schema間での循環参照

- 18-6 CLOBインスタンスへのcomplexTypeのXMLフラグメントのマッピング

- 21-1 リポジトリの階層構造を示すフォルダ・ツリー

- 21-2 WindowsエクスプローラでのOracle XML DBのフォルダ

- 21-3 HTTPやWebDAVおよびWebブラウザを使用したリポジトリ・データへのアクセス

- 21-4 HTTPとURLを使用したパスベースのアクセス

- 21-5 Oracle ASM仮想フォルダの階層

- 21-6 Microsoft Wordを使用した、Oracle XML DBに格納されたコンテンツの更新および編集

- 24-1 RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリ・リソースへのアクセス

- 24-2 RESOURCE_VIEWとPATH_VIEWの構造

- 24-3 RESOURCE_VIEWとPATH_VIEWの解説

- 24-4 UNDER_PATHの構文

- 24-5 EQUALS_PATH の構文

- 24-6 PATHの構文

- 28-1 Oracle XML DBのアーキテクチャ: プロトコル・サーバー

- 28-2 Microsoft WindowsでのWebフォルダの作成

- 28-3 Oracle XML DBリポジトリへのファイルのコピー

- 33-1 リレーショナル・データのXMLビジュアル化に対応するDBUri

- 33-2 SYS_DBURIGENの構文

- 38-1 Oracle Streamsアドバンスト・キューイングおよびXMLメッセージ・ペイロード

- 38-2 HTTPまたはHTTPSを使用してAQ操作を実行するためのiDAPアーキテクチャ

- C-1 UPDATEXMLの構文

- C-2 INSERTCHILDXMLの構文

- C-3 INSERTCHILDXMLBEFOREの構文

- C-4 INSERTCHILDXMLAFTERの構文

- C-5 INSERTXMLBEFOREの構文

- C-6 INSERTXMLAFTERの構文

- C-7 APPENDCHILDXMLの構文

- C-8 DELETEXMLの構文

表一覧

- 1-1 XMLに関連する静的データ・ディクショナリ・ビュー

- 3-1 SQL*Loaderの従来型パスおよびダイレクト・パスによるロード・モード

- 4-1 XPathの共通構造体

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

- 4-3 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の静的なパブリック・ビュー

- 6-9 Oracle固有のXML問合せのXQuery Full Textへの移行

- 8-1 DBMS_XMLGENのファンクションおよびプロシージャ

- 11-1 XMLに関連するPL/SQL API

- 11-2 XMLおよびHTMLのDOMノード型およびその子ノード型

- 13-1 Java DOM API for XMLType: クラス

- 14-1 OCIXmlDbInitXMlCtx()のパラメータ

- 14-2 Cでの一般的なXMLType操作

- 16-1 XMLType記憶域モデルについての考慮事項

- 16-2 XMLTypeの索引付けについての考慮事項

- 16-3 XMLType記憶域モデル: 相対的なメリット

- 17-1 XMLTypeのXML Schema関連メソッド

- 17-2 バイナリXMLのためのCREATE TABLEエンコード・オプション

- 18-1 要素内の注釈

- 18-2 グローバルなcomplexType要素を宣言する要素内の注釈

- 18-3 XML Schema宣言内の注釈

- 18-4 XML Schema文字列データ型のSQLへのマッピング

- 18-5 XML Schemaバイナリ・データ型(hexBinary/base64Binary)のSQLへのマッピング

- 18-6 SQLへのXML Schema数値基本型のデフォルトのマッピング

- 18-7 XML Schema日時データ型のSQLへのマッピング

- 18-8 SQLへのその他のXML Schema基本および派生データ型のデフォルトのマッピング

- 19-1 基礎となるSQL構造体にリライトされるXPath式のサンプル

- 20-1 プロシージャDBMS_XMLSCHEMA.COPYEVOLVEのパラメータ

- 20-2 プロシージャDBMS_XMLSCHEMA.COPYEVOLVEに関連するエラー

- 20-3 XML Schemaの拡張: XMLType表の一時表の列

- 20-4 XML Schemaの拡張: XMLType列の一時表の列

- 20-5 プロシージャCOPYEVOLVEのマッピング表

- 20-6 プロシージャDBMS_XMLSCHEMA.INPLACEEVOLVEのパラメータ

- 21-1 Oracle XML DBリポジトリの用語の同義語

- 21-2 PATH_VIEWとRESOURCE_VIEWの違い

- 21-3 Oracle XML DBリポジトリへのアクセス: APIオプション

- 24-1 RESOURCE_VIEWの構造

- 24-2 PATH_VIEWの構造

- 24-3 UNDER_PATH SQL関数のシグネチャ

- 25-1 Oracle XML DBバージョニングの用語

- 25-2 パッケージDBMS_XDB_VERSIONのPL/SQLファンクションおよびプロシージャ

- 26-1 DBMS_XDB_REPOSのリソース・アクセスおよび管理サブプログラム

- 26-2 DBMS_XDB_REPOS: セキュリティ管理サブプログラム

- 26-3 DBMS_XDB_CONFIG: 構成管理サブプログラム

- 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 URIType PL/SQLメソッド

- 33-2 URIFACTORY PL/SQLメソッド

- 33-3 DBUriServlet: オプションの引数

- 34-1 XMLデータ型とOracle Databaseデータ型のWebサービスによるマッピング

- 35-1 DBMS_XDB_ADMIN管理プロシージャ

- 39-1 JSON_QUERYラッパー句の例

- 39-2 JSONオブジェクト・フィールドの構文例

- C-1 Oracle固有のXML更新問合せのXQuery Updateへの移行

はじめに

このマニュアルでは、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 12cとOracle Database 12c Enterprise Editionとの使用可能な機能およびオプションの違いは、『Oracle Database新機能ガイド』 を参照してください。このマニュアルでは、Oracle Database 12cリリース1 (12.1)の新機能についても説明しています。

- 『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 Databaseアドバンスト・キューイング・ユーザーズ・ガイド

- 『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/

- 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://download.oracle.com/javaee/1.2.1/api/index.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に格納されています。いくつかの例で発注書を変換するために使用されているXSLTスタイルシートはファイルpurchaseorder.xslで、リポジトリの場所/home/OE/purchaseorder.xslに格納されています。このXML Schemaとスタイルシートも 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 12cリリース1 (12.1.0.2)でのOracle Databaseの変更

- Oracle Database 12cリリース1 (12.1.0.1)での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.1)でのOracle XML DBの変更

- Oracle Database 11gリリース1 (11.1)でのOracle XML DBの変更

Oracle Database 12cリリース1 (12.1.0.2)でのOracle Databaseの変更

『Oracle XML DB開発者ガイド』でのOracle Database 12cリリース1 (12.1.0.2)の変更点は次のとおりです。

新機能

このリリースの新機能は次のとおりです。

JSONのサポート

Oracle Databaseは、JavaScript Object Notation (JSON)をサポートするようになりました。

「Oracle DatabaseのJSON」も参照してください。

レルム構成のためのPL/SQLサブプログラム

PL/SQLサブプログラムgetHTTPConfigRealmとsetHTTPConfigRealmが、パッケージDBMS_XDB_CONFIGに追加されました。

Oracle Database 12cリリース1 (12.1.0.1)でのOracle XML DBの変更

『Oracle XML DB開発者ガイド』でのOracle Database 12cリリース1 (12.1.0.1)の変更点は次のとおりです。

新機能

このリリースの新機能は次のとおりです。

Oracle XML DBは必須(削除不可)

Oracle XML DBはOracle Databaseの必須コンポーネントになりました。削除できない上、Oracle Databaseを作成する場合は必ず含める必要があります。データベースの新規作成時、または(まだ存在しない場合は)既存のデータベースをOracle Database 12cにアップグレードする際、自動的にインストールされます。「Oracle XML DBの自動インストール」も参照してください。

XQuery Updateのサポート

Oracle XML DBではXQuery Updateをサポートするようになりました。XMLデータを更新するためのOracle固有のSQL関数は非推奨になっています。

関連項目:

- XQueryとOracle XML DB

- 「XMLデータの更新」

- "非推奨となったXMLデータを更新するためのOracle SQL関数については、非推奨となった機能を参照してください。

XQuery Full Textのサポート

Oracle XML DBではXQuery Full Textをサポートするようになりました。

関連項目:

- XQueryとOracle XML DB

- 「全文問合せ用のXMLデータの索引付け」

新しいXQuery拡張式プラグマ

新たに導入されたXQuery拡張式プラグマは次のとおりです。

- (#ora:child-element-name name #) - 挿入される子要素に使用する名前を指定します。

- (#ora:no_schema #) - XQuery Full Text式でXML Schemaに基づくXMLTypeデータを使用した場合に、エラーを発生させません。

- (#ora:use_xmltext_idx #) - XML検索索引(使用可能な場合)を使用して問合せを評価します。XMLIndex索引またはストリーミング評価は使用しません。

関連項目:

「Oracle XQuery拡張式プラグマ」

レプリケーションおよびローリング・アップグレードのサポート

次の新機能により、レプリケーションおよびローリング・アップグレードに対するサポートが強化されました。

Oracle GoldenGateおよびOracle Data Guard SQL ApplyによるXMLTypeのサポート

Oracle GoldenGateレプリケーションおよびOracle Data Guard SQL Apply (ロジカル・スタンバイ)は、すべてのXMLType記憶域モデルでサポートされるようになりました。

関連項目:

- Oracle GoldenGateを使用したXMLTypeデータのレプリケーションの詳細は、『Oracle GoldenGate Oracleインストレーションおよびセットアップ・ガイド』を参照してください。

- Oracle GoldenGateの詳細は、Oracle GoldenGateのドキュメントを参照してください

- SQL Applyでサポートされるデータ型の詳細は、『Oracle Data Guard概要および管理』を参照してください。

ローリング・アップグレードでOracle XML DBリポジトリをサポート

ローリング・アップグレードを実行する場合、Oracle XML DBリポジトリ操作は、SQL Apply手順の一部としてスタンバイ・データベースに適用されます。

適用される制限の詳細は、「既存のOracle XML DBのインストールのアップグレードまたはダウングレード」を参照してください。

XMLTypeに対するパラレルDMLのサポート

パラレルDMLのサポートは、SecureFiles LOBを使用したXMLType記憶域モデル(バイナリXML)で向上しています。CREATE TABLE AS SELECTおよびINSERT AS SELECTの両方で、パフォーマンスと拡張性が向上しています。

関連項目:

『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』

XMLIndexの改善

XMLIndexを使用したXMLデータの索引付けの改善点は次のとおりです。

XMLIndex索引の同期化の向上

索引の同期化の改善点は次のとおりです。

- UNDOの領域の使用量が低減。

- 索引付けの実行中にエラーが発生した場合、索引の同期化作業の大部分を保存。

XMLIndexのハッシュ・パーティション化のサポート

(レンジ・パーティション化とリスト・パーティション化の他に)ハッシュ・パーティション化を使用してパーティション化されたXMLType表および列に対して、パーティション化されたローカルのXMLIndex索引を作成できます。

関連項目:

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

PL/SQLパッケージDBMS_XDBの分割

PL/SQLパッケージDBMS_XDBのサブプログラムおよび定数は、次のパッケージに分割されました。

- DBMS_XDB_ADMIN

- DBMS_XDB_CONFIG

- DBMS_XDB_REPOS

パッケージDBMS_XDB_CONFIGおよびDBMS_XDB_REPOSはOracle Database 12cリリース1 (12.1.0.1)で新たに導入されました。パッケージDBMS_XDBは、下位互換性のために引き続き存在します。

関連項目:

- 『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XDB_CONFIG」

- "DBMS_XDBからDBMS_XDB_CONFIGに移行した、非推奨となったPL/SQLサブプログラムおよび定数については、「非推奨となった機能」を参照してください

- 『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XDB_REPOS」

Digestアクセス認証によるリポジトリへのアクセス

Basic認証の他に、Digestアクセス認証(Digest認証とも呼ばれる)を使用してOracle XML DBリポジトリにアクセスできるようになりました。これにより、ユーザーの資格証明(ユーザー名、パスワードなど)を暗号化することで、データ全体の暗号化に伴うオーバーヘッドが生じません。

ユーザーの資格証明では、大/小文字が区別されます。具体的には、認証を受けるユーザー名は作成された名前と正確に一致する必要があります(デフォルトでは、すべて大文字)。

関連項目:

- ダイジェスト認証の構成方法は、「HTTPの認証メカニズムの構成および管理」を参照してください

- インストール、アップグレードおよびダウングレードの考慮事項は、「既存のOracle XML DBのインストールのアップグレードまたはダウングレード」を参照してください

DBFSのサポート

Oracle XML DBリポジトリから、リポジトリ・パス/dbfsの下にあるOracle Database File System (DBFS)のファイルとフォルダにアクセスできるようになりました。この新しい機能を使用すると、DBFSファイルとフォルダへのFTPおよびHTTP(S)/WebDAVアクセスが可能です。

関連項目:

- 『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』

- 『Oracle Databaseアップグレード・ガイド』

XQuery API for Java (XQJ)のサポート

Oracle XML Developer's KitおよびXQuery API for Java (XQJ)を使用し、JavaプログラムのXQuery式を使用してデータベースのXMLデータにアクセスできるようになりました。具体的には、ローカルのJavaプログラムから、リモート・データベースに格納されているXMLデータにアクセスできます。

関連項目:

- 「XQueryとXQJを使用したデータベース・データへのアクセス」

- XQJの使用の詳細は、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。

非推奨となった機能

次の機能は今回のリリースで非推奨となり、今後のリリースではサポートされない可能性があります。

- XMLTypeのCLOB記憶域(非構造化記憶域とも呼ばれる)は非推奨になりました。かわりにXMLTypeのバイナリXML記憶域を使用してください。
無意味な空白を維持する必要がある場合は、元のXML文書のコピーを2つ(1つはデータベースとXMLの処理で使用するXMLTypeインスタンスとして、もう1つはドキュメントの再現性を実現するCLOBインスタンスとして)格納します。

- オブジェクト・リレーショナルXMLTypeデータに埋め込まれているCLOBインスタンスとして格納されたXMLフラグメントに対するXMLIndex索引の作成は、非推奨になりました。このようなフラグメントのデータを索引付けする必要がある場合は、オブジェクト・リレーショナル記憶域ではなく、バイナリXML記憶域を使用して文書を格納します。

- 次に示す、パッケージDBMS_XMLSCHEMA内のPL/SQLサブプログラムは非推奨になりました。

- generateSchema

- generateSchemas

これらの構造体の代用はなく、この変更に対する回避策はありません。

- DBMS_XDB_CONFIGは新しいPL/SQLパッケージです。Oracle XML DBの構成に関する関数、プロシージャおよび定数はすべて、パッケージDBMS_XDBからDBMS_XDB_CONFIGに移行しました。これらは、パッケージDBMS_XDBでは非推奨です。かわりにパッケージDBMS_XDB_CONFIGで使用することをお薦めします。
パッケージDBMS_XDBで非推奨となったサブプログラムは次のとおりです。

- ADDHTTPEXPIREMAPPING

- ADDMIMEMAPPING

- ADDSCHEMALOCMAPPING

- ADDSERVLET

- ADDSERVLETMAPPING

- ADDSERVLETSECROLE

- ADDXMLEXTENSION

- CFG_GET

- CFG_REFRESH

- CFG_UPDATE

- DELETEHTTPEXPIREMAPPING

- DELETEMIMEMAPPING

- DELETESCHEMALOCMAPPING

- DELETESERVLET

- DELETESERVLETMAPPING

- DELETESERVLETSECROLE

- DELETEXMLEXTENSION

- GETFTPPORT

- GETHTTPPORT

- GETLISTENERENDPOINT

- SETFTPPORT

- SETHTTPPORT

- SETLISTENERENDPOINT

- SETLISTENERLOCALACCESS

パッケージDBMS_XDBで非推奨となった定数は次のとおりです。

- XDB_ENDPOINT_HTTP

- XDB_ENDPOINT_HTTP2

- XDB_PROTOCOL_TCP

- XDB_PROTOCOL_TCPS

関連項目:

『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XDB_CONFIG」

- XMLデータを更新するためのOracle SQL関数はすべて非推奨になっています。かわりにXQuery Updateを使用することをお薦めします。非推奨のXML更新関数は次のとおりです。

- updateXML

- insertChildXML

- insertChildXMLbefore

- insertChildXMLafter

- insertXMLbefore

- insertXMLafter

- appendChildXML

- deleteXML

関連項目:

XMLデータを更新するための非推奨の関数

- Oracle SQL関数sys_xmlgenは非推奨になりました。かわりにSQL/XML生成関数を使用することをお薦めします。

関連項目:

「SQL関数を使用したXMLデータの生成」

- 次のOracle XQuery関数は非推奨になりました。かわりに、対応する標準のXQuery関数(同じ名前に名前空間接頭辞fnの付いた関数)を使用してください。

- ora:matches: かわりにfn:matchesを使用

- ora:replace: かわりにfn:replaceを使用

- XML変換をサポートする次のOracle構造体は非推奨になりました。

- PL/SQLパッケージDBMS_XMLTRANSLATIONS

- Oracle XPath関数ora:translate

- XML Schema注釈xdb:maxOccurs、xdb:srclangおよびxdb:translate

これらの構造体の代用はなく、この変更に対する回避策はありません。

関連項目:

非推奨となったXML変換の構造体

- 次のXML Schema注釈は非推奨になりました。

- xdb:defaultTableSchema

- xdb:maintainOrder

- xdb:mapUnboundedStringToLob

- xdb:maxOccurs脚注 1

- xdb:SQLCollSchema

- xdb:SQLSchema

- xdb:srclang脚注 1

- xdb:storeVarrayAsTable

- xdb:translate脚注 1

これらの構造体の代用はなく、この変更に対する回避策はありません。

- エクスポート・パラメータdata_optionsの値xml_clobsは、Oracle Database 12cリリース1 (12.1)から非推奨になりました。

関連項目:

「XMLType表のエクスポートおよびインポートの概要」

サポート対象外機能

次の機能は、Oracleではサポートされなくなりました。今回のリリースでサポート対象外となった機能の詳細リストは、『Oracle Databaseアップグレード・ガイド』を参照してください。

- CTXSYS.CTXXPATH索引はサポートされていません。かわりにXMLIndex索引を使用します

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

『Oracle XML DB開発者ガイド』でのOracle Database 11gリリース2 (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 XMLTypeデータ上のXMLIndex索引

その他の変更

次の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 XML DB開発者ガイド』でのOracle Database 11gリリース2 (11.2.0.2)の変更点は次のとおりです。

新機能

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データはデフォルトでBasicFiles LOB記憶域オプションを使用して格納されていました。今後、バイナリXMLデータのLOB記憶域では、デフォルトでSecureFiles LOB記憶域オプションが可能なかぎり使用されます。

SecureFiles LOB記憶域が使用できない場合は、デフォルトでBasicFiles LOB記憶域が使用されます。これは、次のいずれかの場合に発生します。

- XMLType表の表領域で、自動セグメント領域管理が使用されていない。

- ファイルinit.oraの設定により、SecureFiles LOB記憶域を使用できない。例として、パラメータDB_SECUREFILEを参照してください。

関連項目:

- 自動セグメント領域管理の詳細は、『Oracle Database管理者ガイド』を参照してください。

- パラメータDB_SECUREFILEの詳細は、『Oracle Databaseリファレンス』を参照してください。

- 「非推奨の機能」

この機能は、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」

非推奨となった機能

次の機能は今回のリリースで非推奨となり、今後のリリースではサポートされない可能性があります。

- BasicFiles LOB記憶域を使用してバイナリXMLとして格納されているXMLTypeデータ。新機能「バイナリXMLのデフォルトLOB記憶域」を参照してください。

- Oracle XQuery関数ora:view: かわりに、XQuery関数fn:docおよびfn:collectionを使用してください。「XQueryとOracle XML DB」を参照してください。

Oracle Database 11gリリース2 (11.2.0.1)でのOracle XML DBの変更

『Oracle XML DB開発者ガイド』でのOracle Database 11gリリース2 (11.2.0.1)の変更点は次のとおりです。

新機能

Oracle Database 11gリリース2(11.2.0.1)では、Oracle XML DBの次の機能が新たに導入されました。

XMLType表および列のパーティション化

オブジェクト・リレーショナル形式で格納されたXMLTypeデータの場合、XMLType実表またはXMLType列を持つ実表をパーティション化すると、ヒープに基づく表記憶域を使用するすべてのコレクション表に対しても、デフォルトで自動的に同一レベル・パーティション化が行われるようになりました。同一レベル・パーティション化とは、実表のパーティションごとに、対応するコレクション表パーティションが存在するということです。子要素は、その親要素の実表パーティションに対応するコレクション表パーティションに格納されます。

関連項目:

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

アクセス制御の拡張

アクセス制御リスト(ACL)が拡張され、カスタマイズ可能なファイングレイン・アクセス制御を行うことができます。

独自の権限を定義して、柔軟な方法でそれらの権限をユーザーおよびロールに関連付けることができます。アクセス制御エントリ(ACE)では、開始日と終了日を指定できます。アプリケーションのユーザーおよびロールのアクセスを制御できます。これらは必ずしも、データベースのユーザーおよびロールと同じとはかぎりません。

関連項目:

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

リポジトリの読取りおよび書込みパフォーマンスの拡張

Oracle XML DBリポジトリの読取りおよび書込み操作のパフォーマンスが向上しました。

バイナリXMLのパフォーマンス拡張およびパーティション化

バイナリXML表に対する問合せおよびDML操作のパフォーマンスが向上しました。また、仮想列をパーティション化キーとして使用して、バイナリXML表をパーティション化できるようになりました。

XMLIndexの拡張

XMLIndexを使用すると、通常は構造化されていないコンテンツに埋め込まれた構造化XMLコンテンツのアイランドに索引を付けることができます。このためXMLIndex索引では、構造化XMLコンテンツと非構造化XMLコンテンツのどちらにも索引を付けることができます。

パーティション化されたXMLType表のデータに対して、ローカルのXMLIndex索引を作成できます。

関連項目:

「XMLIndex」

コストベースのXPathリライト

新しいオプティマイザ・ヒントを使用して、XQuery式のコストベースの最適化を要求できます。

関連項目:

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

オブジェクト・リレーショナル記憶域の新しいデフォルトの型マッピング

オブジェクト・リレーショナル形式で格納されているXMLTypeデータでは、XML Schemaデータ型がSQLデータ型にマップされます。デフォルトのマッピング・セットは定義されていますが、指定したXML Schemaの特定部分に使用される特定のマッピングを指定することにより、これらを上書きできます。

新しいデフォルトのマッピング・セットが今回用意されました。Oracle Database 11gリリース2 (11.2.0.1)より前に使用可能であったデフォルト・マッピングとの違いを次に示します。新しいデフォルトのマッピング・セットでは、

- xs:floatは、NUMBERではなくBINARY FLOATにマップされています。

- xs:dateTimeは、TIMESTAMPではなくTIMESTAMP WITH TIMEZONEにマップされています。

- 4000バイトより長いxs:stringインスタンスは、デフォルトでVARCHAR2(4000)型ではなくCLOB型になります。

デフォルトでは、下位互換性を確保するため、古いデフォルトのマッピング・セットが使用されます。新しいデフォルトのマッピングをかわりに使用するには、次の両方を実行する必要があります。

- init.oraファイル内のデータベース・パラメータcompatibleを11.2以上に設定します。

- Oracle XML DB構成ファイルxdbconfig.xml内の要素default-type-mappingsをpost-11.2に設定します。

関連項目:

「XML Schemaデータ型のSQLデータ型へのマッピング方法」

非推奨となった機能

次の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、XMLExistsおよびXMLCast」を参照してください。

- 関数XMLCastおよびXMLQueryの使用方法の詳細は、「Oracle XML DBのXMLCAST SQL/XML関数」を参照してください。

- Oracle SQL関数existsNode: かわりに、SQL/XML関数XMLExistsを使用してください。「Oracle XML DBの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を使用してください。「XMLTypeに対するファンクション索引の非推奨化」を参照してください。

Oracle Database 11gリリース1 (11.1)でのOracle XML DBの変更

『Oracle XML DB開発者ガイド』でのOracle Database 11gリリース1 (11.1)の変更点は次のとおりです。

新機能

Oracle Database 11gリリース1(11.1)では、Oracle XML DBの次の機能が新たに導入されました。

バイナリXML

バイナリXMLは、抽象データ型XMLTypeの記憶域モデルです。バイナリ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次索引によって構成されます。XMLTypeデータの索引を参照してください。

注意:

CTXSYS.CTXXPath索引は、Oracle Database 11gリリース1(11.1)で非推奨になりました。CTXXPathによって提供されていた機能は、XMLIndexで提供されるようになります。

CTXXPath索引をXMLIndex索引に置換することをお薦めします。今後リリースされるデータベースでは、CTXXPathはサポートされなくなります。

関連項目:

新規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が使用されます。

XML Schema注釈xdb:storeVarrayAsTableのデフォルト値をtrueに変更

以前のリリースでは、XML Schema注釈xdb:storeVarrayAsTableのデフォルト値はfalseでしたが、trueに変更されました。

これは、XMLコレクションがOrdered Collections in Tables(OCT)内に一連の行として格納されることを意味します。各行がコレクション内の要素に対応します。注釈がxdb:storeVarrayAsTable = "false"となっている場合、コレクション全体がかわりにシリアライズされてLOB列にvarrayとして格納されます。

xdb:storeVarrayAsTable = "true"を使用すると、コレクションを効率的に使用して問合せ、更新、およびBツリー索引の作成を行うことができます。

リポジトリのイベント

アプリケーションでは、リソースの作成、削除、更新など、Oracle XML DBリポジトリに関するイベントのハンドラによって、リスナーを登録できるようになりました。「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リポジトリにアクセスできるようになります。「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固有の基本権限もいくつか新たに用意されています。 リポジトリのアクセス制御を参照してください。

関連項目:

- 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関数やプロシージャにアクセスできます。「ネイティブなOracle XML DB Webサービス」を参照してください。

インプレースXML Schemaの拡張

ほとんどのケースで、対応するXMLインスタンス・ドキュメントをコピーせずに、XML Schemaを拡張できるようになりました。

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標準をサポートしています。「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ノードの処理」を参照してください。

関連項目:

- バイナリ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をお薦めします。「Oracle XML DBデータのエクスポートとインポート」を参照してください。

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アクセスで使用されます。

関連項目:

DBMS_NETWORK_ACL_ADMINパッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

SQL/XML標準準拠とパフォーマンスの拡張

Oracle XML DBによるSQL/XML標準のサポートが更新され、最新バージョンの標準が反映されています。これには、標準的なSQL関数XMLExistsおよびXMLCastのサポートなどがあります。「XQueryとOracle XML DB」および「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変換のパフォーマンスが強化されました。

脚注の凡例

脚注1:
非推奨となったXML変換のサポートについては、「非推奨となった機能」も参照してください。

第I部 Oracle XML DBの基礎

Oracle XML DBの基礎を説明します。

- Oracle XML DBの概要

- Oracle XML DBを使用する前に

- Oracle XML DBの使用方法の概要

1 Oracle XML DBの概要

Oracle XML DBは、SQLとXMLの両方のデータ・モデルの相互運用を可能にすることで、Oracle DatabaseにネイティブなXMLサポートを提供します。

- Oracle XML DBの概要

- Oracle XML DBのメリット

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

- Oracle XML DBの機能

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

- Oracle XML DBの技術サポート

- Oracle XML DBの例

- OTNでのOracle XML DBの事例およびデモ

1.1 Oracle XML DBの概要

Oracle XML DBは、XMLデータの格納、生成、アクセス、検索、検証、変換、拡張および索引付けなどの高パフォーマンスの処理に関連する一連のOracle Databaseテクノロジです。SQLとXMLの両方のデータ・モデルの相互運用を可能にすることで、ネイティブなXMLサポートを提供します。

Oracle XML DBは、Oracle9iリリース2 (9.2)以上のOracle Databaseに組み込まれています。

Oracle XML DBおよびXMLType抽象データ型により、Oracle DatabaseはXML対応になります。XMLデータをXMLType列または表として格納すると、Oracle Databaseはコンテンツに対してXML固有の操作を実行できます。たとえば、XMLの検証や最適化の操作などです。XMLType記憶域では、データベース内のXMLコンテンツを非常に効率的に処理できます。

Oracle XML DBには、次のような機能があります。

- XMLデータの抽象SQLデータ型であるXMLTypeが用意されています。

- XMLコンテンツの信頼性、可用性、拡張性、堅牢なセキュリティなど、企業レベルのOracle Database機能を提供します。XML固有のメモリーを管理および最適化します。

- 業界標準の方法で、XMLデータをアクセスおよび更新できます。FTP、HTTP(S)およびWebDAVを使用して、XMLコンテンツをOracle Databaseの内外に移動できます。業界標準のAPIにより、Java、CおよびPL/SQLを使用してXMLコンテンツのプログラム・アクセスおよび操作を行うことができます。

- SQLおよびXQueryを使用してXMLデータにアクセスし、同時にそのデータを格納、更新および変換できます。

- SQLデータに対してXML操作を実行できます。

- 単純で軽量なリポジトリであるOracle XML DBリポジトリが備わっています。このリポジトリによって、ファイル/フォルダ/URL隠喩を使用して、XMLコンテンツを含むデータベース・コンテンツを編成および管理できます。

- 異なるシステムのデータにゲートウェイを介してアクセスし、1つの共通のデータ・モデルとして組み合せることができます。これによって、異なるストアのデータを処理する必要があるアプリケーション開発の複雑さが低減されます。

- Oracle XML DBをOracle XML Developer's Kit (XDK)とともに使用して、Oracle Fusion MiddlewareまたはOracle Databaseの中間層で動作するアプリケーションを構築します。

Oracle XML DBの機能は、関連するXML標準(XML Parser、XSLT Virtual Machine、XML DOM、XML Schema Validatorなど)のOracle XML Developer's KitのC実装に部分的に基づいています。

関連項目:

- 「XMLTypeデータ型」

- http://www.oracle.com/technetwork/database-features/xmldb/overview/index.htmlのOracle XML DBに関する最新情報およびホワイト・ペーパー

- 『Oracle XML Developer's Kitプログラマーズ・ガイド』

1.2 Oracle XML DBのメリット

Oracle XML DBでは、XML、SQL、Java、インターネットなど、すべての主要な標準がサポートされています。これは、XML操作の優れたパフォーマンスと拡張性を提供します。これにより、XMLの分野にトランザクション制御、データ整合性、レプリケーション、信頼性、可用性、セキュリティ、拡張性などのデータベース機能が追加されました。

図1-1は、Oracle XML DBでサポートされている標準の概要を示しています。

図1-1 Oracle XML DBのメリット

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

Oracle XML DBでは、標準データ・モデル、標準SQLおよび標準XMLを使用して、構造化、非構造化または半構造化のデータを格納および管理できます。XML文書に対してSQL操作を実行したり、(表などの)オブジェクト・リレーショナル・データに対してXML操作を実行することができます。

多くのアプリケーションのデータおよびWebコンテンツは、リレーショナル・データベースまたはファイル・システム内、あるいはその両方に格納されます。多くの場合、XMLデータはデータ交換に使用され、リレーショナル・データベースまたはファイル・システムから生成できます。交換されるXMLデータのボリュームが大きくなると、このデータを再生成するコストが増加し、XMLコンテンツの保存にはこれらの格納方法は効率的ではありません。

図1-2 データとコンテンツの統合: 一般的なXMLアーキテクチャ

多くの場合、企業は構造化データと非構造化データを異なる方法で管理しています。

- 表内に格納された非構造化データの場合、ドキュメント・アクセスが透過的になり、表アクセスが複雑になります。

- 通常はバイナリ・ラージ・オブジェクト(BLOBインスタンスなど)に格納された構造化データの場合、ドキュメント・アクセスが複雑になり、表アクセスが透過的になります。

1.2.1.1 XML操作のためのデータベース機能

Oracle Databaseは、索引付けと検索、更新とトランザクション処理、制約を使用した関係の管理、複数のデータ・ビュー、優れたパフォーマンスと拡張性など、XML操作のためのデータベース機能を提供します。これにより、XML Schema、XQuery、XPathおよびDOMがサポートされます。

- 索引付けおよび検索 - データベースのデータをある程度構造化できるように、問合せもある程度構造化できます。ある問合せでは、2014年の3月と4月の間に作成されすべての製品定義を検索できます。別の問合せでは、説明に"wireless"と"router"という単語が含まれるが"wireless router"という用語は含まれない製品を検索できます。
前者のような問合せは、構造化データを対象とし、通常は日付列のBツリー索引によってサポートされます。後者のような問合せは、非構造化データを対象とし、Oracle Databaseの場合は通常、Oracle Text (全文)索引によってサポートされます。アプリケーションでは構造化問合せと非構造化問合せを結合でき、対象データには構造化データと非構造化データが混在していてもかまいません。

XMLデータの場合も、状況は同様です。Oracle XML DBには、高度に構造化されたデータおよび問合せから高度に非構造化されたデータおよび問合せまでのXMLの能力範囲全体を対象とできる索引付け機能が用意されています。

関連項目:

- XMLデータの問合せと更新

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

- 「全文問合せ用のXMLデータの索引付け」

- 『Oracle Textアプリケーション開発者ガイド』

- 『Oracle Textリファレンス』

- 更新およびトランザクション処理: 商用のリレーショナル・データベースでは、レコードのサブパーツを高速更新することによって、更新を試行しているユーザー間の競合が最小化されています。従来、ドキュメント中心のデータは、XMLを介して協調環境を構築しているため、この要件はより重要になります。ファイル記憶域またはCLOB記憶域では、Oracle XML DBで行われる細分化された同時実行性制御を行うことができません。

関連項目:

XMLデータの問合せと更新

- 関係の管理: 通常、なんらかの構造を持つデータには外部キー制約があります。一般に、XMLデータを格納するシステムにはこの機能がないため、アプリケーション・コードで任意の制約を実装する必要があります。Oracle XML DBを使用すると、XML Schemaの定義に基づいてXMLデータを制約できるため、構造化データが持つ関係を制御できます。

関連項目:

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

- XMLデータの問合せと更新の発注書の例

- データの複数のビュー: 多くの企業アプリケーションでは、別々のモジュール用に、それぞれ異なる方法でデータをグループ化する必要があります。そのため、これらの複数の方法でデータを組み合せることができるように、リレーショナル・ビューが必要になります。Oracle XML DBでは、XMLでビューを使用することによって、様々なアプリケーションで使用する場合など、XMLに別々の論理的な抽象概念が作成されます。

関連項目:

XMLTypeビュー

- パフォーマンスとスケーラビリティ: データは、高速な格納、取出しおよび問合せが可能である必要があります。通常、ファイルまたはCLOB値のロードおよび解析は、リレーショナル・データのアクセスより遅くなります。Oracle XML DBでは、XMLの格納および取出しが大幅に高速化されます。

関連項目:

- Oracle XML DBを使用する前に

- Oracle XML DBの使用方法の概要

- 簡単な開発: データベースは、個々のデータ要素を簡単に操作、変換および変更するための標準的な手段を提供する、最も重要なアプリケーション・プラットフォームです。一般的なXMLパーサーでは、XMLデータに対する標準的な読取りアクセスが提供されますが、個別のXML要素を簡単に変更および格納する方法は提供されません。Oracle XML DBでは、データを格納、変更および取得するための標準的な方法がいくつかサポートされています。たとえば、XML Schema、XQuery、XPath、DOMおよびJavaなどを使用できます。

関連項目:

- XQueryとOracle XML DB

- Java DOM API for XMLType

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

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

1.2.1.2 データベースでデータをXMLとして格納する場合のメリット

データベースでデータをXMLとして格納することには、記憶域に非依存であることや、表示や交換が簡単であるという利点があります。

- 記憶域に非依存: リレーショナル設計を使用する場合、クライアント・プログラムでは、データの格納場所、形式、表および表間の関係が認識されている必要があります。XMLTypeを使用すると、その情報がなくてもアプリケーションを作成でき、データベース管理者は構造化データを物理表および列の記憶域にマップできます。

関連項目:

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

- 簡単な表示: XMLは、Webブラウザ、多くの一般的なデスクトップ・アプリケーションおよびほぼすべてのインターネット・アプリケーションでネイティブに認識されます。一般的に、リレーショナル・データは、アプリケーションから直接アクセスできません。一般のクライアントがリレーショナル・データにアクセスできるようにするには、追加のプログラミングを行う必要があります。Oracle XML DBでは、データはXMLとして格納され、データベース外部ではXMLとして使用可能になります。データベースのコンテンツを表示するためのプログラミングは必要ありません。

関連項目:

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

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

- XMLTypeビュー。

- 簡単な交換: XMLは、Business-to-Business(B2B)のデータ交換で使用される言語です。通常、XMLを任意の表構造に格納する必要がある場合は、XMLの内容を独自の方法で解釈し、分解します。言語を分解すると、情報が失われ、交換が困難になります。Oracle XML DBでは、XMLをネイティブに認識し、格納および取出し処理でのDOM再現性を提供することによって、完全な交換が可能になります。

関連項目:

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

- XMLTypeビュー

1.2.2 データの双対性: XMLおよびリレーショナル

Oracle XML DBでは、XMLデータとリレーショナル・データとして、対照的かつ双対的にデータを表示します。

Oracle XML DBの主要機能の1つは、XMLデータをリレーショナル・データであるかのように処理し、リレーショナル・データをXMLデータであるかのように処理できることです。XMLコンテンツの操作時にリレーショナル・モデルの機能を使用でき、リレーショナル・コンテンツの操作時にXMLの柔軟性を利用できます。個別のビジネス問題の様々な側面に対して最適のツールを使用できます。

この双対性とは、同じデータを表内の行として公開し、SQLを使用して操作できること、または同じデータをXML文書のノードとして公開し、XQuery、DOM変換またはXSL変換を使用して操作できることを意味します。アクセス方法と処理方法は、基礎となる記憶域方法とは関係がありません。

これらの機能によって、一般的なビジネス問題に対する単純なソリューションを提供できます。

- XMLデータをSQL問合せから直接生成できます。そのXMLデータを、データベースに常駐するXSLTプロセッサを使用して、HTMLなどの他の形式に変換できます。

- SQL問合せ、オンライン分析処理(OLAP)およびビジネス・インテリジェンス/データ・ウェアハウス操作を使用して、データ形式の変換を行わずにXMLコンテンツにアクセスできます。

- テキスト、空間データおよびマルチメディア操作をXMLコンテンツで実行できます。

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

XMLTypeビューでは、既存のリレーショナル・データまたはオブジェクト・リレーショナル・データをXML形式にラップする方法が提供されます。

これは、XML形式でないレガシー・データをXML形式に移行する必要がある場合に特に有効です。XMLTypeビューを使用すると、アプリケーション・コードまたは格納データを変更する必要がありません。

XMLTypeビューを使用するには、最初にXML Schemaデータ型と、SQLデータ型または双方向XMLエンコーディング型の間の双方向マッピングを表す注釈が付いたXML Schemaを登録する必要があります。その後、適切な型のインスタンスを構築する基礎となる問合せを指定することによって、このマッピングに準拠するXMLTypeビューを作成できます。

関連項目:

XMLTypeビュー

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

Oracle XML DBはXML操作のパフォーマンスと拡張性に優れ、複雑、大規模または多数のXML文書の格納と取得を管理できます。

Oracle XML DBの主要なパフォーマンス機能は次のとおりです。

- ネイティブなXMLType。抽象データ型XMLTypeには2つの記憶域モデルがあり、それぞれが特定の一連のユースケースに対して効率的に機能するよう最適化されています。 XMLデータの問合せと更新およびXMLType記憶域および索引付けの選択を参照してください。

- 最適化されたXQuery、XPathおよびXSLTの処理。「XQuery用のパフォーマンス・チューニング」およびXMLTypeデータの変換および検証を参照してください。

- 構造化された検索または全文検索のためのXMLデータの索引付け。「XMLTypeデータの索引」および「XQueryを使用しないXMLデータの全文検索」を参照してください。

- 遅延評価された仮想的なDOM。「PL/SQL DOM API for XMLType (DBMS_XMLDOM)」を参照してください。

- Oracle XML DBリポジトリに対する階層索引。Oracle XML DBリポジトリ操作のパフォーマンス・ガイドラインを参照してください。

- 並列度およびOracle Exadata Smart Scan。XMLデータの問合せおよび更新は並行して実行できます。Oracle Exadata Smart ScanはXMLデータに対して自動的に有効になります。

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

Oracle XML DBを使用すると、ローカルおよびリモートのXMLType表やビューの形式で、XMLデータへのプロトコル・アクセスおよびプログラム・アクセスが可能になります。これにより、リソースのバージョニングとアクセス制御がWebDAVリポジトリに提供されます。

図1-3に、Oracle XML DBのソフトウェア・アーキテクチャを示します。主な特徴は次のとおりです。

- XMLType表およびビューの記憶域。

- XMLType表およびビューは、XMLIndex、BツリーおよびOracle Text索引を使用して索引付けできます。

- XMLTypeビュー内のデータは、ローカル表またはリモート表に格納できます。リモート表には、データベース・リンクを使用してアクセスできます。

- XQuery UpdateおよびXQuery Full Textを含むXQueryのサポート。

- Oracle XML DBリポジトリ。Oracle XML DBに登録されるXML Schemaに関連付けられたXML文書など、任意の種類のドキュメントをリポジトリに格納できます。リポジトリ内のドキュメントには、次のいずれかの方法でアクセスできます。

- HTTPプロトコル・ハンドラを介したHTTP(S)

- WebDAVおよびFTPプロトコル・ハンドラを介したWebDAVおよびFTP

- Java Database Connectivity(JDBC)などのOracle Net Servicesを介したSQL

図1-3 XMLType記憶域

関連項目:

- Oracle XML DBでのXMLデータの操作

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

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

1.4 Oracle XML DBの機能

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データ型

- XMLType記憶域モデル

- XML Schemaのサポート

- XMLに関連する静的データ・ディクショナリ・ビュー

- SQL/XML標準関数

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

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

1.4.1 XMLTypeデータ型

XMLTypeを使用すると、XML開発者は、リレーショナル・データベースのコンテキスト内で作業中にXML標準の機能を使用でき、SQL開発者は、XMLデータを操作中にリレーショナル・データベースの機能を使用できます。

XMLTypeは、XMLデータの抽象ネイティブSQLデータ型です。これは、XMLTypeインスタンスをVARCHAR2、CLOB、BLOBまたはBFILEインスタンスから作成するためのPL/SQLおよびJavaコンストラクタを提供します。また、様々なXML操作用のPL/SQLメソッドも提供します。

他のSQLデータ型と同じようにXMLTypeを使用できます。たとえば、XMLType表やビュー、またはリレーショナル表にXMLType列を作成できます。

XMLTypeは、PL/SQLストアド・プロシージャのパラメータ、戻り値および変数に使用できます。

Java Database Connectivity (JDBC)、XQuery for Java (XQJ)およびOracle Data Provider for .NET (ODP.NET)などのJavaおよびC言語用Application Programming Interface (API)を使用して、XMLTypeデータを操作することもできます。

XMLTypeはOracle Databaseオブジェクト型であるため、XMLTypeオブジェクト・インスタンスの表も作成できます。デフォルトでは、XMLType表または列に整形式のXML文書を含めることができます。

XMLデータに準拠するようXMLType表または列を制約でき、この場合、データベースでは、XML Schemaに対して有効であるXMLデータのみが表または列に確実に格納されます。無効な文書は除外されます。

関連項目:

- Oracle Databaseのオブジェクト型およびオブジェクト・リレーショナル形式の記憶域の詳細は、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照してください。

- XQJの使用については、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。

- XMLTypeコンストラクタおよびメソッドの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

1.4.2 XMLType記憶域モデル

XMLTypeは、データおよびその使用を最適にするための様々な記憶域モデルを提供する抽象データ型です。抽象データ型であるため、アプリケーションおよびデータベース問合せの柔軟性が増し、同じインタフェースをすべてのXMLType操作に使用できます。

XMLType表および列は、次に示す方法で格納できます。

- バイナリXML記憶域(デフォルト): XMLTypeデータは、XMLデータ専用に設計された事後解析のバイナリ形式で格納されます。バイナリXMLは、簡潔で事後解析型であり、XML Schema対応のXMLデータです。これは、事後解析の永続性とも呼ばれます。

- オブジェクト・リレーショナル記憶域: XMLTypeデータは、一連のオブジェクトとして格納されます。これは、構造化記憶域およびオブジェクトベースの永続性とも呼ばれます。

注意:

Oracle Database 12cリリース1 (12.1.0.1)以降、XMLType用の非構造化(CLOB)記憶域モデルは非推奨です。バイナリXML記憶域をかわりに使用してください。

適切な索引を使用すると、バイナリXML記憶域は、ほとんどのユースケースで優れたパフォーマンスを提供します。ただし、一部の高度なユースケースでは、オブジェクト・リレーショナル記憶域を使用する方がメリットがある場合があります。

XMLType記憶域は、データベースのインポート/エクスポートを使用してモデル間で変更できます。アプリケーション・コードの変更は不要です。アプリケーションをチューニングする際に、XML記憶域オプションを変更できます。

バイナリXML記憶域の場合、SecureFilesがデフォルトの記憶域オプションです。脚注1ただし、次のいずれかに当てはまる場合、SecureFiles LOB記憶域は使用できません。その場合は、BasicFilesがバイナリXMLデータのデフォルト・オプションになります。

- XMLType表の表領域で、自動セグメント領域管理が使用されていない。

- ファイルinit.oraの設定により、SecureFiles LOB記憶域を使用できない。例として、パラメータDB_SECUREFILEを参照してください。

関連項目:

- XMLType記憶域および索引付けの選択

- Oracle XML DBデータのエクスポートとインポート

- 『Oracle Database SQL言語リファレンス』のCREATE TABLEの項にあるLOB_storage_clauseの説明

- LOB記憶域オプション、SecureFilesおよびBasicFilesの詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照してください。

- 自動セグメント領域管理の詳細は、『Oracle Database管理者ガイド』を参照してください。

- パラメータDB_SECUREFILEの詳細は、『Oracle Databaseリファレンス』を参照してください。

1.4.3 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脚注 2)は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記憶域またはオブジェクト・リレーショナル記憶域のいずれか)を使用して格納できます。XML Schemaに基づかないXMLデータは、バイナリXML記憶域を使用してのみ格納できます。

また、既存のリレーショナル・データおよびオブジェクト・リレーショナル・データをXMLTypeビューとしてラップすることもできます(オプションでXML Schemaに基づく形式にできます)。受信したXML文書からXMLType記憶域にマップし、登録済のXML Schemaを使用してそのマッピングを指定できます。

関連項目:

- XMLType記憶域モデルの詳細は、XMLType記憶域および索引付けの選択を参照してください。

- Oracle XML DBでのXML Schemaの使用方法の詳細は、XML Schemaの格納と問合せ: 基本を参照してください。

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

一般的に、XML Schemaの方が、XML文書構造を定義する方法としてDTDよりも強力です。それでもやはり、Oracle XML DBではある程度までDTDを使用できます。

XML Schemaの場合と同様、DTDは、XML文書の使用可能な構造を定義する一連の規則です。DTDは、SGMLから書式を導出するテキスト・ファイルです。これらは、DTD要素DOCTYPEを使用するか、DOCTYPE参照を介して外部ファイルを使用して、XML文書に関連付けることができます。

Oracle XML DBでは、DTDではなくXML Schemaを使用してXMLType記憶域への構造化マッピングを定義しますが、XMLプロセッサは引き続きDTDにアクセスして解析できます。

注意:

DTDを使用して、この内部に定義されているXMLエンティティを取得できます。DTDから使用される情報は、エンティティのみです。DTD内の構造や型情報は、Oracle XML DBでは使用されません。

インラインDTDの定義

XMLインスタンス・ドキュメントにインラインDTDの定義が含まれる場合、その定義はドキュメントの解析時に使用されます。すべてのDTDの検証およびエンティティ宣言の処理は、この時点で行われます。ただし、解析後、実体参照は実際の値で置換され、元の実体参照は失われます。

外部DTDの定義

Oracle XML DBでは、Oracle XML DBリポジトリに格納された外部DTDの定義がサポートされます。/public/flights.dtdなど外部DTDの定義を含むXML文書を処理する必要があるアプリケーションでは、最初に、DTDドキュメントが/public/flights.dtdというパスでOracle XML DBに格納されていることを確認する必要があります。

関連項目:

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

1.4.5 XMLに関連する静的データ・ディクショナリ・ビュー

複数の静的データ・ディクショナリ・ビューがXMLに関連します。

表1-1に、これらのビューを示します。特定のビューに関する情報を取得するには、SQLコマンドDESCRIBEを使用します。

DESCRIBE USER_XML_SCHEMAS

表1-1 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パッケージおよびタイプ・リファレンス』

1.4.6 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標準関数の詳細は、 XMLデータの問合せと更新およびXQueryとOracle XML DBを参照してください。

- XMLデータを生成するためのSQL/XML標準関数の詳細は、「SQL関数を使用したXMLデータの生成」を参照してください。

- SQL/XML標準関数を使用するその他の例は、 Oracle XML DBの使用方法の概要を参照してください。

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

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

すべてのOracle XML DB機能には、C、PL/SQLおよびJavaからアクセスできます。

次のような様々な方法で、Oracle XML DBを利用する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を使用したプログラミングよりも柔軟性がありますが、実行時により多くのリソースを必要とする場合があります。

1.4.8 Oracle XML DBリポジトリ: 概要

Oracle XML DBリポジトリは、ファイル/フォルダ/URL隠喩を使用してXMLデータを処理するためのOracle Databaseのコンポーネントです。

Oracle XML DBリポジトリに含まれるリソースは、フォルダ(ディレクトリ、コンテナ)またはファイルのいずれかです。

リリース(フォルダまたはファイル)には、次の特性があります。

- パスおよび名前で識別されます。

- これにはコンテンツ(データ)が含まれ、XMLデータの場合がありますが、そうでなくてもかまいません。

- コンテンツに加えて、OwnerやCreationDateなどのシステム定義のメタデータ(プロパティ)のセットを持ちます。Oracle XML DBでは、この情報を使用してリソースを管理します。

- ユーザー定義のメタデータを持つ場合もあります。これは、システム定義のメタデータと同様に、コンテンツの一部ではないが、コンテンツに関連付けられている情報です。

- リソースにアクセスできる人およびその目的の操作を決定するアクセス制御リストが関連付けられています。

Oracle XML DBリポジトリは特にXMLコンテンツを取り扱うものですが、リポジトリを使用してXML以外の種類のデータを格納することもできます。リポジトリを使用して、Oracle Databaseに格納されているあらゆるデータにアクセスできます。

リポジトリ内のデータには、次の方法でアクセスできます。

- SQL - ビューRESOURCE_VIEWおよびPATH_VIEWを使用

- 標準プロトコル: FTP、HTTP(S)およびWebDAV

- PL/SQL: PL/SQLパッケージDBMS_XDB_REPOSを使用

- Java: Oracle XML DB Resource API for Javaを使用

Oracle XML DBは、リポジトリ・データにアクセスおよび操作するためのAPIに加えて、IETF WebDAVに基づく、次のリポジトリ・サービス用のAPIも提供します。

- バージョニング – PL/SQLパッケージDBMS_XDB_VERSIONを使用

- ACLセキュリティ - アクセス制御リスト(ACL)を使用

- フォルダリング - リポジトリ・パス名を使用

図1-4に、Oracle XML DBリポジトリのアーキテクチャを示します。

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

関連項目:

Oracle XML DBリポジトリ

1.5 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を検索できます。

- ANSI/ISO/IEC 9075-14:2011, Information technology—Database languages—SQL—Part 14: XML-Related Specifications (SQL/XML)。

- W3CのDOMレベル1.0および2.0コア勧告。動的アクセスのために、サーバーに格納されたXMLをXML DOMとして取り出すことができます。

- Java Database Connectivity(JDBC)API。XMLデータへのJavaアクセスを提供します。

- XQuery API for Java (XQJ)。XQueryを使用してXMLデータへのJavaアクセスを提供します。

- W3CのXSL 1.0勧告。XSLTを使用して、サーバーでXML文書を変換できます。

- プロトコル・サポート。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にアクセスできます。Webサービスは、WSDLおよびUDDIを使用して、Oracle XML DBおよびOracle Fusion Middlewareにより構築、公開または検索できます。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標準関数」を参照してください。

- XQJの使用については、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。

- OracleによるSQL/XML標準のサポートの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- XLinkおよびXPointerのサポートの詳細は、「Oracle XML DBでのXLinkおよびXIncludeの使用方法」を参照してください。

- プロトコル・サポートの詳細は、 プロトコルを使用したリポジトリへのアクセスを参照してください。

- Javaサーブレットの使用の詳細は、「JavaでのOracle XML DBアプリケーションの作成方法」を参照してください。

- SOAPの使用方法の詳細は、 Oracle Streams AQを使用したXMLデータの交換およびOracle Databaseアドバンスト・キューイング・ユーザーズ・ガイドを参照してください。

1.6 Oracle XML DBの技術サポート

Oracleサポート・サービスの通常のサポート・チャネルの他に、Oracle DatabaseのXML対応テクノロジの技術サポートが、Oracle Technology Network (OTN)のディスカッション・フォーラムから無償で利用できます。

ディスカッション・フォーラムのURLは、次のとおりです。https://community.oracle.com/community/database

1.7 Oracle XML DBの例

Oracle XML DBおよびXMLTypeの使用方法について説明する例は、様々なデータベース・スキーマ、サンプルXML文書およびサンプルXML Schemaに基づいています。

関連項目:

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

1.8 OTNでのOracle XML DBの事例およびデモ

OTNに接続し、Oracle XML DBの例、ホワイト・ペーパー、事例およびデモを参照してください。

OTNのURLは次のとおりです。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の多くの機能の使用方法を示します。このデモの一部は、 Oracle XML DBの使用方法の概要でも説明されています。

- SAX Loaderアプリケーション。このアプリケーションは、データベース外で複数のXML文書を含む大規模ファイルを分割し、一連の個別の文書としてデータベースに挿入する効率的な方法を示します。これは、スタンドアロンでWebベースのアプリケーションとして提供されます。

脚注の凡例

脚注1:
Oracle Database 11g リリース2 (11.2.0.2)より前は、BasicFilesオプションがバイナリXML記憶域のデフォルトでした。バイナリXMLデータに対するBasicFilesオプションの使用は非推奨になりました。

脚注2:
xsdは、XML Schema名前空間のスキーマのスキーマで使用される接頭辞のため、xsd:stringなど、XML Schemaデータ型に使用される名前空間の接頭辞にもなります。xsdは、XML Schemaファイルのファイル拡張子としてもしばしば使用されます。

2 Oracle XML DBを使用する前に

Oracle XML DBのソリューションを計画する場合に考慮する基本的な設計基準を示します。

- Oracle XML DBのインストール

- Oracle XML DBのユースケース

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

2.1 Oracle XML DBのインストール

Database Configuration Assistant (DBCA)を使用し、汎用テンプレートを使用してOracle Databaseを構築すると、Oracle XML DBが自動的にインストールされます。

Oracle XML DBがすでにインストールされているかどうかは、自分で判断できます。次の条件に当てはまる場合は、インストールされています。

- データベース・スキーマ(ユーザー・アカウント)XDBが存在する。確認するには、次の問合せを実行します。

SELECT * FROM ALL_USERS;

- ビューRESOURCE_VIEWが存在する。確認するには、次のコマンドを使用します。

DESCRIBE RESOURCE_VIEW

関連項目:

- Oracle XML DBの手動インストールの詳細は、 Oracle XML DBの管理を参照してください。

- データベース・スキーマXDBの詳細は、『Oracle Database 2日でセキュリティ・ガイド』を参照してください。

2.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に基づいて検証する必要がある。

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

Oracle XML DBアプリケーションを計画する場合は、いくつかの基本的な設計基準を考慮することをお薦めします。

例を次に示します。

- XMLデータを格納する方法

- XMLデータの構造

- アプリケーションの実装に使用する言語

- XMLデータを処理する方法

ただし、通常は、次のOracle XML DB機能から開始することをお薦めします。ほとんどのユースケースでは、これらを考慮すれば十分です。

- 記憶域モデル - バイナリXML

- 索引付け - XML検索文字列、XMLIndex (構造化コンポーネントあり)

- データベース言語 - SQL、SQL/XML関数あり

- XML言語 - XQueryおよびXSLT

- クライアントAPI - OCI、Thin JDBC、SQL .NET

関連項目:

- XMLType記憶域および索引付けの選択

- 「SQL/XML標準関数」

- XQueryとOracle XML DB

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

- C API for XML

- Java DOM API for XMLType

- Oracle XML DBおよびOracle Data Provider for .NET

2.3.1 XMLデータ記憶域

Oracle DatabaseにXMLデータを格納する方法は複数あります。

図2-1に、XMLTypeの表およびビューの記憶域の概要を示します。

図2-1 XMLデータに対するOracle XML DBの記憶域オプション

既存のリレーショナル・データがある場合は、XMLTypeビューをそのデータに作成することで、そのデータにXMLデータとしてアクセスできます。次を使用して、XMLTypeビューを定義できます。

- SQL/XML関数。 リレーショナル・データからのXMLデータの生成およびXQueryとOracle XML DBを参照してください。

- オブジェクトタイプ: オブジェクト表、オブジェクト・コンストラクタおよびオブジェクト・ビュー

アプリケーション用に選択した記憶域オプションにかかわらず、Oracle XML DBでは同じ機能が提供されます。使用する記憶域モデルは、アプリケーションのパフォーマンスおよびXMLデータの再現性に影響する場合がありますが、データを問合せおよび更新する頻度やアプリケーションで使用されるAPIとは関係がありません。

関連項目:

「XMLType記憶域モデル」

2.3.2 XMLデータの構造

XMLデータがどのように構造化されているか、およびXML Schemaに基づいているかどうかは、それを格納する方法に影響を及ぼすことがあります。

XMLデータがXML Schemaに基づいていない場合、その構造化の方法とは関係なく、XMLType表またはビューにバイナリXMLとして、またはOracle XML DBリポジトリのフォルダ内のファイルとして格納できます。オブジェクト・リレーショナル形式で格納することはできません。

XMLデータがXML Schemaに基づいている場合は、バイナリXMLまたはオブジェクト・リレーショナル形式で格納する必要があります。

関連項目:

XMLType記憶域および索引付けの選択

2.3.3 アプリケーションの実装に使用する言語

Oracle XML DBアプリケーションは、JavaまたはPL/SQLでプログラミングできます。

- Java(JDBC、Javaサーブレット)

関連項目:

- Java DOM API for XMLType

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

- PL/SQL

関連項目:

- PL/SQL API for XMLType

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

2.3.4 XMLの処理オプション

Oracle XML DBには、様々なXMLの処理オプションが用意されています。

Oracle XML DBアプリケーションを設計するときには次のものを使用でき、かつ考慮する必要があります。

- XMLの生成およびXMLTypeビュー。XMLデータを生成(または再生成)する必要があるかどうか。 リレーショナル・データからのXMLデータの生成を参照してください。

- アプリケーションがデータ中心、ドキュメント中心、またはその両方のいずれであるか。 Oracle XML DBの使用方法の概要を参照してください。

- DOM再現性、ドキュメントの再現性。XMLType記憶域は、オブジェクト・リレーショナルまたはバイナリXMLに関係なく、DOM再現性を維持します。つまり、XMLTypeとして格納されているXML文書から作成されたDOMは、元の文書から作成されたDOMと同じです。ただし、無意味な空白は異なる可能性があります。「DOM再現性」、「SYS_XDBPD$とオブジェクト・リレーショナル記憶域のDOM再現性」およびPL/SQL API for XMLTypeを参照してください。
DOM再現性以外にも、ドキュメントの再現性(無意味な空白)を維持する必要がある場合は、元の文書のコピーを2つ(1つはデータベースとXMLの処理で使用するXMLTypeインスタンスとして、もう1つはドキュメントの再現性を実現するCLOBインスタンスとして)格納します。

- XPath検索。SQL文に埋め込まれたXPath構文を使用すると、データベース内のXMLコンテンツを問い合せることができます。「XMLデータの問合せと更新」、「Oracle XML DBリポジトリのデータへのアクセス」、「RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス」および「XQueryを使用しないXMLデータの全文検索」を参照してください。

- XML文書はどれほどの頻度でアクセス、更新および操作されるか。 XMLデータの問合せと更新を参照してください。

- 更新の対象は文書のフラグメントか、または文書全体か。XPath式を使用して、文書全体を再書込みせずに、更新中に文書の個々の要素および属性を指定できます。これは、特に大規模なXML文書の場合により効率的です。「XMLデータの更新」を参照してください。

- どのような種類の索引付けがアプリケーションおよびデータに最も適しているか。「XMLTypeデータの索引」および「XQueryを使用しないXMLデータの全文検索」を参照してください。

- XSLT: XMLデータをHTMLやWMLなどの他の言語に変換する必要があるか、その場合は、アプリケーションによってこれがどのように実行されるか。Oracle XML DBにXML文書を格納中に、文書の構造が特定のXML Schemaに準拠するかどうか(妥当かどうか)を確認できます(オプション)。 XMLTypeデータの変換および検証を参照してください。

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

Oracle XML DBリポジトリを使用するアプリケーションの設計に関する考慮事項には、アクセス方法、セキュリティ・ニーズ、バージョニングが必要かどうかなどがあります。

リポジトリへのアクセス方法には、主に次の2つがあります。

- ナビゲーション・ベースのアクセスまたはパス・ベースのアクセス。これはコンテンツ/ドキュメントおよびデータ指向アプリケーションの両方に適しています。Oracle XML DBでは、次の言語およびアクセスAPIが提供されています。

- リソース・ビューおよびパス・ビューを介したSQLアクセス。 RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス を参照してください。

- パッケージDBMS_XDBまたはパッケージDBMS_XDB_ADMIN、DBMS_XDB_CONFIGおよびDBMS_XDB_REPOSを使用したPL/SQLアクセス。 Oracle XML DBリポジトリへのPL/SQLアクセス を参照してください。

- コンテンツ指向のアプリケーションに最適なHTTP(S)、WebDAVまたはFTPを使用したプロトコルベースのアクセス。 プロトコルを使用したリポジトリへのアクセスを参照してください。

- 問合せベースのアクセス。これはデータ指向アプリケーションに最適です。Oracle XML DBでは、次のAPIを介して、SQL問合せを使用するアクセスが可能です。

- (JDBCを介する)Javaアクセス。「Java DOM API for XMLType」を参照してください。

- PL/SQLアクセス。 PL/SQL API for XMLTypeを参照してください。

リポジトリ・データにアクセスするためのこれらのオプションは、Oracle XML DBリポジトリ・データへのアクセスでも説明しています。

次のアクセス基準についても考慮します。

- どの程度のセキュリティ・レベルが必要か。 リポジトリのアクセス制御を参照してください。

- データのバージョニングが必要かどうか。 リソース・バージョンを参照してください。

2.3.6 Oracle XML DBとその他のデータベース・オプションおよび機能との連携

Oracle XML DBはOracle Databaseに不可欠の部分であり、他のデータベースのオプションおよび機能と連携して機能します。

- Oracle Streamsアドバンスト・キューイング(AQ) – XMLペイロードをマージします。 Oracle Streams AQを使用したXMLデータの交換およびOracle Databaseアドバンスト・キューイング・ユーザーズ・ガイドを参照してください。

- Oracle GoldenGateおよびOracle Active Data Guard – XMLデータをレプリケートおよび保護したり、ローリング・アップグレードを実行します。Oracle GoldenGateおよび『Oracle Data Guard概要および管理』を参照してください。

- Oracle Exadata Storage Server Software – XMLデータを高いパフォーマンスかつ高い可用性でスケーラブルに使用します。『Oracle Database高可用性概要』を参照してください。

- Oracle Real Application Clusters (Oracle RAC) – XMLデータをデータベース・インスタンスのクラスタとともに使用します。『Oracle Real Application Clusters管理およびデプロイメント・ガイド』を参照してください。

- Oracle Multitenantオプション - 各プラガブル・データベースが独自のOracle XML DBリポジトリを持つマルチテナント・アーキテクチャでXMLデータを使用します。『Oracle Database概要』を参照してください。

- 圧縮および暗号化 - SecureFiles LOB記憶域を使用するバイナリXMLデータを圧縮および暗号化できます。オブジェクト・リレーショナル形式で格納されているXMLデータの場合、XMLの要素と属性を個別に圧縮または暗号化できます。

- 並行実行 - 次の操作を並行して実行できます。

- XMLTypeデータの問合せ

- SecureFiles LOBを使用してバイナリXMLとして格納されているXMLTypeデータのDML

- Oracle TextのCONTEXT索引が定義されているXMLType表の直接ロード

関連項目:

Oracle Database概要

3 Oracle XML DBの使用方法の概要

Oracle XML DBの様々な使用方法の概要について説明します。

この概要では、XMLType表および列の作成およびパーティション化、データ整合性の適用、データベースXMLコンテンツのロード、問合せおよび更新、リレーショナル・データからのXMLデータの生成を行う方法について説明します。また、XML文書で使用するキャラクタ・セットをOracle XML DBが判断する方法についても説明します。

主なXML Schema機能を示す発注書

この章の例の多くでは、発注書のXMLコンテンツへのアクセスおよび管理の方法を示します。発注書は高度に構造化された文書ですが、ほとんど構造化されていないXML文書に対しても、ここに示す方法を使用することができます。

ここで例として使用する発注書は、次のような一般的なXML文書の主要な機能を示す発注書XML Schemaに準拠しています。

- グローバル要素PurchaseOrderは、complexType PurchaseOrderTypeのインスタンスです。

- PurchaseOrderTypeでは、PurchaseOrder要素を構成する一連のノードが定義されます。

- LineItem要素は、LineItems要素のコレクションで構成されます。

- 各LineItem要素は、2つの要素(DescriptionおよびPart)で構成されます。

- Part要素には、属性Id、QuantityおよびUnitPriceがあります。

関連項目:

- ほとんどの用途に推奨されるOracle XML DB機能は、「Oracle XML DBのアプリケーション設計に関する考慮事項」を参照してください。

- Oracle XML DBのより高度な機能の詳細は、 XMLType API、XML Schemaとオブジェクト・リレーショナルXMLType および Oracle XML DBリポジトリを参照してください。

- この章の例で使用される発注書XML Schemaについては、「発注書XML Schema」を参照してください

この章の内容は次のとおりです。

- XMLType表および列の作成

- バイナリXMLとして格納されたXMLTypeデータでの仮想列の作成

- バイナリXMLとして格納されたXMLTypeデータが含まれる表のパーティション化

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

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

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

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

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

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

3.1 XMLType表および列の作成

XMLTypeは抽象データ型であるため、XMLType表または列は容易に作成できます。

記憶域オプションとXML Schemaを指定しない基本的なCREATE TABLE文では、XMLTypeデータはバイナリXMLとして格納されます。脚注 1

例3-1ではXMLType列を作成し、例3-2ではXMLType表を作成します。

関連項目:

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

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

CREATE TABLE mytable1 (key_column VARCHAR2(10) PRIMARY KEY, xml_column XMLType);

例3-2 XMLType表の作成

CREATE TABLE mytable2 OF XMLType;

3.2 バイナリXMLとして格納されたXMLTypeデータでの仮想列の作成

仮想列は、バイナリXMLとして格納されているXMLTypeデータに対してのみ作成できます。このような列は、データのパーティション化および制約に役立ちます。

XMLデータの仮想列は他のデータ型の場合と同じ方法で作成できますが、若干異なる構文を使用します。(特に、列定義に関連付けて制約を指定することができません。)

XML要素または属性に基づく仮想列を作成するには、その要素や属性を含むSQL式によって仮想列を定義します。したがって、作成される列はファンクション・ベースです。

これには、例3-3および例3-4に示すように、SQL/XML関数XMLCastおよびXMLQueryを使用します。関数XMLQueryのXQuery式引数は、子および属性の軸のみを使用する簡単なXPath式にする必要があります。

例3-3では、バイナリXMLとして格納されるXMLType表po_binaryxmlを作成しています。属性/PurchaseOrder/@orderDate内のXMLデータを表す仮想列date_colを作成しています。

例3-4では、主キー用のVARCHAR2列key_colとXMLデータ用のXMLType列xml_colという2つの列を持つリレーショナル表rel_tabを作成しています。

XMLTypeは抽象データ型なので、仮想列をXMLType表または列に作成する場合、それらの列は非表示になります。これらはDESCRIBE文などに表示されません。表示されないことで、DESCRIBEなどの操作を使用するツールが、仮想列に惑わされずに正常に機能することができます。

関連項目:

- 「バイナリXMLとして格納されたXMLTypeデータが含まれる表のパーティション化」

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

- 仮想列を使用した表の作成の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

例3-3 XMLType表内の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)));

例3-4 XMLType列内のXML属性の仮想列の作成

CREATE TABLE reltab (key_col VARCHAR2(10) PRIMARY KEY,
xml_col XMLType)
XMLTYPE xml_col STORE AS BINARY XML
VIRTUAL COLUMNS
(date_col AS (XMLCast(XMLQuery('/PurchaseOrder/@orderDate'
PASSING xml_col RETURNING CONTENT)
AS DATE)));

3.3 バイナリXMLとして格納されたXMLTypeデータが含まれる表のパーティション化

バイナリXMLとして格納されたXMLTypeデータが含まれる表をパーティション化できます。

2つの可能性があります。

- 表は、XMLType列および非XMLType列を持つリレーショナル形式です。

- 表は、データ型XMLTypeです。

XMLType列の場合、非XMLType列をパーティション化キーとして使用します。例3-5で説明します。

この例では、XMLデータに関して新しいことや特別なことは示されていません。列の1つにXMLTypeデータが含まれることは重要ではありません。異なるのは他のこと、つまり、XMLType表がパーティション化されていることです。

XMLデータには独自の構造がありますが、(XMLTypeのオブジェクト・リレーショナル記憶域を除き)、データベースのデータ構造には直接反映されません。バイナリXMLとして格納されたXMLTypeデータの場合、個別のXML要素および属性がデータベースの個別の列や表にマップされることはありません。

したがって、個別の要素や属性の値に応じてバイナリXMLデータをパーティション化する場合、リレーショナル・データの標準的な手法は適用できません。このため、対象のXMLデータを表す仮想列を作成してから、その仮想列を使用して必要な制約またはパーティションを定義する必要があります。

手順は次のとおりです。

1. 目的のXML要素または属性に対応する仮想列を定義します。

2. その列を使用して、XMLTypeデータを一括してパーティション化します。

これは例3-6で説明されています。仮想列date_colは、発注書の要素PurchaseOrderのorderDate属性をターゲットにしています。この列は、パーティション化キーとして使用されています。

XMLデータが含まれるパーティション化表を使用して最適なパフォーマンスを実現するには、XMLType表ではなくXMLType列を使用し、これにより、非XMLType列を使用してパーティション化することをお薦めします。

注意:

- 仮想列を使用してXMLType表をパーティション化できるのは、記憶域モデルがバイナリXMLである場合のみです。レンジ、ハッシュおよびリストのパーティション化がサポートされています。

- XMLとして格納されたXMLType表のパーティション化は、11gリリース2 (11.2)以降でサポートされます。データベースの互換性(ファイルinit.ora内のパラメータcompatible)が11.2以上の場合にのみサポートされます。

- リレーショナル表にXMLType列が含まれる場合、XMLデータの仮想列を定義する列を使用して表をパーティション化することはできません。

関連項目:

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

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

例3-5 XMLType列を持つリレーショナル表のパーティション化

CREATE TABLE reltab (key_col VARCHAR2(10) PRIMARY KEY,
xml_col XMLType)
XMLTYPE xml_col STORE AS BINARY XML
PARTITION BY RANGE (key_col)
(PARTITION P1 VALUES LESS THAN ('abc'),
PARTITION P2 VALUES LESS THAN (MAXVALUE));

例3-6 XMLType表のパーティション化

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.4 データベースを使用したXMLデータ整合性の規定

SQLおよびXMLの能力と、ルールを適用するデータベースの機能を組み合せることができます。

XML Schemaによって提供される機能を補完するために、SQLを使用できます。XMLType表または列に格納できるのは、整形式のXML文書のみです。整形式のXML文書とは、XML宣言で宣言されたXMLバージョンの構文に準拠しているXML文書です。これには、ルート要素が単一か、タグが適切にネストされているかなどが含まれます。さらに、XMLType表または列がXML Schemaに制限される場合、その表または列に格納できるのはXML Schemaに準拠する文書のみです。これ以外のXML文書をXML Schemaに基づくXMLTypeに格納または挿入しようとすると、エラーが発生します。例3-7に、これを示します。

このようなエラーは、コンテンツが直接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の部分検証と全体検証」

例3-7 不適切な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.

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

SQL制約およびデータベース・トリガーを使用して、一意性と外部キーの関係など、データ整合性プロパティを保証できます。

W3CのXML Schema勧告では、XML文書のコンテンツを定義するための強力な言語が定義されています。ただし、現在はW3CのXML Schema勧告で扱われていない簡単なデータ管理の概念がいくつかあります。たとえば、要素または属性の値が次のいずれかのプロパティを持っているかを確認できることなどです。

- XML文書のセット間で一意であること(UNIQUE制約)

- 現在の文書以外の特定のデータ・ソース内に存在していること(FOREIGN KEY制約)

ただし、Oracle XML DBでは、そうした制約を強制的に適用できます。XMLデータで整合性を規定するために使用するメカニズムは、リレーショナル・データで整合性を規定するためのメカニズムと同じです。一意性と外部キーの関係などの簡単なルールは、SQL制約を指定することによって規定できます。複雑なルールは、データベース・トリガーを指定して規定できます。

Oracle XML DBを使用すると、XML Schema構造体を使用して指定できるルールに加え、データベースを使用して、ビジネス・ルールもXMLコンテンツに実施することができます。データベースでは、XMLが表に直接挿入されているか、Oracle XML DBリポジトリでサポートされているプロトコルの1つを使用してアップロードされているかに関係なく、これらのビジネス・ルールを規定します。

XMLデータには独自の構造がありますが、(XMLTypeのオブジェクト・リレーショナル記憶域を除き)、データベースのデータ構造には直接反映されません。バイナリXMLとして格納されたXMLTypeデータの場合、個別のXML要素および属性がデータベースの個別の列や表にマップされることはありません。

したがって、個別の要素や属性の値に応じてバイナリXMLデータを制約する場合、リレーショナル・データの標準的な手法は適用できません。このため、対象のXMLデータを表す仮想列を作成してから、その仮想列を使用して必要な制約を定義する必要があります。

手順は次のとおりです。

1. 目的のXML要素または属性に対応する仮想列を定義します。

2. その列を使用して、XMLTypeデータを一括して制約します。

バイナリXMLデータは、XMLType表またはリレーショナル表のXMLType列に含まれる場合があります。前者の場合、必要に応じて、制約の作成をCREATE TABLE文の一部として含めることができます。後者の場合、リレーショナル表が作成された後、ALTER TABLE文を使用して制約を作成する必要があります。

関連項目:

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

- 「バイナリXMLとして格納されたXMLTypeデータでの仮想列の作成」

- 『Oracle Databaseエラー・メッセージ』

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

この例では、XMLType表の場合の方法を示しています。ここでは、発注書のReference要素を使用して、仮想列c_xtabrefを定義しています。この列に、表に格納されたすべての文書間でノード/PurchaseOrder/Reference/text()の値が一意であることを保証する一意性制約reference_is_uniqueを定義しています。表にはOE.purchaseorderのデータが入力されています。次に、重複文書DuplicateReference.xmlを挿入しようとしますが、これは一意性制約に違反し、エラーが発生しています。

CREATE TABLE po_binaryxml OF XMLType
(CONSTRAINT reference_is_unique UNIQUE (c_xtabref))
XMLTYPE STORE AS BINARY XML
VIRTUAL COLUMNS
(c_xtabref 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.

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-9 仮想列を使用したバイナリXML列の制約: 一意性

この例では、リレーショナル表のXMLType列の場合の方法を示しています。ここでは、仮想列c_xcolref、および例3-8で定義した一意性制約を参照するfk_refを定義しています。例3-8の場合のように、これは、XMLType列po_binxml_colに格納されたすべての文書間でノード/PurchaseOrder/Reference/text()の値が一意であることを保証しています。

この例では、XMLType列にOE.purchaseorderの同じデータが入力されています。次に、重複文書DuplicateReference.xmlを挿入しようとしますが、これは一意性制約に違反し、エラーが発生しています。

CREATE TABLE po_reltab (po_binxml_col XMLType)
XMLTYPE po_binxml_col STORE AS BINARY XML
VIRTUAL COLUMNS
(c_xcolref AS (XMLCast (XMLQuery('/PurchaseOrder/Reference'
PASSING po_binxml_col RETURNING CONTENT)
AS VARCHAR2(32))));

ALTER TABLE po_reltab ADD CONSTRAINT reference_is_unique UNIQUE (c_xcolref));

INSERT INTO po_reltab SELECT OBJECT_VALUE FROM OE.purchaseorder;
INSERT INTO po_reltab
VALUES (XMLType(bfilename('XMLDIR', 'DuplicateReference.xml'),
nls_charset_id('AL32UTF8')));
INSERT INTO po_reltab
*
ERROR at line 1:
ORA-00001: unique constraint (OE.REFERENCE_IS_UNIQUE) violated

例3-10 仮想列を使用したバイナリXML列の制約: 外部キー

この例は例3-9と似ていますが、例3-8で定義した一意性制約を持つ列を参照する外部キー制約fk_refを使用しています。ここでは、ファイルDuplicateReference.xmlの文書の挿入は、この文書が表po_binaryxmlの(仮想)列c_tabref内にあるため、成功しています。表po_binaryxml内の文書と一致しない文書の挿入です。

CREATE TABLE po_reltab (po_binxml_col XMLType)
XMLTYPE po_binxml_col STORE AS BINARY XML
VIRTUAL COLUMNS
(c_xcolref AS (XMLCast (XMLQuery('/PurchaseOrder/Reference'
PASSING po_binxml_col RETURNING CONTENT)
AS VARCHAR2(32))));

ALTER TABLE po_reltab ADD CONSTRAINT fk_ref FOREIGN KEY (c_xcolref)
REFERENCES po_binaryxml(c_xtabref);

INSERT INTO po_reltab
VALUES (XMLType(bfilename('XMLDIR', 'DuplicateReference.xml'),
nls_charset_id('AL32UTF8')));

INSERT INTO po_reltab
VALUES ('<PurchaseOrder><Reference>Not Compliant</Reference></PurchaseOrder>');
INSERT INTO po_reltab VALUES ('<PurchaseOrder><Reference>Not Compliant
</Reference></PurchaseOrder>')
*
ERROR at line 1:
ORA-02291: integrity constraint (OE.FK_REF) violated - parent key not found

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

XML Schemaに基づくXMLコンテンツがOracle XML DBリポジトリにロードされると、制約およびトリガーを使用して定義された整合性ルールも規定されます。この例では、XML Schemaに基づくXMLコンテンツが、FTPなどのプロトコルを使用してOracle XML DBリポジトリにアップロードされると、データベース整合性も適用されることを示します。この例では、一意性以外の別の制約も違反しています。

$ 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などのクライアントは単に汎用エラー・メッセージをレポートします。

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

XMLコンテンツをOracle XML DBにロードする方法は複数あります。

- 表ベースのロード:

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

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

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

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

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

- パスベースのリポジトリのロード方法:

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

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

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

SQLまたはPL/SQLの簡単なINSERT操作を使用して、XML文書をデータベースにロードできます。

文書は、XMLType列または表として格納する前に、XMLTypeコンストラクタの1つを使用してXMLTypeインスタンスに変換する必要があります。

関連項目:

- XMLデータの問合せと更新

- 「PL/SQL API for XMLType: リファレンス」

- XMLTypeコンストラクタの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

XMLTypeコンストラクタを使用すると、VARCHAR、CLOBおよびBFILE値を含む様々なソースからXMLTypeインスタンスを作成できます。このコンストラクタは、XMLTypeの作成に関連する処理量を減らす追加の引数を受け入れます。たとえば、ソースのXML文書が有効だとわかっている場合には、有効かどうかわからない場合に実行される型チェックを無効にする引数をコンストラクタに指定できます。

さらに、ソース・データがデータベース・キャラクタ・セットでエンコードされていない場合、XMLTypeインスタンスはBFILE値またはBLOB値を使用して構成できます。ソース・データのエンコーディングは、コンストラクタのキャラクタ・セットID(csid)引数で指定されます。

SQL INSERTを使用して、コレクションを含む大規模な文書を(XMLType列ではなく)XMLType表に挿入する場合、Oracle XML DBによってロード時間とメモリー使用量が最適化されます。

例3-13に、XMLコンテンツをXMLType表に挿入する方法を示します。この挿入を行う前に、処理するファイルが含まれたディレクトリを指すデータベース・ディレクトリ・オブジェクトを作成する必要があります。作成するためには、CREATE ANY DIRECTORY権限が必要です。

関連項目:

- 『Oracle Database SQL言語リファレンス』のGRANTを参照してください。

- 「コレクションでの大規模な文書のロードおよび取得の考慮事項」

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

CREATE DIRECTORY xmldir AS path_to_folder_containing_XML_file;

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

INSERT INTO mytable2 VALUES (XMLType(bfilename('XMLDIR', 'purchaseOrder.xml'),
nls_charset_id('AL32UTF8')));

nls_charset_idに渡される値は、読み取られるファイルのエンコーディングがUTF-8であることを示します。

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

JavaでDOMを使用してXMLTypeインスタンスをロードできます。

例3-14は、ドキュメント・オブジェクト・モデル(DOM)を指定して最初にJavaでXMLTypeインスタンスを作成することによって、XMLコンテンツをOracle XML DBにロードする方法を示しています。

単純なバルク・ローダー・アプリケーションが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インタフェースです。

例3-14 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();
}

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

CコードでDOMを使用してXMLTypeインスタンスをロードできます。

例3-15に、DOMを指定してXMLTypeインスタンスを作成することによって、CコードでXMLコンテンツをXMLType表に挿入する方法を示します。この例の完全なリストは、「C (OCI)を使用したXMLデータのロード」を参照してください。

注意:

この機能を簡単に説明するために、この例では、デプロイされたシステムで通常使用されるパスワード管理手法を実行していません。本番環境では、Oracle Databaseパスワード管理のガイドラインに従い、サンプル・アカウントをすべて無効化してください。パスワード管理のガイドラインおよびセキュリティに関するその他の推奨事項は、『Oracle Databaseセキュリティ・ガイド』を参照してください。

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

. . .
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();
}

3.5.4 小規模な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を参照してください。

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

SQL*Loaderを使用すると、大量のXMLデータをOracle Databaseにロードできます。

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オプションを使用して、各データ保存で読み取られる行数を少なくします。

関連項目:

XMLデータのロード方法

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

PL/SQLパッケージDBMS_XDB_REPOSを使用すると、XML文書をOracle XML DBリポジトリにロードできます。表ベースではなく、パスベースの方法でリポジトリの文書(リソース)にアクセスできます。

指定のパスのリポジトリにXML文書をロードするには、PL/SQL関数DBMS_XDB_REPOS.createResourceを使用します。例3-16に、これを示します。

Oracle XML DBを構成して使用するための多くの操作は、1つ以上のXML文書の処理に基づいています。たとえば、XML Schemaの登録や、XSL変換の実行などです。これらのXML文書をOracle Databaseで使用可能にする最も簡単な方法は、そのXML文書をOracle XML DBリポジトリにロードすることです。

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

DECLARE
res BOOLEAN;
BEGIN
res := DBMS_XDB_REPOS.createResource('/home/QUINE/purchaseOrder.xml',
bfilename('XMLDIR', 'purchaseOrder.xml'),
nls_charset_id('AL32UTF8'));
END;/

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

文書は、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スタイルシートが含まれていることがあります。

3.6 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データの索引付けの詳細は、XMLTypeデータの索引を参照してください。

3.6.1 例で使用されているXML文書PurchaseOrder

XML Schemaは、例で使用されている発注書を定義します。

ここに示す例は、例3-17のXML文書PurchaseOrderに基づいています。

例3-17 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>

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

疑似列OBJECT_VALUEは、オブジェクト表の値の別名として使用できます。

XMLTypeの単一列からなるXMLType表の場合、XML文書全体が取り出されます。(OBJECT_VALUEは、Oracle Database 10g リリース1より前のリリースで使用されていたvalue(x)およびSYS_NC_ROWINFO$別名に置き換わるものです。)

例3-18では、文書全体が改行なしで正しく出力されるように、SQL*Plus設定のPAGESIZEおよびLONGを使用しています。(読みやすいように、フォーマット出力で示しています。)

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

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.

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

SQL/XML関数XMLQueryを使用すると、XQuery式と一致するノードを抽出できます。結果は、XMLTypeのインスタンスとして戻されます。

例3-19に、複数の問合せの例を示します。

関連項目:

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

例3-19 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.

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

テキスト・ノードおよび属性値には、SQL/XML標準関数XMLQueryおよびXMLCastを使用してアクセスできます。

このためには、XMLQueryに渡されるXQuery式は、文書内の単一のテキスト・ノードまたは属性値(リーフ・ノード)を一意に識別する必要があります。例3-20に、複数の問合せを使用する例を示します。

関連項目:

SQL/XML関数XMLQueryおよびXMLCastの詳細は、XQueryとOracle XML DBを参照してください。

例3-20 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.

3.6.5 XMLEXISTS、XMLCASTおよびXMLQUERYを使用したXML文書の検索

SQL/XML標準関数XMLExists、XMLCastおよびXMLQueryをSQL WHERE句で使用すると、問合せ結果を制限できます。

SQL/XML標準関数XMLExistsは、指定された文書にW3CのXPath式と一致するノードが含まれているかどうかを評価します。これは、関数に指定されたXPath式によって指定されたノードが文書に含まれている場合はブール値のtrueを、そうでない場合はfalseの値を戻します。XPath式には述語を含めることができるため、XMLExistsは、指定されたノードが文書内に存在するかどうか、および指定された値を持つノードが文書内に存在するかどうかを判断できます。

同様に、関数XMLCastおよびXMLQueryを使用すると、問合せ結果を一部のプロパティを満たす文書に制限できます。例3-21に、XMLExists、XMLCastおよびXMLQueryを使用して文書を検索する方法を示します。

例3-22では、XML文書内のノードの値と別のリレーショナル表のデータに基づいて結合を実行しています。

関連項目:

SQL/XML関数XMLQuery、XMLExistsおよびXMLCastの詳細は、XQueryとOracle XML DBを参照してください。

例3-21 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.

この問合せでは、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.

次の問合せは、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.

次の例では、SQL/XML関数XMLQueryおよびXMLExistsを使用して、最初のLineItem要素にId 715515009058の注文が含まれるPurchaseOrder要素についてReference要素を検索します。関数XMLExistsをWHERE句で使用して、選択する行を決定し、XMLQueryをSELECTリストで使用して、選択された文書のどの部分を結果に表示するかを制御します。

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.

例3-22 XMLType表とリレーショナル表のデータの結合

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.

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

SQL/XML関数XMLTableを使用すると、XQuery式と一致する一連のノードに対してSQL操作を実行できます。

例3-19は、XPath式と一致する1つ以上のノードを含むXMLTypeインスタンスを戻す方法を示しています。指定されたXPath式と一致するノードが文書に複数含まれている場合、このような問合せでは、一致するすべてのノードが含まれるXMLフラグメントを戻します。XML文書と異なり、XMLフラグメントには、ルート要素である単一の要素はありません。

このような結果は、次の場合に一般的です。

- コレクションに含まれている一連の要素を取り出す場合。この場合、フラグメント内のすべてのノードは同じタイプです(例3-23を参照)。

- 対象のXPath式がワイルドカードで終わる場合。この場合、フラグメント内のノードは異なるタイプになることがあります(例3-25を参照)。

SQL/XML関数XMLTableを使用すると、XMLTypeインスタンスに含まれているXMLフラグメントを分割し、コレクション要素データを新しい仮想表に挿入することができ、その後、SQLを結合式などで使用して問い合せることができます。特に、XMLフラグメントを仮想表に変換することにより、複数のノードを戻すXMLQuery式の評価の結果を処理しやすくなります。

関連項目:

SQL/XML関数XMLTableの詳細は、XQueryとOracle XML DBを参照してください。

例3-23に、PurchaseOrder文書のDescription要素ごとにテキスト・ノードにアクセスする方法を示します。例3-19の単一のXMLフラグメント出力を複数のテキスト・ノードに分割します。

例3-24では、コレクション内の要素数をカウントします。また、ORDER BYやGROUP BYなどのSQLキーワードをSQL/XML関数XMLTableによって作成された仮想表データに適用する方法も示しています。

例3-25では、SQL/XML関数XMLTableを使用して、指定された要素の子要素の数をカウントする方法を示します。XMLTableに渡されるXPath式には、PurchaseOrder要素の直接の子孫である全要素と一致するワイルド・カード(*)が含まれます。XMLTableで作成された仮想表の各行には、XPath式と一致するノードが含まれます。仮想表内の行数をカウントすることによって、要素PurchaseOrderの子要素の数が判明します。

例3-23 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.

この例では、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を適用します。この例は、例9-2を参照してください。

例3-24 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.

この例の問合せでは、SQL/XML関数XMLExistsへのXPath式と一致する一連のXML文書が検索されます。これにより、次の2つの列を含む仮想表が生成されます。

- reference: この列には、選択された各文書のReferenceノードが含まれます。

- lineitem: この列には、選択された各文書の一連のLineItemノードが含まれます。

文書ごとにLineItemノードの数がカウントされます。相関結合によって、GROUP BYはLineItem要素が属するPurchaseOrder要素を正しく判別できます。

例3-25 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.

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

XMLコンテンツを更新する場合は、文書のコンテンツ全体または文書の特定部分のみを置換できます。

XML文書を部分的に更新する機能は非常に強力で、特に大きな文書に小さな変更を行う場合に、更新の実行に必要なネットワーク・トラフィックとディスクの入出力を大幅に削減できます。

文書に対する複数の変更を1回の操作で実行できます。どちらの場合も、XQuery式を使用して更新するノードを特定し、そのノードに新しい値を指定します。

例3-26では、要素Userに関連付けられたテキスト・ノードを更新します。

例3-27では、XML文書内の要素全体を置換します。XQuery式によって要素が参照され、置換値はXMLTypeオブジェクトとして渡されます。

文書に対する複数の変更を1つの文で実行できます。例3-28では、要素CostCenterおよびSpecialInstructionsに属するテキスト・ノードの値を1つのSQL UPDATE文で変更します。

例3-26 テキスト・ノードの更新

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 =
XMLQuery('copy $i := $p1 modify
(for $j in $i/PurchaseOrder/User
return replace value of node $j with $p2)
return $i'
PASSING OBJECT_VALUE AS "p1", 'SKING' AS "p2" RETURNING CONTENT)
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-27 XQuery Updateを使用した要素全体の置換

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 =
XMLQuery('copy $i := $p1 modify
(for $j in $i/PurchaseOrder/LineItems/LineItem[1]
return replace node $j with $p2)
return $i'
PASSING OBJECT_VALUE AS "p1",
XMLType('<LineItem ItemNumber="1">
<Description>The Lady Vanishes</Description>
<Part Id="37429122129" UnitPrice="39.95"
Quantity="1"/>
</LineItem>') AS "p2"
RETURNING CONTENT)
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-28 XQuery Updateを使用したテキスト・ノード値の変更

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 purchaseorder
SET OBJECT_VALUE =
XMLQuery('copy $i := $p1 modify
((for $j in $i/PurchaseOrder/CostCenter
return replace value of node $j with $p2)
(for $j in $i/PurchaseOrder/SpecialInstructions
return replace value of node $j with $p3))
return $i'
PASSING OBJECT_VALUE AS "p1",
'B40' AS "p2",
'Priority Overnight Service' AS "p3"
RETURNING CONTENT)
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.

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

Oracle XML DBを使用して、リレーショナル・データからXMLデータを生成できます。

関連項目:

- XQueryとOracle XML DB

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

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

標準のSQL/XML関数を使用すると、XML文書を1つ以上生成できます。

SQL/XML関数XMLQueryは、これを行うための最も一般的な方法です。この操作に使用できるSQL/XML関数には、他に次のものがあります。

- XMLElementは、要素を作成します。

- XMLAttributesは、属性を要素に追加します。

- XMLForestは、要素のフォレストを作成します。

- XMLAggは、要素のコレクションから単一の要素を作成します。

例3-29の問合せでは、これらの関数を使用して、表departments、locations、countries、employeesおよびjobsの情報を含むXML文書を生成します。

この問合せは、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関数でフォーマット出力が生成されなくても問題ありません。ただし、生成された出力を手動で検証することは困難になります。

また、SQL/XML生成関数を使用して構築されるXMLTypeビューを作成および問合せすることもできます。例3-30および例3-31に、これを示します。このようなXMLTypeビューには、リレーショナル・データをXMLコンテンツとして永続的に保持する効果があります。また、XMLTypeビューの行は、Oracle XML DBリポジトリに文書として永続的に保持できます。

例3-31では、SQL/XML関数XMLExistsに渡されるXPath式によって、問合せ結果セットは、Executive部門の情報が含まれたノードに制限されます。結果は、わかりやすくするためフォーマット出力しています。

注意:

XMLTypeビューで操作するXML式でのXPathリライトは、XPath式で参照するノードが、SQL関数XMLAggを使用して作成された要素の子孫でない場合にのみサポートされます。

例3-29 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>

例3-30 従来のリレーショナル表の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;

例3-31 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 BATCHED| 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.

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

SQL関数DBURITypeを使用して、リレーショナル・データからXMLデータを生成できます。

関数DBURITypeは、指定された表またはビューの1つ以上の行を単一のXML文書として公開します。ルート要素の名前は、表またはビューの名前から導出されます。ルート要素には、一連のROW要素が含まれます。表またはビュー内の行ごとにROW要素が1つずつあります。各ROW要素の子は、表またはビューの列から導出されます。各子要素には、指定された行の列の値を持つテキスト・ノードが含まれます。

例3-32に、SQL関数DBURITypeを使用して、データベース・スキーマHRの表departmentsのコンテンツにアクセスする方法を示します。メソッドgetXML()を使用して結果の文書をXMLTypeインスタンスとして戻します。

例3-33では、XPath述語を使用して、DBURITypeによって生成されるXML文書に含める行を制限する方法を示します。この例のXPath式によって、値が10のDEPARTMENT_ID列のみにXML文書が制限されます。

SQL関数DBURITypeを使用すると、リレーショナル表の一部または全部の行を1つ以上のXML文書として簡単に公開できます。関数DBURITypeに渡されるURLを拡張してビューまたは表から単一列を戻すことができますが、その場合、URLには、ターゲットの表またはビューの単一行を識別する述語も含まれる必要があります。

例3-34に、これを示します。述語[DEPARTMENT_ID="10"]句は、department_id列に値10が含まれるdepartments行について、department_name列の値を問合せで戻します。

SQL関数DBURITypeは、次の点でSQL/XML関数よりも柔軟性が低くなっています。

- DBURITypeでは、生成された文書の形式を制御できません。

- データは、単一の表またはビューからのみ生成できます。

- 生成される文書は、1つ以上のROW要素で構成されます。各ROW要素には、ターゲット表の列ごとの子が含まれます。

- 子要素の名前は、列の名前から導出されます。

XML要素の名前を制御する場合、複数の表からの列を含める場合、または生成される文書に含める表の列を制御する場合は、必要な列を単一行として公開するリレーショナル・ビューを作成してから、関数DBURITypeを使用して、そのビューのコンテンツからXML文書を生成します。

例3-32 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-33 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.

例3-34 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.

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

XML文書で使用するキャラクタ・セットをOracle XML DBが決定する方法はいくつかあります

注意:

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を使用すると、システムが停止したりセキュリティに悪影響を及ぼす可能性があります。入力した文書要素の名前にデータベース・キャラクタ・セットでサポートされない文字が含まれている場合、その文字は置換文字(通常は「?」)で置き換えられます。このため、解析が終了して例外が発生します。リカバリ不能なエラーが発生する場合もあります。

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

XMLエンコーディング宣言を使用して、指定された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

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

文書がデータベースにロードされるときには、XMLデータがCLOB値またはVARCHAR値から取得される場合を除き、文字エンコーディングはエンコーディング宣言によって決まります。

XMLデータがCLOB値またはVARCHAR値から取得される場合、これらの2つのデータ型は常にデータベース・キャラクタ・セットでエンコードされるので、エンコーディング宣言の存在は無視されます。

さらに、プログラムAPIまたは転送プロトコルのいずれかを介してデータをOracle XML DBにロードするときは、外部エンコーディングを指定して文書のエンコーディング宣言をオーバーライドできます。XML Schemaに基づくXML文書に指定のエンコーディングに対して不適切な文字が含まれている場合、その文書をロードしようとするとエラーが発生します。

次の各例で、外部エンコーディングを指定するいくつかの方法を示します。

- PL/SQLファンクションDBMS_XDB_REPOS.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_REPOS.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

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

XMLデータがCLOB値またはVARCHAR値に格納されている場合を除き、これをSQLクライアント、プログラムAPIまたは転送プロトコルを使用してOracle XML DBから取り出す場合に使用するエンコーディングを指定できます。

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)のキャラクタ・セット

脚注の凡例

脚注1:
XML Schemaに基づくデータのXMLType記憶域モデルは、参照するXML Schemaの登録時に指定したものです。登録時に記憶域モデルが指定されなかった場合、オブジェクト・リレーショナル記憶域が使用されます。

第II部 Oracle XML DBでのXMLデータの操作

ここでは、XQuery、XMLType操作およびXMLデータの索引付けについて説明します。

- XQueryとOracle XML DB

- XMLデータの問合せと更新

- XMLTypeデータの索引

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

4 XQueryとOracle XML DB

XQuery言語は、Oracle XML DBのXMLデータと対話する主な方法の1つです。この言語でのサポートには、SQL*PlusコマンドXQUERYおよびSQL/XML関数XMLQuery、XMLTable、XMLExistsおよびXMLCastがあります。

- XQuery言語の概要

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

- SQL/XML関数XMLQUERY、XMLTABLE、XMLExistsおよびXMLCast

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

- Oracle XQuery拡張関数

- Oracle XQuery拡張式プラグマ

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

- Oracle XML DBでのXQueryサポート

4.1 XQuery言語の概要

XQueryはXMLデータの問合せおよび更新のために設計されたW3C言語です。

Oracle XML DBでは、次のW3C XQuery標準をサポートしています。

- XQuery 1.0勧告

- XQuery Update Facility 1.0勧告

- XQuery and XPath Full Text 1.0勧告

この項では、XQuery言語の概要を示します。詳細は、この言語に関する最新の書籍や、それを定義している標準に関する文書(すべてhttp://www.w3c.org/から入手可能)を参照してください。

4.1.1 XQuery式に含まれるXPath式

XPath言語はXML文書をナビゲートするためのW3C勧告です。そしてXQuery言語のサブセットです。つまり、XPath式もXQuery式です。

XPathはXML文書をノードのツリーとしてモデル化します。このツリーを移動し、述語およびノード・テスト機能を適用するための一連の操作が備わっています。XPath式をXML文書に適用すると、ノードのセットが戻されます。たとえば、式/PO/PONOは、文書のPOルート要素の下にあるすべてのPONO子要素を選択します。

表4-1に、XPathで使用する共通構造体を示します。

表4-1 XPathの共通構造体

XPath構造体

説明

/

XPath式のツリーのルートを示します。たとえば、/POは、名前がPOであるルート・ノードの子を示します。

/

指定された要素ノードの子要素ノードを識別するためのパス区切りとして使用します。たとえば、/PurchaseOrder/Referenceは、ルート要素の子であるPurchaseOrder要素の子、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値として取得することもできます。

注意:

Oracle SQL関数およびXMLTypeメソッドは、W3C XPath勧告に準拠しています。このことは、XPath式がどのノードもターゲットにしていない場合にXMLデータに適用されると、空のシーケンスが戻される必要があることを示します。この場合にエラーが発生してはいけません。

4.1.2 XQuery: シーケンスに基づく関数言語

XQueryは多くの点で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データ・モデル(XDM)を定義します。XQueryシーケンスはXDMインスタンスとも呼ばれます。

4.1.2.1 XQueryとシーケンス

XQueryは常にシーケンスの操作に関わります。このためXQueryは集合操作言語に類似しています。ただしシーケンスは順序付けされていて、重複項目を含むことができる点が異なります。XQueryシーケンスが他の言語のシーケンスと異なる点は、ネストされたXQueryシーケンスは実際の効果において常にフラット化されるという点です。

多くの場合、シーケンスを順序のないものとして処理することにより最適化を促進できます。ただしそれは可能な場合に限られ、ユーザーの責任となります。この順序なしモードは、ネストされた反復(for)の処理で順序を結合する場合や、XPath式を処理する場合に適用できます(たとえば/a/bでは、一致するb要素は文書順序に関係なく処理できます)。

XQueryシーケンスはゼロ個以上の項目から構成されています。項目は、アトム型(スカラー)の値またはXMLノードです。項目は、XML Schemaの型に基づくリッチ型体系を使用して型指定されます。この型体系は、ブール、数値、および文字列といった単純なスカラー型に制限されていたXPath 1.0から大きく変更された部分です。

4.1.2.2 参照が透過的なXQuery

XQueryは関数言語です。このため、評価され、その評価によって値(結果)が戻される、実行可能な式の集合からなります。XQuery式の評価結果は2つの部分、つまり(a)シーケンス(XDMインスタンス)と(b)更新の保留中リストで構成され、少なくともどちらかは空です。簡単に説明すると、シーケンスは式の値と呼ばれることがあり、特に更新の保留中リストが空の場合は、実行するデータ更新がないことを意味します。

XQueryは関数言語なので、参照が透過的でもあります。つまり、同じコンテキストで評価された同じ式は、同じ値を戻します。

こうした数学的長所の例外には、次のものがあります。

- 外部環境との相互作用から値を導出するXQuery式。たとえば、fn:current-time(...)またはfn:doc(...)といった式は常に同じ値を戻すとはかぎりません。これは、それらの式が、変化する外部の条件に依存しているためです(時刻の変化、ターゲット文書のコンテンツの変化)。
fn:docのような場合には、XQueryは単一の問合せの実行の内部で参照が透過的なものと定義されます。単一の問合せの内部では、同じ引数を伴うfn:docの呼出しは、同じ文書を結果とします。

- 個別のXQuery言語の実装に依存するものとして定義されているXQuery式。そうした式の評価結果は、実装に応じて異なる場合があります。関数fn:docは、本質的に実装により定義される関数の例です。

XQuery Updateは、参照の透過性の例外に該当しないため、リストには含まれません。詳細は、「データに対するXQuery Updateの副次的な影響」を参照してください。

参照の透過性は、XQuery変数にも適用されます。同じコンテキストでの同じ変数は同じ値を持ちます。関数言語はこの点で、数学で言う形式主義に似ており、手続き型、または命令型のプログラミング言語とは異なっています。手続き型言語の変数は、実際にはメモリー位置の名前で、現在の値や状態を持っており、任意の時点におけるその内容により表現されます。XQueryなど宣言型言語における変数は、実際には静的な値の名前です。

4.1.2.3 データに対するXQuery Updateの副次的な影響

参照の透過性は、XQuery式の評価に適用されます。ただし、この評価によってユーザーのデータに副次的な影響がまったく生じないわけではありません。特に、XQuery Updateを使用してデータを変更する場合です。その変更内容は、XQueryの更新式を評価した結果の副次的な影響です。

ただし、副次的な影響と式の値とは異なります。評価から戻される値には更新の保留中リストが含まれ、それには実行する更新が記載されています。所定のXQuery式では、評価のコンテキストに関係なく(前述の例外はありますが)、この記載内容は同じです。

XQuery Update標準では、データのXDMインスタンスの更新方法を定義します。これらの更新内容が永続的なデータ・ストア(XMLType表および列など)に伝播される方法は実装に依存します。

4.1.2.4 XQuery Updateのスナップショット

XQuery式(問合せ)では、複数の更新操作をコールできます。XQuery Updateでは、同じ問合せでのこのような操作はすべてアトミック操作として実行され、すべて成功するか、またはすべて失敗するか(エラーが発生した場合)のいずれかになります。

つまり、変更の単位はXQuery問合せ全体です。このアトミックな更新動作を実現するため、XQuery Updateでは、問合せを評価する前に、問合せによってコールされる変更対象のデータ(XDMインスタンス)のスナップショットを取得します。問合せによってコールされる更新操作を更新の保留中リストに追加します。スナップショットは、更新ターゲットであるXDMインスタンスの評価コンテキストです。

XQuery式を評価する最後のステップとして、更新の保留中リストが処理され、指示された更新操作をアトミックに適用して、スナップショットを終了します。

スナップショット・セマンティクスのアトミック性は、指定された問合せで使用されている一連の更新操作が記載順に適用されるとはかぎらないことを意味します。実際には、更新操作の適用順序は、XQuery Update機能の標準によって固定および指定されます。

つまり、更新操作では同じ問合せにおける他の更新操作の結果を確認しません。中間的または暫定的な更新の状態という概念はなく、問合せの更新操作はすべてまとめてアトミックに適用されます。

4.1.2.4.1 スナップショット・セマンティクスを使用しないOracle XML Update関数(非推奨)

XMLデータを更新する非推奨のOracle SQL関数では、スナップショット・セマンティクスを使用しません。つまり、式にこのような関数コールが複数含まれている場合、それらは適用可能な順序(最も深いものが先)で処理され、各関数の適用結果は、その後に適用された更新関数によって参照されます。

これは、Oracleの更新関数(updateXMLなど)とXQuery Update関数との動作の大きな違いです。セマンティクスの違いに加え、パフォーマンスにも差があります。一般に、XQuery Updateのアトミック型の更新は、Oracle固有の関数による増分更新よりも、高いパフォーマンスを実現します。

4.1.2.5 XQuery Full Textの全文検索機能

XQuery and XPath Full Text 1.0勧告(XQuery Full Text)では、問合せでの全文検索に対するXQueryサポートを定義しています。それは、検索を実行してAllMatchesモデルのインスタンスを戻す全文選択の演算子を定義して、XQuery Data Model (XDM)を補完します。AllMatchesインスタンスには、指定された検索コンテキスト項目の全文問合せに対して実行可能なすべての解決が記述されます。各解決はMatchインスタンスに記述され、それには含む必要のある検索のコンテキスト・トークン(StringIncludeインスタンス)と除外する必要のあるStringExcludeインスタンスが含まれます。

簡単にいえば、XQuery Full Textはcontains全文式をXQuery言語に追加します。このような式を問合せで使用して、要素ノードとその子孫要素のテキストを検索します(属性ノードのテキストも検索可能)。

4.1.3 XQuery式

XQuery式では大/小文字が区別されます。XQuery式は、単純式または更新式のいずれかで、後者の式はデータの変更を表します。正確には、実行可能なXQuery式は次のとおりです。

- 基本更新式: insert、delete、replaceまたはrenameの各式、あるいは更新関数のコール(XQuery Update Facility 1.0勧告を参照)。

- 更新式: 基本更新式、または別の更新式を含んでいる(変換式以外の)式(これは再帰的定義です)。

- 単純式: XQuery 1.0式。更新処理はコールしません。

単純式の評価結果として戻される更新の保留中リストは空です。更新式の評価結果として戻されるシーケンス値は空です。

単純式は次のとおりです。

- 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は、値が整数の42である式です。(厳密には、値が型を表現していないので、これは型表現ではありません)。

- contains全文式: 全文検索を表すXQuery式。この式は、XQuery and XPath Full Text 1.0勧告によって提供されます。Oracleがサポートしているcontains全文式(FTContainsExpr)は、検索項目を指定する検索コンテキストと、これらの項目をフィルタ処理し、一致を取り出す全文選択の2つの部分で構成されています。
選択部分の構成要素は次のとおりです。

- トークンおよび句(一致で使用)。

- オプションのmatchオプション(ステミングの使用など)。

- オプションのブール演算子(全文選択の結合に使用)。

- オプションの制約演算子(位置フィルタなど。例: ordered window)。

詳細は、「XQuery Full Textのサポート」を参照してください。

4.1.4 FLWOR式

XQuery一般について考えた場合、特にFLWOR式には多くの学習事項があります。この項では、概要を簡単に紹介します。

FLWORはXQueryで最も一般的な式構文です。FLWOR(「フラワー」と読みます)は、for、let、where、order by、およびreturnを表しています。FLWOR式には1つ以上のforまたはlet句と、1つのreturn句を持ちます。1つのwhereおよびorder by句がオプションです。更新式を含むことができるのはreturn句のみで、それ以外の句はできません。

- 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式の最終的な結果です。フラット化されたシーケンスになります。
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シーケンスを構成する唯一の方法です。

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

Oracle XML DBのXQuery言語サポートは、SQL/XML関数XMLQuery、XMLTable、XMLExistsおよびXMLCastのネイティブ実装により提供されています。便宜性の観点から、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関数をさらに最適化することができます。結果として生じる最適化された演算子ツリーは、ストリーム方式で実行されます。

注意:

Oracle XML Developer's Kit (XDK)では、中間層のXQueryをサポートしています。XQueryを使用するためにOracle Databaseにアクセスする必要はありません。XDKによって、XQuery API for Java (XQJ)を使用したXQuery式の評価が可能になります。

関連項目:

- SQL/XML関数XMLQUERY、XMLTABLE、XMLExistsおよびXMLCastおよび「SQL*Plus XQUERYコマンドの使用」

- XQuery言語を拡張するOracle固有のXQuery関数については「Oracle XQuery拡張関数」

- Oracle XML DBのXQueryサポートの詳細は、「Oracle XML DBのXQueryサポート」

- XMLデータの問合せと更新

- XQJの使用については、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。

4.2.1 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を使用しても、期待できるパフォーマンスは、同じ一般的なレベルです。これは、いずれも最適化のリライト対象になります。

4.2.2 事前定義済のXQuery名前空間と接頭辞

いくつかの名前空間と接頭辞は、Oracle XML DBにおけるXQueryで使用するために事前定義されています。

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

接頭辞

名前空間

説明

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標準で事前定義されています。

4.3 SQL/XML関数XMLQUERY、XMLTABLE、XMLExistsおよびXMLCast

SQL/XML関数XMLQuery、XMLTable、XMLExists、XMLCastは、SQL/XML標準により、SQL言語とXQuery言語の一般インタフェースとして定義されています。

このマニュアルでは、それらはSQL/XMLの問合せおよび更新関数と呼ばれています。他の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言語リファレンス』を参照してください。

- XQuery言語の詳細は、http://www.w3.org/を参照してください。

- Oracle XML DBでの他のSQL/XML関数の使用方法の詳細は、「SQL関数を使用したXMLデータの生成」を参照してください。

4.3.1 Oracle XML DBのXMLQUERY SQL/XML関数

SQL/XML関数XMLQueryを使用して、XMLデータを構成または問い合せます。

この関数は引数としてXQuery式、文字列としてリテラル、そしてオプションで、XQueryコンテキスト項目をSQL式として取ります。コンテキスト項目は、XQuery式を評価する際のXPathコンテキストを確立します。この他に、XMLQueryは、XQuery式の評価の際にXQuery変数にバインドされた値を持つ任意の数のSQL式を引数として受け取ります。

関数はXQuery式の評価結果をXMLTypeインスタンスとして戻します。

図4-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で非推奨になりました。

関連項目:

Oracle DatabaseにおけるSQL/XML関数XMLQueryの参考情報は、『Oracle Database SQL言語リファレンス』を参照してください。

4.3.2 Oracle XML DBのXMLTABLE SQL/XML関数

SQL/XML関数XMLTableは、XQuery式の評価結果を新規の仮想表に対するリレーショナル行と列に分解します。このデータは、既存のデータベース表に挿入でき、またSQLを使用して(join式など)問合せできます。

例5-9を参照してください。

SQLのFROM句でXMLTableを使用します。

図4-2 XMLTABLEの構文

XML_namespaces_clause ::=

注意: DEFAULT string句を1つのみ指定できます。

XMLTABLE_options ::=

XML_passing_clause::=

XML_table_column ::=

- XQuery_stringは、XMLTableコールの行パターンと呼ばれる場合があります。これは、リテラル文字列としての完全な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から始まります。最大で1個のFOR ORDINALITY句がある必要があります。

- FOR ORDINALITY列を除き、生成された各列に列のデータ型を指定する必要があります。XMLTypeまたは任意のSQLデータ型(構文の説明でdatatypeと呼ばれる)を指定できます。

- データ型XMLTypeの場合、仕様(SEQUENCE) BY REFも含める場合は、PATH式(string)でターゲットとなっているソース・データへの参照がcolumnのコンテンツとして戻されます。それ以外の場合、columnにはそのターゲット・データのコピーが含まれます。
参照によってXMLTypeデータを戻すことで、ソース・データにおいてcolumnのPATH式でターゲットとなっているノード外のノードをターゲットにするその他の列を指定できます。例5-13を参照してください。

- オプションのPATH句は、XQuery式stringにより扱われたXQueryの結果の一部がcolumnコンテンツの一部として使用されることを示しています。このXQuery式は、列パターンと呼ばれる場合があります。複数のPATH句を使用してXQueryの結果を異なる仮想表の列に分割できます。
PATHを指定しない場合、XQuery式のcolumnとみなされます。たとえば、次の2つの式は等価です。

XMLTable(... COLUMNS foo)
XMLTable(... COLUMNS foo PATH 'FOO')

XQuery式stringはパスXQuery_stringに対して相対的であるため、相対パスの表記にする必要があります。

- オプションのDEFAULT句は、PATH式の結果が空のシーケンス(またはNULL)になる場合に使用する値を指定します。exprは、デフォルト値の生成用に評価するXQuery式です。

関連項目:

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言語リファレンス』を参照してください。

4.3.2.1 SQL/XML関数XMLTABLEのコールのチェーン

XMLType表に複数レベルで含まれているデータをリレーショナル表(またはビュー)の個別の行として公開する必要がある場合は、単一レベルの分割と同じ一般的な方法を使用します。つまり、SQL/XML関数XMLTableを使用して、表を構成する列の定義および列へのXMLノードのマッピングを行います。

ただし、この場合は、分割してリレーショナル列に格納する各文書レベルに関数XMLTableを適用します。複数のXMLTableコールをチェーンするこの技術は、XMLType表内の文書とリレーショナル表内の行との間に、1対多(1:N)関係がある場合はいつでも使用します。

1つのレベルのXMLTypeデータを、あるXMLTableコールから次のコールに渡し、その列タイプをXMLTypeで指定します。

2つのXMLTableコールをチェーンする場合、各コールの行パターンは、そのコールの列パターンで参照されるすべてのノードに対して共通の祖先である最深ノードを対象とします。

これについては例4-1に示しています。

XMLType表po_binaryxmlの各PurchaseOrder要素にLineItems要素が含まれていて、この要素に1つ以上のLineItem要素が含まれているとします。各LineItem要素には、DescriptionやItemNumber属性などの子要素があります。このような下位レベルのデータをリレーショナル値としてアクセス可能にするには、XMLTableを使用してLineItem要素のコレクションを投影します。

要素PurchaseOrderを、XMLTableの最初のコールで分割すると、その子孫であるLineItem要素は、XMLフラグメントが含まれている型XMLTypeの列にマップされます。この列は次に、XMLTableへの2回目のコールに渡され、リレーショナル値の複数の列として複数の部分に分割されます。

XMLTableの最初のコールでは、/PurchaseOrderを行パターンとして使用します。これは、PurchaseOrderが、列パターンReferenceおよびLineItems/LineItemの最深の共通祖先ノードであるためです。

XMLTableの2回目のコールでは、/LineItemを行パターンとして使用します。これは、そのノードが、各列パターン(@ItemNumber、Description、Part/@Idなど)の最深の共通祖先ノードであるためです。

最初のXMLTableコールから2回目のコールに渡される列(po.lineitem)の列パターン(LineItems/LineItem)は、2回目のXMLTableコールが分解する繰返し要素(LineItem)で終わります。この繰返し要素は先行スラッシュ(/)で作成され、2回目のXMLTableコールの行パターンの最初の要素として使用されます。

このようにして、各ケースの行パターンは、絶対パスで表します。つまり/で開始します。これは、XMLTableによる分割の開始点になります。一方で、列パターンの先頭がスラッシュ(/)になることはありません。つまり、同じXMLTableコールの行パターンと常に相対的になります。

例4-1 XMLTableコールのチェーン

SELECT po.reference, li.*
FROM po_binaryxml 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;

4.3.3 Oracle XML DBのXMLEXISTS SQL/XML関数

SQL/XML標準関数XMLExistsは、指定されたXQuery式から空でないXQuery順序が戻されるかどうかをチェックします。その場合、関数はTRUEを戻します。それ以外の場合はFALSEを戻します。

図4-3に、関数XMLExistsの構文を示します。

図4-3 XMLExistsの構文

XML_passing_clause::=

- XQuery_stringは完結したXQuery式で、プロローグをリテラル文字列として含む場合があります。XQueryのPASSING句(構文図のXML_passing_clause)を使用してバインドするXQuery変数を含めることができます。SQL/XML関数XMLQueryに対し認識されている、事前定義された名前空間の接頭辞は、XQuery_stringでも認識されています。詳細は、「事前定義済のXQuery名前空間と接頭辞」を参照してください。

- 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

注意:

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を使用できます。

4.3.4 ノードを検索するためのXMLExistsの使用

SQL/XML標準関数XMLExistsを使用して、特定のノードを検索できます。XMLExistsを使用してファンクション索引を作成できます。また、XMLIndex索引を作成して、任意のXQuery検索を高速化することもできます。

例4-2では、XMLExistsを使用して、SpecialInstructionsがExpediteに設定されている行を選択します。

例4-2 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.

4.3.5 Oracle XML DBのXMLCAST SQL/XML関数

SQL/XML関数XMLCastを使用して、SQLデータ型にXQuery値をキャストできます。

図4-4に、SQL/XMLの標準関数XMLCastの構文を示します。

図4-4 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データ型に変換されます。この変換に失敗すると、エラーが発生します。変換が成功すると、戻される結果は、ターゲット・データ型のインスタンスになります。

注意:

- Oracle Database 11gリリース2以前では、一部のユーザーは一部の処理の実行にOracle SQL関数extractValueを使用していました。これらの処理は、SQL/XML関数XMLQueryおよびXMLCastを使用してより効率的に実行できるようになっています。関数extractValueは、Oracle Database 11gリリース2で非推奨になりました。

- 関数extractValueでは、XPath式の引数が複数のテキスト・ノードに一致するとエラーが発生します。XMLQueryの結果にXMLCastを適用すると、テキスト・ノードが連結されて戻され、エラーは発生しません。

関連項目:

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

- 「XMLIndex」

4.3.6 XMLフラグメントのスカラー値を抽出するためのXMLCASTの使用

標準SQL/XML関数XMLCastを使用して、XMLフラグメントのスカラー値を抽出できます。

例4-3の問合せは、Referenceノードのスカラー値を抽出します。

例4-3 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.

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

XQuery関数fn:collectionを使用して、データベースの表およびビュー内のデータを問い合せることができます。

XQuery関数fn:docとfn:collectionを使用して、Oracle XML DBリポジトリのリソースに対して問い合せること(「XQueryを使用したOracle XML DBリポジトリ内でのXMLデータの問合せ」を参照)に加えて、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以外)列、またはある列と他方のような一方の名前が、表4-3で指定された正しい型の値である。他の型を使用すると、エラーが発生します。

表4-3 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とURIスキームoradbを使用したリレーショナル・データの問合せ」

4.5 Oracle XQuery拡張関数

Oracle XML DBには、W3C標準に用意されているものの他に、いくつかのXQuery関数が追加されています。それらの追加関数はOracle XML DB名前空間、http://xmlns.oracle.com/xdbにあります。この名前空間は事前定義の接頭辞oraを使用します。

注意:

Oracle Database 12cリリース1より前は、標準のXQuery関数fn:matchesとfn:replaceはサポートされておらず、Oracle XML DBでは、かわりにOracle XQuery関数(ora:matchesとora:replace)が使用されていました。これらのOracle XQuery関数は、Oracle Database 12cリリース1で非推奨になりました。かわりに、標準のXQuery関数(名前空間接頭辞fn)を使用してください。

4.5.1 ora:contains XQuery関数

Oracle XQueryおよびXPath関数ora:containsについて説明します。

ora:contains構文

ora:contains (input_text, text_query [, policy_name] [, policy_owner])

Oracle 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関数」

4.5.2 ora:sqrt XQuery関数

Oracle XQuery関数ora:sqrtは、数値引数の平方根を戻し、引数はXQuery型xs:decimal、xs:float、またはxs:doubleのいずれかです。戻り値のXQuery型は引数と同じです。

ora:sqrt構文

ora:sqrt (number)

4.5.3 ora:tokenize XQuery関数

Oracle XQuery関数ora:tokenizeでは、正規表現を使用して入力文字列target_stringを文字列のシーケンスに分割できます。

ora:tokenize構文

ora:tokenize (target_string, match_pattern [, match_parameter])

関数ora:tokenizeでは、正規表現match_patternと一致する部分文字列はそれぞれ、分割位置を示すセパレータとして扱われます。トークンのシーケンスは、型xs:string*のXQuery値(xs:string値のシーケンス)として戻されます。target_stringが空のシーケンスの場合は、それが戻されます。オプションの引数match_parameterは、検索文字列を修飾するコードで、大文字/小文字の区別などを指定できます。

引数の型は次のとおりです。

- target_string - xs:string?脚注3

- match_pattern - xs:string

- match_parameter - xs:string

4.5.4 ora:matches XQuery関数(非推奨)

Oracle XQuery関数ora:matchesは、Oracle Database 12cリリース1 (12.1.0.1)から非推奨になりました。かわりに、標準のXQuery関数fn:matchesを使用してください。

ora:matches構文

ora:matches (target_string, match_pattern [, match_parameter])

Oracle 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?脚注4

- match_pattern - xs:string

- match_parameter - xs:string

関連項目:

SQL条件REGEXP_LIKEの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

4.5.5 ora:replace XQuery関数(非推奨)

Oracle XQuery関数ora:replaceは、Oracle Database 12cリリース1 (12.1.0.1)から非推奨になりました。かわりに、標準のXQuery関数fn:replaceを使用してください。

ora:replace構文

ora:replace (target_string, match_pattern, replace_string [, match_parameter])

Oracle 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?脚注5

- match_pattern - xs:string

- replace_string - xs:string

- match_parameter - xs:string

さらにora:replaceは引数replace_stringを必要とし(regexp_replaceではオプション)、位置や出現回数を表す引数は使用しません。検索は最初の文字から開始され、すべての出現箇所が置換されます。

関連項目:

SQL関数regexp_replaceの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

4.6 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:child-element-name name #) - 挿入される子要素に使用する名前を指定します。一般に、このプラグマがないと、挿入される要素の名前はコンパイル時に不明とされます。名前を指定するとコンパイル時の最適化が可能で、実行時のパフォーマンスが向上します。
たとえば、次のSQL文では、要素LineItemsの子として挿入される要素ノードの名前に、LineItemを指定します。挿入される要素データはXQuery変数p2の値で、バインド変数:1から取得します。

UPDATE oe.purchaseorder p SET p.OBJECT_VALUE =
XMLQuery(
'copy $i :=
$p1 modify (for $j in $i/PurchaseOrder/LineItems
return (#ora:child-element-name LineItem #)
{insert node $p2 into $j)
return $i'
PASSING p.OBJECT_VALUE AS "p1", :1 AS "p2" RETURNING CONTENT)
WHERE XMLQuery(
'/PurchaseOrder/Reference/text()'
PASSING p.OBJECT_VALUE RETURNING CONTENT).getStringVal() =
'EMPTY_LINES';

このプラグマは、オブジェクト・リレーショナル形式またはバイナリXMLとして格納されたXMLTypeデータに適用されます。

- (#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:no_xmlquery_rewrite #)脚注 6: プラグマに続くXQuery式内のXQueryプロシージャのコールを最適化しません。かわりに機能上の評価を使用します。
これは、SQLヒント/*+ NO_XML_QUERY_REWRITE */と同じ効果がありますが、プラグマの範囲は後に続くXQuery式のみです(SQL文全体ではありません)。

関連項目:

「XML Schemaに基づくXMLTypeデータに対するXQueryの最適化」: オブジェクト・リレーショナル形式でXML Schemaに基づくXMLType表をターゲットとするXQuery式の例を示します

- (#ora:xmlquery_rewrite #)脚注 6: プラグマに続くXQuery式の最適化を試みます。つまり、もし可能な場合は、機能面で評価しないでください。
ora:no_xmlquery_rewriteとora:xmlquery_rewriteの両方の使用例として、次の問合せでは、XMLQueryに対するXQuery式の引数は、一般的に機能面で評価されますが、プラグマora:xmlquery_rewriteの後に続くfn:collection部分式は可能なかぎり最適化されます。

SELECT XMLQuery('(#ora:no_xmlquery_rewrite#) (: Do not optimize expression :)
{for $i in (#ora:xmlquery_rewrite#) (: Optimize subexp. :)
{fn:collection("oradb:/HR/REGIONS")},
$j in (#ora:xmlquery_rewrite#) (: Optimize subexpr. :)
{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;

- (#ora:no_schema #): XQuery Full Text式でXML Schemaに基づくXMLTypeデータを使用した場合に、エラーを発生させません。かわりに、XML Schemaに基づかないデータに対して暗黙的にデータをキャストします。つまり具体的には、XML Schemaデータ型を無視します。
XQuery Full Textがサポートされるのは、バイナリXMLとして格納されているXMLTypeデータのみなので、このプラグマが適用されるのも同じ場合のみです。

- (#ora:use_xmltext_idx #) – XML検索索引(使用可能な場合)を使用して問合せを評価します。XMLIndex索引またはストリーミング評価は使用しません。
XML検索索引は、バイナリXMLとして格納されているXMLTypeデータにのみ適用され、このプラグマも同様です。

- (#ora:transform_keep_schema #) - プラグマに従うXQuery式によって返される文書のXML Schema情報を維持します。これは、コピー・セマンティクスを使用するXQuery Updateで役立ちます。
プラグマを使用しない場合、XML Schemaに基づくデータがXQuery Update操作中にコピーされるとき、XML Schema情報が失われます。これは、XQuery Update標準で指定される動作です。その後、更新されたデータをXML Schemaベースの列または表に挿入しようとすると、エラーが発生し、挿入しようとしたデータは型指定がなくなるため、XML Schemaに準拠しなくなります。

プラグマを使用する場合、データはXML Schema情報を維持するため、挿入エラーが発生しません。ここでは、プラグマを使用する例を示します。

SELECT XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/xdbconfig.xsd"; (: :)
(#ora:transform_keep_schema#)
{copy $NEWXML :=
$XML modify (for $CFG in $NEWXML/xdbconfig//httpconfig
return (replace value of node
$CFG/http-port with xs:int($PORTNO)))
return $NEWXML}'
PASSING CFG AS "XML", 81 as "PORTNO" RETURNING CONTENT)
FROM DUAL;

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

可能な場合は、Oracle XML DBによって、問合せの静的(コンパイル時)型チェックが実行されます。

Oracle XML DBはすべてのXQuery式を型チェックします。しかし、実行時の型チェックはコストがかかることがあります。最適化技法として、指定された問合せに対してコンパイル時に十分な静的型情報を利用できる場合は常に、Oracle XML DBはその問合せの静的な(コンパイル時)型チェックを行います。指定された問合せに対してコンパイル時に十分な静的型情報を利用できない場合は、Oracle XML DBはその問合せの動的(実行時)型チェックを使用します。

静的型チェックでは、コンパイル時にエラーが発生するので、実行時間を節約できることがあります。静的型チェック・エラーには、データ型エラーと、XML Schemaの観点から無効であるXPath式の使用の両方を含みます。

コンパイル時に十分な静的型情報を提供する一般的な方法には、次の方法があります。

- リレーショナル・データに関してXQueryとfn:docまたはfn:collectionを使用。

- XQueryを使用して、問合せコンパイル時にXML Schema情報を利用できるXMLType表、列またはビューを問い合せます。

- XML Schemaに基づくXMLType表または列から入力データを取得する変換式で、XQuery Updateを使用。

この項では、静的型チェックの有効性と、型情報を通信するこれら2つの手段の使用方法を示す例を紹介します。

fn:collectionおよびURIスキームoradbによってその場で生成されるXMLデータは、ROWを最上位の要素に持ちますが、例4-4の問合せには、ROWのラッパー要素が欠けています。この脱落により、問合せのコンパイル時エラーが発生します。このようにfn:collectionとoradbによりリレーショナル・データをラップし忘れる誤りはよくあることですが、静的型チェックがないと、診断が困難な場合があります。例5-5に正しいコードを示します。

例4-5では、XQueryの静的型チェックにより、XPath式とそのターゲットXML Schemaに基づくデータの不一致を検出します。要素CostCenterが、ここではcostcenterと誤ったスペルになっています(XQueryおよびXPathは大文字/小文字を区別します)。例5-11に正しいコードを示します。

例4-4 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)

例4-5 XQuery式の静的型チェック: XML Schemaベースのデータ

-- 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)

4.8 Oracle XML DBでのXQueryサポート

Oracle XML DBのXQuery言語サポートには、SQLサポートとXQueryの関数と演算子のサポートが含まれます。

4.8.1 XQueryとSQLのサポート

Oracle XML DBのXQuery言語サポートは、リレーショナル記憶域の使用範囲とXMLデータの問合せの使用範囲のベスト・フィットの実現を目指しています。Oracle XML DBは一般的なXQuery実装ですが、それと同時に、リレーショナル問合せとXML問合せの連携動作に特に注意して設計されています。

この項では、Oracle XML DBのXQuery実装の個別のプロパティについて説明します。XQuery標準は、言語処理の一部の特性について、実装により定義されるのか、実装に依存するのかを明示的にコール・アウトしています。また、XQuery標準で規定されているが、Oracle XML DBでサポートされていない機能もいくつかあります。

関連項目:

「XQuery Full Textのサポート」

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

XQuery標準では、実装により定義される言語処理のいくつかの点が指定されています。

- 暗黙的タイムゾーン・サポート: Oracle XML DBでは、暗黙的タイムゾーンを常にZと仮定しています。タイムゾーンのないxs:date、xs:timeおよびxs:datetimeのインスタンスは、自動的にUTCに変換されます。

- copy-namespacesのデフォルト値: copy-namespaces宣言のデフォルト値(XQuery Updateで使用)はinheritです。

- 再検証モード: XQuery Update変換式の再検証のデフォルト・モードはskipです。ただし、変換式の結果が、XMLType表または列内のXML Schemaに基づくデータに対する更新である場合は、XML Schemaの検証が適用されます。

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

Oracle XML DBではサポートされていない、XQuery標準で規定されている機能を示します。

- 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 Update関数fn:put。

4.8.1.3 XQueryのオプション機能

Oracle XML DBでサポートされていないオプションのXQuery機能が指定されます。

XQuery標準では、いくつかの機能が特定の実装でオプションであることが指定されています。次に示すオプションのXQuery機能は、Oracle XML DBではサポートされていません。

- スキーマ検証機能

- モジュール機能

次に示すオプションのXQuery機能は、Oracle XML DBでサポートされています。

- XQuery静的型指定機能

- XQuery Update静的型指定機能

関連項目:

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

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

Oracle XML DBでは、いくつかの例外はありますが、最新のXQuery 1.0およびXPath 2.0の関数と演算子の仕様に含まれるほとんどのXQuery関数とXQuery演算子がサポートされています。

Oracle XML DBでは、次に示すXQuery関数とXQuery演算子はサポートされていません。

- 関数fn:tokenize。かわりにOracle XQuery関数ora:tokenizeを使用してください。

- 関数fn:idおよびfn:idref。

- 引数のない関数fn:collection。

- XQuery関数のオプションの照合パラメータ。

4.8.2.1 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/を参照してください。

4.8.3 XQuery Full Textのサポート

Oracle XML DBでは、バイナリXMLとして格納されているXMLTypeデータに対してXQuery Full Textがサポートされます。Oracle Textテクノロジでは、このサポートの基準となる全文索引と検索が提供されます。

ここで説明されていない用語の詳細は、XQuery and XPath Full Text 1.0勧告(以後、XQuery Full TextまたはXQFTと表記)を参照してください。

XQuery Full Textがサポートされるのは、バイナリXMLとして格納されているXMLTypeデータに対してのみです。オブジェクト・リレーショナル形式として格納されているXMLTypeデータの全文検索は、XQuery Full TextではなくOracle Text索引を使用して実行できます。

OracleのXQuery Full Textサポートについて、OracleでのXQFTの実装はOracle Textを基礎とし、それによりOracle製品とそれを使用して開発されたアプリケーションに全文索引と検索機能を提供するものと一般的に理解されています。この項で説明しているXQFTサポートの詳細は、このOracle Textに基づいた実装から導かれたものです。

関連項目:

- 『Oracle Textアプリケーション開発者ガイド』

- 『Oracle Textリファレンス』

- オブジェクト・リレーショナル形式で格納されているXMLTypeデータを全文検索する方法の詳細は、「XQueryを使用しないXMLデータの全文検索」を参照してください。

4.8.3.1 XQuery Full Text、XML Schemaに基づくデータ、およびプラグマora:no_schema

バイナリXMLとして格納されているXML Schemaに基づくXMLTypeデータの問合せには、Oracleプラグマora:no_schemaとXQuery Full Textを使用します。データは、XML Schemaに基づかないデータのように扱われます。

バイナリXMLとして格納されているXMLTypeデータの問合せには、XQuery Full Textを使用できます。ただし、XML Schemaに基づくデータでそれを使用する場合、問合せではXQuery拡張式プラグマora:no_schemaも使用する必要があり、そうしないとエラーが発生します。

また、XQuery Full Textのためにora:no_schemaを使用すると、XMLデータはXML Schemaに基づかないデータに暗黙的にキャストされます。つまり、OracleのXQuery Full Textサポートでは、すべてのXMLデータをXML Schemaに基づかないデータのように扱います。

つまり具体的には、XML Schemaデータ型を使用するXQuery Full Text条件を問合せに含めた場合、その型に関する考慮事項は無視されます。たとえば、2つのXML Schemaデータの値を比較する場合、単純な文字列の比較として扱われます。OracleのXQuery Full Textサポートでは、XML Schemaを認識しません。

関連項目:

「プラグマora:no_schema: XQuery Full TextでのXML Schemaに基づくデータの使用」

4.8.3.2 XMLExistsでのXQuery Full Textの使用制限

SQL/XML関数XMLExistsとともにXQuery Full Textを使用する場合、制限が指定されています。

SQL/XML関数XMLExistsのPASSING句にSQL式として渡すことのできるXMLTypeインスタンスは1つのみで、同じ句内に含まれるその他の非XMLType SQL式はすべて、組込みSQLデータ型のコンパイル時定数、またはこのようなデータ型のインスタンスにバインドされているバインド変数のいずれかである必要があります。この制限を順守しないと、コンパイル時エラーORA-18177が発生します。

4.8.3.3 サポートされているXQuery Full TextのFTSelection演算子

Oracle XML DBでは、XQuery Full TextのFTSelection演算子のサブセットがサポートされています。

Oracle XML DBでは、次に示すXQuery Full TextのFTSelection演算子のみをサポートしています。適用される制限がある場合は注記します。「する必要があります」、「しないでください」という言葉が使用されている場合、指定された制限を順守しないとエラーが発生します。ここにリストされていない演算子を使用すると、エラーが発生します。

- FTAnd (ftand)

- FTMildNot (not in)
演算子FTMildNotの各オペランドは、語または句、つまりFTWordsのインスタンスにする必要があります。式にはしないでください。Oracleでは、Oracle Text演算子MNOTと同じようにFTMildNotを扱います。

- FTOr (ftor)

- FTOrder (ordered)
Oracleでは、ウィンドウのコンテキスト(FTWindow)で使用されている場合にのみFTOrderの使用をサポートします。それ以外の場合はサポートされません。たとえば、ordered window 5 wordsは使用可能ですが、windowを付けずにorderedを単独では使用できません。Oracleでは、ORDERオプションに値TRUEが設定されているOracle Text演算子NEARと同じようにFTOrderを扱います。

- FTUnaryNot (ftnot)
FTUnaryNotはFTAndとともに使用する必要があります。FTUnaryNotを単独では使用できません。たとえば、ftand ftnotは使用可能ですが、ftandを付けずにftnotを単独では使用できません。Oracleでは、Oracle Text演算子NOTと同じようにFTUnaryNotを扱います。

- FTWindow (window)
Oracleでは、Oracle Text演算子NEARと同じようにFTWindowを扱います。ウィンドウ・サイズは、文や句(window 2 paragraphsなど)ではなく単語でのみ指定し、100以下の定数として指定する必要があります。

- FTWords
FTWordsValueはXQueryリテラル文字列またはSQLバインド変数にする必要があり、その値は、評価によってXMLType以外の値が戻されるSQL式から、SQL関数XMLExistsまたはXMLQueryに渡されます。

また、FTAnyallOption (存在する場合)はanyにする必要があります。つまり、FTWordsは項目が1つのみのシーケンスに対応する必要があります。

注意:

FTWordsは項目が1つのみのシーケンスに対応していても、句全体を単一の文字列で表すことで、複数の語からなる句を引き続き検索できます。そのため、たとえばOracle XML DBではFTWordsに{"found" "necklace"}は使用できませんが、"found necklace"は使用できます。

4.8.3.4 サポートされているXQuery Full TextのMatchオプション

Oracle XML DBでは、XQuery Full Textのmatchオプションのサブセットがサポートされています。

Oracle XML DBでは、次に示すXQuery Full Textのmatchオプションのみをサポートしています。適用される制限がある場合は注記します。「する必要があります」、「しないでください」という言葉が使用されている場合、指定された制限を順守しないとエラーが発生します。ここにリストされていないmatchオプションを使用すると、エラーが発生します。

- FTStemOption (stemming、no stemming)

次の例外を除いて、XQueryおよびXPath Full Text 1.0勧告で指定されているデフォルト動作が、サポートされていない各matchオプションに使用されています。

- FTLanguage (サポート対象外) - 使用されている言語は、デフォルト・レクサーで定義された言語、すなわちデータベースのインストール時に使用された言語です。

- FTStopWordOption (サポート対象外) - 使用されているストップリストは、その言語に定義されたストップリストです。

関連項目:

- デフォルト・レクサーについては、『Oracle Textリファレンス』を参照してください。

- サポートされる各言語に使用されているストップリストについては、『Oracle Textリファレンス』を参照してください。

4.8.3.5 サポート対象外のXQuery Full Text機能

Oracle XML DBではサポートされていないXQuery Full Text機能を示します。

「サポートされているXQuery Full TextのFTSelection演算子」に記載されていないすべてのFTSelection演算子と、「サポートされているXQuery Full TextのMatchオプション」に記載されていないすべてのmatchオプションの他に、次のXQuery Full Text機能もOracle XML DBではサポートされていません。

- FTIgnoreOption

- FTWeight (重みの宣言、FTPrimaryWithOptionsで使用)

- FTScoreVar (スコア変数、XQuery ForClauseおよびLetClauseまたはXPath 2.0 SimpleForClauseで使用)

4.8.3.6 XQuery Full Textのエラー

XQuery Full Textの使用時に発生することがあるコンパイル時エラーについて説明します。

OracleでサポートされていないXQuery Full Text (XQFT)機能を使用すると必ずコンパイル時エラーが発生します。

また、対応するXML検索索引が作成されていないか、またはその索引が取得されていない場合、サポートされているXQFT式をSQL WHERE句(通常はXMLExists)内で使用すると必ずコンパイル時エラーORA-18177が発生します。

関連項目:

- 「サポート対象外のXQuery Full Text機能」

- XML検索索引の作成およびエラーORA-18177の処理の詳細は、「全文問合せ用のXMLデータの索引付け」を参照してください

- forwardおよびdescendent以外の軸の詳細は、「XQuery用のパフォーマンス・チューニング」を参照してください

- SQLの組込みデータ型の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

脚注の凡例

脚注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:
Oracle Database 12cリリース1 (12.1.0.1)より前は、プラグマora:no_xmlquery_rewriteおよびora:xmlquery_rewriteはそれぞれora:xq_procおよびora:xq_qryという名前でした。読みやすさのために名前が変更されていますが、内容には変更ありません。

5 XMLデータの問合せと更新

Oracle Database内のXMLデータ(XML Schemaに基づくものと基づかないものの両方)をアプリケーションで問合せおよび更新する方法は多数あります。

- Oracle XML DBでのXQueryの使用

- SQLおよびPL/SQLを使用したXMLデータの問合せ

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

- 「XQueryとXQJを使用したデータベース・データへのアクセス」

- XQueryをPL/SQL、JDBCおよびODP.NETとともに使用したデータベース・データへのアクセス

- XMLデータの更新

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

関連項目:

- XMLType記憶域の推奨事項は、 Oracle XML DBの使用方法の概要を参照してください。

- XML Schemaに基づくXMLTypeの表および列の使用方法は、XML Schemaの格納と問合せ: 基本を参照してください。

- XQuery Updateを使用したXMLデータの更新の詳細は、XQueryとOracle XML DBを参照してください。

5.1 Oracle XML DBでのXQueryの使用

XQueryは非常に汎用性と表現力に富む言語で、SQL/XML関数XMLQuery、XMLTable、XMLExistsおよびXMLCastにより、それらの表現力と計算力がSQLの長所と組み合されます。

Oracle XML DBでは、通常は次のようにXQueryを使用します。ここでの例は、それらの使用方法の違いを示すように構成されています。

- Oracle XML DBリポジトリ内でXMLデータを問い合せる。
「XQueryを使用したOracle XML DBリポジトリ内でのXMLデータの問合せ」を参照してください。

- リレーショナル表またはビューを、XMLデータと同様に問い合せる。これを実行するには、XQuery関数fn:collectionを使用して、URIスキーム名oradbを使用するURIを、引数としてデータのデータベースの場所とともに引き渡します。
「XQueryとURIスキームoradbを使用したリレーショナル・データの問合せ」を参照してください。

- 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_REPOS.createResource('/public/emps.xml',   empsxmlstring);
res := DBMS_XDB_REPOS.createResource('/public/empsns.xml', empsxmlnsstring);
res := DBMS_XDB_REPOS.createResource('/public/depts.xml',  deptsxmlstring);
END;
/

5.1.1 XQueryシーケンスには任意のXQuery型のデータを含めることが可能

重要なことは、XQueryが汎用のシーケンス操作言語であるということです。式や結果は、XMLデータでなくてもかまいません。XQueryシーケンスは数値、文字列、ブール値、日付など任意のXQuery型の項目と、様々な型のXMLノード(document-node()、element()、attribute()、text()、namespace()など)を含むことができます。

例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>)となります。

例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.1.2 XQueryを使用したOracle XML DBリポジトリ内でのXMLデータの問合せ

XQueryをOracle XML DBリポジトリのXMLデータとともに使用する例を示します。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では、各種の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では、各種のFLWOR句が次の操作を行っています。

- forは、入力文書/public/depts.xml内のdeptno属性について反復を実行し、変数$dを各属性の値に順にバインドします。

- letは変数$eを、入力文書/public/emps.xmlの、deptno属性が$dという値を持つすべてのemp要素で構成されるシーケンスにバインドします(join操作)。

- Together, forとletを同時に使用すると、タプル($d, $e)のストリームを生成できます。ここで$dは部門番号、$eはその部門の従業員の集合を表します。

- whereはそのタプル・ストリームをフィルタリングし、複数の従業員を持つタプルのみを残します。

- order byは、フィルタリングされたタプル・ストリームを平均給与の降順でソートします。平均は、名前空間fnのXQuery関数avgを、属性salaryの値に適用して計算します。この値は$eのemp要素に連結されています。

- returnは、order byで生成された各タプルについて1つのbig-dept要素を構成します。big-deptのtext()ノードには、$dにバインドされた部門番号が含まれます。XQuery関数countで指定されたとおり、headcount子要素には、従業員数が$eにバインドされて含まれます。avgsal子要素には、計算された平均給与が含まれます。

例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-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.1.3 XQueryとURIスキームoradbを使用したリレーショナル・データの問合せ

XQueryを使用してリレーショナル表またはビューのデータをXMLデータであるかのように問い合せる例を示します。例では、XQuery関数fn:collectionを使用して、URIスキーム名oradbを使用するURIを、引数としてデータのデータベースの場所とともに引き渡します。

例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では、各種の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句が次の操作を行っています。

- 外側の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-41を参照してください。

例5-7では、SQL/XML関数XMLTableは、XQuery問合せの結果を仮想リレーショナル・データに分解するために使用されています。この例で使用されているXQuery式は 例5-6で使用されているものと同一です。XQuery式の評価結果はWarehouse要素のシーケンスです。関数XMLTableは、行がWarehouse要素である仮想リレーショナル表を生成します。正確には、この例では、仮想表の各行に対応する疑似列COLUMN_VALUEの値はXMLフラグメント(XMLType型)で、単一のWarehouse要素を持ちます。

関連項目:

例5-7の実行計画は、例5-42を参照してください。

例5-5 XMLQueryを使用した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-6 ネストされたFLWOR式を使用したXMLとしてのリレーショナル・データの問合せ

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-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.1.4 XQueryを使用したXMLTypeデータの問合せ

XQueryを使用してXMLTypeデータを問い合せる例を示します。

例5-8の問合せでは関数XMLQueryでPASSING句を使用して、XMLType列warehouse_specをコンテキスト項目としてXQueryに渡します。これにより、領域が80,000を超えるウェアハウス(/Warehouse/ Area > 80000)のそれぞれについてDetails要素が作成されます。

例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の間の結合を実行します。

関数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の実行計画は、例5-43を参照してください。

例5-11では、XMLTable句PASSINGおよびCOLUMNSを使用します。XQuery式は最上位のPurchaseOrder要素について反復を実行し、コスト・センターA10を含む発注書に対応するPO要素を構成します。結果のPO要素は続いてXMLTableに渡されて処理されます。

例5-11では、PurchaseOrderの子から取得したデータは、POの子、Ref、TypeおよびNameを構成するのに使用されます。Typeのコンテンツは/PurchaseOrder/SpecialInstructionsのコンテンツから取得されますが、SpecialInstructionsのクラスはTypeに対応して異なる方法で分割されます。

関数XMLTableはXQuery評価の結果を、poref、priority、およびcontactの仮想表の3つのVARCHAR2列に分割します。DEFAULT句は、Regularのデフォルトのpriorityを指定するのに使用されます。

例5-11ではRETURNING SEQUENCE BY REF句を使用していません。COLUMNS句によって戻されて使用されるXQueryシーケンスが、参照渡しではなく値渡しされます。すなわち、実ノードへの参照ではなく、ターゲット・ノードのコピーが戻されます。

戻されたシーケンスが値渡しされている場合、COLUMNS句で指定された列は、その戻されたコピーにないデータは参照できません。特に、ソース・データ内のターゲット・ノードの前にあるデータは参照できません。

COLUMNS句の列仕様からソース・データの任意の部分を参照できるようにするには、RETURNING SEQUENCE BY REF句を使用する必要があります。これを使用すると、XQuery式で生成されたシーケンスが参照によって戻されます。

例5-12に、RETURNING SEQUENCE BY REF句の使用方法を示します。この句を使用すると、reference列は、XQuery式でターゲットとなっているノード外のノードを参照できます。LineItemノードのシーケンスは参照によって戻されるため、コードはノードの完全なノード・ツリーにアクセスできます。このため、ノードReferenceを上方向、次に下方向に移動できます。

RETURNING SEQUENCE BY REF句を使用すると、XMLTableの行の生成に使用した最上位のXQuery式の評価結果を、参照によって戻すように指定できます。同様の選択を、COLUMNS句のPATH式の評価結果にも使用できます。このような結果を参照によって戻すように指定するために、XMLType (SEQUENCE) BY REFを列のデータ型として使用できます。

例5-13に、これを示します。参照によってソース文書からXMLデータを戻す、t1およびt2の2つのXMLTable表を連鎖しています。

- 最上位の表t1の列referenceの場合、要素LineItem外のノードに対応するため(例5-12と同様)

- 表t1の列partの場合、列itemがノードPart外のデータをターゲットにする表t2に渡されるため

表t1では、列partに使用される型はXMLType (SEQUENCE) BY REFであるため、partデータはPATH式、LineItem/Partでターゲットとなっているソース・データへの参照です。これが必要なのでは、表t2の列itemのPATH式は要素Part、LineItemの親の属性ItemNumberをターゲットにしているためです。partが参照であると指定しない場合、単にPart要素のコピーになるため、PATH式../@ItemNumberを使用するとエラーが発生します。

例5-14では、SQL/XML関数XMLTableを使用して、XMLTypeコレクション要素LineItemのXMLデータを、仮想表の個別の列に分割します。

関連項目:

- 例5-14の実行計画は、例5-44を参照してください。

- XMLTableを複数の文書レベルに適用する具体例(マルチレベル連鎖)は、「XMLのリレーショナル・ビューの作成: XMLノードの列へのマップ」を参照してください。

例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-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.

例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-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-12 XMLTABLEでのRETURNING SEQUENCE BY REFの使用

SELECT t.*
FROM purchaseorder,
XMLTable('/PurchaseOrder/LineItems/LineItem' PASSING OBJECT_VALUE
RETURNING SEQUENCE BY REF
COLUMNS reference   VARCHAR2(30) PATH '../../Reference',
item        VARCHAR2(4)  PATH '@ItemNumber',
description VARCHAR2(45) PATH 'Description') t
WHERE item = 5;

REFERENCE                      ITEM DESCRIPTION
------------------------------ ---- ------------------------------------
AMCEWEN-20021009123336171PDT   5    Coup De Torchon (Clean Slate)
AMCEWEN-20021009123336271PDT   5    The Unbearable Lightness Of Being
PTUCKER-20021009123336191PDT   5    The Scarlet Empress
PTUCKER-20021009123336291PDT   5    The Unbearable Lightness Of Being
SBELL-20021009123336231PDT     5    Black Narcissus
SBELL-20021009123336331PDT     5    Fishing With John 1 -3
SKING-20021009123336321PDT     5    The Red Shoes
SMCCAIN-20021009123336151PDT   5    Wages of Fear
SMCCAIN-20021009123336341PDT   5    The Most Dangerous Game
VJONES-20021009123336301PDT    5    Le Trou

10 rows selected.

例5-13 連鎖XMLTABLEでの参照によるアクセスの使用

SELECT t1.reference, t2.id, t2.item
FROM purchaseorder,
XMLTable('/PurchaseOrder/LineItems' PASSING OBJECT_VALUE
RETURNING SEQUENCE BY REF
COLUMNS part XMLType (SEQUENCE) BY REF PATH 'LineItem/Part',
reference VARCHAR2(30)         PATH '../Reference') t1,
XMLTable('.' PASSING t1.part
RETURNING SEQUENCE BY REF
COLUMNS id   VARCHAR2(12) PATH '@Id',
item NUMBER       PATH '../@ItemNumber') t2;

例5-14 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.1.5 XQueryでのネームスペースの使用

XQuery declare namespace宣言をXQuery式のプロローグで使用して、名前空間の接頭辞を定義することができます。declare default namespaceを使用して、式のデフォルトの名前空間として名前空間を確立できます。

名前空間宣言を記述した行の末尾にセミコロン(;)を置いた場合、SQL*Plusでは、そのセミコロンがSQLの終端文字として解釈されます。SQL*Plusを使用する場合は、この点に注意が必要です。これを避けるには、次のいずれかを実行します。

- 同じ行のセミコロンの後にテキストを挿入する。

- 同じ行のセミコロンの後に、(: :)のようなコメントを挿入する。

- SQL*PlusコマンドSET SQLTERMINATORを使用して、SQLの終端文字の認識を無効にする。

例5-15は、XQuery式の名前空間宣言の使用方法を示しています。

XQuery名前空間宣言は、XQuery式の外部では無効です。XMLTable式で使用する名前空間接頭辞をXQuery式の外部で宣言するにはXMLNAMESPACES句を使用します。この句はXMLTableのXQuery式の引数でも使用できるため、XQueryプロローグを別個に宣言する必要はありません。

例5-16では、XMLNAMESPACESは名前空間http://example.comに対応する接頭辞eを定義するために使用されます。このネームスペースはCOLUMNS句とXMLTable式のXQuery式で使用されます。

例5-15 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>

例5-16 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と書いてかまいません。

5.2 SQLおよびPL/SQLを使用したXMLデータの問合せ

様々な方法で、XMLType列および表からXMLデータを問い合せることができます。

- SQL、PL/SQLまたはJavaからXMLTypeデータを選択します。

- XMLQueryなどのSQL/XML関数を使用してXMLTypeデータを問い合せます。「XQueryを使用したXMLTypeデータの問合せ」を参照してください。

- XQuery Full TextまたはOracle Text演算子を使用して全文検索を実行します。詳細は、「XQuery Full Textのサポート」、「XMLTypeデータの索引」および「XQueryを使用しないXMLデータの全文検索」を参照してください。

この項の各例では、SQLおよびPL/SQLを使用してXMLデータを問い合せる各種の方法を示します。例5-17では、purchaseorder表に2行を挿入してから、SQL/XML関数XMLCast、XMLQueryおよびXMLExistsを使用してそれらの行のデータを問い合せます。

例5-18では、PL/SQLカーソルを使用してXMLデータを問い合せます。ローカルのXMLTypeインスタンスを使用して、一時データが格納されます。

例5-19および例5-20はいずれも、SQL/XML関数XMLTable使用して、XML発注書からデータを抽出します。次に、そのデータをリレーショナル表に挿入します。例5-19ではSQL、例5-20ではPL/SQLを使用しています。

例5-20では、PL/SQLプロシージャを定義および使用して、XML発注書からデータを抽出し、そのデータをリレーショナル表に挿入します。

例5-21は、出荷先に文字列"Shores"が含まれ、名前に文字列"ll" (Lが2つ)が含まれている顧客から要求された発注書を一覧で表示します。これらの発注書は、顧客別にグループ化してカウントされます。この例では、XQuery Full Textを使用して全文検索を実行します。

例5-22では、XPath式で指定された文書のフラグメントを抽出します。XMLQueryにより戻されるXMLTypeインスタンスは、ノードの集合、単一のノードまたはテキスト値のいずれかになります。例5-22では、XMLTypeメソッドisFragment()を使用して、結果がフラグメントかどうかを判別します。

注意:

フラグメントはXMLType列に挿入できません。SQL/XML関数XMLQueryを使用すると、フラグメントを整形式の文書に変換できます。

例5-17 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.

例5-18 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.

例5-19 SQLを使用した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

例5-20 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

例5-21 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[address/text() contains text "Shores"]'
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

例5-22 XMLQUERYを使用したフラグメントの抽出

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

5.3 SQL*Plus XQUERYコマンドの使用

SQL*Plus XQUERYコマンドを使用して、XQuery式を評価できます。

例5-23は、SQL*PlusコマンドXQUERYの後にXQuery式、式の後にスラッシュ(/)のみを含む行を入力することにより、SQL*PlusコマンドラインでXQuery式を直接入力する方法を示します。Oracle Databaseでは、このコマンドで送信されたXQuery式を、SQL/XML関数XMLQueryおよびXMLTable内のXQuery式と同様に処理します。実行は同一で、同じ最適化を使用します。

XQueryに固有の設定で使用できるSQL*Plus SETコマンドもいくつかあります。現在の設定を参照するにはSHOW XQUERYを使用します。

- SET XQUERY BASEURI: XQUERYのベースURIを設定します。XQuery式内のURIは、このURIに相対的です。

- SET XQUERY CONTEXT: 以降のXQUERY評価で使用するコンテキスト項目を指定します。

関連項目:

『SQL*Plusユーザーズ・ガイドおよびリファレンス』

例5-23 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>

5.4 XQueryとXQJを使用したデータベース・データへのアクセス

XQuery API for Java (XQJ)(JSR-225とも呼ばれる)は、JavaプログラムからXQueryを使用してXMLデータにアクセスするための業界標準の方法を提供します。これにより、XMLのデータ・ソースに対してXQuery式を評価したり、その結果をXMLデータとして処理できます。

OracleではXQuery式を評価するための2つのXQueryエンジンを提供しています。1つは、Oracle XML DBにあり、データベース内のXMLデータに使用し、もう1つは、Oracle XML Developer's Kit内にあり、データベース外部のXMLデータに使用します。

同様に、中間層でのXQJ実装を2種類提供し、これら2つのXQueryエンジンへのアクセスに対応します。いずれの実装も、Oracle XML Developer's Kit (XDK)に含まれています。データがデータベースの内部または外部のどちらに存在するかに関係なく、XDKを使用すればXQJ経由でXMLデータにアクセスできます。

特に、XDKおよびXQJを使用して、Oracle XML DBのXMLデータにアクセスできます。この機能の典型的なユースケースは、ローカルのJavaプログラムからリモート・データベースに格納されているデータにアクセスすることです。

関連項目:

- XQuery API for Java (XQJ) 1.0仕様(2009年3月) https://jcp.org/aboutJava/communityprocess/final/jsr225/index.html
この仕様には、わかりやすい例が含まれており、非常に具体的で役に立ちます。

- Oracle XML Developer's KitでのXQJの使用の詳細は、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。

- XDKでXQJを使用してデータベースのXMLデータにアクセスする方法およびその例については、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。

5.5 XQueryをPL/SQL、JDBCおよびODP.NETとともに使用したデータベース・データへのアクセス

XQueryは、PL/SQL、JDBC、およびOracle Data Provider for .NET (ODP.NET)用のOracle APIとともに使用できます。

例5-24は、XQueryをPL/SQLとともに使用する方法、特に、XMLQueryのPASSING句を使用して動的変数をXQuery式にバインドする方法を示します。バインド変数:1および:2は、PL/SQLバインド変数nbitemsおよびpartidに、それぞれバインドされます。その後、それぞれXQuery変数itemnoおよびidとしてXQueryに渡されます。

例5-25は、XQueryをJDBCとともに使用して、変数をその位置によってSQL/XML関数XMLTableのPASSING句にバインドします。

例5-26は、XQueryをODP.NETおよびC#言語とともに使用する方法を示します。C#の入力パラメータ:nbitemsおよび:partidは、それぞれXQuery変数itemnoおよびidとしてXQueryに渡されます。

関連項目:

- PL/SQL API for XMLType

- Java DOM API for XMLType

- Oracle XML DBおよびOracle Data Provider for .NET

例5-24 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-25 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-26 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>

5.6 XMLデータの更新

XMLデータが一時データか、データベース表に格納されているかに関係なく、Oracle XML DB機能を使用してXMLデータを更新できる方法は複数あります。

5.6.1 XML文書全体の更新

XML文書全体を更新するには、SQLのUPDATE文を使用します。

UPDATE文のSET句の右側にはXMLTypeインスタンスを指定する必要があります。これを作成するには、次のいずれかの方法を使用します。

- XMLインスタンスを戻すSQL関数またはXMLコンストラクタを使用する方法

- 既存のXMLインスタンスを変更およびバインドするPL/SQL DOM APIs for XMLTypeを使用する方法

- 既存のXMLインスタンスを変更およびバインドするJava PL/SQL DOM APIを使用する方法

バイナリXMLとして格納されているXML Schemaに基づかないXML文書は、ピース単位で更新できます。

例5-27では、SQL UPDATE文を使用してXMLTypeインスタンスを更新します。

例5-27 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

5.6.2 XMLノードの置換

新しいXML文書を作成するのではなく、SQL UPDATE文とともにXQuery Updateを使用して既存のXML文書を更新できます。選択された部分のみではなく、文書全体が更新されます。

例5-28では、SQL文字列リテラル'SKING'をXQuery式に変数($p2)として渡します。この簡単な例では、値が文字列リテラルなので、単純にreplace value of node $j with "SKING"と記述することもできました。つまり、ここでは、SQLからXQueryにリテラル文字列を渡すかわりに、リテラルなXQuery文字列を使用することもできます。実際には、実行時にのみ使用可能な値を渡すのが一般的です。例5-28にその方法を示します。これは他の例にも当てはまります。

例5-29では、複数のテキスト・ノードと属性ノードを更新します。

例5-30では、コレクション内で選択されたノードを更新します。

例5-31では、コレクション内で複数回出現するノードを、値の置換操作を使用して更新する際に発生する一般的なエラーを示します。UPDATE文で、Description要素のテキスト・ノードの値をThe Wizard of Ozに設定します。この現在のテキスト・ノードの値はSistersです。この文のWHERE句にはXMLExists式が含まれ、更新する一連のノードを識別します。

例5-31では、目的のノードのみを更新するのではなく、Description要素に属するすべてのテキスト・ノードの値を更新します。これは意図した結果と異なります。

WHERE句は、更新が必要な文書を識別するためにのみ使用でき、その文書内で更新が必要なノードの識別には使用できません。

文書が選択されると、XQuery Updateに渡されるXQuery式により、文書内で更新が必要なノードが判別されます。この例では、XQuery式によって3つすべてのDescriptionノードが識別されるため、関連する3つのテキスト・ノードすべてが更新されています。

コレクション内で複数回出現するノードを正しく更新するには、XQuery Updateに渡されるXQuery式を使用して、XML文書内の更新対象のノードを特定します。XQuery式に適切な述語を設定することによって、文書内の更新対象のノードを限定できます。例5-32では、コレクション内の1つのノードを更新する正しい方法を示します。

例5-28 SQL UPDATEおよびXQuery Updateを使用した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 =
XMLQuery('copy $i := $p1 modify
(for $j in $i/PurchaseOrder/Actions/Action[1]/User
return replace value of node $j with $p2)
return $i' PASSING po.OBJECT_VALUE AS "p1",
'SKING' AS "p2" RETURNING CONTENT)
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>

例5-29 複数のテキスト・ノードと属性ノードの更新

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 =
XMLQuery('copy $i := $p1 modify
((for $j in $i/PurchaseOrder/Requestor
return replace value of node $j with $p2),
(for $j in $i/PurchaseOrder/LineItems/LineItem[1]/Part/@Id
return replace value of node $j with $p3),
(for $j in $i/PurchaseOrder/LineItems/LineItem[1]/Description
return replace value of node $j with $p4),
(for $j in $i/PurchaseOrder/LineItems/LineItem[3]
return replace node $j with $p5))
return $i'
PASSING OBJECT_VALUE AS "p1",
'Stephen G. King' AS "p2",
'786936150421' AS "p3",
'The Rock' AS "p4",
XMLType('<LineItem ItemNumber="99">
<Description>Dead Ringers</Description>
<Part Id="715515009249" UnitPrice="39.95" Quantity="2"/>
</LineItem>') AS "p5"
RETURNING CONTENT)
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>

例5-30 コレクション内で選択されたノードの更新

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 =
XMLQuery(
'copy $i := $p1 modify
((for $j in $i/PurchaseOrder/Requestor
return replace value of node $j with $p2),
(for $j in $i/PurchaseOrder/LineItems/LineItem/Part[@Id="715515009058"]/@Quantity
return replace value of node $j with $p3),
(for $j in $i/PurchaseOrder/LineItems/LineItem
[Description/text()="The Unbearable Lightness Of Being"]
return replace node $j with $p4))
return $i'
PASSING OBJECT_VALUE AS "p1",
'Stephen G. King' AS "p2",
25 AS "p3",
XMLType('<LineItem ItemNumber="99">
<Part Id="786936150421" Quantity="5" UnitPrice="29.95"/>
<Description>The Rock</Description>
</LineItem>') AS "p4"
RETURNING CONTENT)
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>

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

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
SET OBJECT_VALUE =
XMLQuery('copy $i := $p1 modify
(for $j in $i/PurchaseOrder/LineItems/LineItem/Description
return replace value of node $j with $p2)
return $i'
PASSING OBJECT_VALUE AS "p1", 'The Wizard of Oz' AS "p2"
RETURNING CONTENT)
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.

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

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
SET OBJECT_VALUE =
XMLQuery('copy $i := $p1 modify
(for $j in $i/PurchaseOrder/LineItems/LineItem/Description
[text()="Sisters"]
return replace value of node $j with $p2)
return $i'
PASSING OBJECT_VALUE       AS "p1",
'The Wizard of Oz' AS "p2" RETURNING CONTENT)
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.

5.6.2.1 XMLデータのNULL値への更新

XMLデータをNULL値に更新する場合は、特定の考慮事項が適用されます。

- XML要素をNULLに更新すると、要素の属性および子が削除され、要素は空になります。要素のタイプおよび名前空間プロパティは保持されます。例5-33を参照してください。

- 属性値をNULLに更新した場合、値は空の文字列として表示されます。例5-33を参照してください。

- 要素のテキスト・ノードをNULLに更新すると、その要素のコンテンツ(テキスト)は削除されます。要素自体は残りますが、空になります。 例5-34を参照してください。

例5-33では、次のものすべてをNULLに更新します。

- Description要素と、Part要素の属性Id値が715515009058のLineItem要素のQuantity属性

- Description要素のコンテンツ(テキスト)が「The Unbearable Lightness Of Being」であるLineItem要素

例5-33は、ノードの値を削除する2つの異なる、ただし同等の方法を示しています。要素Descriptionおよび属性Quantityでは、既存の値がリテラルな空のXQueryシーケンス()で直接置換されます。要素LineItemでは、SQL NULLがXQuery式に渡され、空のノード値が提供されます。使用されている値がリテラルなので、SQLからXQueryに値を渡さないため、より簡単です。ただし、実際には、実行時にのみ使用可能な値を渡すのが一般的です。例5-33では、空のXQueryシーケンスでこれを行う(SQL NULL値を渡す)方法を示しています。

例5-34では、Description属性の値が「A Night to Remember」であるPart要素のテキスト・ノードをNULLに更新します。この例のXMLデータは、修正された別の発注書XML Schemaに対応しています(「コピーに基づく拡張の使用例」を参照)。そのXML Schemaでは、DescriptionはPart要素の属性であり、兄弟要素ではありません。

関連項目:

例3-26

例5-33 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 =
XMLQuery(
'copy $i := $p1 modify
((for $j in $i/PurchaseOrder/LineItems/LineItem[Part/@Id="715515009058"]/Description
return replace value of node $j with ()) ,
(for $j in $i/PurchaseOrder/LineItems/LineItem/Part[@Id="715515009058"]/@Quantity
return replace value of node $j with ()) ,
(for $j in $i/PurchaseOrder/LineItems/LineItem
[Description/text()= "The Unbearable Lightness Of Being"]
return replace node $j with $p2))
return $i'
PASSING OBJECT_VALUE AS "p1", NULL AS "p2"
RETURNING CONTENT)
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>

例5-34 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 =
XMLQuery(
'copy $i := $p1 modify
(for $j in $i/PurchaseOrder/LineItems/LineItem/Part[@Description="A Night to Remember"]
return replace value of node $j with $p2)
return $i
PASSING OBJECT_VALUE AS "p1", NULL AS "p2" RETURNING CONTENT)
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"/>

5.6.3 XML子ノードの挿入

XQuery Updateを使用して、親のXML要素の下に新しい子(単一の属性または同じ型の1つ以上の要素)を挿入できます。挿入のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

例5-35では、新しいLineItem要素を、要素LineItemsの子として挿入します。Oracle XQueryプラグマora:child-element-nameを使用して、挿入された子要素の名前をLineItemと指定することに注意してください。

更新するXMLデータがXMLスキーマに基づいていて、ネームスペースを参照する場合、挿入するデータも同じネームスペースを参照する必要があります。参照しない場合は、挿入されるデータがXMLスキーマに準拠しないため、エラーが発生します。

注意:

XML Schemaに基づくデータの更新にXQuery Updateを使用する場合は、更新されたデータをXML Schemaに基づく列または表に戻すことを試みるとエラーが発生することに注意してください。このことを回避するには、XQueryプラグマora:transform_keep_schemaを使用します。「Oracle XQuery拡張式プラグマ」を参照してください。

例5-36は例5-35と似ていますが、挿入されるLineItem要素が名前空間を参照しています。これは、関連するXML Schemaでこの要素に対する名前空間が必要であることを前提としています。

例5-37では、1番目のLineItem要素の前に、LineItem要素を挿入します。

例5-38では、Date要素を、Action要素の最後の子として挿入します。

例5-35 コレクションへの要素の挿入

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 =
XMLQuery('copy $i := $p1 modify
(for $j in $i/PurchaseOrder/LineItems
return (# ora:child-element-name LineItem #)
{insert node $p2 into $j})
return $i'
PASSING OBJECT_VALUE AS "p1",
XMLType('<LineItem ItemNumber="222">
<Description>The Harder They Come</Description>
<Part Id="953562951413" UnitPrice="22.95" Quantity="1"/>
</LineItem>') AS "p2"
RETURNING CONTENT)
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.

例5-36 名前空間を使用する要素の挿入

UPDATE purchaseorder
SET OBJECT_VALUE =
XMLQuery('declare namespace e = "films.xsd"; (: :)
copy $i := $p1 modify
(for $j in $i/PurchaseOrder/LineItems
return (# ora:child-element-name e:LineItem #)
{insert node $p2 into $j})
return $i'
PASSING OBJECT_VALUE AS "p1",
XMLType('<e:LineItem ItemNumber="222">
<Description>The Harder They Come</Description>
<Part Id="953562951413" UnitPrice="22.95" Quantity="1"/>
</e:LineItem>') AS "p2"
RETURNING CONTENT)
WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
PASSING OBJECT_VALUE AS "p");

例5-37 要素の前への要素の挿入

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 =
XMLQuery('copy $i := $p1 modify
(for $j in $i/PurchaseOrder/LineItems/LineItem[1]
return insert node $p2 before $j)
return $i'
PASSING OBJECT_VALUE AS "p1",
XMLType('<LineItem ItemNumber="314">
<Description>Brazil</Description>
<Part Id="314159265359" UnitPrice="69.95"
Quantity="2"/>
</LineItem>') AS "p2"
RETURNING CONTENT)
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>

例5-38 最後の子要素としての要素の挿入

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 =
XMLQuery('copy $i := $p1 modify
(for $j in $i/PurchaseOrder/Actions/Action[1]
return insert nodes $p2 as last into $j)
return $i'
PASSING OBJECT_VALUE AS "p1",
XMLType('<Date>2002-11-04</Date>') AS "p2"
RETURNING CONTENT)
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>

5.6.4 XMLノードの削除

例では、XQuery Updateを使用してXMLノードを削除します。

例5-39では、ItemNumber属性に値222が設定されているLineItem要素を削除します。

例5-39 要素の削除

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 =
XMLQuery('copy $i := $p modify
delete nodes $i/PurchaseOrder/LineItems/LineItem[@ItemNumber="222"]
return $i'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
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.6.5 変更されたXMLデータのXMLビューの作成

XQuery Updateを使用して、XMLデータの新しいビューを作成できます。

例5-40では、表purchaseorderのビューを作成します。

例5-40 更新されたXMLデータを使用したビューの作成

CREATE OR REPLACE VIEW purchaseorder_summary OF XMLType AS
SELECT XMLQuery('copy $i := $p1 modify
((for $j in $i/PurchaseOrder/Actions
return replace value of node $j with ()),
(for $j in $i/PurchaseOrder/ShippingInstructions
return replace value of node $j with ()),
(for $j in $i/PurchaseOrder/LineItems
return replace value of node $j with ()))
return $i'
PASSING OBJECT_VALUE AS "p1" RETURNING CONTENT)
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>

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

XQuery式を使用するSQL問合せは、多くの場合、1つ以上の方法で自動的にリライト(最適化)できます。このような最適化は、XML問合せのリライトまたは最適化と呼ばれます。これが発生すると、XQuery式はXML文書に対して直接評価されますが、メモリー内でDOMは構成されません。

XPath式は、XQuery式の適切なサブセットです。XPathリライトは、XML問合せリライトのサブセットであり、XPath式を使用する問合せがリライトされます。

XPathリライトには、次のものがすべて含まれます。

- バイナリXMLとして格納されているXMLTypeデータのシングルパス・ストリーミング - 一連のXPath式が、データの単一のスキャンで評価されます。

- XMLIndex最適化 - XPath式を使用するSQL文が同等のSQL文にリライトされますが、リライト後の文ではXPath式を使用せずにリレーショナルXMLIndex表を参照します。リライトされたSQL文も、基礎となるXMLIndex表で任意のBツリー索引を使用できます。

- オブジェクト・リレーショナル形式で格納されているXMLTypeデータ、またはXMLTypeビューの最適化 - XPath式を使用するSQL文が、XPath式を使用しないかわりにXMLTypeデータの基礎となるオブジェクト・リレーショナルまたはリレーショナル・データ構造を参照する同等の文にリライトされます。リライトされたSQL文も、基礎となるデータ構造で任意のBツリー索引を使用できます。これは、問合せでも更新操作でも発生することがあります。

問合せのチューニングは、SQLのパフォーマンスと同様に、XQueryのパフォーマンスも改善することができます。XQueryのパフォーマンスをチューニングするには、該当するXML記憶域モデルと索引を選択します。

一般のデータベースの問合せと同様に、チューニングが必要かどうかは、問合せの実行計画をチェックして決定します。計画が最適でない場合は、次のマニュアルで個別のチューニング情報を参照してください。

- オブジェクト・リレーショナル記憶域: オブジェクト・リレーショナル記憶域のXPathリライト

- バイナリXML記憶域: 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とOracle XML DBで示した例の一部に対する実行計画を示し、それがどのように実行されるかを説明します。

- 「リレーショナル・データに関するXQueryの最適化」: fn:collectionおよびURIスキームoradbを使用して、その場で作成されたXMLデータをターゲットとするXQuery式の例。

- 「XML Schemaに基づくXMLTypeデータに対するXQueryの最適化」: オブジェクト・リレーショナル形式でXML Schemaに基づくXMLType表をターゲットとするXQuery式の例を示します

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

XQuery式を使用する問合せに対しては、使用されているXMLType記憶域モデルや索引付けなどの様々な要因によって、競合する最適化候補が複数あります。

デフォルトでは、Oracle XML DBは、優先順位付きのルール・セットに従って、特定の問合せおよびコンテキストに対して使用する最適化候補を決定します。この動作は、ルールベースのXML問合せのリライトと呼ばれます。

また、Oracle XML DBはコストベースのXML問合せのリライトを使用することもできます。このモードでは、Oracle XML DBは、特定の問合せに対する様々なXML最適化候補のパフォーマンスを評価し、最もパフォーマンスが高いと予測される組合せを選択します。

オプティマイザ・ヒント/*+ COST_XML_QUERY_REWRITE */を使用すると、特定のSQL文に対してコストベースの最適化を強制できます。

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

リレーショナル・データに対するSQL/XML関数XMLQueryおよびXMLTableの使用は、最適化できます。

例5-41は、XMLとしてアクセスされるリレーショナル・データに対するXMLQueryの最適化を示します。例5-42に、同じコンテキストにおけるXMLTableの最適化を示します。

例5-41 リレーショナル・データに関する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-42 リレーショナル・データに関する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.

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

SQL/XML関数XMLQueryおよびXMLTableのXML Schemaに基づくデータの使用は、最適化できます。

例5-43に、XML Schemaに基づくXMLType表に関するXMLQueryの最適化を示します。例5-44に、同じコンテキストにおけるXMLTableの最適化を示します。

例5-43 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-44 XML Schemaに基づくXMLTypeデータを含むXMLTableの最適化

例5-14の問合せと、その実行計画をもう一度見てみます。この例は、問合せが最適化されていることを示しています。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表を(異なるデータベース・スキーマに)手動で作成します。

これが完了していると仮定して、次の文が適切な索引を作成します。

CREATE INDEX unitprice_index ON lineitem_table("PART"."UNITPRICE");

この索引が定義されている場合、例5-14の問合せにより、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.

5.7.4 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操作で書きなおしができない場合、原因に気がつかないうちにパフォーマンスが低下するかわりに実行が停止します。

注意:

- XMLOptimizationCheckは、Oracle Database 11gリリース2(11.2.0.2)以前は利用できませんでした。旧リリースのユーザーは、イベント19201を直接操作して、XQueryの最適化情報を取得していました。

- OCIユーザーはOCIStmtExecuteまたはイベント19201を使用できます。Javaユーザーが使用できるのはイベントのみです。

関連項目:

「XML Schemaに基づくXMLTypeデータに対するXQueryの最適化」: オブジェクト・リレーショナル形式でXML Schemaに基づくXMLType表をターゲットとするXQuery式の例を示します

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

Oracle XML DBリポジトリに対する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つの方法について説明しています。

5.7.5.1 fn:docとfn:collectionにかわるEQUALS_PATHおよびUNDER_PATHの使用

XQuery関数fn:docとfn:collectionのかわりに、Oracle SQL関数equals_pathおよびunder_pathを使用すると、パフォーマンスを向上できます。

SQL関数equals_pathおよびunder_pathは、それぞれ指定したリポジトリ・パスにあるリソースを参照します。例5-45および例5-46に、関数fn:docおよびequals_pathでのこの処理を示します。関数fn:collectionおよびunder_pathが同じように処理されます。

例5-45 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-46 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 1(/Resource/XMLRef)' PASSING rv.RES RETURNING CONTENT)
AS REF XMLType)
AND equals_path(rv.RES, '/home/OE/PurchaseOrders/2002/Sep/VJONES-20021009123337583PDT.xml')
= 1;

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

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-47に、この詳細を説明します。問合せが自動的にリライトされ、例5-46のようになります。

範囲を明確にするため、プラグマora:defaultTableを、大きい式ではなく適切な文書やコレクションの式、fn:docまたはfn:collectionに直接適用することをお薦めします。

例5-47 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;

脚注の凡例

脚注1:
XQuery関数fn:dataは、その引数の分解に使用されます。この場合は、XMLRefノード型指定されたアトミック値を戻します。

6 XMLTypeデータの索引

頻繁に問い合せるXMLデータの特定部分に着目できるよう当該XMLデータに対して索引を作成し、パフォーマンスを向上できます。XML Schemaに基づくかどうか、および使用されるXMLType記憶域モデルに関係なく、XMLTypeデータに索引付けできる様々な方法があります。

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

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

- XMLIndex

- 全文問合せ用のXMLデータの索引付け

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

注意:

ここで示す実行計画は、説明のためのみに使用しています。ここで示す例を実際の環境で実行しても、実行計画が同一になるわけではありません。

関連項目:

- 索引付けの概要は、『Oracle Database概要』を参照してください。

- アプリケーション開発における索引付けの詳細は、『Oracle Database開発ガイド』を参照してください。

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

XMLデータの索引に関連する一般的なタスクについて説明します。

表6-1は、XMLデータの索引付けに関連するいくつかの基本的なユーザー・タスクの参照先を示します。

表6-1 基本的なXML索引付けタスク

操作の詳細

参照先

索引付けの方法の選択

「XMLTypeデータの索引付けの概要」

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

「オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け」、「ガイドライン: Ordered Collection Tableに対する索引の作成」

XMLIndex索引の作成、削除または名前の変更

例6-5、例6-7

特定の表または列に対するXMLIndex索引名の取得

例6-6

指定されたXMLIndex索引を問合せの評価に使用するかどうかの判断

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

XMLIndex索引の使用の無効化

「XMLIndexの使用の無効化」

表6-2は、構造化コンポーネントを含むXMLIndex索引付けに関連するいくつかのユーザー・タスクの参照先を示します。

表6-2 構造化コンポーネントを含むXMLIndex索引に関連するタスク

操作の詳細

参照先

構造化コンポーネントが含まれるXMLIndex索引の作成

例6-20、例6-19

XMLIndex索引の構造化コンポーネントの削除(すべての構造グループの削除)

例6-22

構造化コンポーネントが含まれるXMLIndex索引と問合せの間のデータ型の対応の確認

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

XMLIndex構造化コンポーネントのコンテンツ表に対するBツリー索引の作成

例6-23

XMLIndex構造化コンポーネントのコンテンツ表に対するOracle Text CONTEXT索引の作成

例6-43

表6-3は、非構造化コンポーネントを含むXMLIndex索引付けに関連するいくつかのユーザー・タスクの参照先を示します。

表6-3 非構造化コンポーネントを含むXMLIndex索引に関連するタスク

操作の詳細

参照先

非構造化コンポーネントが含まれるXMLIndex索引の作成

例6-8、例6-10、例6-30、例6-32、例6-33、例6-34、例6-35

XMLIndex索引の非構造化コンポーネントの削除(パス表の削除)

例6-11

XMLIndex索引作成時の、パス表への名前付け

例6-8

XMLIndex索引作成時の、記憶域オプションの指定

例6-10

XMLIndexパス表にある既存の2次索引すべての表示

例6-12、例6-18

XMLIndex索引に対するパス表名の取得

例6-9

パス表の指定による、非構造化コンポーネントが含まれるXMLIndex索引名の取得

例6-25

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

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

XMLIndexパス表にあるすべての2次索引に関する情報の取得

例6-18

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

例6-13

パス表のVALUE列に対する数値索引の作成

例6-15

パス表のVALUE列に対する日付索引の作成

例6-16

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

例6-17

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-37

XML検索索引の作成

例6-38

バイナリXMLとして格納されているXMLデータの全文検索におけるXML検索索引の使用

例6-39

XML検索索引が問合せで使用されているかどうかの表示

例6-40

XMLIndex構造化コンポーネントのコンテンツ表に対するOracle Text CONTEXT索引の作成

例6-43

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

データベース索引では、表データに対するアクセスを高速化することにより、パフォーマンスが向上します。索引の使用は、更新が少ないオンライン・トランザクション処理(OLTP)環境に特に適しています。

XMLデータを索引付けする基本的な方法は、XMLIndexを使用することです。Oracle Text CONTEXT索引を使用して、XMLIndexの使用を補完することもできます。

バイナリXMLとして格納されているXMLTypeデータを索引付けする方法を選択するときに出発点となるサマリーのディシジョン・ツリーを次に示します。脚注1

XMLデータに、予測可能な構造化データのアイランドが含まれ、問合せが既知である場合

構造化コンポーネントでXMLIndexを使用し、構造化アイランドを索引付けします(アイランドの周囲にあるのが非構造化データの場合も含みます)。

構造化された索引コンポーネントに、使用する問合せが反映されます。既知の問合せのセットは、一定期間に索引定義を正しく更新している場合に変更できます。「XMLIndex構造化コンポーネント」を参照してください。

XMLデータ内で全文コンテンツを問い合せる必要がある場合

XML検索索引を使用します。「XMLデータのためのOracle Text索引」を参照してください。

述語を含む非定型XML問合せをサポートする必要がある場合

非構造化コンポーネントでXMLIndexを使用します。「XMLIndex非構造化コンポーネント」を参照してください。

(周囲のデータが構造化されていない可能性がある場合でも、) XMLデータに、高度に構造化された予測可能なデータのアイランドが含まれますか。

- はい。構造化コンポーネントを含むXMLIndexを使用して、アイランドを索引付けします。「XMLIndex構造化コンポーネント」(6‐12ページ)を参照してください。

- いいえ。XMLデータ内で全文コンテンツを問い合せる必要はありますか。

- はい。XML検索索引を使用します。「XMLデータのためのOracle Text索引」(6‐5ページ)を参照してください。

- いいえ。述語を含む非定型XML問合せをサポートする必要はありますか。その場合は、非構造化コンポーネントを含むXMLIndexを使用します。「XMLIndex非構造化コンポーネント」(6‐16ページ)を参照してください。それ以外の場合は、XMLデータを索引付けする必要はありません。

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

1つ以上のリレーショナル列または1つのファンクション式に対して、索引を作成できます。XMLデータには独自のファイングレイン構造がありますが、その構造は、XMLデータが格納されるデータベース表の構造に必ずしも反映されるとはかぎりません。このような理由から、XMLデータに効果的に索引付けする方法は、他の大部分のデータベース・データに対する索引付けとは多少異なります。

オブジェクト・リレーショナル形式のXMLType記憶域では、要素や属性などのXMLオブジェクトはオブジェクト・リレーショナル列および表に対応しています。これらの列および表に対してBツリー索引を作成する方法は、対応するXMLオブジェクトに効果的に索引付けする場合に最適です。この場合、記憶域モデルはXMLデータのファイングレイン構造を直接反映するため、構造化XMLデータの索引付けにおいて特別な問題は生じません。「オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け」を参照してください。

オブジェクト・リレーショナル形式のXMLType記憶域では、XML文書が分割され、オブジェクト・リレーショナル形式で格納されますが、1つ以上のXMLフラグメントを埋込みのCLOBインスタンスとして格納するように選択できます。通常はフラグメント全体が1つの単位としてアクセスされるため、このような場合は通常、XML SchemaのcomplexTypeまたは複合要素をCLOB記憶域にマッピングします。

ただし、このような埋込みのCLOBフラグメントは、索引付けの際には不透明型の単位としても機能し、個々の部分には索引付けされません。

標準的な索引付けも同様に、バイナリXML記憶域には有効ではありません。いずれの場合も、標準的な索引(Bツリー、ビットマップ)を使用してデータベース列に索引付けすると、多くの場合、XML文書の特定部分にアクセスする際に問題が生じます。

XMLIndexは通常のXML固有の索引により、XMLデータの内部構造に索引付けします。その主な目的の1つとして、バイナリXML記憶域によって課される索引付けの制限を克服することがあげられます。

- 非構造化コンポーネントを含むXMLIndex索引では、文書のXMLタグに索引付けし、それをターゲットとするXPath式に基づいて文書のフラグメントを識別します。また、スカラー・ノードの値に対して索引付けすることで、単独の値または値の範囲に基づく高速参照も可能にします。さらに、索引付けする各ノードに対し、文書の階層情報(親と子、祖先と子孫、および兄弟の関係)を記録します。この索引コンポーネントは、構造が少ない文書または可変構造を持つ文書からXMLフラグメントを抽出する問合せで特に便利です。

- 構造化コンポーネント含むXMLIndex索引では、ほとんどの部分が構造化されていないXMLデータでも、高度に構造化された予測可能な部分に索引付けします。この索引コンポーネントは、構造化コンテンツのアイランドを投影および使用する問合せで特に便利です。

関連項目:

「XMLIndex」

6.2.2 XMLデータのためのOracle Text索引

要素や属性などのXMLノードにアクセスする以外にも、XMLテキスト・ノード内の特定の節に対して高速アクセスを提供する必要があることがあります。XMLデータ内でこのようなコンテンツの問合せを行うには、XQuery Full Text (XQFT)またはOracle固有の全文構造体を使用できます。

いずれの場合も、適切なOracle Text (全文)索引が作成されます。XQFTの場合、索引はXML検索索引であり、バイナリXMLとして格納されたXMLTypeデータでの使用に特化した設計になっています。

全文索引は、特に、XML要素とテキストノード・コンテンツが混在する、文書中心のアプリケーションにおいて有用です。全文検索は、構造化XML検索と組み合せる(XPath式によって識別されるXML文書の一定部分に対して検索を限定する)ことによってさらに強力に、焦点を絞って行えるようになります。

関連項目:

「全文問合せ用のXMLデータの索引付け」

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

1つのケースで複数の索引が該当する場合は、どの索引が使用されるでしょうか。パフォーマンスを最大化する索引(複数可)は、コストベースの最適化によって決定されます。

Oracle Text索引はテキストにのみ適用されるため、XMLデータではテキスト・ノードを意味します。テキスト・ノードがターゲットとされ、対応するOracle Text索引が定義されている場合は、Oracle Text索引が使用されます。特定のコンテキストにおいて他の索引も適している場合は、これらも使用されます。ただし、単に索引が定義され、特定の状況に適用可能に見えることは、必ずしもその索引が使用されことを意味しません。コストベース・オプティマイザによって費用効率が低いと判断されたものは、使用されません。

6.2.4 XMLTypeに対するファンクション索引の非推奨化

Oracle Database 11gリリース2(11.2)以前のリリースでは、XPath式が単一ノードをターゲットにしている場合、XMLTypeデータにおいてファンクション索引の使用が適していることもありました。かわりに、XMLIndexの構造化コンポーネントを使用することをお薦めします。

これにより、ファンクション索引のメンテナンス操作に関連するオーバーヘッドを軽減し、オプティマイザで索引を適切に選択できる状況が増えます。その結果、既存のDML文の変更が不要になります。

さらに、XMLTypeのオブジェクト・リレーショナル記憶域では、Oracle SQL関数extractValue (非推奨)で索引を定義すると、XPathリライトにより、(extractValueに対してファンクション索引ではなく)基礎のオブジェクトに対してBツリー索引が自動的に作成されることがあります。XPathのターゲットは単一の要素または属性である必要があります。XMLQueryに適用されるXMLCastに対しても、同様のショートカットが存在します。

関連項目:

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

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

6.3 XMLIndex

- XMLIndexの利点

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

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

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

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

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

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

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

- XMLIndexの使用の無効化

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

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

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

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

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

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

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

- CREATE INDEXおよびALTER INDEXのPARAMETERS句

6.3.1 XMLIndexの利点

オブジェクト・リレーショナル形式のXMLType記憶域では、Bツリー索引を効果的に使用できます。基礎となるオブジェクトを直接ターゲット化することで、焦点がより明確に絞られます。ただし、バイナリXMLを使用して格納されているXML文書の詳細な構造(要素および属性)を指定する場合、通常は効果を発揮しません。これはXMLIndexの特殊ドメインです。

XMLIndexはドメイン索引で、XMLデータのドメイン用に特化して設計されています。これは論理的索引です。XMLIndex索引は、SQL/XML関数XMLQuery、XMLTable、XMLExistsおよびXMLCastに対して使用できます。

XMLIndexには、他の索引付け方式に比べ、次のような利点があります。

- XMLIndex索引は、問合せのどの部分においても効果があります。つまり、WHERE句での使用に限定されません。これは、XMLデータで使用される他の種類の索引では考えられません。

- 非構造化コンポーネントを含むXMLIndex索引では、SELECTリスト・データとFROMリスト・データの両方に対するアクセスを高速化でき、特にXMLフラグメント抽出において有用です。ファンクション索引は非推奨になったため、文書のフラグメントの抽出には使用できません。

- XMLIndex索引は、XML Schemaに基づく/基づかないにかかわらず、バイナリXMLとして格納されているXMLTypeデータに対して使用できます。Bツリー索引は、オブジェクト・リレーショナル形式で格納されるXML Schemaに基づくデータにのみ適しています。

- XMLIndex索引は、コレクション(文書内に複数回出現するノード)をターゲットとするXPath式による検索において使用できます。ファンクション索引の場合とは異なります。

- 問合せに使用されるXPath式に関する事前の知識は不要です。XMLIndex索引の非構造化コンポーネントは、汎用性に富んでいます。ファンクション索引の場合とは異なります。

- 問合せに使用されるXPath式が事前にわかっている場合は、頻繁に問合せされる構造化された固定のデータ・アイランドをターゲットとする構造化XMLIndexコンポーネントを使用することで、パフォーマンスを向上できます。

- XMLIndex索引(索引の作成とメンテナンス)は、複数のデータベース処理により、並列的に実行できます。非推奨になったファンクション索引の場合とは異なります。

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

XMLIndexを使用して非構造化または半構造化のXMLデータ(一般的にほとんどまたはまったく固定構造を持たないデータ)を索引付けします。それは、バイナリXMLとして格納されるXMLTypeデータに適用されます。

それでも、半構造化XMLデータには、予測可能な構造化データ・アイランドが含まれることがあります。そのため、XMLIndex索引は、そのようなアイランドの索引付け用の構造化コンポーネントと、ほとんど構造を持たないまたは可変構造のデータの索引付け用の非構造化コンポーネントの2つのコンポーネントを持つことができます。

構造化コンポーネントは、構造化コンテンツのアイランドを投影および使用する問合せで使用すると役立ちます。典型的な例は、作成者、日付およびタイトルの固定フィールドを持つ書式自由の仕様です。非構造化コンポーネントは、XMLフラグメントを抽出する問合せで使用すると役立ちます。1つのXMLIndex索引に、必ずしも両方のコンポーネントが含まれている必要はありません。

構造化コンポーネントとは異なり、非構造化コンポーネントは汎用的で、比較的ターゲットを限定しません。文書中心のXMLデータの一般的な索引付けに適しています。典型的な例は、1つのXML Webドキュメント、または書籍のうちの1章です。

XMLIndex索引は、構造化コンポーネントと非構造化コンポーネントのどちらでも作成できます。典型的なユースケースは、構造化データも存在するときは常に文書からXMLフラグメントを抽出するような問合せをサポートする場合などがあります。非構造化コンポーネントは、フラグメントの抽出に使用されます。構造化コンポーネントは、構造化データを確認する問合せ述語(たとえば、SQLのWHERE句など)に使用されます。

特定のXPathサブセットにのみ適用されるように非構造化コンポーネントを制限することもできますが、そのパス表索引ノードの内容のスカラー型が異なる場合は、異なるデータ型を処理するようにVALUE列に対して複数の2次索引を作成する必要があることがあります(「VALUE列に対する2次索引」を参照)。また、非構造化コンポーネントのみを使用した場合、構造化アイランドを投影する問合せに対してプローブやそのパス表の自己結合が何度も行われるために、効率が悪くなることがあります。

一方、構造化コンポーネントは、ほとんど構造を持たない問合せや、XMLフラグメントを抽出する問合せには適していません。構造化データ・アイランドの索引付けには構造化コンポーネントを使用し、ほとんど構造を持たないデータの索引付けには非構造化コンポーネントを使用してください。

図6-1は、第1章の図1-2と同じです。

最後の行はXMLIndexがXMLデータの様々なユースケースに適用できるかどうかを示します。XMLIndexが半構造化XMLデータ(格納されているかどうかに関係なくに)適していることを示します(最後の3列)。構造化コンポーネントでのXMLIndex索引は、構造化アイランドを含むドキュメント中心データに有用です(4列目)。

図6-1 XMLのユースケースとXML索引付け

関連項目:

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

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

- 各XMLIndexコンポーネント・タイプで提供される利点の概要は、「XMLIndexの利点」参照してください。

6.3.3 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のORDER BY、GROUP BY、およびXMLTable仮想表の列を操作するウィンドウ構造体が、構造化されたXMLIndexコンポーネントのリレーショナル索引付け表の実際の列を操作する同じ構造体にリライトされます。
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の使用」

- 「SQL/XML関数XMLQUERY_ XMLTABLE_ XMLExists_およびXMLCast」

- 「XMLTypeに対するファンクション索引の非推奨化」

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

XMLIndex構造化コンポーネントの索引コンテンツ表は通常のリレーショナル表ですが、読取り専用の表でもあるため、表の列を追加または削除したり、表の行を変更(挿入、更新または削除)したりすることはできません。

したがって、通常はリレーショナル索引コンテンツ表は無視してかまいません。DESCRIBEしたり、(2次)索引を作成する以外、それらにアクセスできません。それらに関する統計を明示的に収集する必要はありません。XMLIndex索引自体、またはXMLIndex索引が定義されている実表に関する統計のみ収集する必要があります。索引コンテンツ表に関する統計は透過的に収集され保持されます。

関連項目:

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

6.3.3.2 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-1および例6-2に、問合せ内でXQuery式をキャストして、索引コンテンツ表に使用するSQLデータ型に一致させる方法を示します。

この2つの例では、数字25はどちらも受注品目番号ですが、それぞれ異なる役割を果しています。例6-1では25はデータ型INTEGERのSQL数値であり、例6-2では25はデータ型xs:decimalのXQuery数値です。

例6-1では、XMLQueryの結果がSQLのINTEGER型にキャストされ、SQLの値25と比較されます。例6-2では、属性ItemNumberの値がXMLデータ型xs:decimalに(XQuery内で)キャストされます。これはXQueryの値25と比較され、索引に使用されるSQLデータ型(INTEGER)に対応します。このように、この例では2つの異なる種類のデータ型の変換が行われますが、どちらも型が索引コンテンツ表と一致するように問合せデータが変換されます。

関連項目:

XML Schemaデータ型とSQLデータ型の組込みの対応関係の詳細は、「XML Schemaデータ型のSQLデータ型へのマッピング方法」を参照してください。

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

SELECT count(*) FROM purchaseorder
WHERE XMLCast(XMLQuery('$p/PurchaseOrder/LineItem/@ItemNumber'
PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
AS INTEGER)
= 25;

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

SELECT count(*) FROM purchaseorder
WHERE XMLExists('$p/PurchaseOrder/LineItem[xs:decimal(@ItemNumber) = 25]'
PASSING OBJECT_VALUE AS "p");

6.3.3.3 パーティション交換とXMLIndex

パーティション交換では、1つの表と、別の表のパーティションを変更します。最初の表(exchange_tableと呼びます)は、交換しようとする第2の表(tableと呼びます)のパーティション(partitionと呼びます)と同じ構造を持つ必要があります。

同じ構造を持っていることに加え、2つの表はXMLIndex索引による索引付けという点でも類似している必要があります。次の条件の1つに該当している必要があります。

- どちらにもXMLIndex索引がないこと。

- どちらにもXMLIndex索引があり、次のいずれかが当てはまること。

- どちらの索引にも構造化コンポーネントがない。

- どちらの索引にも構造化コンポーネントがある。

これらの条件のいずれも当てはまらない場合、パーティション交換は実行できません。

どちらの表でも構造化コンポーネントにXMLIndex索引がある場合は、ALTER TABLE EXCHANGE PARTITIONを呼び出す前に一定の前処理を実行する必要があり、呼出し後にも一定の後処理を実行する必要があります。そうしないと、exchange-partition操作でエラーが発生します。

この前処理と後処理を実行するには、例6-3のようにパッケージDBMS_XMLSTORAGE_MANAGEのPL/SQLプロシージャexchangePreProcとexchangePostProcを使用します。XMLTypeの各表、tableとexchange_tableには、構造化コンポーネントを持つXMLIndex索引があります。

関連項目:

- 『Oracle Database SQL言語リファレンス』

- ドメイン索引を持つ表でのALTER TABLE EXCHANGE PARTITIONの使用方法(XMLIndexはドメイン索引)の詳細は、『Oracle Databaseデータ・カートリッジ開発者ガイド』を参照してください。

例6-3 XMLIndex構造化コンポーネントを持つ表のパーティション交換

EXEC DBMS_XMLSTORAGE_MANAGE.exchangePreProc(USER, 'table');
EXEC DBMS_XMLSTORAGE_MANAGE.exchangePreProc(USER, 'exchange_table');

ALTER TABLE table EXCHANGE PARTITION partition WITH TABLE exchange_table
WITH VALIDATION UPDATE INDEXES;

EXEC DBMS_XMLSTORAGE_MANAGE.exchangePostProc(USER, 'table');
EXEC DBMS_XMLSTORAGE_MANAGE.exchangePostProc(USER, 'exchange_table');

6.3.4 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-4では、2つの発注書のパス表の内容を見ていきます。

例6-4 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

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

パス表の列に2次索引を作成した場合でも、パス表そのものは通常は無視できます。

パス表には、それをDESCRIBEしたり、(2次)索引を作成したりする以外はアクセスできません。パス表に関する統計を明示的に収集する必要はありません。統計は、XMLIndex索引、またはXMLIndex索引が定義されている実表についてのみ収集する必要があります。統計は収集され、パス表と2次索引に透過的に保持されます。

関連項目:

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

6.3.4.2 XMLIndexパス表のVALUE列

VALUE列の2次索引は、一致する文字列に関する述語を有するWHERE句のXPath式で使用されます。次に例を示します。

/PurchaseOrder[Reference/text() = "SBELL-2002100912333601PDT"]

列VALUEには、要素または属性ノードの有効テキスト値が格納されます。索引付けの際、コメントおよび処理命令は無視されます。

- 属性では、有効テキスト値は属性値です。

- 単純な要素(子のない要素)では、有効テキスト値は、要素のすべてのテキスト・ノードを連結したものになります。

- 複雑な要素(子のある要素)では、有効テキスト値は、(1)要素そのもののテキスト・ノードを連結したもの、(2)単純要素のすべての子孫の有効テキスト値になります。(これは再帰的定義です。)

ただし、有効テキスト値は4000バイト(単純な要素または属性の場合)および80バイト(複雑な要素の場合)に制限(切捨て)されます。

VALUE列のサイズは、VARCHAR2(4000)に固定されています。索引の作成または更新時のオーバーフロー(4000バイト超)は、すべて切り捨てられます。

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列で使用されます。

6.3.4.3 VALUE列に対する2次索引

XMLIndex索引を作成する際、VALUE列に対して2次索引を指定しない場合でも、VALUE列に対してデフォルトの2次索引が作成されます。このデフォルト索引には、デフォルトのプロパティがあります。具体的には、これはtext(文字列値)データでのみ使用される索引です。

ただし、異なる種類のVALUE索引を作成できます。たとえば、数値の索引が問合せの大半に適している場合は、数値の索引を作成できます。VALUE列に対し、複数の2次索引を作成できます。特定の種類の索引は、それが適切な場合にのみ使用されます。たとえば、数値の索引は、VALUE列が数値である場合にのみ使用されます。その他の値の場合は無視されます。パス表の列の2次索引は、その他の2次索引と同様に扱われます。つまり、これらの索引は変更、削除、不使用としてマーキングするなどが可能です。

関連項目:

- VALUE列に2次索引を作成する例の詳細は、「非構造化コンポーネントを含むXMLIndexの使用」を参照してください

- PARAMETERS句の構文は、「CREATE INDEXおよびALTER INDEXのPARAMETER句」を参照してください

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

いくつかのタイプのXPath式は、XMLIndexにより索引付けされません。

- ora:contains以外のXPath関数の適用。特に、ユーザー定義のXPath関数は索引付けされません。

- child、descendant、およびattribute以外の軸(parent、ancestor、following-sibling、preceding-sibling、following、preceding、およびancestor-or-selfの各軸)。

- 共用体演算子|(垂直バー)を使用する式。

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

XMLIndex索引に対する基本操作には、XMLIndex索引の作成、削除、変更および検証が含まれます。例を示します。

例6-5に示すように、索引タイプをXDB.XMLIndexと宣言して、XMLIndex索引を作成します。

これにより、XMLTypeのpo_binxml表に、po_xmlindex_ixという名前のXMLIndex索引が作成されます。索引に含まれるのは非構造化コンポーネントのみで、構造化コンポーネントは含まれません。

XMLIndex索引に構造化コンポーネントを含めるように指定するには、PARAMETERS句にstructured_clauseを含めます。非構造化コンポーネントを含めるように指定するには、PARAMETERS句にpath_table_clauseを含めます。

この操作は、XMLIndex索引を作成または変更する場合に可能です。例6-5に示すように、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-6に示すように、特定のXMLType表(または列)のXMLIndex索引の名前を取得できます。また、適宜DBA_INDEXESまたはALL_INDEXESからINDEX_NAMEを選択することも可能です。

例6-7に示すように、XMLIndex索引は、他の索引と同様に名前変更または削除できます。この名前変更では、XMLIndex索引の名前のみが変更されます。この処理ではパス表の名前は変更されません。パス表は、個別に名前を変更できます。

同様に、REBUILDなどのALTER INDEXオプションを使用し、他の索引プロパティも変更できます。この点においては、XMLIndexも他の索引タイプと同じです。

XMLIndexのALTER INDEX文のRENAME句は、XMLIndexそのものに対してのみ適用されます。パス表および2次索引の名前を変更するには、これらのオブジェクトの名前を決定し、適切なALTER TABLE文またはALTER INDEX文を直接使用する必要があります。同様に、2次索引の物理プロパティを取得したり、他のなんらかの方法で変更を加えたりする場合は、例6-12の方法に従って2次索引の名前を取得する必要があります。

関連項目:

PARAMETERS句の構文は、「CREATE INDEXおよびALTER INDEXのPARAMETER句」を参照してください

例6-5 XMLIndex索引の作成

CREATE INDEX po_xmlindex_ix ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex;

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

SELECT INDEX_NAME FROM USER_INDEXES
WHERE TABLE_NAME = 'PO_BINXML' AND ITYP_NAME = 'XMLINDEX';

INDEX_NAME
---------------
PO_XMLINDEX_IX

1 row selected.

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

ALTER INDEX po_xmlindex_ix RENAME TO new_name_ix;

DROP INDEX new_name_ix;

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

非構造化コンポーネントを含むXMLIndex索引に対して、該当コンポーネントのパス表や2次索引の操作など、様々な操作を実行できます。

XMLIndex索引に非構造化コンポーネントを含めるには、XMLIndex索引の作成または変更時に、PARAMETERS句でpath_table_clauseを使用できます。詳細は「path_table_clause ::=」を参照してください。

構造化コンポーネントを指定しない場合、パス表を指定しなくても、索引に非構造化コンポーネントが含まれます。ただし、一般的にはパス表を指定することをお薦めします。これにより他のXMLIndex操作で参照できる、ユーザー指向の認識可能な名前が含まれるようになります。

例6-8に、非構造化コンポーネントを含むXMLIndex索引の作成時に、パス表(my_path_table)の名前を付ける方法を示します。

パス表に名前を付けなかった場合、名前はCREATE INDEXに与えた索引名に基づき、システムによって自動的に生成されます。例6-9に、例6-5で作成したXMLIndex索引を使用した例を示します。

デフォルトでは、パス表と2次索引の記憶域オプションは、XMLIndex索引が作成された実表の記憶域プロパティから生成されます。例6-10で示すように、索引の作成時にPARAMETERS句を使用すると、異なる記憶域オプションを指定できます。CREATE INDEX (およびALTER INDEX)のPARAMETERS句は、一重引用符(')で囲む必要があります。

関連項目:

PARAMETERS句の構文は、「CREATE INDEXおよびALTER INDEXのPARAMETER句」を参照してください

XMLIndexは論理的なドメイン索引であり、物理索引ではないため、すべての物理属性はゼロ(0)またはNULLになります。

XMLIndex索引に非構造化コンポーネントと構造化コンポーネントの両方が含まれる場合は、ALTER INDEXを使用して非構造化コンポーネントを削除できます。これを実行するには、パス表を削除します。例6-11に、これを示します。(この場合は、構造化コンポーネントも含むことを前提とします。例6-20では、索引に構造化コンポーネントと非構造化コンポーネントの両方が含まれるようになります。)

例6-10では、パス表に対する記憶域オプションの指定に加え、パス表に対する2次索引にも名前を付けています。

パス表の名前と同様、パス表の列の2次索引の名前は、PARAMETERS句で指定しないかぎり、索引名をベースとして使用して自動的に生成されます。例6-12にこれを示します。これらの名前をパブリック・ビューUSER_IND_COLUMNSで決定する方法も示します。また、pikey索引で3つの列を使用することも示します。

関連項目:

例6-18に、類似するが、さらに複雑なケースを示します。

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

CREATE INDEX po_xmlindex_ix ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
PARAMETERS ('PATH TABLE my_path_table');

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

SELECT PATH_TABLE_NAME FROM USER_XML_INDEXES
WHERE TABLE_NAME = 'PO_BINXML' AND INDEX_NAME = 'PO_XMLINDEX_IX';

PATH_TABLE_NAME
------------------------------
SYS67567_PO_XMLINDE_PATH_TABLE

1 row selected.

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

CREATE INDEX po_xmlindex_ix ON po_binxml (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)');

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

ALTER INDEX po_xmlindex_ix PARAMETERS('DROP PATH TABLE');

例6-12 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.3.6.1 XMLIndexパス表に対する追加の2次索引の作成

XMLIndex非構造化コンポーネントに、2次索引をさらに追加できます。

例6-13、例6-15、例6-16および例6-17の各例では、例6-10で作成されたXMLIndex索引に、2次索引をさらに追加します。

XMLIndex索引のパス表のVALUE列に対し、2次索引をいくつでも追加で作成できます。ファンクション索引やOracle Text索引など、様々な種類が可能です。

問合せの処理時に、指定の索引が指定の要素に対して使用されるかどうかは、その索引が当該値に対して適切であるかどうかや、その索引の使用が費用効率に優れているかどうかによって決まります。

例6-13では、SQL関数substrを使用して、パス表のVALUE列にファンクション索引を作成します。問合せにおいて、XML要素のテキスト・ノードに対してsubstrがよく使用される場合は便利な方法です。

テキスト・ノードが数値を表す要素が多数ある場合、VALUE列に対して数値索引を作成すると有効です。ただし、例6-13と同じような方法で数値索引を直接作成すると、要素値のいずれかが数値ではない場合にORA-01722エラー(無効な数値)が発生します。これを例6-14に示します。

ここで必要となるのは、数値の要素に対して使用されるが、数値を持たない要素に対しては無視される索引です。特に、DBMS_XMLINDEXパッケージのcreateNumberIndexプロシージャは、この目的でのみ存在するものです。このプロシージャに、データベース・スキーマの名前、XMLIndex索引、および作成される数値索引を渡します。数値索引の作成は、例6-15に示します。

このような索引は数値を持たない要素を無視するよう設計されているため、この索引が数値を持たない要素を検出することはありません。非数値要素がある場合に、なんらかの理由によりXMLIndex索引が問合せで使用されなければ、ORA-01722エラーが発生します。ただし、索引が使用されると非数値データは無視されるため、エラーは発生しません。ここでも、索引の使用により結果セットが変わることはありません。結果はまったく同じですが、索引を使用すると、誤ったデータの検出を防ぐことはできます。

日付値の索引の作成は、数値索引の作成と似ています。この場合は、DBMS_XMLINDEX.createDateIndexプロシージャを使用します。例6-16に、これを示します。

例6-17では、Oracle TextのCONTEXT索引をVALUE列に作成します。これは、XML要素のテキスト値に対する全文問合せにおいて便利です。XPath関数ora:containsを使用するXPath述語は、VALUE列のcontains Oracle SQL関数の使用にあわせてリライトされます。CONTEXT索引がVALUE列に対して定義されている場合、述語の評価時に使用されます。Oracle Text索引は、他のすべてのVALUE列の索引に依存しません。

関連項目:

- VALUE列に対して作成されたOracle Text CONTEXT索引が間違った結果を戻すことがあります。この詳細は、「XMLIndexパス表のVALUE列」を参照してください

- 「全文問合せ用のXMLデータの索引付け」

- パラメータTRANSACTIONALの詳細は、「XPathリライトおよびCONTEXT索引」を参照してください

例6-18の問合せは、XMLIndex索引のパス表に対して作成されたすべての2次索引を示します。作成された索引は、明確に太字で示されます。特に注意する必要があるのは、VALUE列に作成されたファンクション索引などは、この例のように表示されない点です。これらの索引の列名は、SYS_NC00007$などのシステム生成名になります。そのため、WHERE句でCOLUMN_NAME = 'VALUE'を使用して問合せを実行しても、これらの列を見ることはできません。

関連項目:

- DBMS_XMLINDEXパッケージのPL/SQLプロシージャcreateNumberIndexおよびcreateDateIndexの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- Oracle Textを使用する方法の詳細は、XQueryを使用しないXMLデータの全文検索を参照してください。

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

CREATE INDEX fn_based_ix ON po_path_table (substr(VALUE, 1, 100));

例6-14 パス表の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

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

CALL DBMS_XMLINDEX.createNumberIndex('OE', 'PO_XMLINDEX_IX', 'API_NUM_IX');

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

CALL DBMS_XMLINDEX.createDateIndex('OE', 'PO_XMLINDEX_IX', 'API_DATE_IX',
'dateTime');

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

CREATE INDEX po_otext_ix ON po_path_table (VALUE)
INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS('TRANSACTIONAL');

例6-18 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.

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

XMLIndex構造化コンポーネントにより、XMLデータ内の構造の特定のアイランドを索引付けします。

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のマルチレベル連鎖を使用します。このような索引を簡単に作成するには、PL/SQL関数DBMS_XMLSTORAGE_MANAGE.getSIDXDefFromViewを使用すれば、索引の作成に必要なXMLTable式を正確に記述できます。

関連項目:

- DBMS_XMLSTORAGE_MANAGE.getSIDXDefFromViewの使用方法の詳細は、「リレーショナル・ビューを使用して公開されるバイナリXMLデータの索引付け」を参照してください

- 例6-27

- 「全文問合せ用のXMLデータの索引付け」

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

- 「structured_clause ::=」

- XMLTable句のXMLType列の詳細は、「XMLIndex_xmltable_clauseの使用」を参照してください

- キーワードCOLUMNSおよびVIRTUALの詳細は、「column_clauseの使用」を参照してください

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

6.3.7.1 XMLIndex構造化コンポーネントでの名前空間とStorage句の使用

構造化コンポーネントを持つXMLIndex索引を作成するとき、使用するXML名前空間と記憶域オプションを指定できます。

例6-19に、XMLIndex索引の作成を示します。この索引には、構造化コンポーネントのみが含まれ(パス表句は含まれない)、XMLNAMESPACES句を使用して名前空間を指定します。索引データを圧縮し、表領域SYSAUXを使用することを指定します。この例では、XML Schemaに基づかないデータを含むバイナリXML表po_binxmlを想定しています。

例6-19に示した各TABLESPACE句は、表レベル(po_ptab表およびli_tab表)で適用されます。特定のXMLIndex索引または特定のパーティションに対してTABLESPACE句を指定することもできます。

例6-19 構造化コンポーネントのみを含む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.3.7.2 XMLIndex索引への構造化コンポーネントの追加

ALTER INDEXを使用して、既存のXMLIndex索引に構造化コンポーネントを追加できます。

例6-20に、非構造化コンポーネントのみを含むXMLIndex索引を作成する方法を示します。PARAMETERS句でパス・ノードに明示的に名前付けしているため、非構造化コンポーネントが作成されます。

例6-20では、ALTER INDEXを使用して、po_itemという名前の構造化コンポーネント(グループ)を追加します。この構造グループには、キーワードXMLTableで指定された2つのリレーショナル表が含まれます。

最上位の表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に含まれるように索引パラメータを更新します。

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

CREATE INDEX po_xmlindex_ix ON po_binxml (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');

6.3.7.3 XMLIndex構造化コンポーネントでの非ブロック・モードによるALTER INDEXの使用

XMLIndex索引の構造化コンポーネントにグループまたは列を追加する際に、ALTER INDEXによるブロックを回避できるため、この索引を使用する問合せでは、待機する必要はありません。

ALTER INDEXを使用して、XMLIndex索引の構造化コンポーネントにグループまたは列を追加する場合、この索引メンテナンス操作では、実表および索引に対して排他DDLロックを取得します。

ALTER INDEX操作が終了するまで、実表はDML操作に対してロックされ、索引を問合せで使用することはできません。つまり、この索引メンテナンス中は、実表に対して問合せやDML操作を実行する別のセッションから索引を使用することはできません。ALTER INDEX操作とそれに附随するロックの期間は、XMLTypeの実列に含まれているデータ量によって異なります。

この問題を回避するには、次の手順を実行します。

1. 構造化コンポーネントのグループまたは列を作成するALTER INDEX文のPARAMETERS句で、ADD_GROUPまたはADD_COLUMNの前にキーワードNONBLOCKINGを指定します。
これにより、必要に応じて索引は更新されますが、実表のデータは索引付けされません。実表のデータに依存しないため、実表のサイズに関係なく高速です。

2. PL/SQLプロシージャDBMS_XMLINDEX.process_pendingを呼び出します。
このプロシージャでは、キーワードNONBLOCKINGが指定されていないかのように、実表の行に索引付けして索引の表にデータを移入します。ただし、この場合、処理および変更のコミットが行われている間にロックされる行はわずか数行です。他の目的ですでにロックされていた行はスキップされます。これにより、ロック競合が大幅に減少し、一部の行への索引付けを可能にしつつ、同時に、その他の行に対して問合せやDML操作を実行できます。

プロシージャprocess_pendingが終了すると、次のOUTパラメータを戻します。

- 索引付けできなかった行の数。この原因は、それらが他の目的でロックされていたか、エラーが発生したためかのいずれかです(この数には、もう1つのOUTパラメータとして戻された数も含みます)。
これらのロックが解除されたことを確認した後で、プロシージャprocess_pendingをもう一度呼び出して、保留中の行の処理を試みます。

- エラーが発生したために索引付けできなかった行の数(これはまれなケースです)。
表SYS_AIXSXI_index_number_ERRORTABでエラーの詳細を確認し、問題の原因を解決するための処置を取ります。index_numberとは、索引オブジェクト番号のことです。

3. すべての行が正常に索引付けされたことをプロシージャprocess_pendingが示すか、解決できない問題が発生して索引付けの操作を完全にキャンセルする判断をユーザーが下すまで、手順2を必要な回数繰り返します。
同じXMLIndex索引に対し、別のALTER INDEX文のPARAMETERS句で、キーワードNONBLOCKING ABORTを指定することにより、索引付けは(手順2の前に)いつでもキャンセルできます。

4. すべての行が正常に索引付けされた場合は、同じXMLIndex索引に対して、別のALTER INDEX文のPARAMETERS句で、キーワードNONBLOCKING COMPLETEを指定します。

例6-21に、これを示します。

表SYS_AIXSXI_index_number_ERRORTABがエラーをレポートするように、表SYS_AIXSXI_index_number_PENDINGTABには、索引の有無に関係なく、実表の行ごとに現在のステータスが記録されます。何か他の目的で行がロックされているか、索引付けを試みてエラーが発生したために、まだ索引付けされていない行がある場合があります。後者の場合は、SYS_AIXSXI_index_number_ERRORTABを参照して、エラーの詳細を確認してください。

関連項目:

「alter_index_group_clause ::=」

例6-21 DBMS_XMLINDEX.PROCESS_PENDINGを使用したXMLデータの索引付け

CREATE INDEX po_struct ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
PARAMETERS ('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''');

ALTER INDEX po_struct
PARAMETERS('NONBLOCKING ADD_GROUP GROUP po_action_group
XMLTABLE po_idx_tab
''/PurchaseOrder''
COLUMNS actions       XMLType       PATH  ''Actions/Action'' VIRTUAL
XMLTABLE po_idx_action
''/Action'' PASSING actions
COLUMNS actioned_by   VARCHAR2(10)  PATH  ''User'',
date_actioned TIMESTAMP     PATH  ''Date''');

DECLARE
num_pending NUMBER := 0;
num_errored NUMBER := 0;
BEGIN
DBMS_XMLINDEX.process_pending('oe', 'po_struct', num_pending, num_errored);
DBMS_OUTPUT.put_line('Number of rows still pending = ' || num_pending);
DBMS_OUTPUT.put_line('Number of rows with errors   = ' || num_errored);
END;
/
Number of rows still pending = 0
Number of rows with errors   = 0

PL/SQL procedure successfully completed.

ALTER INDEX po_struct PARAMETERS('NONBLOCKING COMPLETE');

6.3.7.4 構造化XMLIndexコンポーネントのデータ型の変更

データの一部が構造化XMLIndexコンポーネントの対応する列で使用されているデータ型と一致しないためにエラーが発生する場合は、キーワードMODIFY_COLUMN_TYPEをALTER INDEXに渡すことによって、索引を簡単に変更できることがあります。

たとえば、VARCHAR2(30)列にデータを40文字まで収容する必要がある場合は、それをVARCHAR2(40)などに拡張できます。列を削除してから新しい列を追加するよりも、この方が簡単でより効率的です。ただし、ALTER TABLE MODIFY COLUMNと同じ制約が適用されるので、新旧のデータ型が一致している必要があります。

関連項目:

- ALTER TABLE MODIFY COLUMNの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- 「modify_column_type_clause :==」

6.3.7.5 XMLIndex構造化コンポーネントの削除

XMLIndex索引に非構造化コンポーネントと構造化コンポーネントの両方が含まれる場合は、ALTER INDEXを使用して構造化コンポーネントを削除できます。これを行うには、構造化コンポーネントを構成するすべての構造グループを削除します。

例6-22に、例6-20で追加された構造化コンポーネントを削除する方法を示します。この場合は、その構造グループpo_itemのみを削除します。

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

ALTER INDEX po_xmlindex_ix PARAMETERS('DROP_GROUP GROUP po_item');

6.3.7.6 構造化XMLIndexコンポーネントのリレーショナル表への索引付け

XMLIndex索引の構造化コンポーネントに使用する表は通常のリレーショナル表であるため、標準的な任意のリレーショナル索引を使用して、これらの表に索引付けできます。

詳細は、XMLIndex構造化コンポーネントの項を参照してください。例6-23に、これを示します。この例では、例6-20のXMLIndex索引に対して、索引コンテンツ表(構造化フラグメント)のreference列にBツリー索引を作成します。

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

CREATE INDEX idx_tab_ref_ix ON po_idx_tab (reference);

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

特定のXMLIndex索引が問合せの解決に使用されたかどうかを把握するには、問合せの実行計画を検証します。

特定のXMLIndex索引を使用できるかどうかは、問合せのコンパイル時にOracle Databaseにより決定されます。つまり、索引に対する問合せにその問合せをリライトできるかどうかによって決まります。

非構造化XMLIndexコンポーネントの場合、問合せ内のXPath式が、XMLIndex索引付けに使用するよう指定したパスのサブセットであることをコンパイル時に断定できない場合、索引の非構造化コンポーネントは使用されません。

たとえば、索引付けの際にパス/PurchaseOrder/LineItems//*が含まれる場合、/PurchaseOrder/LineItems/LineItem/Descriptionを含む問合せでは索引を使用できますが、//Descriptionを含む問合せは索引を使用できません。後者は、/PurchaseOrder/LineItemsの子ではない潜在的なDescription要素と一致し、そのDescription要素がデータに出現するかどうかはコンパイル時に判断できません。

特定のXMLIndex索引が問合せの解決に使用されたかどうかを把握するには、問合せの実行計画を検証します。

- 索引の非構造化コンポーネントが使用される場合、そのパス表、順序キー、またはパスIDが実行計画において参照されます。実行計画は、ドメイン索引が使用されていることを直接的に示すことはありません。XMLIndex索引を名前で参照することもありません。例6-24および例6-26を参照してください。

- 索引の構造化コンポーネントが使用される場合、その索引コンテンツ表の1つ以上が実行計画において呼び出されます。例6-27および例6-28を参照してください。

関連項目:

- 『Oracle Database SQL言語リファレンス』

- Oracle Database SQLチューニング・ガイド

例6-24に、例6-8で作成したXMLIndex索引が特定の問合せで使用される様子を示します。ここで示す実行計画のMY_PATH_TABLEへの参照は、XMLIndex索引(例6-8で作成)が問合せで使用されることを示します。同様に、LOCATOR、ORDER_KEY、およびPATHIDの各列への参照も、同じことを示します。

例6-25に示すように、このような実行計画からパス表の名前から、XMLIndex索引の名前を取得できます。(これは例6-9の問合せとほぼ反対のケースです。)

XMLIndexは、SELECTリスト、FROMリスト、および問合せのWHERE句のXPath式で使用でき、SQL/XML関数XMLQuery、XMLTable、XMLExistsおよびXMLCastにおいて有用です。ファンクション索引(XMLTypeでは非推奨)とは異なり、XMLIndex索引は、文書内のXMLフラグメントからデータを抽出する際に使用できます。

例6-26に、これを示します。

例6-26の問合せの実行計画は、パス表を参照することにより、XMLIndexが使用されることを示します。Oracle内部SQL関数sys_orderkey_depthが使用されることも示します。「非構造化コンポーネントを含むXMLIndexを使用するためのガイドライン」を参照してください。

例6-27に、例6-20で作成したXMLIndex索引が2つのWHERE句述語を使用する問合せに対して選択されることを示す実行計画を示します。それは例6-43と同じ問合せで、実行計画にも示されているように、同じXML検索索引が使用されています。

非構造化XMLIndexコンポーネントのみが含まれる場合、WHERE句内に2つの異なるパスがあるため、問合せに対してパス表の自己結合が行われます。

例6-27で、パス表名path_tabが存在することは、索引の非構造化コンポーネントが使用されることを示しています。索引コンテンツ表po_idx_tabが存在することは、構造化索引コンポーネントが使用されることを示しています。XML検索索引po_ctx_idxが存在することは、それも使用されることを示しています。

例6-28に、同じXMLIndex索引が、マルチレベルのXMLTable連鎖を使用する問合せに対して取得されることを示す実行計画を示します。非構造化XMLIndexコンポーネントのみが含まれる場合、2つのXMLTableファンクション・コールに2つの異なるパスがあるため、この問合せに対してもパス表の自己結合が行われます。

この実行計画は、リレーショナル索引コンテンツ表po_idx_tabおよびpo_index_lineitemへの直接アクセスを示しています。パス表path_tabへのアクセスはまったくありません。

関連項目:

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

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

SET AUTOTRACE ON EXPLAIN

SELECT XMLQuery('/PurchaseOrder/Requestor' PASSING OBJECT_VALUE RETURNING CONTENT) FROM po_binxml
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_BINXML                    |     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-25 パス表名からのXMLIndex索引名の取得

SELECT INDEX_NAME FROM USER_XML_INDEXES WHERE PATH_TABLE_NAME = 'MY_PATH_TABLE';

INDEX_NAME
------------------------------
PO_XMLINDEX_IX

1 row selected.

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

SET AUTOTRACE ON EXPLAIN

SELECT li.description, li.itemno
FROM po_binxml, 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_BINXML                    |     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_BINXML".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 2つの述語を使用する問合せに対する構造化XMLIndexコンポーネントの使用

EXPLAIN PLAN FOR
SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem'
PASSING OBJECT_VALUE RETURNING CONTENT)
FROM po_binxml
WHERE XMLExists('/PurchaseOrder/LineItems/LineItem
[Description contains text "Picnic"]'
PASSING OBJECT_VALUE)
AND XMLExists('/PurchaseOrder[User="SBELL"]' PASSING OBJECT_VALUE);

Explained.

----------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name                         |Rows|Bytes| Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                              |   1| 2051|     9   (0)| 00:00:01 |
|   1 |  SORT GROUP BY                       |                              |   1| 3524|            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID BATCHED| PATH_TAB                     |   2| 7048|     3   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN                  | SYS86751_PO_XMLINDE_PIKEY_IX |   1|     |     2   (0)| 00:00:01 |
|   4 |  NESTED LOOPS SEMI                   |                              |   1| 2051|     6   (0)| 00:00:01 |
|   5 |   TABLE ACCESS BY INDEX ROWID        | PO_BINXML                    |   1| 2024|     4   (0)| 00:00:01 |
|*  6 |    DOMAIN INDEX                      | PO_CTX_IDX                   |    |     |     4   (0)| 00:00:01 |
|*  7 |   TABLE ACCESS BY INDEX ROWID BATCHED| PO_IDX_TAB                   |  13|  351|     2   (0)| 00:00:01 |
|*  8 |    INDEX RANGE SCAN                  | SYS86751_86755_OID_IDX       |   1|     |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - filter(SYS_XMLI_LOC_ISNODE("SYS_P1"."LOCATOR")=1)
3 - access("SYS_P1"."RID"=:B1 AND "SYS_P1"."PATHID"=HEXTORAW('3748') )
6 - access("CTXSYS"."CONTAINS"(SYS_MAKEXML(0,"XMLDATA"),'<query><textquery grammar="CONTEXT"
lang="english">{Picnic} INPATH
(/PurchaseOrder/LineItems/LineItem/Description)</textquery><xquery><offset>0</
offset></xquery></query>')>0)
7 - filter("SYS_SXI_0"."USERNAME"='SBELL')
8 - access("PO_BINXML"."SYS_NC_OID$"="SYS_SXI_0"."OID")

Note
-----
- dynamic sampling used for this statement (level=2)

30 rows selected.

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

EXPLAIN PLAN FOR
SELECT po.reference, li.*
FROM po_binxml 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 |     8   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                |                        |       |       |            |          |
|   2 |   NESTED LOOPS               |                        |    17 | 20366 |     8   (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_C007442            |     1 |    10 |     0   (0)| 00:00:01 |
|*  6 |    INDEX RANGE SCAN          | SYS86751_86759_PKY_IDX |    17 |       |     1   (0)| 00:00:01 |
|   7 |   TABLE ACCESS BY INDEX ROWID| PO_INDEX_LINEITEM      |    17 | 11203 |     5   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

4 - filter("SYS_SXI_2"."REFERENCE"='SBELL-20021009123335280PDT')
5 - access("P"."SYS_NC_OID$"="SYS_SXI_2"."OID")
6 - access("SYS_SXI_2"."KEY"="SYS_SXI_3"."PKEY")

Note
-----
- dynamic sampling used for this statement

25 rows selected.

6.3.9 XMLIndexの使用の無効化

XMLIndexの使用を無効にするには、オプティマイザ・ヒント/*+ NO_XML_QUERY_REWRITE */またはオプティマイザ・ヒント/*+ NO_XMLINDEX_REWRITE */を使用します。

これらの各ヒントにより、すべてのXMLIndex索引の使用が無効になります。NO_XML_QUERY_REWRITEは、XMLIndexの使用を無効にする他に、XQueryの最適化もすべて無効にします(XMLIndexはXPathリライトの一部です)。

例6-29に、これらのオプティマイザ・ヒントの使用方法を示します。

注意:

NO_INDEXオプティマイザ・ヒントは、XMLIndexには適用されません。

関連項目:

XQueryの最適化を詳細に管理できるXQueryプラグマora:no_xmlquery_rewriteおよびora:xmlquery_rewriteの詳細は、「XQueryのオプション機能」を参照してください。

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

SELECT /*+ NO_XMLINDEX_REWRITE */
count(*) FROM po_binxml WHERE XMLExists('$p/*' PASSING OBJECT_VALUE AS "p");

SELECT /*+ NO_XML_QUERY_REWRITE */
count(*) FROM po_binxml WHERE XMLExists('$p/*' PASSING OBJECT_VALUE AS "p");

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

問い合せる可能性の高いXPath式がわかっている場合は、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句」を参照してください

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

XPath式のサブセットに対し、XMLIndex索引を定義する例をいくつか示します。

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

CREATE INDEX po_xmlindex_ix ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
PARAMETERS ('PATHS (INCLUDE (/PurchaseOrder/LineItems//*
/PurchaseOrder/Reference))');

この文では、次に示すように、最上位要素であるPurchaseOrderおよびその子に対してのみ索引付けする索引を作成します。

- すべてのLineItems要素およびその子孫

- すべてのReference要素

索引に使用される一連の空白のパスに対し、指定のパスを含めていきます。

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

ALTER INDEX po_xmlindex_ix REBUILD
PARAMETERS ('PATHS (INCLUDE ADD (/PurchaseOrder/Requestor
/PurchaseOrder/Actions/Action//*))');

この文では、索引付けに使用されたパスに対し、2つのパスを追加します。これらのパスは、Requestor要素と、Action要素の子孫(およびその祖先)に対して索引付けします。

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

XMLIndex索引付けに使用されるXPath式で名前空間接頭辞が使用される場合、NAMESPACE MAPPING句をPATHSリストで使用して接頭辞を指定できます。次に例を示します。

CREATE INDEX po_xmlindex_ix ON po_binxml (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"))');

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

XMLIndexパスのサブセット化に適用されるルールについて説明します。

- パスはchild軸およびdescendant軸のみを参照し、さらに、要素ノードおよび属性ノード、またはその名前(ワイルドカードを使用可能)のみをテストする必要があります。特に、パスには述語を含めないでください。

- パス除外とパス包含を一度に指定できません。いずれかの方法を指定する必要があります。

- パス除外(包含)によって索引が作成された場合は、パス除外(包含)によってのみ修正が可能です。索引の修正は、パスのサブセット化をさらに制限するか、さらに拡張するかのいずれかです。たとえば、特定のパスを含める索引を作成した後に、特定のパスを除外するよう修正することはできません。

6.3.11 非構造化コンポーネントを含む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_binxml, XMLTable('//LineItem' PASSING OBJECT_VALUE);

次のように記述しないでください。

SELECT count(li.value)
FROM po_binxml p, XMLTable('//LineItem' PASSING p.OBJECT_VALUE
COLUMNS value VARCHAR2(30) PATH 'Description') li;

- 問合せのFROMリストで使用されるXPath式の数は、なるべく少なくしてください。たとえば、次のように記述します。

SELECT li.description
FROM po_binxml p,
XMLTable('PurchaseOrder/LineItems/LineItem' PASSING p.OBJECT_VALUE
COLUMNS description VARCHAR2(256) PATH 'Description') li;

次のように記述しないでください。

SELECT li.description
FROM po_binxml 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_binxml 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-26を参照してください。

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

構造化コンポーネントを含むXMLIndexを使用する際に役立つ複数のガイドラインがあります。

- 構造化コンポーネントを含むXMLIndexを使用して、リレーショナル列としてXMLデータを投影および索引付けします。ファンクション索引は使用しないでください。XMLとの使用は非推奨です。「XMLTypeに対するファンクション索引の非推奨化」を参照してください。

- 構造化コンポーネントが含まれるXMLIndex索引と問合せの間のデータ型の対応の確認。「XMLIndex構造化コンポーネントのデータ型に関する考慮事項」を参照してください。

- XMLTypeデータに関してリレーショナル・ビューを作成する場合(SQL関数XMLTableなどを使用して)、同じリレーショナル列をターゲットとする、構造化されたコンポーネントを持つXMLIndex索引を作成することも考慮してください。XMLデータのリレーショナル・ビューを参照してください。

- フラグメント抽出と値のフィルタリング(検索)の両方に単一のXQuery式を使用するかわりに、SELECT句でSQL/XML関数XMLQueryを使用し、WHERE句のフラグメントおよびXMLExistsを抽出して値をフィルタリングします。
こうすることで、Oracle XML DBがフラグメント抽出の機能的に、あるいはストリーミング評価を使用して評価できます。値のフィルタリングの場合、こうするとOracle XML DBが適切な構造のコンポーネントを持つXMLIndex索引を取得できます。

- 問合せの結果の順序を設定するには、SQLのORDER BY句とSQL/XML関数XMLTableを使用します。XQueryのorder by句は使用しないでください。構造化されたコンポーネントを含むXMLIndex索引を使用する場合は、特に使用を避けてください。

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

レンジ・パーティション化、リスト・パーティション化、またはハッシュ・パーティション化を使用して、XMLType表や、XMLType列が含まれる表をパーティション化する場合、その表にXMLIndex索引を作成することもできます。オプションで、索引の作成とメンテナンスが並列で実行されるようにできます。

索引作成とメンテナンスを確実に並列化するには、XMLIndex索引を作成または変更するとき、PARALLEL句を(オプションで)使用します。

XMLIndex索引を作成するときにキーワードLOCALを使用すると、索引とその記憶域表すべてが、実表に関連してローカルに同一レベル・パーティション化されます。

キーワードLOCALを使用しない場合は、パーティション化された表にXMLIndex索引を作成できません。また、コンポジット・パーティション化した表には、XMLIndex索引を作成できません。

PARALLEL句を使用しており、実表がパーティション化されていたり、実表で並列度が有効になっている場合は、これによりDML操作(INSERT、UPDATE、DELETE)と索引DDL操作(CREATE、ALTER、REBUILD)の両方のパフォーマンスを向上させることができます。

索引に並列度を指定すると、問合せサーバー・プロセスそれぞれに個別に記憶域パラメータが適用されるため、記憶域の消費も多くなります。たとえば、INITIAL値が5M、並列度が12で作成された索引は、作成時に少なくとも60Mの記憶域を消費します。

CREATE INDEXおよびALTER INDEXのPARALLEL句の構文は、他のドメイン索引のものと同じです。

{ NOPARALLEL | PARALLEL [ integer ] }

例6-33では、並列度10でXMLIndex索引を作成します。実表がパーティション化されている場合、この索引は同一レベル・パーティション化されます。

例6-33では、パス表と2次索引は、XMLIndex索引そのものと同じ並列度(10)を継承して作成されます。パス表と2次索引に対して個別のPARALLEL句を使用し、異なる並列度を設定することも可能です。例6-34に、これを示します。ここでも、キーワードLOCALにより、実表がパーティション化されている場合、この索引は同一レベル・パーティション化されます。

例6-34では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コンポーネント」

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

CREATE INDEX po_xmlindex_ix ON sale_info (sale_po_clob) INDEXTYPE IS XDB.XMLIndex
LOCAL PARALLEL 10;

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

CREATE INDEX po_xmlindex_ix ON sale_info (sale_po_clob) INDEXTYPE IS XDB.XMLIndex
LOCAL NOPARALLEL PARAMETERS ('PATH TABLE po_path_table (PARALLEL 10)
PIKEY INDEX po_pikey_ix
VALUE INDEX po_value_ix (PARALLEL 5)');

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

非構造化コンポーネントのみを含むXMLIndex索引メンテナンスのコストを遅延して、コミット時やデータベースの負荷が軽減されているときにのみ、メンテナンスを実行できます。これにより、DMLパフォーマンスを向上させることができ、索引の同期化時に非同期索引行のバルク・ロードを有効にできます。

この機能は、非構造化コンポーネントのみが含まれる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-35では、明日から毎週月曜日の午後3時に同期化されるXMLIndex索引を作成します。

例6-36では、例6-35で作成された索引を手動で同期化します。

XMLIndex索引の同期化が遅延されると、索引に対する最終同期化以降、実表に対して加えられたすべてのDML変更(挿入、更新、削除)は、DML操作当たり1行ずつ、保留中の表に記録されます。この表の名前は、静的なパブリック・ビューUSER_XML_INDEXES、ALL_XML_INDEXES、およびDBA_XML_INDEXESのPEND_TABLE_NAME列の値です。

この表を検証すると、指定のXMLIndex索引を同期化させる最適な時期を決定できます。保留中の表の行数が多くなると、同期化が必要な索引も多くなります。

保留中の表のサイズが大きい場合、syncIndexのコール時にパラメータREINDEXをTRUEに設定すると、例6-36に示すようにパフォーマンスを向上できます。REINDEXがTRUEの場合は、すべての2次索引が削除され、保留中の表データを一括ロードした後に再作成されます。

関連項目:

- repeat_intervalの構文は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスの「カレンダ構文」の項を参照してください。

- PL/SQLプロシージャDBMS_XMLINDEX.syncIndexの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

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

CREATE INDEX po_xmlindex_ix ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
PARAMETERS ('ASYNC (SYNC EVERY "FREQ=HOURLY; INTERVAL = 1")');

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

EXEC DBMS_XMLINDEX.syncIndex('OE', 'PO_XMLINDEX_IX', REINDEX => TRUE);

6.3.14.1 エラーORA-08181が発生した場合のXMLIndex索引の同期化

問合せを行うとエラーORA-08181が発生する場合は、問合せのXMLType実表に対して、非構造化コンポーネントを含むXMLIndex索引が作成されているかどうかを確認してください。その場合は、DBMS_XMLINDEX.syncIndexを使用して、XMLIndex索引を手動で同期化します。

これは、エラーORA-08181が次の状況で発生した場合にのみ適用されます。

1. プラガブル・データベースPDB1で、XMLType表または列XTABCOLを作成し、非構造化コンポーネントが含まれるXMLIndex索引を使用して索引付けを行った。

2. PDB1をコンテナ・データベースに接続している。

3. PDB1を新しいプラガブル・データベースPDB2にクローニングした。

4. PDB2で問合せXTABCOLを実行すると、エラーORA-08181が発生する。

同期化しても引き続きエラーが発生する場合は、別の原因を探します。エラーORA-08181は様々な状況で発生する可能性のある一般的なエラーで、これは原因の1つにすぎません。

関連項目:

「Oracle XML DBとデータベース統合」

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

Oracle Databaseのコストベース・オプティマイザにより、使用される索引(ある場合)も含め、所定の問合せをどのように評価すると最も費用効率が高いかが決定します。これを正確に実行するには、様々なデータベース・オブジェクトの統計を収集する必要があります。

注意:

次は、パッケージDBMS_STATS内のプロシージャのみに適用され、ANALYZE INDEXには適用されません。

XMLIndexについては、通常はXMLIndex索引が定義されている実表に関する統計のみ収集する必要があります(DBMS_STATS.gather_table_statsプロシージャなどを使用)。これにより、XMLIndex索引自体、パス表とその2次索引、および構造化コンポーネント・コンテンツ表とその2次索引に関する統計が自動的に収集されます。

実表の統計を削除すると(DBMS_STATS.delete_table_statsプロシージャを使用)、他のオブジェクトに関する統計も削除されます。同様に、XMLIndex索引に関する統計を収集すると(DBMS_STATS.gather_index_statsプロシージャを使用)、パス表とその2次索引、および構造化コンポーネント・コンテンツ表とその2次索引に関する統計も収集されます。

例6-37では、実表po_binxmlに関する統計を収集します。XMLIndex索引、パス表、および2次パス表索引に関する統計が自動的に収集されます。

関連項目:

XMLIndex索引の統計情報を記録するデータベース・ビューの詳細は、「XMLIndexに関連するデータ・ディクショナリの静的なパブリック・ビュー」を参照してください。

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

CALL DBMS_STATS.gather_table_stats(USER, 'PO_BINXML', ESTIMATE_PERCENT => NULL);

6.3.16 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として使用して問い合せます。

6.3.17 CREATE INDEXおよびALTER INDEXのPARAMETERS句

XMLIndex索引の作成または変更では、多くの場合、SQL文CREATE INDEXまたはALTER INDEXでPARAMETERS句が使用されます。これを使用して、詳細に索引特性を指定できます。

- XMLIndexで使用するPARAMETERS句の構文は、CREATE INDEXおよびALTER INDEXのPARAMETERS句の構文を参照してください。

- PARAMETERS句の1000文字の制限を回避するために、パッケージDBMS_XMLINDEX内のPL/SQLプロシージャregisterParameterおよびmodifyParameterを使用できます。XMLIndexの登録済パラメータ句の使用を参照してください。

関連項目:

- 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パッケージおよびタイプ・リファレンスの「カレンダ構文」の項を参照してください。

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

CREATE INDEXまたはALTER INDEX文のPARAMETERS句に使用する文字列値には、1000文字の制限があります。この制限を回避するには、パッケージDBMS_XMLINDEX内のPL/SQLプロシージャregisterParameterおよびmodifyParameterを使用できます。

これらのプロシージャごとに、(長さ制限のない)パラメータの文字列と、その文字列の登録に使用する識別子を指定します。次に索引PARAMETERS句で、リテラル文字列ではなく、キーワードPARAMで始まる識別子を指定します。

識別子は、CREATE INDEXまたはALTER INDEX文で使用する前に、登録しておく必要があります。

関連項目:

例6-20

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

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 :==

modify_column_type_clause :==

modify_column_type_options :==

6.3.17.3 XMLIndex_parameters_clauseの使用

XMLIndex索引を作成するとき、XMLIndex_parameters_clauseがなければ、新しい索引には非構造化コンポーネントのみが含まれます。XMLIndex_parameters_clauseがあってもPARAMETERS引数が空('')の場合、結果は同じであり、索引には非構造化コンポーネントのみが含められます。

関連項目:

- CREATE INDEXのXMLIndex_parameters_clauseの使用コンテキストの詳細は、Oracle Database SQL言語リファレンスを参照してください。

- ALTER INDEXのXMLIndex_parameters_clauseの使用コンテキストの詳細は、Oracle Database SQL言語リファレンスを参照してください。

6.3.17.4 XMLIndex_parameterの使用

XMLIndex_parametersを使用する場合は、特定の考慮事項が適用されます。

- XMLIndex_parametersでは、XMLIndex_parameter_clauseを1種類当たり最大1回しか使用できません。たとえば、PATHS句を最大で1回、path_table_clauseを最大で1回などです。

- XMLIndex索引を作成するとき、structured_clauseがなければ、新しい索引には非構造化コンポーネントのみが含められます。structured_clauseが存在すれば、新しい索引には構造化コンポーネントのみが含められます。

6.3.17.5 PATHS句の使用

PATHS句を使用する場合は、特定の考慮事項が適用されます。

- CREATE INDEX文では、PATHS句を最大で1回使用できます。つまり、create_index_paths_clauseの前に、PATHSを最大で1回使用できます。

- create_index_paths_clause句はCREATE INDEXでのみ、また、alter_index_paths_clause句はALTER INDEXでのみ使用されます。

6.3.17.6 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を使用して作成しなおします。

6.3.17.7 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をそれぞれ指定する必要があります。

6.3.17.8 value_clauseの使用

value_clauseを使用する場合は、特定の考慮事項が適用されます。

- VALUE列は、VARCHAR2(4000)として作成されています。

- value_clause句がキーワードVALUEでのみ構成される場合は、通常のデフォルト属性によって値索引が作成されます。

- path_id_clause句がキーワードPATH IDでのみ構成される場合は、通常のデフォルト属性によってパスID索引が作成されます。

- order_key_clause句がキーワードORDER KEYでのみ構成される場合は、通常のデフォルト属性によって順序キー索引が作成されます。

6.3.17.9 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はFALSEです。

- ALWAYS以外のASYNCオプションの場合、STALEはTRUEです。

6.3.17.10 groups_clauseおよびalter_index_group_clauseの使用

groups_clause句は、CREATE INDEX (alter_index_group_clause句のADD GROUPの後)でのみ使用されます。alter_index_group_clause句は、ALTER INDEXでのみ使用されます。

6.3.17.11 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列が暗黙的に渡されます。

6.3.17.12 column_clauseの使用

column_clauseを使用する場合は、特定の考慮事項が適用されます。

XMLIndex索引でXMLTableのマルチレベル連鎖を使用する場合、あるレベルのXMLTable表は、その前のレベルのXMLType列に対応します。構文の説明で、キーワードVIRTUALはオプションとして示されています。実際には、これはXMLType列でのみ使用され、その場合は必須です。XMLType列以外に使用するとエラーになります。VIRTUALは、XMLType列自体が生成されないことを指定します。つまり、そのデータは、対応するXMLTable表により指定されたリレーショナル列の形式でのみ、索引に格納されます。

6.4 全文問合せ用のXMLデータの索引付け

XMLデータの全文検索を行う必要がある場合は、バイナリXMLとしてXMLTypeデータを格納し、XQuery Full Text (XQFT)を使用することをお薦めします。これには、XML検索索引を使用します。これが、この項の内容です。

移植性やコードの標準化が問題にならない場合や、XMLTypeデータがオブジェクト・リレーショナル形式で格納されている場合は、かわりにOracle固有の全文構造体とOracle Textが提供している構文、具体的にはOracle SQL関数containsまたはOracle XPath関数ora:containsを使用できます。「XQueryを使用しないXMLデータの全文検索」で説明しています。

関連項目:

- 例6-43

- Oracle XML DBでOracle Text操作を使用する方法の詳細は、XQueryを使用しないXMLデータの全文検索を参照してください。

バイナリXMLとして格納されているXMLTypeデータに対しては、XQuery Full Text (XQFT)問合せを実行できます。SQL WHERE句内のXMLExists式でXQFT全文述語を使用する場合は、XML検索索引を作成する必要があります。この項では、このような索引の作成と使用について説明します。

関連項目:

「XQuery Full Textのサポート」

6.4.1 XML検索索引の作成と使用

XQuery Full Text問合せでは、パフォーマンスを高めるためにXML検索索引を使用できます。

XML検索索引を作成するには、データベース・ロールCTXAPPを付与されている必要があります。一般的にこのロールは、Oracle Text索引の作成、Oracle Text索引プリファレンスの設定、またはOracle Text PL/SQLパッケージの使用に必要です。

索引を作成する前に、Oracle Textパス・セクション・グループを作成して、そのXML_ENABLE属性をtに設定する必要があります。これにより、パス・セクション・グループがXML対応になります。

パフォーマンスを向上させるには、Oracle Textデータ・ディクショナリ内にBASIC_STORAGE型の索引プレファレンスを作成して、次の属性を指定します。

- D_TABLE_CLAUSE: XML文書の構造に関する情報が含まれている索引データ表$Dの列DOCに対して、SECUREFILE記憶域を指定します。キャッシュおよび圧縮レベル(MEDIUM)を指定します。

- I_TABLE_CLAUSE: 全文トークンと索引付けされた文書でのその出現に関する情報が含まれている索引データ表$Iの列TOKEN_INFOに対して、SECUREFILE記憶域を指定します。キャッシュを指定します(ただし圧縮は不要)。

これについては例6-38で、XML Schemaに基づかないXMLType表po_binxml (標準のデータベース・スキーマOE内の表purchaseorderと同じデータを持つ)を使用して説明します。

索引プレファレンスBASIC_STORAGEは、Oracle Text索引を構成するデータベース表および索引に対する表領域および作成パラメータを指定します。

関連項目:

- セクション・グループの詳細は、『Oracle Textリファレンス』を参照してください。

- プロシージャCTX_DDL.set_sec_grp_attrの詳細は、『Oracle Textリファレンス』を参照してください。

- プロシージャCTX_DDL.create_preferenceの詳細は、『Oracle Textリファレンス』を参照してください。

- プロシージャCTX_DDL.set_attributeの詳細は、『Oracle Textリファレンス』を参照してください。

- プレファレンスBASIC_STORAGE、D_TABLE_CLAUSEおよびI_TABLE_CLAUSEの詳細は、『Oracle Textリファレンス』を参照してください。

例6-39では、データ問合せを実行して、テキストにBigとStreetの両方がこの順序で含まれるDescription要素を取得します。

例6-40は、索引po_ctx_idxの取得を指示する、問合せの実行計画を示しています。

例6-38 XML検索索引の作成

BEGIN
CTX_DDL.create_section_group('mysecgroup', 'PATH_SECTION_GROUP');
CTX_DDL.set_sec_grp_attr('mysecgroup', 'XML_ENABLE', 'T');

CTX_DDL.create_preference('mypref', 'BASIC_STORAGE');
CTX_DDL.set_attribute('mypref',
'D_TABLE_CLAUSE',
'TABLESPACE my_ts
LOB(DOC) STORE AS SECUREFILE
(TABLESPACE my_ts COMPRESS MEDIUM CACHE)');
CTX_DDL.set_attribute('mypref',
'I_TABLE_CLAUSE',
'TABLESPACE my_ts
LOB(TOKEN_INFO) STORE AS SECUREFILE
(TABLESPACE my_ts NOCOMPRESS CACHE)');
END;
/

CREATE INDEX po_ctx_idx ON po_binxml(OBJECT_VALUE)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS('storage mypref section group mysecgroup');

例6-39 XQuery Full Text問合せ

SELECT XMLQuery('for $i in /PurchaseOrder/LineItems/LineItem/Description
where $i[. contains text "Big" ftand "Street"]
return <Title>{$i}</Title>'
PASSING OBJECT_VALUE RETURNING CONTENT)
FROM po_binxml
WHERE XMLExists('/PurchaseOrder/LineItems/LineItem/Description
[. contains text "Big" ftand "Street"]'
PASSING OBJECT_VALUE);

例6-40 XQuery Full Text問合せの実行計画

------------------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |            |     1 |  2014 |     4   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| PO_BINXML  |     1 |  2014 |     4   (0)| 00:00:01 |
|*  2 |   DOMAIN INDEX              | PO_CTX_IDX |       |       |     4   (0)| 00:00:01 |
------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("CTXSYS"."CONTAINS"(SYS_MAKEXML(0,"XMLDATA"),'<query><textquery
grammar="CONTEXT" lang="english"> ( ( {Big} ) and ( {Street} ) )  INPATH
(/PurchaseOrder/LineItems/LineItem/Description)</textquery></query>')>0)

Note
-----
- dynamic sampling used for this statement (level=2)
- Unoptimized XML construct detected (enable XMLOptimizationCheck for more information)

21 rows selected.

6.4.2 XML検索索引を取得できない場合の対処方法

特定の条件が確実に満たされるように問合せを変更することで、評価によってXML検索索引が取得されるようにできます。

SQL WHERE句内のXMLExists式でXQuery全文述語を使用しながら、XML検索索引を作成しなかったり、なんらかの理由でその索引を使用できない場合には、コンパイル時エラーORA-18177が発生します。

このエラーが発生する場合、実行計画では索引を取得するように指示されていません。つまり、その計画には、操作DOMAIN INDEXの後に索引名が含まれていません。

この場合は、索引を使用できるように問合せを変更してください。取得する索引では、次の条件の両方を満たす必要があります。

- 検索コンテキストのXMLノードを計算する式は、ステップがforward軸およびdescendent軸のみに沿ったXPath式にする必要があります。

- SQL/XML関数XMLExistsのPASSING句にSQL式として渡すことのできるXMLTypeインスタンスは1つのみで、同じ句内に含まれるその他の非XMLType SQL式はすべて、組込みSQLデータ型のコンパイル時定数、またはこのようなデータ型のインスタンスにバインドされているバインド変数のいずれかである必要があります。

6.4.3 プラグマora:no_schema: XQuery Full TextでのXML Schemaに基づくデータの使用

XQuery Full TextとXML検索索引を使用する場合は、一般に、XML Schemaに基づかないXMLTypeデータの使用をお薦めします。ただし、状況によっては、バイナリXMLとして格納されているXML SchemaベースのXMLTypeデータを使用できます。このコンテキストでは、Oracle XQueryプラグマora:no_schemaが役立つ場合があります。

デフォルトで、XML検索索引を使用してXML Schemaに基づくデータを評価する場合は、コンパイル時エラーORA-18177が発生します。これは、全文索引機能が型を認識しないため、関連付けられたXML Schemaを利用しないことが原因です。適用されるすべてのテキストが型指定なしとして扱われます。このエラーは、データが適切に型キャストされている場合でも発生するため、XML Schemaの暗黙的な型キャストには依存しません。例6-41に、これを示します。

問合せの全文条件が、XML Schema型と型指定された操作に依存することを想定していたユーザーは、発生したエラーによってこれを意識するようになります。

型に依存する条件を使用するためには、関連するXQuery式を明示的に適切な型にキャストする必要があります。Oracle XML DBでは、XML Schemaを使用して暗黙的な型キャストを実行することはありません。型キャストを適切に実行できないと、予期しない結果が生じる可能性があります。

例6-42は、適切な条件が評価されるように型キャストを明示的に指定した、XML Schemaに基づくデータの問合せを示しています。

ただし、XQuery Full Text式を使用する場合は通常、XML Schemaに基づくデータを扱うときでも、型指定されたデータは含めません。型指定されたデータを条件で使用する場合は、適切な型にキャストする必要があるので注意してください。

つまり、型指定されたデータが問合せに含まれていないことがわかっている、または特定の型指定されたデータを型指定されていないデータとして扱っても問題ない、あるいは型指定が必要なデータは明示的に型キャストする場合は、問合せでOracle XQueryプラグマora:no_schemaを使用すれば、エラーの発生を防ぎつつ、XML検索索引を使用して問合せを評価できます。

例6-41 XML Schemaに基づくデータを使用したXQuery Full Text問合せ: エラーORA-18177

SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem'
PASSING OBJECT_VALUE RETURNING CONTENT)
FROM oe.purchaseorder
WHERE XMLExists('/PurchaseOrder
[LineItems/LineItem/@ItemNumber > xs:integer("20")
and Actions/Action/User contains text "KPARTNER"]'
PASSING OBJECT_VALUE);
FROM oe.purchaseorder
*
ERROR at line 3:
ORA-18177: XQuery full text expression '/PurchaseOrder
[LineItems/LineItem/@ItemNumber > xs:integer("20")
and Actions/Action/User contains text "KPARTNER"]'
cannot be evaluated using XML text index

例6-42 XML Schemaに基づくデータでのXQueryプラグマora:no_schemaの使用

SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem'
PASSING OBJECT_VALUE RETURNING CONTENT)
FROM oe.purchaseorder
WHERE XMLExists('(# ora:no_schema #)
{/PurchaseOrder
[LineItems/LineItem/@ItemNumber > xs:integer("20")
and Actions/Action/User contains text "KPARTNER"]}'
PASSING OBJECT_VALUE);

6.4.4 プラグマora:use_xmltext_idx: XML検索索引の強制的な使用

XQueryプラグマora:use_xmltext_idxを使用して、XML検索索引の使用を強制できます。

XMLデータを使用する問合せは、存在する索引の種類や数などによって、様々な方法で評価できます。デフォルトの評価方法が最もパフォーマンスに優れているとはかぎらず、既存のXML検索索引を強制的に使用した方がより効率的な場合があります。XQueryプラグマora:use_xmltext_idxを使用すれば、これを行うことができます。(XML検索索引は、バイナリXMLとして格納されているXMLTypeデータにのみ適用されます。)

たとえば、WHERE句に2つのXMLExists式があり、いずれか一方にのみXQuery Full Textの条件が含まれ、全文条件がない方のXMLExists式にはXMLIndex索引を適用するとします。このような問合せでは、通常、XML検索索引を使用してWHERE句全体を評価した方がより効率的です。

問合せに全文条件がない場合でも、XML検索索引を使用することによって、問合せの評価の効率性が向上する可能性があります。

例6-43の問合せでは、プラグマora:use_xmltext_idxの使用方法を示しています。XMLExistsの最初の句にのみ全文条件が使用されています。プラグマが指定されているので、全文索引(po_ctx_idx、例6-38で作成)は、両方のXMLExists句で使用されます。

例6-43 XQueryプラグマora:use_xmltext_idxを使用した全文問合せ

SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem'
PASSING OBJECT_VALUE RETURNING CONTENT)
FROM po_binxml
WHERE XMLExists('/PurchaseOrder/LineItems/LineItem
[Description contains text "Picnic"]' PASSING OBJECT_VALUE)
AND XMLExists('(# ora:use_xmltext_idx #) {/PurchaseOrder[User="SBELL"]}'
PASSING OBJECT_VALUE);

6.4.5 Oracle Text索引の使用からXML検索索引への移行

バイナリXMLとして格納されているXMLTypeデータに対するレガシー問合せで、SQL関数CONTAINSまたは非推奨のXPath関数ora:containsと、XML非対応のOracle Text索引が使用されている場合は、かわりにXQuery Full Text構造体を使用することを検討してください。

XQuery and XPath Full Text (XQFT)標準は、Oracle Database 12cリリース1 (12.1)からOracle XML DBでサポートされるようになりました。このサポートは、バイナリXMLとして格納されているXMLTypeデータにのみ適用されます。そのリリースより前は、XMLデータの全文問合せに使用できたのはXML非対応のOracle Text索引のみ(XML検索索引ではなく)だったので、全文問合せでは必ずOracle固有の構造体(SQL関数CONTAINSまたはXPath関数ora:contains)が使用されていました。

これを使用しているレガシー・コードがある場合は、そのコードを移行してXQFTを使用することをお薦めします。この項では、問合せで使用されているCONTAINSおよびora:containsを置き換える場合に使用できるXQFTの構造体について説明します。

XML非対応の(XML検索索引ではない) Oracle Text索引は、全文問合せで使用する以外にも、Oracle Textの構造演算子HASPATHとともに使用して、指定されたドキュメント・セクションが存在すること(つまり、指定されたXPath式にNULL以外のターゲットが含まれているかどうか)をテストできます。

索引のこのような使用方法は、XML検索索引を使用することで代替できます。HASPATHを使用する問合せを簡単なXQuery式を使用する問合せで置き換えるには、Oracle XQueryプラグマora:use_xmltext_idxを使用して、XML検索索引を取得するように指定します。この項では、これについても説明します。

表6-9に、Oracle固有の構造体を使用する一般的な問合せからXQuery Full Textを使用する問合せへのマッピングを示します。

表6-9 Oracle固有のXML問合せのXQuery Full Textへの移行

元の例

置換後の例

CONTAINS(t.x, 'HASPATH (/P/LIs/LI/Description

XMLExists('(# ora:use_xmltext_idx #)
{$d/P/LIs/LI/Description

または、データがXML Schemaに基づく場合:

XMLExists('(# ora:use_xmltext_idx #)
{(# ora:no_schema #)
{$d/P/LIs/LI/Description

CONTAINS(t.x, 'Big INPATH
(/P/LIs/LI/Description)') > 0

XMLExists('$d/P/LIs/LI/Description
[. contains text "Big"]'
PASSING t.x AS "d")

または、データがXML Schemaに基づく場合:

XMLExists('(# ora:no_schema #)
{$d/P/LIs/LI/Description
[. contains text "Big"]}'
PASSING t.x AS "d")

XMLExists('$d/P/LIs/LI/Description
[ora:contains(., "Big AND Street") > 0]'
PASSING t.x AS "d")

XMLExists('$d/P/LIs/LI/Description
[. contains text "Big" ftand "Street"]'
PASSING t.x AS "d")

CONTAINS(t.x, '(Big) AND (Street) INPATH
(/P/LIs/LI/Description)') > 0

XMLExists('$d/P/LIs/LI/Description
[. contains text "Big" ftand "Street"]'
PASSING t.x AS "d")

CONTAINS(t.x, '(Big) OR (Street) INPATH
(/P/LIs/LI/Description)') > 0

XMLExists('$d/P/LIs/LI/Description
[. contains text "Big" ftor "Street"]'
PASSING t.x AS "d")

CONTAINS(t.x, '({Big}) NOT ({Street}) INPATH
(/P/LIs/LI/Description)') > 0

XMLExists('$d/P/LIs/LI/Description
[. contains text
"Big" ftand ftnot "Street"]'
PASSING t.x AS "d")

CONTAINS(t.x, '({Street}) MNOT ({Big Street}) INPATH
(/P/LIs/LI/Description)') > 0

XMLExists('$d/P/LIs/LI/Description
[. contains text
"Street" not in "Big Street"]'
PASSING t.x AS "d")

CONTAINS(t.x, '(NEAR (({Big}, {Street}), 3) INPATH
(/P/LIs/LI/Description)') > 0

XMLExists('$d/P/LIs/LI/Description
[. contains text
"Big" ftand "Street" window 3 words]'
PASSING t.x AS "d")

(適用なし: Oracle Text問合せはXML名前空間に非対応)

XMLExists('declare namespace
ipo="http://www.example.com/IPO";
/ipo:P/ipo:LIs/ipo:LI/ipo:Description
[. contains text "Big"]'
PASSING t.x AS "d")

脚注 3

パスのテストには述語式を含めることができ、それは元の問合せ(HASPATHを使用)でも置換後の問合せでも同じです。例: /PurchaseOrder/LineItems/LineItem/Part[@Id < "31415927"]

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

XMLノードに対応する基礎となるデータベース列に対してBツリー索引を作成することで、オブジェクト・リレーショナル形式で格納されたXMLTypeデータを効果的に索引付けできます。

索引付けされるデータが単一の場合、つまりXMLインスタンス文書で一度のみ発生する可能性がある場合、表面的上ファンクション索引を作成するショートカットを使用できます。この場合、索引を定義する式はファンクション・アプリケーションで、単一データをターゲットとするXPath式の引数を使用します。ショートカットはXMLQueryに適用されるXMLCastに対して定義され、もう1つのショートカットはOracle SQL関数extractValueに対して定義されます(非推奨)。

多くの場合、Oracle XML DBでは、基礎となるオブジェクト・リレーショナル表または列に対して適切な索引が自動的に作成されますが、CREATE INDEX文が示すように、ターゲットとなるXMLTypeデータに対して、ファンクション索引は作成されません。

extractValueショートカットの場合、作成される索引はBツリー索引です。XMLQueryに適用されるXMLCastの場合、作成される索引は、ファンクション式から得られるスカラー値に対するファンクション索引です。これについては、「繰り返し使用しないテキスト・ノードまたは属性値の索引付け」で説明します。

索引付けされるデータがコレクションの場合、このようなショートカットを使用できません。手動でBツリー索引を作成する必要があります。これについては、「繰り返し使用する(コレクション)要素の索引付け」で説明します。

関連項目:

全文検索のためにオブジェクト・リレーショナル形式で格納されているXMLTypeデータを索引付けする方法の詳細は、XQueryを使用しないXMLデータの全文検索を参照してください。

6.5.1 繰り返し使用しないテキスト・ノードまたは属性値の索引付け

サンプル・データベース・スキーマOEの表purchaseorderはオブジェクト・リレーショナルに格納されます。各発注書には単一のReference要素が含まれます。つまりこの要素は単一です。したがって、ショートカットを使用して、基礎となるオブジェクト・リレーショナル・データに索引を作成できます。

例6-44に、Reference要素のテキスト・コンテンツをターゲットとし、XMLQueryに適用されるXMLCastを使用して、表面上ファンクション索引を作成しようとするCREATE INDEX文を示します。(この要素のコンテンツはテキストのみのため、要素をターゲットにすることは、XPathノード・テストtext()を使用してテキスト・ノードをターゲットにすることと同じです。)

例6-45は、同じデータをターゲットにし、Oracle SQL関数extractValue(非推奨)を使用して表面上ファンクション索引を作成します。

実際、例6-44と例6-45では、ターゲットとなるXMLTypeデータに対してファンクション索引は作成されません。かわりに、Oracle XML DBによってCREATE INDEX文がリライトされ、基礎となるスカラー・データに対して索引が作成されます。

関連項目:

このようなCREATE INDEX文に適用されるXPathリライトの詳細は、例19-7および例19-8を参照してください。

これらのショートカットのいずれかを使用するとき、CREATE INDEX文は前述のように基礎となるスカラー・データ上に索引を作成できない場合があります。そのかわり、実際には参照されるXMLTypeデータにファンクション索引を作成します。(これは索引の値がスカラーである場合でも当てはまります)。

このような場合は、索引を削除し、同じXPathをターゲットとする構造化コンポーネントを含むXMLIndex索引をかわりに作成します。一般的に、XMLTypeデータに対してはファンクション索引を使用しないことをお薦めします。

これは使用される格納方法にかかわらず、XMLTypeデータの一般的なルールです。ファンクション索引のかわりに構造化コンポーネントでXMLIndexを使用します。このルールはOracle Database 11gリリース 2 (11.2)から適用されます。このルールを守ることにより、ファンクション索引のメンテナンス操作に関連するオーバーヘッドを軽減し、オプティマイザで索引を適切に選択できる状況が増えます。

関連項目:

「XMLTypeに対するファンクション索引の非推奨化」

例6-44 単一の要素で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-45 単一の要素でEXTRACTVALUEを使用したCREATE INDEX

CREATE INDEX po_reference_ix ON purchaseorder
(extractValue(OBJECT_VALUE, '/PurchaseOrder/Reference'));

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

オブジェクト・リレーショナル形式で格納されたXMLTypeデータでは、コレクションはXMLTypeインスタンスのOrdered Collection Table (OCT)として格納されるため、メンバーに直接アクセスできます。オブジェクト・リレーショナル記憶域は、XMLデータのファイングレイン構造を直接反映するため、各コレクション・メンバーをターゲットとする索引を作成できます。

このような索引は、手動で作成する必要があります。Oracle SQL関数extractValue(非推奨)に対して表面上ファンクション索引を作成する場合に、Bツリー索引を自動的に作成する専用の機能は、コレクションに適用されません(extractValueに渡されるXPath式は、単一要素をターゲットにする必要があります)。

コレクションに対してBツリー索引を作成するには、コレクションの管理に使用するSQLオブジェクトの構造を理解する必要があります。その情報に基づき、従来のオブジェクト・リレーショナルSQLコードを使用して、適切なSQLオブジェクト属性に対して索引を直接作成できます。この方法の例は、「ガイドライン: Ordered Collection表に対する索引の作成」を参照してください。

脚注の凡例

脚注1:
オブジェクト・リレーショナル形式で格納されているXMLTypeデータについては、オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付けを参照してください。データの構造化が高度に進んでいる場合、または索引の作成時点で問合せが既知でない場合には、この方法が適している可能性があります。

脚注2:
実際のパス表の実装は多少異なることがあります。

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

XSLTスタイルシートを使用してXMLTypeデータを変換したり、XML Schemaに対してXMLTypeインスタンスを検証するためのOracle SQL関数およびXMLType APIがいくつかあります。

- XSL変換とOracle XML DB

- XMLTypeインスタンスの検証

7.1 XSL変換とOracle XML DB

組込みのOracle XML DB XSLTプロセッサを使用して、XML Schemaに基づく文書にXSL変換を適用できます。データベース内のXML固有の最適化により、必要なメモリー量が大幅に削減され、解析に関連するオーバーヘッドも削減されてネットワーク・トラフィックが緩和されます。

W3CのXSLT勧告は、XML文書の形式を別の形式に変換する方法を指定するためのXML言語を定義します。XSLT標準の詳細は、http://www.w3.org/TR/xsltを参照してください。

変換には、1つのXML Schemaから別のXML Schemaへのマッピング、またはXMLからHTMLやWMLなどの他の形式へのマッピングが含まれる場合があります。

XSL変換は、必要なメモリー量および処理量の面からコストがかかる場合があります。通常のXSLプロセッサでは、処理を開始する前に、ソース・ドキュメント全体とスタイルシートを解析してメモリーにロードする必要があります。通常、XSLプロセッサはDOMを使用して文書やスタイルシートの動的なメモリー表現を行い、任意の部分へのランダム・アクセスを可能にします。次に、XSLプロセッサは、スタイルシートをソース・ドキュメントに適用して、3番目の文書を生成します。

変換の前に文書とスタイルシートを解析してメモリーにロードするには、大量のメモリーとプロセッサ・リソースが必要です。文書のごく一部のみを変換する必要がある場合は、特に非効率です。

Oracle XML DBには、XSL変換をデータベース内で実行するXSLTプロセッサが含まれています。この方法で、XML固有の最適化を実現できます。これによって、変換の実行に必要なメモリー量が大幅に削減され、解析に関連するオーバーヘッドも削減されてネットワーク・トラフィックが緩和されます。

ただし、これらの最適化は、変換対象のソースがスキーマに基づくXML文書である場合にのみ使用できます。その場合、処理を開始する前に解析する必要はありません。Oracle XML DBで遅延ロードされた仮想DOMが、ノードへのアクセス時にオン・デマンドでコンテンツのみをロードします。処理の必要な部分の文書のみがロードされるため、必要なメモリー量が削減されます。

XMLデータは次の方法で変換できます。

- Oracle Databaseを使用 - Oracle SQL関数のXMLtransform、XMLTypeのメソッドtransform()、またはPL/SQLパッケージのDBMS_XSLPROCESSORを使用する。

- 中間層を使用 - XSLT Processor for Javaなど、Oracle XML Developer's Kitの変換オプションを使用する。

関連項目:

- SQL関数XMLTransformの詳細は、Oracle Database SQL言語リファレンスを参照してください。

- PL/SQLパッケージDBMS_XSLPROCESSORの詳細は、「PL/SQL XSLT Processor for XMLType (DBMS_XSLPROCESSOR)」およびOracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。

- XSLT Processor for Javaの詳細は、Oracle XML Developer's Kitプログラマーズ・ガイドを参照してください。

これらの各XML変換方法では、ソースXML文書およびXSLスタイルシートを、XMLTypeインスタンスの形式で入力として受け取ります。SQL関数XMLtransformおよびXMLTypeメソッドtransform()では、変換の結果としてXML文書または非XML文書(HTMLなど)が発生します。しかし、PL/SQLパッケージDBMS_XSLPROCESSORでは、変換の結果は有効なXML文書であることが求められます。パッケージDBMS_XSLPROCESSORを使用した変換によって生成されるHTMLデータは、XHTMLデータ(つまり、有効なXMLデータと有効なHTMLデータ)である必要があります。

例7-1は、XSLTスタイルシートPurchaseOrder.xslの一部を示しています。完全なスタイルシートについては、「XSLTスタイルシートの例、PurchaseOrder.xsl」を参照してください。

例7-1のスタイルシートに関して、Oracle XML DB固有のものはありません。スタイルシートは、XMLType表または列に格納でき、Oracle XML DBリポジトリ内にXML Schemaに基づかないXMLデータとしても格納できます。

例7-1 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>

...

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

SQL関数XMLtransformでは、XSLTスタイルシートを使用してXML文書を変換します。スタイルシートで指定したように、処理された出力をXML、HTMLなどで戻します。

図7-1に、Oracle SQL関数XMLtransformの構文を示します。この関数は引数としてXMLTypeインスタンスとXSLTスタイルシートを受け取ります。スタイルシートはXMLTypeインスタンスまたはVARCHAR2文字列リテラルのいずれかです。スタイルシートをインスタンスに適用し、XMLTypeインスタンスを戻します。

図7-1 XMLTRANSFORMの構文

Oracle SQL関数XMLtransformのかわりにXMLTypeメソッドtransform()を使用することもできます。どちらも機能は同じです。

図7-2に、XSLTスタイルシートを使用してXMLtransformがXML文書を変換する方法を示します。XSLTスタイルシートで指定したように、処理された出力をXML、HTMLなどで戻します。データベース内にXMLTypeとして格納されたXML文書の取得または生成時は、通常はXMLtransformを使用します。

関連項目:

Oracle XML DBの概要の図1-3

図7-2 XMLTRANSFORMの使用

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

Oracle SQL関数XMLtransformおよびXMLTypeメソッドtransform()を使用して、XMLTypeとして格納されているXMLデータを様々な形式に変換する例を示します。

例7-2では、この章の他の例を実行するために必要なXML Schemaおよび表を設定します。ここに示したdeleteSchemaのコールは、XML Schemaの作成前に既存のスキーマがないようにするためのものです。そのようなスキーマが存在しない場合は、deleteSchemaでエラーが発生します。

例7-3ではXSLTスタイルシートを格納してからそれを取得し、Oracle SQL関数のXMLTransformでそれを使用して、例7-2で格納したXMLデータを変換します。

例7-4では、その場で作成したXSLスタイルシートでXMLTypeのメソッドtransform()を使用します。

例7-5では、XMLTransformを使用してXSLスタイルシートを適用し、HTMLコードを生成します。PL/SQLコンストラクタXDBURITypeは、Oracle XML DBリポジトリからXSLスタイルシートを読み取ります。

例7-5に、HTML結果の一部のみを示します。省略した部分は、省略記号(. . .)で示しています。図7-3に、変換された結果がWebブラウザでどのように表示されるかを示します。

例7-2 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 purchase-order documents, and insert the 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>'));

例7-3 SQL関数XMLTRANSFORMを使用してXSLスタイルシートを適用

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>

例7-4 一時XSLスタイルシートでのXMLTypeメソッド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;

例7-5 XMLTRANSFORMを使用して、XDBURITypeで取得したXSLスタイルシートを適用

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.

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

DBUriサーブレットで生成されたXMLコンテンツに、XSL変換を適用できます。

図7-3に、このような変換の結果を示します。URLは次のとおりです(ここでは、分割して切り捨てられています)。

http://localhost:8080/oradb/SCOTT/PURCHASEORDER/ROW/PurchaseOrder[Reference="SBELL-2003030912333601PDT"]
contenttype=text/html&transform=/home/SCOTT/xsl/purchaseOrder.xsl...

パラメータtransformが存在するため、DBUriサーブレットはSQL関数XMLTransformを使用して、/home/SCOTT/xsl/purchaseOrder.xslにあるXSLスタイルシートを、メインのURLで識別されるPurchaseOrder文書に適用します。変換の結果、HTMLコードがブラウザに返されて表示されます。また、URLでは、パラメータcontentTypeを使用して、最後の文書のMIMEタイプがtext/htmlになることを指定します。

図7-3 DBUriサーブレットを使用したPurchaseOrderのデータベースXSL変換

図7-4に、HTML文書として表示されたdepartments表を示します。これを実行するためにコードは必要ありません。必要なのは、SQL/XML関数に基づくXMLTypeビュー、業界標準のXSLスタイルシート、およびDBUriサーブレットのみです。

図7-4 DBUriサーブレットを使用したDepartments表のデータベースXSL変換

7.2 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パッケージおよびタイプ・リファレンス』を参照してください。

7.2.1 XML Schemaの部分検証と全体検証

XML Schemaに基づく文書をデータベースに挿入するとき、これらを部分的または完全に検証できます。

7.2.1.1 部分検証

バイナリXML記憶域の場合、XML Schemaに基づく文書がXMLType表または列に挿入されるたびに、Oracle XML DBによりこれらの文書の全体検証が実行されます。オブジェクト・リレーショナルXML記憶域の場合は、部分検証のみが実行されます。これは、オブジェクト・リレーショナル記憶域の場合、XML Schemaの完全な検証はパフォーマンスの面で非常にコストが高くなるためです。

部分検証では、文書内に必須の要素および属性がすべて存在すること、および予期しない要素または属性のないことが確認されるのみです。つまり、XML文書の構造がXML Schemaから導出されたSQLデータ型定義に準拠していることのみが確認されます。部分検証では、インスタンス・ドキュメントがXML Schemaに完全に準拠しているかどうかは確認されません。

例7-6に、オブジェクト・リレーショナル形式で格納されている表PurchaseOrderにXML文書を挿入する間に部分検証が失敗した例を示します。

例7-6 不適切な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'

7.2.1.2 全体検証

XML Schemaに基づくデータをバイナリXML記憶域にロードすると、ターゲットXML Schemaに対してデータの全体検証が行われます。オブジェクト・リレーショナルXMLType記憶域の場合、いつでも全体検証を強制できます。

全体検証を強制するには、次のいずれかを使用します。

- 表レベルのCHECK制約

- PL/SQLのBEFORE INSERTトリガー

どちらの方法でも、妥当なXML文書のみがXMLType表に格納されることが保証されます。

TABLE CHECK制約を使用する方法のメリットは、コーディングが簡単なことです。この方法のデメリットは、この方法がOracle SQL関数XMLisValidに基づいているため、XML文書が妥当であるかどうかしか示されないことです。XML文書が妥当でない場合、TABLE CHECK制約では、その理由についての情報を提供できません。

BEFORE INSERTトリガーの場合は、必要なコーディングが表レベルの制約よりわずかに多くなります。このトリガーでは、XMLTypeのschemaValidate()メソッドを起動してXML文書を検証します。schemaValidate()を使用するメリットは、例外が発生した場合にそのインスタンス・ドキュメントの問題点に関する追加情報が提供されることです。また、BEFORE INSERTトリガーを使用すると、無効な文書が存在する場合に適切な処置を行うことができます。

7.2.1.2.1 XML Schemaの全体検証による処理時間とメモリーの消費

バイナリXML記憶域を使用していない場合は、XML Schemaの全体検証を実行すると、多くの処理時間とメモリーが消費されます。このため、XML Schemaの全体検証は、必要なときにのみ実行してください。XML文書を検証するアプリケーションを使用する場合は、全体検証に関連するオーバーヘッドを回避することによって、バイナリ以外のXML記憶域での全体のスループットを向上させることができます。受信するXML文書の妥当性について確認できない場合は、スキーマに対して妥当なXML文書のみがXMLType表または列に含まれていることをデータベースで確認できます。

例7-7に、CHECK制約をXMLType表に追加してXML Schemaの全体検証を実行する方法を示します。例7-7のXML文書InvalidReferenceは、XML Schemaに従った妥当なXML文書ではありません。XML Schemaでは、Reference要素に関連付けられたテキスト・ノードの最小長を18文字とすることが定義されています。この例に示す文書では、ノードの値はSBELL-20021009で、14文字の長さしかありません。部分検証ではこのエラーは捕捉されません。制約またはトリガーがないかぎり、この文書をデータベースに挿入することが可能です。

例7-7 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表のコンテンツにアクセスできます。例7-8は、BEFORE INSERTトリガーを使用して、XMLType表に挿入されるデータが、指定されたXML Schemaに準拠していることを検証する方法を示しています。

例7-8 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)
LSX-00213: only 0 occurrences of particle "sequence", minimum is 1
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'

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

ここでの例は、Oracle SQL関数XMLIsValidと、XMLTypeメソッドisSchemaValid()およびschemaValidate()を使用して、Oracle XML DBにXMLTypeとして格納されているXMLデータを検証する方法を示しています。

例7-9および例7-10に、PL/SQLメソッドisSchemaValid()を使用して、XML Schemaに対してXMLインスタンスを検証する方法を示します。

XMLTypeメソッドschemaValidate()をINSERTおよびUPDATEトリガー内で使用すると、表に格納されているすべてのインスタンスがXML Schemaに対して検証されたことを確認できます。例7-11に、これを示します。

例7-12では、Oracle SQL関数XMLIsValidを使用して、次の操作を実行します。

- XMLTypeインスタンスが指定されたXML Schemaに準拠していることの確認

- CHECK制約を使用した、受信したXML文書が妥当であることの確認

注意:

「XMLTypeインスタンスの検証」で示した検証の関数およびプロシージャを使用すると、簡単に検証チェックを実行できます。これらのうち、schemaValidateのみが、エラーの発生時に検証が失敗した理由を示します。

例7-9 SQLでメソッドISSCHEMAVALID()を使用したXMLの検証

SELECT x.xmlcol.isSchemaValid('http://www.example.com/schemas/ipo.xsd',
'purchaseOrder')
FROM po_tab x;

例7-10 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.

例7-11 トリガー内でメソッド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;
/

例7-12 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";

第III部 XMLデータに対するリレーショナル・データ

XMLデータとして既存のリレーショナル・データを表示できる、様々な方法があります。

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

- XMLデータのリレーショナル・ビュー

- XMLTypeビュー

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

Oracle XML DBには、データベースのリレーショナル・データからXMLデータを生成(構成)するための機能が用意されています。リレーショナル・コンテンツからXMLデータを生成するためのSQL/XML標準関数およびOracle固有の関数とパッケージがあります。

- XMLデータの生成の概要

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

- DBMS_XMLGENを使用したXMLデータの生成

- SYS_XMLAGG Oracle SQL関数

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

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

関連項目:

SQL/XML関数XMLQueryおよびXMLTableを使用したXMLデータの構成の詳細は、XQueryとOracle XML DBを参照してください。

8.1 XMLデータの生成の概要

XMLデータは、Oracle XML DBで、標準SQL/XML関数、Oracle固有のSQL関数、パッケージDBMS_XMLGENのPL/SQLサブプログラムまたはDBURITypeを使用して生成できます。

- 標準SQL/XML関数を使用します。「SQL関数を使用したXMLデータの生成」を参照してください。

- Oracle SQL関数を使用します。次の項を参照してください。

- XMLROOT Oracle SQL関数

- XMLCOLATTVAL Oracle SQL関数

- XMLCDATA Oracle SQL関数

- SYS_XMLAGG Oracle SQL関数この関数は、行のグループを操作し、複数のXML文書を1つに集約します。

- PL/SQLパッケージDBMS_XMLGENの使用。「DBMS_XMLGENを使用したXMLデータの生成」を参照してください。

- DBURITypeインスタンスを使用してデータベース・データからXML文書を構成します。 URIを使用したデータ・アクセスを参照してください。

関連項目:

- Oracle XML DBの使用方法の概要

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

- PL/SQL API for XMLType

- Java DOM API for XMLType

8.2 SQL関数を使用したXMLデータの生成

Oracle XML DBには、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は非常に汎用性が高く、このマニュアルではSQL/XML問合せおよび更新関数と呼んでいます。

XMLを生成する次のSQL関数は、(SQL/XML標準の一部ではなく) Oracle固有です。

- XMLROOT Oracle SQL関数

- XMLCOLATTVAL Oracle SQL関数

- XMLCDATA Oracle SQL関数

- SYS_XMLAGG Oracle SQL関数この関数は、リレーショナル行のグループを操作し、複数のXML文書を1つに集約します。

すべてのXML生成SQL関数では、スカラーおよびユーザーのデータ型インスタンスが正規のXML形式に変換されます。この正規マッピングでは、ユーザー定義のデータ型の属性はXML要素にマップされます。

関連項目:

- SQL/XML関数XMLQueryを使用したXMLデータの構成の詳細は、XQueryとOracle XML DBを参照してください。

- OracleによるSQL/XML標準のサポートの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

8.2.1 XMLELEMENTおよびXMLATTRIBUTES SQL/XML関数

SQL/XML標準関数XMLElementは、リレーショナル・データからXML要素を構成します。SQL/XML標準関数XMLAttributesをXMLElementとともに使用すると、生成される要素の属性を指定できます。

SQL/XML標準関数XMLElementは、引数としてXML要素名、その要素の属性のコレクション(オプション)、およびその要素のコンテンツを構成する0 (ゼロ)個以上の追加の引数を取ります。戻り値はXMLTypeインスタンスです。

図8-1 XMLELEMENTの構文

キーワードENTITYESCAPINGおよびNOENTITYESCAPINGの説明は、「生成されたXMLデータにおける文字のエスケープ」を参照してください。これらのキーワードは、標準SQL/XML関数XMLElementおよびXMLAttributesに対応するためのOracleの拡張です。

関数XMLElementの最初の引数は、作成されるrootXML要素名に名前を付ける識別子を定義します。ルート要素識別子の引数は、リテラル識別子(図8-1のidentifier)を使用することで、またはEVALNAMEに識別子を評価する式(value_expr)を続けることで定義できます。ただし、識別子は、定義されてもNULLにできません。NULLの場合、エラーが発生します。EVALNAMEの使用の可能性は、標準SQL/XML関数XMLElementに対応するためのOracleの拡張です。

関数XMLElementのオプションのXML-attributes-clause引数は、生成されるルート要素の属性を指定します。この関数の構文を図8-2に示します。

オプションのXML-attributes-clause引数の他に、関数XMLElementは、ルート要素のコンテンツ(子要素とテキスト・コンテンツ)を構成する0 (ゼロ)個以上のvalue_expr引数を取ります。XML-attributes-clause引数も存在する場合、XML-attributes-clause引数の後にこれらのコンテンツ引数が続く必要があります。個々のコンテンツ引数式が評価され、結果がXMLフォーマットに変換されます。値引数の評価結果がNULLだった場合、その引数にはコンテンツが作成されません。

注意:

別名(c_alias)の前のASは、SQL/XML標準で必要ですが、Oracleではオプションです。

オプションのXML-attributes-clause引数は、SQL/XML標準関数XMLAttributesを使用してルート要素の属性を指定します。関数XMLAttributesは、関数XMLElementのコールでのみ使用できます。単独では使用できません。

図8-2 XMLAttributes句の構文(XMLATTRIBUTES)

キーワードENTITYESCAPINGおよびNOENTITYESCAPINGの説明は、「生成されたXMLデータにおける文字のエスケープ」を参照してください。これらのキーワードは、標準SQL/XML関数XMLElementおよびXMLAttributesに対応するためのOracleの拡張です。

キーワードSCHEMACHECKおよびNOSCHEMACHECKは、生成された属性のいずれかがOracle XML DBで登録されているXML Schemaに対応するスキーマの場所を指定するか確認し、指定している場合は、それに対応するXML Schemaに基づくXMLデータを生成するか確認するため、それら属性で実行時チェックが行われるかどうか判断します。NOSCHEMACHECKで提供されているデフォルト動作では、チェックは行いません。12cリリース1 (12.1)より前のリリースでは、デフォルト動作ではチェックを行います。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に文字列リテラルを評価する式が続く名前になります。

注意:

標準SQL/XML構文に対するOracleの拡張は次のとおりです。

- EVALNAMEを使用できること。

- 別名(c_alias)の前のASはオプションであること。

属性値式がNULLであると評価された場合、その式に対応する属性は作成されません。属性値式のデータ型は、オブジェクト型またはコレクションにできません。

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

SQL/XML標準で規定されているとおり、明示された識別子に含まれる文字はいかなる場合もエスケープされません。必ず、有効なXML名を使用してください。これはすべてのSQL/XML関数に当てはまります。

特に、XMLElementのルート要素識別子(図8-1のidentifier)やXMLAttributesのAS句で名前を指定された属性識別子の別名に当てはまります(図8-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の拡張です。

8.2.1.2 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を使用します(例8-1を参照)。

関連項目:

http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#isoformatsにある、XMLの日付およびタイムスタンプのフォーマットに関するXML Schemaの仕様

8.2.1.3 XMLElementの例

ここでの例は、SQL/XML関数XMLElementの使用方法を示しています。

例8-1では、XMLElementを使用して、XML Schemaの標準フォーマットと異なるフォーマットを持つXMLの日付を生成します。

例8-2では、XMLElementを使用して、従業員の名前をコンテンツとして持つEmp要素を各従業員に1つずつ生成します。

例8-3では、XMLElementを使用して、従業員名と雇用日を提供する子要素を持つEmp要素を各従業員に1つずつ生成します。

例8-4では、XMLElementを使用して、属性idおよびnameを持つEmp要素を各従業員に1つずつ生成します。

「生成されたXMLデータにおける文字のエスケープ」で前述のとおり、ルート要素名、およびAS句により定義される属性の名前に含まれる文字はエスケープされません。識別指名に含まれる文字は、その名前が、評価された式から作成される場合にのみエスケープされます(列の参照と同様)。

例8-5は、XMLElementを使用して構成されたXNLデータによって、ルート要素名と属性名がエスケープされないことを示します。大なり記号(>)とカンマ(,)はXML要素や属性名では許容されないため、無効なXMLが作成されます。

文字のエスケープに関する詳細説明は、SQL/XML標準に含まれています。

例8-6では、名前空間を使用してXML Schemaに基づく文書を作成する方法を示します。XML Schema http://www.oracle.com/Employee.xsdが存在し、ターゲットの名前空間が存在しない場合、例8-6の問合せによって、そのスキーマに準拠したXMLTypeインスタンスが作成されます。

例8-7では、XMLElementを使用して、従業員と部門情報を含むXML文書を生成します。ここでは、サンプルのデータベース・スキーマ表hr.departmentsを使用します。

例8-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.

例8-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データを生成することもできます。

例8-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.

例8-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.

例8-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.

例8-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.

例8-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.

8.2.2 XMLFOREST SQL/XML関数

SQL/XML標準関数XMLForestを使用して、XML要素のフォレストを構成します。

その引数は評価する式で、オプションで別名も付けられます。図8-3 は、XMLForestの構文を説明するものです。

図8-3 XMLFORESTの構文

値の式(図8-3のvalue_expr)がそれぞれXML形式に変換され、オプションで識別子c_aliasが属性識別子として使用されます(c_aliasは文字列リテラルまたはEVALNAMEに文字列リテラルを評価する式が続く名前になります)。EVALNAMEの使用の可能性は、標準SQL/XML関数XMLForestに対応するためのOracleの拡張です。

オブジェクト型またはコレクションの場合、AS句は必須です。それ以外の方の場合、AS句はオプションです。指定された式でAS句が省略されている場合は、評価された値の式に含まれる文字はエスケープされ、要素の囲みタグ名を形成します。エスケープの方式は「生成されたXMLデータにおける文字のエスケープ」での定義によります。値の式の評価結果がNULLだった場合、その式には要素が作成されません。

例8-8では、XMLElementとXMLForestを使用して、name属性を含み、雇用日および部門をコンテンツとして含む子要素を持つEmp要素を各従業員に1つずつ生成します。

例8-8 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.

関連項目:

例8-20

例8-9では、XMLForestを使用して、ユーザー定義のデータ型インスタンスから階層XMLデータを生成します。

例8-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.

この例を例8-7および例8-25と比較してください。

8.2.3 XMLCONCAT SQL/XML関数

SQL/XML標準関数XMLConcatを使用して、複数のXMLTypeインスタンスを連結することにより、XMLフラグメントを構成します。

図8-4はXMLConcatの構文を説明するものです。関数XMLConcatには次の2つの形式があります。

- 1つ目の形式では、XMLTypeインスタンスのVARRAYであるXMLSequenceType値を引数として取り、VARRAYのすべての要素を連結して単一のXMLTypeインスタンスを戻します。この形式は、XMLTypeインスタンスのリストを単一のインスタンスに縮小する場合に有効です。

- 2つ目の形式では、任意の数のXMLTypeインスタンスを取り、それらの値を連結します。値の1つがNULLである場合、その値は結果に出力されません。すべての値がNULLである場合、結果はNULLになります。この形式は、任意の数のXMLTypeインスタンスを同じ行に連結するために使用できます。関数XMLAggを使用すると、複数行にわたってXMLTypeインスタンスを連結できます。

図8-4 XMLCONCATの構文

例8-10では、SQL/XML関数XMLConcatを使用して、XMLSequenceType値(XMLTypeインスタンスのVALLAY)のXMLTypeインスタンスを連結して戻します。

例8-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.

例8-11では、XMLConcatを使用して、従業員の姓と名のXML要素を作成して連結します。

例8-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.

8.2.4 XMLAGG SQL/XML関数

SQL/XML標準関数XMLAggを使用して、XML要素のコレクションからXML要素のフォレストを構成します。これは集計関数です。

図8-5 XMLAGGの構文

図8-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が戻されます。

例8-12では、SQL/XML関数XMLAggおよびXMLElementを使用して、従業員のジョブIDおよび姓を要素のコンテンツとして持つEmployee要素を含むDepartment要素を作成します。また、その部門に属するEmployee要素を従業員の姓で順序付けします。また、その部門に属するEmployee要素を従業員の姓で順序付けします (わかりやすいように、この結果をフォーマット出力しています)。

例8-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によって行が集計されるため、単一の従業員行が戻されます。

例8-13は、GROUP BY句を使用して、戻された一連の行を複数のグループにグループ化し、Department要素を構成する方法を示しています。(ここではわかりやすいように、この結果をフォーマット出力しています。)

例8-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を使用すると、表に存在するいくつかの階層関係を反映できます。例8-14では、部門30の部門要素を生成します。この要素内に、部門の各従業員に対応する子要素empがあります。各従業員要素内に、その従業員の各依存に対応するdependent要素があります。

例8-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.

8.2.5 XMLPI SQL/XML関数

SQL/XML標準関数XMLPIを使用して、XML処理命令(PI)を構成します。

図8-6に構文を示します。

図8-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が戻されます。

例8-15では、XMLPIを使用して簡単な処理の指示を生成します。

例8-15 SQL/XML関数XMLPIの使用

SELECT XMLPI(NAME "OrderAnalysisComp", 'imported, reconfigured, disassembled')
AS pi FROM DUAL;

これによって、次の出力が生成されます。

PI
----------------------------------------------------------
<?OrderAnalysisComp imported, reconfigured, disassembled?>

1 row selected.

8.2.6 XMLCOMMENT SQL/XML関数

SQL/XML標準関数XMLCommentを使用して、XMLコメントを構成します。

図8-7に構文を示します。

図8-7 XMLCommentの構文

引数value_exprの評価結果は文字列で、生成されるXMLコメントの本文として使用されます。つまり、結果は<!--string-result-->で、ここでstring-resultがvalue_exprの文字列評価結果です。string-resultが空の文字列の場合、次のようにコメントは空になります。<!---->。

構成されたXMLが有効なXMLコメントでない場合はエラーが発生します。特に、string-resultに、ハイフン(-)が連続して2つ含まれてはいけないことに注意してください(--)。

関数XMLCommentはXMLTypeのインスタンスを戻します。string-resultがNULLの場合、関数はNULLを戻します。

例8-16では、XMLCommentを使用して簡単なXMLコメントを生成します。

例8-16 SQL/XML関数XMLCOMMENTの使用

SELECT XMLComment('This is a comment') AS cmnt FROM DUAL;

この問合せによって、次の出力が生成されます。

CMNT
--------------------------
<!--This is a comment-->

8.2.7 XMLSERIALIZE SQL/XML関数

SQL/XML標準関数XMLSerializeは、文字列またはXMLデータのLOB表現を取得するために使用します。

図8-8にXMLSerializeの構文を示します。

図8-8 XMLSerializeの構文

引数value_exprが評価され、結果のXMLTypeインスタンスがシリアライズされて、作成された文字列またはLOBのコンテンツを生成します。存在する場合は脚注1、指定されたdatatypeは、次のいずれかであることが必要です(デフォルトのデータ型はCLOB)。

- VARCHAR2(N)。ここでNはバイト単位のサイズ脚注2

- 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とともに指定した場合、エラーが発生します。UTF-16文字の場合、xml_encoding_specは次のいずれかである必要があります。

- encoding=UTF-16BE - ビッグ・エンディアンUTF-16エンコーディング

- encoding=UTF-16LE - リトル・エンディアンUTF-16エンコーディング

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がデフォルトの動作です。

例8-17では、XMLSerializeを使用して、シリアライズされたXMLデータを含むCLOBインスタンスを生成します。

例8-17 SQL/XML関数XMLSERIALIZEの使用

SELECT XMLSerialize(DOCUMENT XMLType('<poid>143598</poid>') AS CLOB)
AS xmlserialize_doc FROM DUAL;

これによって、次の出力が生成されます。

XMLSERIALIZE_DOC
-------------------
<poid>143598</poid>

8.2.8 XMLPARSE SQL/XML関数

SQL/XML標準関数XMLParseは、XMLデータを含む文字列を解析してXMLTypeインスタンスの対応する値を構成するために使用します。

図8-9に構文を示します。

図8-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を戻します。

例8-18では、XMLParseを使用してXMLコードの文字列を解析し、XMLTypeインスタンスを生成します。

例8-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文書およびフラグメントに関する説明

8.2.9 XMLROOT Oracle SQL関数

Oracle SQLファンクションXMLRootは、XML値のルート情報項目へのVERSIONプロパティの追加や、オプションのSTANDALONEプロパティの追加に使用できます。通常、これはデータモデル準拠の確認に使用します。

SQL関数XMLRootはSQL/XML標準関数である時期がありましたが、SQL/XML 2005時点で標準関数として非推奨になりました。Oracle SQL関数としてOracle XML DBでは使用できます。

図8-10にXMLRootの構文を示します。

図8-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を戻します。

例8-19では、XMLRootを使用して、version属性およびstandalone属性を持つXML宣言を追加します。

例8-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.

8.2.10 XMLCOLATTVAL Oracle SQL関数

Oracle SQL関数XMLColAttValは、渡された引数の値を含むXMLのcolumn要素のフォレストを生成します。この関数は、SQL/XML ANSI-ISO標準関数に対応するためのOracleの拡張です。

図8-11はXMLColAttValの構文を説明するものです。

図8-11 XMLCOLATTVALの構文

引数はcolumn要素のname属性の値として使用されます。c_alias値は属性識別子として使用されます。

キーワードASにリテラル文字列c_aliasを続ける方法の他に、AS EVALNAMEに、評価結果が属性識別子として使用される文字列になる式を続ける方法もあります。

引数値value_exprは属性valuesとしてのみ使用されているため、いずれにしてもエスケープする必要はありません。XMLForestとは対照的です。つまり、XMLColAttValを使用すると、SQL列と値をエスケープせずに転送できます。

例8-20では、XMLColAttValを使用して、name属性を含み、雇用日および部門をコンテンツとして含むcolumn要素を持つEmp要素を各従業員に1つずつ生成します。

例8-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.

関連項目:

例8-8

8.2.11 XMLCDATA Oracle SQL関数

Oracle SQL関数XMLCDATAを使用して、XML CDATAセクションを生成します。

図8-12に構文を示します。

図8-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を戻します。

例8-21では、XMLCDATAを使用して、XML CDATAセクションを生成します。

例8-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>

8.3 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を比較)

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

パッケージDBMS_XMLGENを使用すると、リレーショナル・データからXMLデータを生成できます。

図8-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をコールして、すでに割り当てられているリソースを解放します。

図8-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です。

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

PL/SQLパッケージDBMS_XMLGENには、リレーショナル・データからXMLデータを生成するためのファンクションおよびプロシージャが用意されています。

表8-1に、パッケージDBMS_XMLGENのファンクションおよびプロシージャの概要を示します。

表8-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問合せ文字列sqlQueryの問合せ結果をXML形式に変換します。

CLOBインスタンスを返します。

getXMLType(
sqlQuery IN VARCHAR2,
dtdOrSchema IN NUMBER := NONE)
RETURN XMLType;

SQL問合せ文字列sqlQueryの問合せ結果をXML形式に変換します。

XMLTypeインスタンスを返します。

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を使用してすべてのバインド変数に新しい値をリバインドする必要があります。

8.3.3 DBMS_XMLGENの例

ここでの例は、PL/SQLパッケージDBMS_XMLGENの使用方法を示しています。

例8-22では、DBMS_XMLGENを使用して、オブジェクト・リレーショナル表から従業員データを選択してXML文書を作成し、結果のCLOB値を表に挿入します。

すべての行に対してXMLデータ全体を生成するかわりに、パッケージDBMS_XMLGENのフェッチ・インタフェースを使用して、1回に固定の行数を取り出すことができます。これによって特に行数が多い場合に、応答時間が短縮され、また結果のXMLにドキュメント・オブジェクト・モデル(DOM)Application Program Interface(API)を使用する必要があるアプリケーションのスケーリングに有効です。

例8-23では、DBMS_XMLGENを使用してHR.employees表から結果を取り出します。

例8-24では、DBMS_XMLGENとオブジェクト型を使用してネスト構造を表現しています。

リレーショナル・データの場合、結果はネストされた要素がないXML文書になります。ネストしたXML構造にするには、オブジェクト・リレーショナル・データを使用します。この場合のマッピングは次のとおりです。

- オブジェクト型はXML要素にマップします。XML Schemaの格納と問合せ: 基本を参照してください。

- 型の属性は、親要素のサブ要素にマップされます。

注意:

複雑な構造にするには、オブジェクト型を使用し、オブジェクト・ビューまたはオブジェクト表を作成します。正規マッピングを使用して、オブジェクト・インスタンスをXMLにマップしてください。

アットマーク(@)を列名または属性名で使用すると、マッピングでXMLの囲み要素の属性に変換されます。

ユーザー定義のデータ型インスタンスをDBMS_XMLGENファンクションに入力すると、ユーザー定義データ型インスタンスは正規マッピングを使用してXML文書にマップされます。ユーザー定義のデータ型の属性はXML要素にマップされます。アットマーク「@」で始まる名前の属性は、その前にある要素の属性にマップされます。

ユーザー定義のデータ型インスタンスを使用して、結果のXML文書内でネストできます。

たとえば、例8-25で定義されたempおよびdeptという2つの表を考えてみます。部門とその従業員のデータの階層ビューを生成するために、例8-25では、適切なオブジェクト型を定義してデータベース内に構造を作成します。

デフォルト名ROWは、NULLに設定しているため存在しません。deptnoおよびempnoは囲み要素の属性になっています。

例8-26では、DBMS_XMLGEN.getXMLTypeを使用して、オブジェクト・ビューによって発注書をXML形式で生成します。

例8-27では、問合せのカーソル変数の開き方、およびカーソル変数を使用してDBMS_XMLGENの新しいコンテキスト・ハンドルを作成する方法を説明します。

関連項目:

カーソル変数(REF CURSOR)の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

例8-28に、DBMS_XMLGENを使用する場合のNULL処理の指定方法を示します。

関数DBMS_XMLGEN.newContextFromHierarchyは通常CONNECT BY句を使用して形成される階層問合せ文字列を引数として取ります。再帰要素が含まれる階層XML文書の生成に使用されるコンテキストを戻します。

階層問合せでは、レベル番号(CONNECT BY問合せを使用して生成される疑似列)とXMLTypeインスタンスの2つの列が戻されます。レベルは、結果XML文書の階層内のXMLType値の位置を判断するために使用されます。

newContextFromHierarchyから作成されたコンテキストに対して、スキップ行数または最大行数を設定するとエラーになります。

例8-29では、DBMS_ XMLGEN.newContextFromHierarchyを使用して、管理者(従業員階層)を生成します。

コンテキストの作成に使用する問合せ文字列にホスト変数が含まれている場合、問合せの実行前にPL/SQLメソッドsetBindValueを使用して、変数値を指定できます。例8-30に、これを示します。

例8-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.

例8-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.

例8-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.

例8-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.

例8-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.

例8-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.

例8-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.

例8-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.

例8-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.

8.4 SYS_XMLAGG Oracle SQL関数

Oracle SQL関数sys_XMLAggは、式により表されるすべてのXML文書またはフラグメントを集計し、単一のXML文書を生成します。この関数は、デフォルト名ROWSETの新しい要素の式の結果を囲みます。

Oracle関数sys_XMLAggはSQL/XML標準関数sys_XMLAggに類似していますが、XMLAggは単一のノードを戻し、XMLFormatパラメータを取ります。そのパラメータを使用して結果のXML文書を様々な方法でフォーマットできます。

図8-14 SYS_XMLAGGの構文

関連項目:

- sys_XMLAggの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- XMLFormatパラメータの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

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

集計前にXMLAgg ORDER BY句を使用するには、最初のXMLAGG引数の後にORDER BY句を指定します。

これを例8-31に示します。

例8-31 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 dev_tab 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.

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

標準SQL/XML関数XMLTableを使用すると、複数の行として抽出された文書の関連する部分の行セットを戻すことができます。

例8-32を参照してください。

例8-32 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でのこの標準の実装では、便宜性を考慮してオプションとなっています。

脚注2:
上限値は32767または4000バイト(初期化パラメータMAX_STRING_SIZEの値によって異なる)。詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

9 XMLデータのリレーショナル・ビュー

XMLデータのリレーショナル・データベース・ビューでは、XMLコンテンツへの従来のリレーショナル・アクセスを提供します。

- XMLデータのリレーショナル・ビューの作成および使用の概要

- XMLのリレーショナル・ビューの作成: XML文書ごとに1行

- XMLのリレーショナル・ビューの作成: XMLノードの列へのマップ

- リレーショナル・ビューを使用して公開されたバイナリXMLデータの索引付け

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

9.1 XMLデータのリレーショナル・ビューの作成および使用の概要

Oracle XML DBで提供されるXML特有の関数およびメソッドを使用すると、XMLコンテンツへのリレーショナル・アクセスを提供する、従来のデータベース・ビューを作成できます。これによって、Oracle Databaseには対処していてもXMLに対処しているとはかぎらないプログラマ、ツールおよびアプリケーションでも、データベースに格納されたXMLコンテンツを操作できます。

リレーショナル・ビューでは、XQuery式とXMLTableなどのSQL/XML関数を使用して、ビューの列とXML文書のノードとの間のマッピングを定義できます。

関連項目:

- XQueryとOracle XML DB

- XMLTypeデータの索引

9.2 XMLのリレーショナル・ビューの作成: XML文書ごとに1行

XMLType表内の各文書をリレーショナル・ビューの行として公開するには、CREATE OR REPLACE VIEW AS SELECTを使用し、XMLType表と、SQL/XML関数XMLTableを使用してXMLデータから作成したリレーショナル表とを結合して抽出します。

標準SQL/XML関数XMLTableを使用して、XML文書のノードをビューの列にマップできます。この方法は、XMLType表内の文書とビュー内の行の間に、1対1 (1:1)の関係がある場合はいつでも使用できます。

例9-1では、XMLType表po_binaryxmlの行ごとに1行ずつ含む、リレーショナル・ビューpurchaseorder_master_viewを作成します。

例9-1 XMLコンテンツのリレーショナル・ビューの作成

CREATE TABLE po_binaryxml OF XMLType
XMLTYPE STORE AS BINARY XML;

INSERT INTO po_binaryxml SELECT OBJECT_VALUE FROM OE.purchaseorder;

CREATE OR REPLACE VIEW purchaseorder_master_view AS
SELECT po.*
FROM po_binaryxml 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)

9.3 XMLのリレーショナル・ビューの作成: XMLノードの列へのマップ

XMLType表の複数のレベルからのデータをリレーショナル・ビューの個別の行として公開するには、各レベルにSQL/XML関数XMLTableを適用します。この方法は、XMLType表内の文書とビュー内の行の間に、1対多(1:N)関係がある場合はいつでも使用できます。

つまり、ビューを構成する列を定義し、XMLノードをその列にマップするという、単一レベルの分割(「XMLのリレーショナル・ビューの作成: XML文書ごとに1行」を参照)と同じ一般的な方法を使用します。ただし、この場合は、分割してリレーショナル列に格納する各文書レベルにXMLTableを適用します。

たとえば、各PurchaseOrder要素にLineItems要素が含まれていて、この要素に1つ以上のLineItem要素が含まれているとします。各LineItem要素には、DescriptionやItemNumber属性などの子要素があります。このような下位レベルのデータをリレーショナル値としてアクセス可能にするには、XMLTableを使用してPurchaseOrder要素とLineItemコレクションの両方を投影します。

要素PurchaseOrderを分割すると、その子孫であるLineItem要素は、XMLフラグメントが含まれている型XMLTypeの列にマップされます。この列は次に、XMLTableへの2回目のコールに渡され、リレーショナル値の複数の列として複数の部分に分割されます。

例9-2に、これを示します。ここでは、XMLTableを使用して、XMLType表po_binaryxml内の文書とリレーショナル・ビューpurchaseorder_detail_view内の行との間に1対多(1:N)の関係をもたらします。このビューはコレクションの個別のメンバーへのアクセスを提供し、コレクション・メンバーを行のセットとして公開します。

例9-2では、ビューpurchaseorder_detail_viewの各行は、XMLType表po_binaryxmlに格納されているXML文書内の各LineItem要素に対応しています。

例9-2のCREATE OR REPLACE VIEW文では、ビューを構成する一連のリレーショナル列を定義します。SELECT文は、コンテキストとしてpo_binaryxml表を関数XMLTableに渡し、列referenceおよびlineitemを含む、仮想表pを作成します。これらの列には、発注書のReferenceおよびLineItem要素がそれぞれ含まれます。

列lineitemにはLineItem要素のコレクションがXMLTypeインスタンスとして含まれ、各行が各要素に対応します。これらの行は次に、2つ目のXMLTable式に渡され、そのコンテキストとして機能します。この2つ目のXMLTable式により、明細/項目行の仮想表が作成され、各列が要素LineItemの様々な子孫ノードに対応します。これらの子孫の大半は属性(ItemNumberやPart/@Idなど)です。子孫の1つは子要素Descriptionです。

要素Referenceは、列referenceとしてビューpurchaseorder_detail_viewに投影されます。ビューpurchaseorder_detail_viewの行をビューpurchaseorder_master_viewの対応する行に結合するのに使用できる外部キーを提供します。CREATE OR REPLACE VIEW文の相関結合によって、ビューにアクセスするたびに、要素Referenceと、関連するLineItem要素の間の1対多(1:N)の関係が保持されます。

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

CREATE OR REPLACE VIEW purchaseorder_detail_view AS
SELECT po.reference, li.*
FROM po_binaryxml 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)

9.4 リレーショナル・ビューを使用して公開されたバイナリXMLデータの索引付け

バイナリXMLデータに対するXMLIndex索引の構造化コンポーネントのリレーショナル列が、そのデータに対するリレーショナル・ビューの列と一致する場合は、実質的に、そのビューも索引付けされます。

リレーショナル・ビューで公開されるXMLTypeデータがバイナリXMLとして格納されている場合、ビューの列に対応する構造化コンポーネントを含むXMLIndex索引を作成すれば、通常はパフォーマンスを向上できます。このような索引は、ビューの動作と同じように、XMLデータの部分をリレーショナル列に投影します。索引の列とビューの列が一致する場合、ビュー自体が索引付けされます。

このようなXMLIndex索引の作成を簡単にするには、PL/SQLファンクションDBMS_XMLSTORAGE_MANAGE.getSIDXDefFromViewを使用すれば、索引の作成に必要なXMLTable式を正確に記述できます。それがこの関数の唯一の機能で、リレーショナル・ビュー用のXMLIndex索引の作成に使用できるXMLTable式を戻します。ビューを引数として取得し、CLOBインスタンスを戻します。例9-3に、これを示します。

例9-4に、例9-3で使用したXMLTable式を示します。

関連項目:

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

- PL/SQL関数DBMS_XMLSTORAGE_MANAGE.getSIDXDefFromViewの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

例9-3 リレーショナル・ビューの列に対応するXMLIndex索引

CALL DBMS_XMLINDEX.registerParameter(
'my_param',
DBMS_XMLSTORAGE_MANAGE.getSIDXDefFromView('PURCHASEORDER_MASTER_VIEW'));Foot 1

CREATE INDEX my_idx on po_binaryxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
PARAMETERS ('PARAM my_param');

例9-4 PL/SQL関数getSIDXDefFromViewによって戻されたXMLTable式

SELECT DBMS_XMLSTORAGE_MANAGE.getSIDXDefFromView('PURCHASEORDER_MASTER_VIEW')
FROM DUAL;

XMLTABLE po_binaryxml_XTAB_1 '/PurchaseOrder' PASSING OBJECT_VALUE
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'

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

ここでの例は、XMLデータのリレーショナル問合せを示しています。これらの例では、XMLType表および列に対してリレーショナル・ビューを作成するメリットをいくつか示します。

例9-5および例9-6に、XMLデータのマスターおよび詳細なリレーショナル・ビューの問合せ方法を示します。例9-5では、マスター・ビューに問い合せ、列useridがSで始まる行を検索します。

例9-6ではマスター・ビューと詳細ビューを結合します。itemno列の値が1で、対応するpurchaseorder_master_viewの行に値がSBELLのuserid列が含まれているpurchaseorder_detail_viewの行を検索します。

例9-7では、XMLコンテンツのリレーショナル・ビューを使用して、XML文書のビジネス・インテリジェンス問合せを実行する方法を示します。この例の問合せは、タイトルがUPCコード715515009058および715515009126で識別される発注を含むPurchaseOrder文書を選択します。

例9-7の問合せは、PurchaseOrder文書ごとに、発注された各映画タイトルの本数を判別します。たとえば、部品番号715515009126には、発注された品目の本数が1のPurchaseOrder文書は4つあり、発注された品目の本数が3のPurchaseOrder文書は7つあります。

例9-5 XMLデータのマスター・リレーショナル・ビューの問合せ

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.

例9-6 XMLデータのマスターおよび詳細なリレーショナル・ビューの問合せ

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.

例9-7 ビューを使用した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.

脚注の凡例

脚注1:
getSIDXDefFromViewに渡すview-name引数は、実際の登録名と同様、大文字で指定する必要があります。

10 XMLTypeビュー

リレーショナル・データおよびオブジェクト・リレーショナル・データに対するXMLTypeビューを作成できます。

- XMLTypeビューの概要

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

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

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

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

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

10.1 XMLTypeビューの概要

XMLTypeビューは、既存のリレーショナル・データおよびオブジェクト・リレーショナル・データをXML形式でラップします。これにより、XMLデータを予期し、XML SchemaなどのXML機能を使用するコンテキストで既存のデータを使用できます。

XMLTypeビューを使用する主なメリットは次のとおりです。

- 基本のレガシー・データを移行せずに、XML Schema機能を使用するOracle XML DBのXML機能を使用できます。

- XMLTypeビューでは、様々な形式の記憶域を使用してデータを格納できます。XMLTypeとして格納するか、またはどのXMLType記憶域モデルを使用するかについて、急いで決める必要はありません。

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リライトの詳細は、 オブジェクト・リレーショナル記憶域のXPathリライトで説明しています。

XML Schemaに基づくXMLTypeビューを作成するには、最初にXML Schemaを登録します。ビューがオブジェクト・ビューである場合、つまりオブジェクト型を使用して構成されている場合、XML Schemaには、XMLとSQLオブジェクト型の間の双方向マッピングを表す注釈が必要です。その後、適切なSQLオブジェクト型のインスタンスを構築する基礎となる問合せを指定することによって、登録されたXML Schemaに準拠するXMLTypeビューを作成できます。

関連項目:

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

- XMLデータのリレーショナル・ビュー

- XMLType記憶域および索引付けの選択

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に制限される必要があります。

- オブジェクト型またはオブジェクト・ビューに基づく方法。これによって、リレーショナルまたはオブジェクト・リレーショナルのレガシー・データをXMLに物理的に移行せずに、基礎となるリレーショナル表またはオブジェクト・リレーショナル表から直接XMLTypeビューを構成できます。XML Schemaに基づくXMLTypeビューでは、既存のオブジェクト型へのマッピングをXML Schemaに注釈として付けるか、または既存のオブジェクト型からXML Schemaを生成する必要があります。

- XMLType表から直接構成する方法。

10.2 XMLTypeビューのCREATE VIEW: 構文

XMLTypeビューを作成するためのCREATE VIEW句の構文を示します。

図10-1に、この構文を示します。CREATE VIEWの構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

図10-1 XMLTypeビューの作成の句: 構文

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

XML Schemaに基づかないXMLTypeビューのXMLデータは、登録されたXML Schemaに準拠するように制約されません。XML Schemaに基づかないXMLTypeビューを作成するには、SQL/XMLパブリッシング関数を使用します。

例10-1に、SQL/XML関数XMLELementを使用してXMLTypeビューを作成する方法を示します。

リレーショナル表またはリレーショナル・ビュー内の既存のデータは、この方法を使用してXMLデータとして公開できます。ビューがSQL/XMLパブリッシング関数によって生成されると、XQuery式を使用してそのビューにアクセスする問合せは、多くの場合リライトされます。最適化された問合せは、基礎となるリレーショナル列に直接アクセスできます。詳細は、 オブジェクト・リレーショナル記憶域のXPathリライトを参照してください。

XMLTypeビューに対してDML操作を行うことができますが、通常、DML操作を処理するためにINSTEAD OFトリガーを作成する必要があります。

関連項目:

SQL/XMLパブリッシング関数の詳細は、 リレーショナル・データからのXMLデータの生成を参照してください。

例10-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>

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

XML Schemaに基づくXMLTypeビューのXMLデータは、XML Schemaに準拠するように制約されます。スキーマに基づくXMLTypeビューを作成するには、SQL/XMLパブリッシング関数を使用するか、オブジェクト型またはビューを使用します。

次のいずれかの方法で、スキーマに基づくビューを作成します。

- SQL/XMLパブリッシング関数を使用する方法。

関連項目:

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

- オブジェクト型またはオブジェクト・ビューを使用する方法。この方法は、XMLデータにマップするオブジェクト型、ビューおよび表がすでにある場合に便利です。

関連項目:

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

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

SQL/XMLパブリッシング関数を使用して、XML Schemaに基づくXMLTypeビューを作成できます。

1. 必要なXML構造を含むXML Schema文書を作成および登録します。XML型とSQLオブジェクト型の間のマッピングを定義する注釈をXML Schemaに付ける必要はありません。

2. XML Schemaに準拠するXMLTypeビューを作成するには、SQL/XMLパブリッシング関数を使用します。

この2つの手順を、それぞれ例10-2および例10-3に示します。

例10-4に、XMLTypeビューに対する問合せを示します。

例10-2では、従業員を定義するXML構造を含むemp_simple.xsdというXML Schemaがあると想定します。この例では、目的の場所http://www.oracle.com/emp_simple.xsdを使用してXML Schemaを登録します。

SQL/XMLパブリッシング関数を使用してXML Schemaに基づくコンテンツを生成する場合、すべての要素に適切な名前空間情報を指定し、xsi:schemaLocation属性を使用してスキーマの場所を指定する必要があります。これらは、XMLAttributes句を使用して指定できます。例10-3に、これを示します。

注意:

XML Schema参照とともにSQL/XML関数XMLAttributesを使用してXMLTypeビューを作成する場合は、可能であればビューを作成する前に必ずXML Schemaを登録します。そのようにしない場合、XML Schemaの登録後に、生成される文書がXML Schemaに基づくようにビューを再コンパイルすることが必要になります。

例10-3では、関数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インスタンス上で検証や抽出などの操作が実行されたときに、後で検出されます。

例10-4では、XMLTypeビューを問い合せて、employeesおよび departments表からXMLの結果が戻されています。問合せの結果は、わかりやすくするためフォーマット出力しています。

例10-2 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;

例10-3 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;

例10-4 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>

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

複数の名前空間を含む複合XML Schemaが存在する場合は、SQL/XMLパブリッシング関数で提供される部分的にエスケープされたマッピングを使用して、適切な名前空間と接頭辞を持つ要素を作成する必要があります。

例10-5の問合せでは、正しい名前空間、接頭辞およびターゲット・スキーマの場所を持つXMLインスタンスが作成されます。これをemp_simple_xmlビューの定義で問合せとして使用できます。

XML Schemaにターゲットの名前空間が存在しない場合は、xsi:noNamespaceSchemaLocation属性を使用してターゲットの名前空間を示すことができます。例10-6に、このようなXML Schemaを示します。

例10-7では、例10-6のXML Schemaに準拠するビューが作成されます。XMLAttributes句によって、noNamespaceスキーマの場所属性を含むXML要素が作成されます。

例10-8では、XML Schema dept.xsdに準拠するビューdept_xmlが作成されます。

例10-5 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>

例10-6 ターゲットの名前空間が存在しない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;

例10-7 ターゲットの名前空間が存在しない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;

例10-8 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 AS "DeptNo",
d.department_name AS "DeptName",
d.location_id AS "Location"),
(SELECT XMLagg(
XMLElement("Employee",
XMLForest(
e.employee_id AS "EmployeeId",
e.last_name AS "Name",
e.job_id AS "Job",
e.manager_id AS "Manager",
to_char(e.hire_date,'YYYY-MM-DD') AS "Hiredate",
e.salary AS "Salary",
e.commission_pct AS "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>

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

XML型とSQLオブジェクト型およびオブジェクト属性との間のマッピングを定義する注釈をXML Schemaに付けて、オブジェクト型またはビューからXML Schemaに基づくXMLTypeビューを作成できます。

XML Schemaに基づくXMLTypeビューをオブジェクト型またはオブジェクト・ビューから作成するには、次の手順を実行します。

1. オブジェクト型が存在しない場合は、作成します。

2. XML Schemaを作成してから登録し、XML型とSQLオブジェクト型および属性間のマッピングを定義する注釈を付けます。
XML Schemaを登録する前に注釈を付けます。通常は、既存のデータをラップしてXMLTypeビューを作成する前に行います。

このようなXML Schema文書が登録されると、次の検証が実行される場合があります。

- simpleTypeに基づく属性または要素に対するSQLType。SQL型は、対応するXMLTypeデータのXML型と互換性がある必要があります。たとえば、XML stringのデータ型は、VARCHAR2またはラージ・オブジェクト(LOB)データ型にのみマップできます。

- complexTypeに基づく要素に対して指定されたSQLType。これは、LOBまたはcomplexTypeの宣言と互換性がある構造を持つオブジェクト型のいずれかです。オブジェクト型には、正しいデータ型を持つ正しい数の属性が含まれます。

関連項目:

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

3. XMLTypeビューを作成し、XML SchemaのURLおよびルート要素名を指定します。ビューを定義する問合せによって、まずオブジェクト・インスタンスが作成され、これらのインスタンスがXMLに変換されます。

a. オブジェクト・ビューを作成します。

b. そのオブジェクト・ビューのXMLTypeビューを作成します。

次の各項では、オブジェクト型またはオブジェクト・ビューを使用して、XML Schemaに基づくXMLTypeビューを作成する例について説明します。これらは、従業員データおよび部門データを含むリレーショナル表に基づきます。

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

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

2つのXMLTypeビューをそれぞれ作成するために、同じリレーショナル・データが使用されます。従業員ビューemp_xmlでは、XML文書で従業員を記述し、ネストした情報として従業員の部門が含まれます。部門ビューdept_xmlでは、XMLデータで部門を記述し、ネストした情報として部門の従業員が含まれます。

10.4.2.1 ネストした部門情報を使用した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を作成します

10.4.2.1.1 手順1. XMLType従業員ビューに対応するオブジェクト型の作成

XML Schemaに基づくビューに対応するオブジェクト型を作成します。

例10-9は、その他の手順で使用されるオブジェクト型を作成しています。

例10-9 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);
/

10.4.2.1.2 手順2. XML Schema emp_complex.xsdの作成および登録

XML Schema emp_complex.xsdを作成および登録します。スキーマにより、XMLの要素と属性が、対応するオブジェクト・リレーショナル・オブジェクト属性にマップされます。

XML Schemaのemp_complex.xsdを作成し、オブジェクト型の対応するオブジェクト属性に、XML要素および属性がどのようにマップされるかを指定してから(xdb:SQLType注釈)、登録します。例10-10に登録する方法を示します。

例10-10では、目的の場所http://www.oracle.com/emp_complex.xsdを使用してXML Schemaを作成して登録します。

例10-10 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"/>
<xsd:complexType name="EMP_TType" xdb:SQLType="EMP_T" 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:SQLType="DEPT_T"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="DEPT_TType" xdb:SQLType="DEPT_T"
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;
/

10.4.2.1.3 手順3a.オブジェクト型emp_tを使用したXMLTypeビューemp_xmlの作成

オブジェクト型を使用してXMLTypeビューを作成します。

例10-11では、オブジェクト型emp_tを使用してXMLTypeビューを作成します。

例10-11では、OBJECT ID句でSQL/XML関数XMLCastを使用して、XML従業員番号をSQLデータ型BINARY_DOUBLEに変換します。

関連項目:

ビューemp_xmlを作成する他の方法(オブジェクト・ビューemp_vを使用)は、手順3b: オブジェクト・ビューemp_vを使用したXMLTypeビューemp_xmlの作成を参照してください。

例10-11 オブジェクト型emp_tを使用した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;

10.4.2.1.4 手順3b.オブジェクト・ビューemp_vを使用したXMLTypeビューemp_xmlの作成

オブジェクト・ビューを使用してXMLTypeビューを作成します。

例10-12では、オブジェクト・ビューemp_vを作成して、そのオブジェクト・ビューに基づいてXMLTypeビューemp_xmlを作成します。

関連項目:

ビューemp_xmlを作成する他の方法(オブジェクト型emp_tを使用)は、手順3a: オブジェクト型emp_tを使用したXMLTypeビューemp_xmlの作成を参照してください。

例10-12 オブジェクト・ビューの作成と、そのオブジェクト・ビューに基づく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;

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

ネストされた従業員情報がビューの各部門に含まれるように、XMLTypeビューdept_xmlが作成されます。

ビューの作成の最後の手順では、2つの方法があります。

- 「手順3a: オブジェクト型dept_tを使用したXMLTypeビューdept_xmlの作成」: 部門用のオブジェクト型dept_tを使用してXMLTypeビューdept_xmlを作成します

- 「手順3b: リレーショナル・データを直接使用したXMLTypeビューdept_xmlの作成」: リレーショナル・データを直接使用してXMLTypeビューdept_xmlを作成します

10.4.2.2.1 手順1. XMLType部門ビューに対応するオブジェクト型の作成

XML Schemaに基づくビューに対応するオブジェクト型を作成します。

例10-13は、その他の手順で使用されるオブジェクト型を作成しています。

例10-13 オブジェクト型の作成

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);
/

10.4.2.2.2 手順2. XML Schema dept_complex.xsdの登録

XML Schema dept_complex.xsdを登録します。

例10-14に、これを示します。

例10-14 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"/>
<xsd:complexType name="DEPT_TType" xdb:SQLType="DEPT_T"
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:SQLCollSchema="HR"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="EMP_TType" xdb:SQLType="EMP_T" 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;
/

10.4.2.2.3 手順3a.オブジェクト型dept_tを使用したXMLTypeビューdept_xmlの作成

オブジェクト型dept_tを使用してXMLTypeビューdept_xmlを作成します。

例10-15に、これを示します。

例10-15 オブジェクト型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;

10.4.2.2.4 手順3b.リレーショナル・データを直接使用したXMLTypeビューdept_xmlの作成

オブジェクト型dept_tを使用せずに、SQL/XMLパブリッシング関数を使用してリレーショナル表からXMLTypeビューdept_xmlを作成できます。

例10-16に、これを示します。

注意:

XML Schemaおよび要素情報は、ビュー・レベルで指定する必要があります。これは、SELECTリストでは、基礎となる表から別のXML SchemaのXMLが任意で作成される可能性があるためです。

例10-16 リレーショナル・データを直接使用した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;

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

たとえば、XMLデータを変換したり、戻される行を制限することによって、XMLType表のXMLTypeビューを作成できます。

例10-17では、基礎となるXMLType表に含まれる行を制限して、XMLTypeビューを作成します。XML Schema dept_complex.xsdを使用して、基礎となる表を作成しています。「ネストした従業員情報を使用したXMLType部門ビューの作成」を参照してください。

例10-18は、XSLスタイルシートを使用してXMLデータを変換することによって、XMLTypeビューを作成する方法を示しています。

関連項目:

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

例10-17 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';

dallas_dept_viewによって、XMLType表の行が、所在地がダラスである部門に制限されます。

例10-18 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;

10.6 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と同様に動作します。

10.7 XMLTypeビューでのデータ操作言語(DML)の使用

特定のXMLTypeビューは、暗黙的に更新可能でないことがあります。その場合は、すべてのDMLを処理するために、INSTEAD OFトリガーを作成する必要があります。XMLTypeビューが暗黙的に更新可能であるかどうかを識別するには、それに対して問合せを実行して、そのビューが、本来更新可能であるオブジェクト・ビューまたはオブジェクト・コンストラクタに基づいているかどうかを確認します。

例10-19に、これを示します。

例10-19 暗黙的に更新可能な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_t.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"/>
<xsd:complexType name="DEPT_TType" xdb:SQLType="DEPT_T"
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 =
XMLQuery('copy $i := $p1 modify
(for $j in $i/Department/DNAME
return replace value of node $j with $p2)
return $i'
PASSING d.OBJECT_VALUE AS "p1", 'Shipping' AS "p2" RETURNING CONTENT)
WHERE XMLExists('/Department[DEPTNO=300]' PASSING OBJECT_VALUE);

第IV部 XMLType API

Oracle XML DBのXMLType PL/SQL、Java、C APIおよびOracle Data Provider for .NET (ODP.NET)を使用して、XMLデータにアクセスして操作できます。

- PL/SQL API for XMLType

- PL/SQLパッケージDBMS_XMLSTORE

- Java DOM API for XMLType

- C API for XML

- Oracle XML DBおよびOracle Data Provider for .NET

11 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)

11.1 Overview of PL/SQL API for XMLTypeの概要

PL/SQL Application Program Interface (API) for XMLTypeには、DOM API、パーサーAPI、プロセッサAPIなどがあります。

- 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): DOMの作成や、XML文書のコンテンツおよび構造にアクセスするために使用します。

- PL/SQL XSLT Processor for XMLType(パッケージDBMS_XSLPROCESSOR): XSLTを使用してXML文書を他のフォーマットに変換するために使用します。

11.1.1 PL/SQL API for XMLType: 機能

PL/SQL API for XMLTypeを使用すると、XMLType表、列およびビューを作成したり、別のキャラクタ・セットでエンコードされたデータからXMLTypeインスタンスを構築したり、様々な方法でXMLTypeにアクセスして操作することができます。

関連項目:

- Oracle XML DBアーキテクチャおよび新機能の概要は、「Oracle XML DBの機能」を参照してください。

- XMLデータの問合せと更新

- 『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

11.1.1.1 XMLデータの遅延ロード(実体化の遅延)

XMLの遅延ロードでは、データ行が要求されたときにのみデータ行がロードされるため、大規模なXML文書と多くの同時ユーザーが関与するアプリケーションのスケーラビリティが向上します。

XMLTypeでは動的メモリーまたは仮想ドキュメント・オブジェクト・モデル(DOM)が提供されるため、XMLの遅延ロード(実体化の遅延と言われることもあります)というメモリー節約プロセスを使用できます。このプロセスは、データ行が要求されたときに、データ行のみをロードすることによって、メモリー使用量を最適化します。メモリーの使用量が大きくなりすぎた場合に、文書内の参照済の部分を廃棄します。XMLの遅延ロードは、多くの同時ユーザーが大規模なXML文書にアクセスする必要がある高度にスケーラブルなアプリケーションをサポートします。

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

SQLデータ型XMLTypeではXML Schemaがサポートされています。

XML Schemaを作成し、XMLを使用してオブジェクト・リレーショナル記憶域からのマッピングに注釈を付けることができます。PL/SQL DOM APIを使用するには、まずXML Schemaを作成して登録します。その後、作成するXMLType表および列が、登録したXML Schemaに準拠するように指定できます。

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

PL/SQLを使用して、Oracleでサポートされているキャラクタ・セットのいずれかでエンコードされたデータから、XMLTypeインスタンスを作成できます。これを行うには、PL/SQLのXMLTypeコンストラクタまたはXMLTypeのcreateXML()メソッドを使用します。

ソースの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を使用すると、システムが停止したりセキュリティに悪影響を及ぼす可能性があります。入力した文書要素の名前にデータベース・キャラクタ・セットでサポートされない文字が含まれている場合、その文字は置換文字(通常は「?」)で置き換えられます。このため、解析が終了して例外が発生します。リカバリ不能なエラーが発生する可能性があります。

11.1.2 PL/SQL API for XMLType: リファレンス

PL/SQL Application Program Interface (API) for XMLTypeについて説明します。

表11-1に、XMLデータの操作に使用できるPL/SQLのAPIのリファレンス・ドキュメントを示します。PL/SQLのAPIの主なリファレンスは、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』です。

関連項目:

- Java APIs for XMLの詳細は、『Oracle Database XML Java API Reference』を参照してください。

- C API for XMLの詳細は、『Oracle Database XML C APIリファレンス』を参照してください。

- C++ API for XMLの詳細は、Oracle Database XML C++ APIリファレンスを参照してください。

表11-1 XMLに関連するPL/SQL API

API

ドキュメント

説明

XMLType

『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「XMLType」

XMLTypeデータのXML操作(検証、変換)で使用するPL/SQLの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_ADMIN

『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XDB_ADMIN」

データベース管理者がOracle XML DBリポジトリを管理するためのPL/SQL API

DBMS_XDB_CONFIG

『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XDB_CONFIG」

Oracle XML DBの構成セッションを管理するためのPL/SQL API

DBMS_XDB_CONSTANTS

『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XDB_CONSTANTS」

Oracle XML DBで使用するPL/SQL定数

DBMS_XDB_REPOS

『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XDB_REPOS」

アプリケーション開発者が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_XMLSCHEMA_ANNOTATE

『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XMLSCHEMA_ANNOTATE」

Oracle固有のXML Schema注釈を追加および管理するためのPL/SQL API。

DBMS_XMLSTORAGE_MANAGE

『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XMLSTORAGE_MANAGE」

XML Schemaの登録後にXMLデータの記憶域を管理および変更するための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実装

11.2 PL/SQL DOM API for XMLType(DBMS_XMLDOM)

PL/SQL DOM API for XMLType (DBMS_XMLDOM)では、DOMを使用してXMLTypeインスタンスを操作できます。

関連項目:

各DBMS_XMLDOMメソッドの説明は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

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

World Wide Web Consortium (W3C)によって勧告されたドキュメント・オブジェクト・モデル(DOM)は、XML文書の構造にアクセスするための汎用APIです。

DOMは、XML文書の構造にアクセスするための汎用APIです。動的HTMLを使用すると、Webページのアニメーション、対話および動的更新が可能になります。DOMは、WebページおよびXML文書に、言語およびプラットフォームに依存しないオブジェクト・モデルを提供します。DOMは、XMLのコンポーネントおよび要素にアクセスおよび操作するための、言語およびプラットフォームに依存しないインタフェースを記述します。XML文書の構造を、コンテンツに依存しない汎用的な方法で表現します。XML文書のコンテンツ、属性およびスタイルを動的に削除、追加および編集するアプリケーションを作成できます。DOMによって、すべてのブラウザ、サーバーおよびプラットフォームで適切に動作するアプリケーションを作成できます。

11.2.1.1 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プログラマーズ・ガイド』

11.2.1.2 W3CのDOM勧告のサポート

XMLデータにアクセスして操作するためのすべてのOracle XML DB APIは、W3Cで承認された標準のXML処理要件に準拠しています。PL/SQL DOMは、W3CのDOM仕様のレベル1および2をサポートします。

- 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のOracleサポートは次のとおりです。

- 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の拡張機能を介してデータベースに完全に統合されています。

11.2.1.3 DOMとSAXの違い

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/を参照してください。

11.2.2 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およびC DOM API for XMLTypeは、W3CのDOM勧告に準拠して、リレーショナル列またはオブジェクト・リレーショナル列にXMLTypeの動的メモリー・インスタンスとして、XMLデータのオブジェクト・リレーショナル記憶域を定義および実装します。W3CのDOM勧告の詳細は、「PL/SQL DOM API for XMLTypeを使用するためのXMLデータの準備」 を参照してください。

11.2.2.1 XML Schemaのサポート

PL/SQL DOM API for XMLTypeは、XML Schemaをサポートしています。Oracle XML DBは、XML Schema内で注釈をメタデータとして使用し、XML文書およびその文書のデータベース・スキーマへのマッピングの両方を決定します。

注意:

下位互換性および柔軟性を得るために、PL/SQL DOMは、XML Schemaに基づく文書とスキーマに基づかない文書の両方をサポートします。

Oracle XML DBにXML Schemaが登録されると、PL/SQL DOM API for XMLTypeは、ノード・オブジェクトの階層として関連XML文書の動的メモリー内ツリー表現を構築します。各ツリー表現は、独自の特別なインタフェースを持ちます。多くのノード・オブジェクト型は子ノード型を持つことができ、これによって、さらに特別な追加のインタフェースを実装できます。ノード型には、様々な型の子ノードを持つことができるものと、子ノードを持つことができないリーフ・ノードがあります。

11.2.2.2 DOMのパフォーマンスの向上

Oracle XML DBは、DOMを使用して、複数のバックエンド・データ・ソースとXML間でデータを変換する標準的な方法を提供します。これによって、環境内の様々なデータ・ソースに個別のXML変換方法を使用する必要がなくなります。

XMLデータを交換する必要があるアプリケーションでは、単一のネイティブなXMLデータベースを使用して、XML文書をキャッシュできます。そのため、XML DBは、Webアプリケーションとバックエンド・データ・ソース間の中間キャッシュとして機能することによって、リレーショナル・データベース内かファイル・システム内かにかかわらず、アプリケーションのパフォーマンスを向上させることができます。

関連項目:

Java DOM API for XMLType

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

Oracle XML DBに基づくアプリケーションを構築する場合、Oracle XML Developer's Kit (XDK)で提供される追加のコンポーネントは必要ありません。ただし、エンドツーエンドで実行するXML対応アプリケーションの統合スイートをデプロイするために、XDKのコンポーネントとともにOracle XML DBを使用することはできます。

これらのXDK機能は、Oracle XML DBに基づくXMLアプリケーションを開発する場合に特に役立ちます。

- 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およびコンパイラ: コンパイルされたXSLスタイルシートを使用する、高パフォーマンスなCベースのXSLT変換エンジンを提供します。

- XML JavaBeans: Javaコンポーネントを使用して、XML文書を解析、変換、比較、取得および圧縮します。

関連項目:

『Oracle XML Developer's Kitプログラマーズ・ガイド』

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

XML Schemaを作成して、それに注釈を付けてXMLをSQLオブジェクトにマップして、XML Schemaを登録します。

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データを操作します。

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

XML SchemaをXML文書で参照できるようにするには、まず、Oracle XML DBに登録する必要があります。XML Schemaを登録すると、その中で宣言される要素および属性が、データベース内の対応するSQLオブジェクト型の属性にマップされます。

XML Schemaの登録完了後、このXML Schemaに準拠、および参照するXML文書をOracle XML DBで管理できます。準拠する文書を格納するための表および列を、このXML Schemaによって定義されたルート要素に対して作成できます。

関連項目:

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パッケージおよびタイプ・リファレンス』を参照してください。

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

XML Schema内で宣言された要素および属性は、対応するSQLオブジェクト型の個別の属性にマップされます。コメント、処理命令、名前空間、宣言および接頭辞など、XML文書内のエンコードされた他の情報は、直接表現されません。

このような追加情報を格納するため、SYS_XDBPD$というバイナリ属性が、生成されたすべてのSQLオブジェクト型に存在します。この属性では、元のXML文書内で、他のデータベース属性を使用して格納されないすべての情報が格納されます。このような補足情報を保持することで、Oracle XML DB内に格納されるXML文書のDOM再現性が保証されます。つまり、データベースから取得されるXML文書は、格納された元の文書と同じものです。

注意:

このマニュアルの多くの例では、簡略化のため属性SYS_XDBPD$を省略しています。ただし、この属性は、スキーマの登録によって生成されたSQLオブジェクト型に常に存在します。

関連項目:

「SYS_XDBPD$とオブジェクト・リレーショナル記憶域のDOM再現性」

11.2.6 XMLTypeビューによる既存データのXMLとしてのラップ

既存のリレーショナル・データおよびオブジェクト・リレーショナル・データをXMLアプリケーションで使用できるようにするには、それに基づいてXMLTypeビューを作成します。これにより、PL/SQL DOM APIを使用して結果のXMLデータにアクセスできます。

XMLとSQLオブジェクト型間のマッピングを表す注釈を含むXML Schemaを登録した後、このXML Schemaに準拠するXMLTypeを作成できます。

関連項目:

XMLTypeビュー

11.2.7 Oracle XML DBによってサポートされるDBMS_XMLDOMメソッド

いくつかの例外はありますが、Oracle XML DBでは、すべてのDBMS_XMLDOMメソッドがサポートされています。

次のメソッドはOracle XML DBでサポートされていません。

- writeExternalDTDToFile()

- writeExternalDTDToBuffer()

- writeExternalDTDToClob()

関連項目:

各DBMS_XMLDOMメソッドの説明は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

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

DOMでは、オブジェクトベースのツリー構造を作成するためのXML文書内の要素の使用方法が指定されます。これにより、XML文書に格納されたオブジェクトを管理および使用するためのインタフェースが定義されて公開されます。DOMは様々なシステムの文書の格納をサポートします。

DOM仕様では、ドキュメントという用語は、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

表11-2に、XMLおよびHTMLのノード型と、それに対応する使用可能な子ノード型を示します。

表11-2 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は、次のインタフェースも指定します。

- NodeListインタフェース: 次のような、順序付けられたノードのリストを処理します。

- ノードの子

- 要素インタフェースのgetElementsByTagName()メソッドによって戻された要素

- NamedNodeMapインタフェース: 要素の属性など、名前属性によって参照される、順序付けられていない一連のノードを処理します。

11.2.9 PL/SQL関数NEWDOMDOCUMENTおよびDOMDOCUMENTのノード

PL/SQL関数newDOMDocumentは、指定されたXMLType値でDOM文書ハンドルを構成します。結果のハンドルの型はDOMDocumentです。

PL/SQLアプリケーションの一般的な使用例は次のとおりです。

1. XMLTypeインスタンスのフェッチまたは構成

2. XMLTypeインスタンス上でのDOMDocumentノードの構成

3. DOM APIを使用したXMLデータへのアクセスおよび操作

注意:

DOMDocumentでは、ノード型はXMLフラグメントのデータ自体ではなく、XMLフラグメントへのハンドルを表します。

たとえば、ノード値をコピーすると、DOMDocumentによって、基礎となる同じデータへのハンドルもコピーされます。一方のハンドルによって変更されたデータは、もう一方のハンドルでアクセスしても参照できます。DOMDocumentハンドルが構成されたXMLType値はデータであり、このハンドルに対して行われたすべてのDOM操作の結果が反映されます。

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

DOMDocumentインスタンスの基礎となるドキュメント構造を変更した場合、変更はすべての適切なNodeListオブジェクトおよびNamedNodeMapオブジェクトに反映されます。

たとえば、DOMユーザーが要素の子を含むNodeListオブジェクトを取得し、その要素に子を追加(または子の削除や既存の子の変更)した場合、これらの変更は自動的にNodeListに伝播されます。同様に、ツリー内のノードへの変更は、NodeListオブジェクトおよびNamedNodeMapオブジェクトのノードへのすべての参照に伝播されます。

Text、CommentおよびCDATASectionインタフェースは、CharacterDataインタフェースを継承します。

11.2.11 PL/SQL DOM API for XMLType (DBMS_XMLDOM)の使用方法の概要

PL/SQLパッケージDBMS_XMLDOMの使用には、通常、DOM文書の作成、DOMツリーの検索と拡張、およびノードの作成と操作が関与します。

図11-1に、PL/SQL DOM API for XMLType (DBMS_XMLDOM)の使用方法を示します。

- DOM文書(DOMDocument)は、既存のXMLTypeから作成するか、または空の文書として作成できます。newDOMDocumentプロシージャが、XMLTypeインスタンスまたは空の文書を処理します。
これによって、DOMDocumentインスタンスが作成されます。

- DOM API PL/SQLメソッド(createElement()、createText()、createAttribute()、createComment()など)を使用して、DOMツリーを検索および拡張します。

- DOMElement()およびDOMText()などのPL/SQLメソッドの結果をPL/SQL関数makeNodeに渡して、DOMNodeインタフェースを取得することもできます。

図11-1 PL/SQL DOM API for XMLTypeの使用

11.2.12 PL/SQL DOM API for XMLTypeの例

PL/SQL DOM API for XMLTypeの使用例を示します。

このインタフェースを使用する際、DOMDocumentインスタンスごとにfreeDocumentプロシージャを必ずコールするようにしてください。このプロシージャにより、文書とそのノードがすべて解放されます。DOMDocumentインスタンスが解放された後でも、DOMDocumentインスタンスが構築されたXMLTypeインスタンスにアクセスできます。

例11-1では、動的メモリー内のXML文書の階層的な表現であるDOM文書を作成します。

例11-1では、DOM文書へのハンドルを使用して、操作、出力、一部の変更、および変更後の出力を行います。ハンドルによりDOM文書を操作すると、この文書で表現されるXMLデータにも間接的に影響するため、変更後にそのデータを問い合せると、変更した結果が示されます。

DOM文書は、PL/SQL関数newDOMDocumentを使用してXMLType変数から作成されます。この文書へのハンドルは、makeNode関数を使用して作成されます。また、この文書は、writeToBuffer関数を使用してVARCHAR2バッファに書き込まれ、さらに、このバッファは、DBMS_OUTPUT.put_lineを使用して出力されます。

様々なDBMS_XMLDOMプロシージャを使用してこの文書を操作した後、XMLType変数内の(変更された)データは表内に挿入され、問い合せることで変更を確認できます。データがデータベース表内に挿入されると、永続的になります。それまではメモリー内にのみ存在します。この永続性は、動的メモリー内の文書(DOMDocumentインスタンス)が解放されてからデータベース問合せが作成されるという事実からわかります。

例11-2では、空のDOM文書を作成し、要素ノード(<ELEM>)をこの文書に追加します。DBMS_XMLDOM APIノード・プロシージャを使用して、要素ノードの名前(<ELEM>)、値(NULL)および型(1 =要素ノード)を取得します。

例11-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.

例11-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

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

Oracle XML DBでは、抽象ストリームおよびストリーム操作の各メソッドが提供され、これらを使用して、64 KBを超えるXMLノードを処理できます。

Oracle Database 11gリリース(11.1)以前は、Oracle XML DBにより処理されるテキスト・ノードまたは属性値のサイズはそれぞれ64KBに制限されていました。リリース11.1以降、この制限はなくなりました。

このサイズ制限を克服し、ノードにグラフィック・ファイル、PDFファイル、およびマルチバイト文字エンコーディングを含めるには、次の抽象ストリームが使用できます。これらの抽象PL/SQLストリームは、対応するJavaストリームに類似しています。各入力ストリームには関連ライターまたはデータ・プロデューサがあり、各出力ストリームには関連リーダーまたはデータ・コンシューマがあります。

- バイナリ入力ストリーム: バイトの連続した(配列ではない)線形空間として、データ・コンシューマにはソース・データへの読取り専用アクセスが与えられます。コンシューマは、(表現内容を問わず)基礎となるバイナリ形式のソース・データに反復して読取りアクセスできます。つまり、変換されていないRAW形式のソース・データへ読取りアクセスします。コンシューマは、このバイト・シーケンスがノードに存在しているとみなします。ソース・データの形式や表現の指定はありません。特に、関連付けられたキャラクタ・セットはありません。

- バイナリ出力ストリーム: バイトの連続した(配列ではない)線形空間として、データ・プロデューサにはターゲット・データへの書込み専用アクセスが与えられます。プロデューサはバイナリ形式のターゲット・データに反復して書込みアクセスできます。つまり、データ・セマンティクスのない純粋なバイナリ形式でのターゲット・データへ書込みアクセスします。プロデューサはバイト・シーケンスを渡し、ターゲット・データはこれらのバイトと置換されます。データ変換は行われません。

- 文字入力ストリーム: 文字の連続した(配列ではない)線形空間として、データ・コンシューマには、ソース・データの表現や形式とは関係なくソース・データへの読取り専用アクセスが与えられます。ソース・データの変換は行われる場合も、行われない場合もあります。

- 文字出力ストリーム: 文字の連続した(配列ではない)線形空間として、データ・プロデューサはターゲット・データに反復して書込み専用アクセスができます。プロデューサは文字シーケンスを渡し、ターゲット・データはこの文字シーケンスと置換されます。渡されたデータの変換は行われる場合も、行われない場合もあります。

入力ストリームにはそれぞれ、open、read、closeという抽象メソッドがあります。出力ストリームにはそれぞれ、open、write、flush、closeという抽象メソッドがあります。出力ストリームについては、ノードが物理的に書き込まれる前にストリームを閉じる必要があります。

読取りおよび書込みには、4つの一般ノード・アクセス・モデルがあります。各アクセス・モデルには、バイナリ・バージョンとキャラクタ・バージョンの両方があります。データ型DOMNodeで定義されているバイナリ・ストリーム・メソッドおよび文字ストリーム・メソッドは、これらのアクセス・モデルを認識します。

アプリケーションはクライアントとして機能し、そのサービス・プロバイダとしてパーサーを使用します。パーサーのモードによって、ストリーム・データ・フローの起動元がパーサーであるか、アプリケーションであるかが決定されます。

- パーサーがプッシュ・モードである場合は、アプリケーションから出力ストリームのパーサーにデータがプッシュされて、要求した操作の結果がパーサーから戻されます。

- パーサーがプル・モードである場合は、アプリケーションによって、入力ストリームのパーサーからデータがプルされます。ストリームの各データ項目が、1つの解析イベントの結果となります。

アクセス・モデルはそれぞれ別の項で説明しており、パッケージDBMS_XMLDOMの大規模ノードで動作するPL/SQLのファンクションおよびプロシージャについても説明しています。各サブプログラムの名前は、データを読み取る(get)か書き込む(set)か、およびパーサーがプッシュ・モード(push)で使用されているか、プル・モード(pull)で使用されているかを反映しています。

- 大規模ノード処理の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を使用した大規模XMLノードの処理」を参照してください。

- 『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

- 大規模ノード処理のためのJava関数の詳細は、『Oracle Database XML Java API Reference』を参照してください。

- 大規模ノード処理のためのC関数の詳細は、『Oracle Database XML C APIリファレンス』 を参照してください。

11.2.14 大規模ノード処理のGet-Pushモデル

このモデルでは、プッシュ・モードのパーサーを使用して、DOMノードの値を取得します。Oracle XML DBでは、パーサーによって読み取られた出力ストリームにノード・データを書き込みます。

このモデルでノード値を読み取るため、バイナリ出力ストリームまたは文字出力ストリームが作成され、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で実行しているところを示しています。

例11-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
...

例11-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;

11.2.15 大規模ノード処理のGet-Pullモデル

このモデルでは、プル・モードのパーサーを使用して、DOMノードの値を取得します。Oracle XML DBでは、パーサーによって書き込まれた入力ストリームからイベント・データを読み取ります。

このモデルでノード値を読み取るため、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モデルの項で説明している定義済メソッドで読み取ることができる新しいPL/SQL SYS.utl_BinaryInputStreamのインスタンスを戻します。ノードのデータ型は、RAWまたはBLOBである必要があります。それ以外の場合は、例外が発生します。

FUNCTION getNodeValueAsCharacterStream (n IN DBMS_XMLDOM.domnode)
RETURN SYS.utl_CharacterInputStream;

このファンクションは、定義済メソッドで読み取ることができる新しいPL/SQL SYS.utl_CharacterInputStreamのインスタンスを戻します。ノード・データが文字の場合は、現在のセッションのキャラクタ・セットに変換されます。ノード・データが文字以外の場合は、まず文字データに変換されます。

例11-5では、ノード値をバイナリ・データとして50バイトずつ読み取っています。

例11-6では、ノード値を文字データとして50文字ずつ読み取っています。

例11-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;

例11-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;

11.2.16 大規模ノード処理のSet-Pullモデル

このモデルでは、取出しモードのパーサーを使用して、DOMノードの値を設定します。Oracle XML DBでは、パーサーによって書き込まれた入力ストリームからイベント・データを読み取ります。

このモードでノード値を書き込むため、バイナリ入力ストリームまたは文字入力ストリームが作成され、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セッションのキャラクタ・セットになります。

例11-7は、ノード値をMyBinaryInputStreamと呼ばれるユーザー定義サブタイプSYS.utl_BinaryInputStreamで定義されたreadメソッドで作成したバイナリ・データに設定しているところを示しています。

MyBinaryInputStream型のオブジェクトを使用して、ノード値を次のように設定できます。

DECLARE
istream     MyBinaryInputStream = MyBinaryInputStream ();
node        DBMS_XMLDOM.domnode;
...
BEGIN
...
-- This drives the read methods in MyBinaryInputStream
DBMS_XMLDOM.setNodeValueAsBinaryStream (node, istream);
...
END;

例11-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);

11.2.17 大規模ノード処理のSet-Pushモデル

このモデルでは、プッシュ・モードのパーサーを使用して、DOMノードの値を設定します。Oracle XML DBでは、パーサーによって読み取られた出力ストリームにノード・データを書き込みます。

このモードでノード値を新たに書き込むため、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セッションのキャラクタ・セットからノードのキャラクタ・セットに変換されます。

例11-8では、50バイトのセグメントをSYS.utl_BinaryOutputStreamに書き込むことで、ノード値をバイナリ・データに設定しています。

例11-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;

11.2.18 大規模ノード処理のバイナリ・ストリームか文字ストリームかの判断

サブプログラムDBMS_XMLDOM.useBinaryStreamを使用して、大規模ノードのコンテンツにアクセスする場合に文字ストリームを使用するか、バイナリ・ストリームを使用するかを判断します。

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を使用してのみアクセスできます。

11.3 PL/SQL Parser API for XMLType(DBMS_XMLPARSER)

PL/SQL Parser API for XMLType (DBMS_XMLPARSER)は、PL/SQL APIによってアクセス可能な解析結果ツリーを構築します。解析が正常に実行されない場合、エラーが発生します。

XMLパーサーまたはプロセッサというソフトウェア・モジュールは、XML文書を読み取り、その文書のコンテンツおよび構造にアクセスします。XMLパーサーは、他のモジュール(通常はアプリケーション)のかわりに作業を行います。

XML文書は、エンティティというデータの格納単位で構成され、各エンティティには解析対象または解析対象外のデータが含まれます。解析対象データは文字で構成され、その一部は文字データを構成し、その一部はタグとして機能します。タグ付けは、文書のデータ格納レイアウトおよび論理構造の記述をエンコーディングします。XMLは、データ格納レイアウトおよび論理構造を制約するメカニズムを提供します。

図11-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インタフェースを取得します。

図11-2 PL/SQL Parser API for XMLTypeの使用

例11-9では、単純なXML文書を解析します。XMLパーサー(DBMS_XMLPARSER.parserのインスタンス)を作成し、これを使用して、indoc変数のXML文書(テキスト)を解析します。解析によって、DBMS_XMLPARSER.getDocumentを使用してパーサーから取り出されるDOM文書が作成されます。文書全体を含んだDOMノードが作成され、そして、このノードが出力されます。DOM文書を解放(破棄)した後、DBMS_XMLPARSER.freeParserを使用して、パーサーのインスタンスが解放されます。

注意:

メソッドDBMS_XMLPARSER.setErrorLog()はサポートされません。

関連項目:

各DBMS_XMLPARSERメソッドの説明は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

例11-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>

11.4 PL/SQL XSLT Processor for XMLType(DBMS_XSLPROCESSOR)

PL/SQLパッケージDBMS_XSLPROCESSORを使用して、あるXML文書を別のXML文書に変換したり、XMLデータをHTML、PDFまたは他の形式に変換することができます。このパッケージは、DOMツリーで文書を検索して、それにExtensible Stylesheet Language Transformation (XSLT)文を適用して、変換された文書を生成します。

W3CのXSL勧告では、ソース・ツリーから結果ツリーへ変換する規則が記載されています。XSLで表現する変換は、XSLTスタイルシートと呼ばれます。指定した変換は、パターンをXSLTスタイルシートで定義したテンプレートに関連付けることで実行されます。結果ツリーの一部を作成するために、テンプレートはインスタンス化されます。XSLTは、XMLデータをWebブラウザで表示するために、HTMLに変換する場合にも広く使用されます。

注意:

Oracle XML DBアプリケーションには、個別のXMLパーサーは必要ありません。ただし、外部処理を必要とするアプリケーションでは、最初にXML Parser for PL/SQLを使用して文書構造を公開できます。Oracle XML Developer's KitのXML Parser for PL/SQLは、XML文書(または単独のDTD)を解析して、通常はクライアントで実行しているアプリケーションでこのXML文書を処理できるようにします。PL/SQL API for XMLTypeは、サーバーで実行され、データベースにネイティブに統合されたアプリケーションに使用されます。サーバーでアプリケーションを実行するメリットには、パフォーマンスの向上、アクセスや操作のオプションの拡張などが含まれます。

関連項目:

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

11.4.1 PL/SQL XSLT Processor for XMLType: 機能

PL/SQL XSLT Processor for XMLType (DBMS_XSLPROCESSOR)は、W3CのXSLT最終勧告(REC-xslt-19991116)に準拠します。これは単一のXSLスタイルシートを複数の文書に適用する便利で効率的な方法を提供します。

PL/SQLパッケージDBMS_XSLPROCESSOR内のメソッドでは、XSLプロセッサの実装に固有のPL/SQLデータ型である、PROCESSORおよびSTYLESHEETが使用されます。setErrorLog()メソッドの例外を除き、Oracle XML DBでは、すべてのDBMS_XSLPROCESSORメソッドがサポートされています。

関連項目:

各DBMS_XSLPROCESSORメソッドの説明は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

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

XSLTプロセッサを作成して、DOM文書からSTYLESHEETオブジェクトを構築して、プロセッサおよびスタイルシートを使用して文書を変換して、DOM API for XMLTypeを使用してXSLT処理の結果を操作します。

図11-3に、XSLT Processor for XMLType (DBMS_XSLPROCESSOR)の使用方法を示します。

図11-3 PL/SQL XSLT Processor for XMLTypeの使用

次の手順を実行します。

1. newProcessorを使用して、XSLTプロセッサを構成します。

2. newStylesheetを使用して、DOM文書からSTYLESHEETオブジェクトを構築します。

3. オプションとして、setParamsを使用してSTYLESHEETオブジェクトにパラメータを設定できます。

4. processXSLを使用して、このプロセッサおよびSTYLESHEETオブジェクトを使用しDOM文書を変換します。

5. PL/SQL DOM API for XMLTypeを使用して、XSLT処理の結果を操作します。

例11-10では、processXSLプロシージャを使用してXML文書を変換します。これは、同じパーサー・インスタンスを使用して、変換するXMLテキストとXSLTスタイルシートの2つの異なるDOM文書を作成します。XSLプロセッサ・インスタンスが作成され、このスタイルシートをソースのXMLに適用して、新しいDOMフラグメントを生成します。DOMノード(outnode)が、このフラグメントから作成され、このノードのコンテンツが出力されます。freeDocFrag、freeParserおよびfreeProcessorプロシージャをそれぞれ使用して、出力されたDOMフラグメント、パーサーおよびXSLTプロセッサ・インスタンスが解放されます。

例11-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>

12 PL/SQLパッケージDBMS_XMLSTORE

PL/SQLパッケージDBMS_XMLSTOREを使用して、オブジェクト・リレーショナル形式で格納されているXML文書でデータを挿入、更新または削除できます。これは、パッケージDBMS_XMLGENによって生成されるマッピングに類似した正規のXMLマッピングを使用します。これは、マッピングをオブジェクト・リレーショナルの構造体に変換し、対応する値をリレーショナル表で挿入、更新または削除します。

- DBMS_XMLSTOREパッケージの使用

- DBMS_XMLSTOREを使用したXML文書の挿入

- DBMS_XMLSTOREを使用したXMLデータの更新

- DBMS_XMLSTOREを使用したXMLデータの削除

12.1 DBMS_XMLSTOREパッケージの使用

コンテキスト・ハンドルを作成し、1つ以上の挿入、更新または削除を実行して、コンテキストを閉じます。

PL/SQLパッケージDBMS_XMLSTOREを使用するには、次の手順を実行します。

1. DBMS_XMLSTORE.newContext関数をコールし、DML操作に使用する表名を指定してコンテキスト・ハンドルを作成します。大/小文字を区別する場合は、関数に渡す文字列に二重引用符(")で囲みます。

デフォルトでは、XML文書は<ROW>タグで行を識別します。これは、XMLデータの生成時にDBMS_XMLGENパッケージで使用されるデフォルトと同じです。この動作は、setRowTag関数を使用してオーバーライドできます。

2. (オプション) 1つ以上の挿入、更新または削除を実行します(この手順は繰り返すことができます)。

- 挿入の場合、パフォーマンスを向上させるには、列ごとにDBMS_XMLSTORE.setUpdateColumnプロシージャをコールして、挿入する列リストを指定できます。デフォルト動作では(列のリストを指定しない場合)、対応する要素がXML文書内に存在しているすべての列に値が挿入されます。

- 更新の場合、関数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によって識別される行内のすべての列が更新されます。

- 削除の場合、削除する行を識別するために、(擬似)キー列を指定します。これは更新する行の指定と同じ方法で行います(前述を参照)。

3. PL/SQL関数のinsertXML、updateXMLまたはdeleteXMLに文書を指定します。この手順を複数のXML文書に対して繰り返すことができます。

4. DBMS_XMLSTORE.closeContext関数をコールしてコンテキストをクローズします。

12.2 DBMS_XMLSTOREを使用したXML文書の挿入

PL/SQLパッケージDBMS_XMLSTOREを使用して、XML文書を表またはビューに挿入できます。これにより、文書が解析されて、値のバインド先のINSERT文が作成されます。デフォルトでは、XML文書内の要素で表されるすべての列に値が挿入されます。

例12-1では、DBM_XMLSTOREを使用して、2人の新入社員に関する情報をemployees表に挿入します。挿入する情報は、XMLデータとして提供されています。

例12-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.

12.3 DBMS_XMLSTOREを使用したXMLデータの更新

PL/SQLパッケージDBMS_XMLSTOREを使用して、既存のデータを更新(変更)できます。行を識別するのにまとめて使用される列ごとにsetKeyColumnプロシージャを1回ずつコールして、更新する行を指定します。(SQLでは、UPDATE文のWHERE句を使用して行を指定します。)

この列のセットは、キー列と同様に機能し、組み合せて使用することにより、更新する一意の行を指定します。ただし、(setKeyColumnとともに)使用する列は、表内のキーである必要はありません。行を一意に指定するかぎり、setKeyColumnへのコールとともに使用できます。

例12-2では、DBM_XMLSTOREを使用して情報を更新します。この例では、従業員番号188の名前が誤って「Kelly」として記録されていると仮定し、この名前を「Pat」に訂正します。employee_id列が、employees表の主キーであるため、更新用に一意の行を識別するには、employee_id列を指定するsetKeyColumnへの1回のコールで十分です。

次のUPDATE文は、例12-2で使用されているDBM_XMLSTOREと同等です。

UPDATE hr.employees SET first_name = 'Pat' WHERE employee_id = 188;

例12-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.

12.4 DBMS_XMLSTOREを使用したXMLデータの削除

PL/SQLパッケージDBMS_XMLSTOREを使用して、既存のデータを削除できます。行を識別するのにまとめて使用される列ごとにsetKeyColumnプロシージャを1回ずつコールして、削除する行を指定します。(SQLでは、UPDATE文のWHERE句を使用して行を指定します。)

例12-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.

13 Java DOM API for XMLType

Java DOM API for XMLTypeでは、DOMを使用してXMLTypeインスタンスを操作できます。これを使用すると、Java Database Connectivity (JDBC)を介してXMLデータをフェッチするなど、JavaでXMLデータを操作できます。

- Java DOM API for XMLTypeの概要

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

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

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

- Java DOM API for XMLTypeの機能

- Thick接続を使用したJava DOM APIに対するMS Windows Javaセキュリティ・マネージャの権限

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

- Java DOM API for XMLTypeのクラス

- 非推奨またはサポート外になったXMLTypeのクラスとメソッドのJava DOM API

- Java DOM API for XMLTypeの使用

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

- バイナリXMLでのJava DOM APIおよびJDBCの使用

関連項目:

「XQueryとXQJを使用したデータベース・データへのアクセス」

13.1 Java DOM API for XMLTypeの概要

Oracle XML DBはJava Document Object Model (DOM) Application Program Interface (API) for XMLTypeをサポートします。これはXML Schemaに基づく文書とスキーマに基づかない文書の両方に対する、クライアントおよびサーバー用の汎用APIです。

DOMは、XML文書のメモリー内ツリーベースのオブジェクト表現で、要素および属性へのプログラム・アクセスを可能にします。DOMオブジェクトおよびインタフェースは、W3C勧告の一部です。 PL/SQL API for XMLTypeで説明したとおり、Oracle XML DB DOM APIは、W3CのDOMレベル1.0およびレベル2.0のコア勧告に準拠しています。

Java DOM API for XMLTypeでは、Oracle XML DBに格納されたすべての整形式のXML文書を処理します。XML文書は、XML Schemaに基づくかどうか、および基礎となるXMLType記憶域モデルの形式に関係なく、同様に表示されます。Java DOM APIは、クライアントおよびサーバーの両方で動作します。

Java DOM API for XMLTypeを使用すると、別のキャラクタ・セットでエンコードされたデータからXMLTypeインスタンスを作成できます。

Java DOM API for XMLTypeを使用して、JavaアプリケーションからOracle XML DBリポジトリに格納されたXML文書にアクセスできます。ネーミングは、W3CのDOM勧告で指定されている、DOMへのJavaバインディングに準拠しています。リポジトリには、XML Schemaに基づくドキュメントおよび基づかないドキュメントの両方を含めることができます。

JDBCを使用してXMLTypeデータにアクセスするには、クラスoracle.xdb.XMLTypeを使用します。

Java DOM API for XMLTypeは、Javaパッケージoracle.xml.parser.v2を使用して実装されます。

関連項目:

『Oracle Database XML Java API Reference』

13.2 JDBCを使用したXMLTypeデータへのアクセス

Java Database Connectivity (JDBC)は、Oracle XML DB内のXML文書など、Oracle Database内のすべてのデータにアクセスするための、Javaアプリケーション用のSQLベースの方法です。

XMLデータを作成するには、oracle.xdb.XMLType JavaクラスのcreateXML()メソッドを使用します。

注意:

入力としてストリームを引き渡す場合は、メソッドXMLType.createXML()とThickドライバを使用してください。この場合、Thinドライバは使用できません。

XMLデータのJDBC 4.0標準データ型はjava.sql.SQLXMLです。getObject()メソッドでは、oracle.xdb.XMLType型のオブジェクトが戻されます。Oracle Database 11gリリース2 (11.2.0.3)から、oracle.xdb.XMLTypeがインタフェースjava.sql.SQLXMLを実装しています。

13.2.1 JDBCを使用したOracle XML DB内のXML文書へのアクセス

JDBCユーザーは、XMLType表を問い合せて、SQL XMLTypeデータ型でサポートされるすべてのSQL/XML関数をサポートするJDBC XMLTypeインタフェースを取得できます。Java(JDBC)API for XMLTypeインタフェースは、DOMDocumentインタフェースを実装できます。

例13-1に、JDBCを使用してXMLType表を問い合せる方法を示します。

次のいずれかの方法で、JDBCを使用してXMLTypeデータを選択できます。

- SQLでSQL/XML関数XMLSerializeを使用し、Javaでoracle.sql.CLOB、java.lang.Stringまたはoracle.sql.BLOBとして結果を取得します。例13-2のJavaスニペットに、これを示します。

- PreparedStatementでメソッドgetObject()をコールして、XMLTypeインスタンス全体を取得します。このメソッドの戻り値は、oracle.xdb.XMLType型です。これによって、XMLTypeクラスでJava関数を使用して、データにアクセスできます。この方法を例13-3に示します。

例13-3では、getObject()メソッドを使用してResultSetからXMLTypeインスタンスを直接取得します。

例13-4では、XMLType型の出力パラメータをSQL文にバインドします。この出力パラメータは、XMLTypeデータ型として登録されます。

例13-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();
}

例13-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
}

例13-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();
}

例13-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;
}
}
}

13.3 JDBCを使用したXMLデータベース文書の操作

Oracle XML DBで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インスタンスを作成します。例13-5に、これを示します。

- PreparedStatementでsetObject()を使用して、XMLTypeインスタンス全体を設定します。例13-6に、これを示します。

XMLType値を選択すると、JDBCによって、列が不透明型として記述されます。列型の名前を選択し、それをXMLTYPEと比較すると、XMLTypeインスタンスを処理しているかどうかを確認できます。例13-7に、これを示します。

例13-8では、XMLType列に格納されているPurchaseOrder要素内のdiscount要素を更新します。ここではJDBCおよびoracle.xdb.XMLTypeクラスを使用します。XMLパーサーを使用してDOMツリーを更新し、更新されたXML値をXMLType列に書き込みます。

例13-9は、例13-8から得られる更新済の発注書を示します。

例13-10では、次のものがすべて処理されます。

- XMLType表からのXMLTypeインスタンスの選択

- XPath式に基づくXMLTypeインスタンスの一部の抽出

- 要素の有無の確認

- XSLに基づく別のXML形式へのXMLTypeインスタンスの変換

- XML Schemaに対するXMLType文書の妥当性の確認

例13-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();

例13-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();

例13-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 instance
}

例13-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;

例13-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>

例13-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));
}
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);
}
}
}

13.4 JDBCを使用した、データベースへの大規模なXML文書のロード

Java Database Connectivity (JDBC)を使用して大規模なXML文書をデータベースにロードするには、Java CLOBオブジェクトを使用して文書を保持し、JavaメソッドinsertXML()を使用して挿入します。

大規模なXML文書(通常4000文字を超える場合)がJDBCのStringオブジェクトを使用してXMLTypeの表または列に挿入されると、次のランタイム・エラーが発生します。

"java.sql.SQLException: Data size bigger than max size for this type"

このエラーは、JavaのCLOBオブジェクトを使用して大規模なXML文書を保持することで回避できます。例13-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)

JavaメソッドinsertXML()は、メソッドgetCLOB()をコールして、XMLデータを格納するCLOBオブジェクトを作成して戻します。getCLOB()メソッドの仮パラメータは例13-12で定義され、次のとおりです。

- xmlData - XMLType列に挿入するXMLデータ

- conn - データベース接続オブジェクト(Oracle Connection Object)

関連項目:

『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』

例13-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();
}
}

例13-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;
}

13.5 Java DOM API for XMLTypeの機能

Java DOM API for XMLTypeは、XMLオブジェクトの子およびプロパティ(名前、名前空間など)を取得するために、文書内でのディープ検索およびシャロウ検索をサポートします。これにより、アプリケーションはその場で(動的に)作成するなど、XML文書をプログラムで作成できます。そのような文書は、登録されたXML Schemaに準拠することもあれば、しないこともあります。

Java API for XMLTypeはDOM 2.0勧告に準拠し、名前空間を認識します。

JavaクラスXMLDocumentおよびXDBDocument(非推奨)は、W3Cドキュメント・オブジェクト・モデル(DOM)・インタフェースのインスタンスです。このドキュメント・インタフェースからドキュメントの要素にアクセスすると、W3CのDOM勧告に指定されたすべての操作を実行できます。DOMは、次のものに対して機能します。

- XML Schemaに基づく、基づかないに関係なく、あらゆる種類のXML文書

- 文書で使用される次のいずれかの形式の基礎となる記憶域

- バイナリ・ラージ・オブジェクト(Binary Large Object: BLOB)

- オブジェクト・リレーショナル

Java DOM APIを使用してOracle XML DBからXMLデータを取得する場合:

- 接続がThinの場合は、XMLDocumentインスタンスを取得します。

- 接続がThickまたはkprbの場合は、getDOM()メソッドでXDBDocumentインスタンスを、getDocument()メソッドでXMLDocumentインスタンスを取得します。getDOM()メソッドとXDBDocumentクラスは非推奨になりました。

13.6 Thick接続を使用したJava DOM APIに対するMS Windows Javaセキュリティ・マネージャの権限

アプリケーションのセキュリティ・ポリシーを実装するためにMS Windows上でJavaセキュリティ・マネージャ(クラスSecurityManager)を使用する場合は、Thick接続でJava DOM API for XMLTypeを使用するために、特定の権限をセキュリティ・ポリシー・ファイルに追加する必要があります。

例13-13では、このようなポリシー・ファイルの内容を示しています。ここで、c:\myworkspaceはOracle XML DBに関連するJARを含むワークスペース・フォルダです。(ポリシー・ファイルは、同じフォルダにある必要があります。)

例13-13で使用しているライブラリは、orageneric12およびoraxml12です。最後の2文字(ここでは12)は、データベースのメジャー・リリース番号に対応している必要があります(したがって、たとえばOracle Database 13 リリース2の場合、orageneric13とoraxml13を使用します)。

ポリシー・ファイルを作成すると、次のコマンドライン・スイッチを使用してプログラムを呼び出すことができます。

-Djava.security.manager=default -Djava.security.policy=c:\myworkspace\ojdbc.policy

例13-13 Java DOM APIの権限を付与するポリシー・ファイル

grant codeBase "file:c:\myworkspace" {
permission java.lang.RuntimePermission "loadLibrary.orageneric12";
permission java.lang.RuntimePermission "loadLibrary.oraxml12";
}

grant codeBase "file:c:\myworkspace\xdb6.jar" {
permission java.lang.RuntimePermission "loadLibrary.orageneric12";
permission java.lang.RuntimePermission "loadLibrary.oraxml12";
}

grant codeBase "file:c:\myworkspace\ojdbc6.jar" {
permission java.lang.RuntimePermission "loadLibrary.orageneric12";
permission java.lang.RuntimePermission "loadLibrary.oraxml12";
}

13.7 XML Schemaに基づく文書の作成

XML Schemaに基づく文書を作成するには、Java DOM API for XMLTypeの拡張機能を使用して、使用するXML Schema URLを指定します。また、作成中の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に基づく文書の場合)

例13-14では、Java DOM API for XMLTypeを使用してDOMオブジェクトを作成し、関連するXML Schemaで指定された形式で格納します。この例では、XML Schemaに対する検証は示されていません。

例13-14 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();

13.8 Java (JDBCまたはSQLJ)でのXMLTypeインスタンス表現

XMLTypeインスタンスは、oracle.xdb.XMLTypeによってJavaで表現されます。XMLTypeインスタンスがJDBCまたはSQLJのクライアントを使用してフェッチされると、このインスタンスは提供されたXMLTypeクラスのオブジェクトとして自動的に明示されます。

このクラスのオブジェクトは、データ操作言語(DML)文の値としてバウンドできます。通常、この値はXMLTypeです。

13.9 Java DOM API for XMLTypeのクラス

Oracle XML DBは、W3CのDOMレベル2勧告をサポートします。また、アプリケーションとOracle XML Developer's Kit for Javaの相互作用を容易にするOracle固有の拡張機能も提供します。Java DOM API for XMLTypeでは、W3C DOMインタフェースを実装するクラスが提供されます。

Oracleの拡張機能のリストは、次のURLを参照してください。

http://www.oracle.com/technetwork/database-features/xmldb/overview/index.html

XMLDocumentは、インスタンス化されたXML文書用のDOMを表すクラスです。Document引数を取るXMLTypeコンストラクタを使用して、XML文書からXMLTypeインスタンスを取得できます。

XMLType createXML(Connection conn, Document domdoc)

表13-1に、Java DOM API for XMLTypeのクラスおよび実装されるW3CのDOMインタフェースを示します。Java DOM APIクラスは、oracle.xml.parser.v2パッケージに入っています。

表13-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

13.10 非推奨またはサポート外になったXMLTypeのクラスとメソッドのJava DOM API

Oracle Database 11gリリース1より前のリリースで使用されていたXMLTypeのJava DOM APIのいくつかのクラスとメソッドは、非推奨になったか、サポートが停止されました。

Oracle Database 9i (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を使用

13.11 Java DOM API for XMLTypeの使用

XMLType表または列からデータを取得し、そこからJava XMLDocumentインスタンスを取得します。Java DOM API for XMLTypeを使用して、データのDOMツリーの要素を操作します。

図13-1に、Java DOM API for XMLTypeの使用方法を示します脚注1。次の手順を実行します。

1. XMLType表または表のXMLType列からXMLデータを取り出します。XMLデータをフェッチすると、OracleによってXMLTypeインスタンスが作成されます。これにより、getDocument()メソッドを使用してXMLDocumentインスタンスを取得できます。

2. Java DOM API for XMLTypeを使用してDOMツリーの要素を操作します。変更されたデータはXMLTypeインスタンスに格納されますが、データはJDBC更新を使用して戻されます。

XMLTypeおよびXMLDocumentインスタンスは、各クラスでclose()メソッドを使用してクローズする必要があります。クローズすると、保持されていた基礎となるメモリーがすべて解放されます。

図13-1 Java DOM API for XMLTypeの使用

13.12 Javaを使用した大規模XMLノードの処理

Oracle XML DBでは、抽象ストリームおよびストリーム操作の各メソッドが提供され、これらを使用して、64 KBを超えるXMLノードを処理できます。Thickまたはkprb接続でJavaクラスXMLNodeおよびXMLAttrを使用して、大規模ノードを操作します。

注意:

大規模ノード機能は、Thickまたはkprb接続でのみ動作します。Thin接続では動作しません。

Oracle Database 11gリリース(11.1)以前は、Oracle XML DBにより処理されるテキスト・ノードまたは属性値のサイズはそれぞれ64KBに制限されていました。リリース11.1以降、この制限はなくなりました。

以前ノードのサイズが制限されていたのは、ノード値を設定および取得するJavaメソッドでjava.lang.String型の引数のみがサポートされていたためです。文字列の最大サイズはJava VMの実装により依存していますが、限定されています。リリース11.1以前は、oracle.xdb.dom.XDBNode.javaクラス内に含まれているノード値を管理するJava DOM APIは次のようになっていました。

public String getNodeValue ();
public void setNodeValue (String value);

リリース11.1以前は、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では拡張され、任意のサイズのテキスト・ノード値およびバイナリ・ノード値をサポートしています。

関連項目:

- 大規模ノードにおけるPL/SQLの使用方法の詳細は、「DBMS_XMLDOMを使用した大規模ノード処理」を参照してください。

- 非推奨のXDBNodeクラスおよびXDBAttributeクラスの詳細は、「非推奨またはサポート外になったXMLTypeのクラスとメソッドのJava DOM API」を参照してください。

13.12.1 Java DOMへのストリーム拡張

Java String、Reader、およびWriterデータはすべてUCS2で表現されます。これは、データベース・キャラクタ・セットと同じではない場合があります。また、ノード文字データはキャラクタ・セットIDでタグ付けされており、ノード値が移入するときに設定されます。

次に示すoracle.xml.parser.v2.XMLNode.javaのメソッドにより、サイズが64KBを超えるノードにアクセスできます。リーフ・ノード(属性、PI、CDATAなど)ではないノードを取得または設定しようとすると、これらのAPIにより例外が発生します。また、その値を実際に書き込み、ノードへのストリーム・アクセス状態を維持する場合に使用するリソースを解放するclose()を使用してください。

13.12.1.1 Get-Pullモデル

メソッドgetNodeValueAsBinaryStream()およびgetNodeValueAsCharacterStream()を使用して、取出しモードのパーサーによってDOMノードの値を取得できます。Oracle XML DBでは、パーサーによって書き込まれた入力ストリームからイベント・データを読み取ります。

バイナリ入力ストリームの場合:

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
}
...

13.12.1.2 Get-Pushモデル

このモデルでは、プッシュ・モードのパーサーを使用して、DOMノードの値を取得します。Oracle XML DBでは、パーサーによって読み取られた出力ストリームにノード・データを書き込みます。

バイナリ出力ストリームの場合:

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にプッシュされます。

13.12.1.3 Set-Pullモデル

このモデルでは、取出しモードのパーサーを使用して、DOMノードの値を設定します。Oracle XML DBでは、パーサーによって書き込まれた入力ストリームからイベント・データを読み取ります。

バイナリ入力ストリームの場合:

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からノードのキャラクタ・セットに変換されます。

13.12.1.4 Set-Pushモデル

このモデルでは、プッシュ・モードのパーサーを使用して、DOMノードの値を設定します。Oracle XML DBでは、パーサーによって読み取られた出力ストリームにノード・データを書き込みます。

バイナリ出力ストリームの場合:

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()メソッドをコールするときのみ反映されます。

13.13 バイナリXMLでのJava DOM APIおよびJDBCの使用

Java DOM API for XMLおよびJava Database Connectivity (JDBC)を使用して、Oracle XML DBに対して、バイナリXMLとしてエンコードされたXMLデータを読書きできます。この処理には通常の読書きプロシージャが関与します。

XMLデータは、データ型XMLTypeを使用してOracle XML DBに格納でき、この抽象データ型の記憶域モデルの1つが、XMLデータの簡潔なXML Schema対応のエンコーディングであるバイナリXMLです。バイナリXMLはデータベース内のXMLTypeの記憶域モデルとして使用することができますが、データベース外にあるXMLデータに対しても使用することができます。XMLデータのクライアント側処理には、Oracle XML DB内に格納されているデータや、データベース外に存在する一時データが関わることがあります。

バイナリ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データに対して操作します。

例13-15に、これを示します。

関連項目:

- 「XMLType記憶域モデル」

- 『Oracle XML Developer's Kitプログラマーズ・ガイド』

例13-15 バイナリ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");
}
}

脚注の凡例

脚注1:
ここでは、XMLデータがXML Schemaに登録済であり、XMLTypeの列に格納されていると想定しています。

14 C API for XML

C DOM API for XMLTypeでは、CでDOMを使用してXMLTypeインスタンスを操作できます。

- C API for XMLの概要

- OCIを使用したデータベースに格納されているXMLTypeデータへのアクセス

- クライアントでのXMLTypeインスタンスの作成

- C DOM API関数のXMLコンテキスト・パラメータ

- XMLコンテキストの初期化および終了

- バイナリXMLでのC API for XMLの使用

- Oracle XML DBでのOracle XML Developer's Kit Pull Parserの使用

- Cでの一般的なXMLType操作

14.1 C API for XMLの概要

C API for XMLは、Oracle XML Developer's Kit (XDK)およびOracle XML DBで使用されるDOM APIです。データベース内外のXMLデータに対してこれを使用できます。

DOMは、World Wide Web Consortium (W3C)のDOM 2.0勧告に準拠していることを示しています。

C API for XMLには、XDKで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)インタフェースは、将来のリリースで非推奨になる予定です。

XMLデータの操作に使用できるCおよびC++のApplication Programming Interface (API)のリファレンス・ドキュメントは、『Oracle Database XML C APIリファレンス』および『Oracle Database XML C++ APIリファレンス』です。

関連項目:

- PL/SQL API for XMLの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- Java APIs for XMLの詳細は、『Oracle Database XML Java API Reference』を参照してください。

14.2 OCIを使用したデータベースに格納されている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コンテキスト・パラメータ」

14.3 クライアントでのXMLTypeインスタンスの作成

C DOM APIメソッドのXMLCreateDocument()およびXmlLoadDom()を使用して、クライアント側に新しいXMLTypeインスタンスを構成できます。

XMLCreateDocument()を使用して、空のXMLTypeインスタンスを構成できます。これは、他の型に対してOCIObjectNew()を使用するのに類似しています。

次のように、XmlLoadDom()を使用して、空でないXMLTypeインスタンスを構成します。

1. 例14-1に示すように、xmlctxを初期化します。

2. ユーザー・バッファ、ローカル・ファイルまたはURIからXMLデータを構成します。これらの戻り値は(xmldocnode *)で、他の一般的なC APIで使用できます。

3. 必要に応じて、(xmldocnode *)を(void*)にキャストし、バインド値として直接提供できます。

14.4 C DOM API関数のXMLコンテキスト・パラメータ

XMLコンテキストは、すべてのC DOM API関数に必須のパラメータです。このOPAQUE型のコンテキストは、データ・エンコーディング、エラー・メッセージの言語などに関係する情報をカプセル化します。コンテキストの内容は、Oracle XML Developer's KitアプリケーションおよびOracle XML DBに対して異なります。

Oracle XML DBでは、OCI関数OCIXmlDbInitXmlCtx()でXMLコンテキストを初期化し、OCIXmlDbFreeXmlCtx()でXMLコンテキストを終了します。

14.4.1 OCIXmlDbInitXmlCtx()の構文

OCI関数OCIXmlDbInitXmlCtx()は、XMLコンテキストを初期化します。

OCIXmlDbInitXmlCtx()の構文は次のとおりです。

xmlctx *OCIXmlDbInitXMlCtx (OCIEnv        *envhp,
OCISvcHp      *svchp,
OCIError      *errhp,
ocixmldbparam *params,
ub4           num_params);

表14-1に、パラメータを示します。

表14-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から読み取るパラメータ数。

14.4.2 OCIXmlDbFreeXmlCtx()の構文

OCI関数OCIXmlDbFreeXmlCtx()は、XMLコンテキストを終了します。

xctx (IN)パラメータが終了対象のXMLコンテキストである場合のOCIXmlDbFreeXmlCtx()の構文は次のとおりです。

void OCIXmlDbFreeXmlCtx (xmlctx *xctx);

14.5 XMLコンテキストの初期化および終了

C DOM APIを使用してXML文書を構成し、Oracle Databaseにこれを保存するCプログラムの例を示します。

例14-1に、これを示します。構成された文書は、表my_tableに格納されます。OCI関数のOCIXmlDbInitXmlCtx()およびOCIXmlDbFreeXmlCtx()は、それぞれXMLコンテキストを初期化および終了するために使用されます。これらの関数は、ヘッダー・ファイルocixmldb.hで定義されます。

コードでは、ここには示されていない、ヘルパー関数のexec_bind_xml、init_oci_handlesおよびfree_oci_handlesが使用されます。ヘルパー関数を含む、この例の完全なリストは、Oracleが提供するXML Schemaおよび例の「XMLコンテキスト(OCI)の初期化および終了」を参照してください。

例14-1のCコードでは、データベース・スキーマcapiuserでmy_table表を作成するため、次のSQLコードを最初に実行したことを前提としています。

CONNECT CAPIUSER
Enter password: password

Connected.

CREATE TABLE my_table OF XMLType;

例14-4では、my_table表を問い合せ、例14-1で挿入されたデータを表示します。

例14-1 OCIXMLDBINITXMLCTX()およびOCIXMLDBFREEXMLCTX()の使用

#ifndef S_ORACLE
#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 */
static sword exec_bind_xml(OCISvcCtx *svchp,
OCIError *errhp,
OCIStmt *stmthp,
void *xml,
OCIType *xmltdo,
OraText *sqlstmt);

/* Helper function 2: Initialize OCI handles and connect */
static sword init_oci_handles(test_ctx *ctx);

/* Helper function 3: Free OCI handles and disconnect */
static 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.

14.6 バイナリXMLでのC API for XMLの使用

C APIを使用して、Oracle XML DBに対して、バイナリXML形式でエンコードされたXMLデータを読み書きすることができます。この処理には通常の読書きプロシージャが関与します。

バイナリXMLはXMLデータの簡潔な、XML Schema対応のエンコーディングです。バイナリXMLはデータベース内のXMLTypeデータの記憶域モデルとして使用できますが、データベース外にあるXMLデータにも使用することができます。

バイナリXMLデータはXML Schemaに対応しており、必要に応じて、各種のコード体系を使用できます。バイナリXMLデータを操作するには、関連するXML Schemaとエンコーディングについて、データとこのメタデータの両方が必要です。

データベースに格納されているXMLTypeデータの場合、このメタデータもデータベースに格納されます。ただし、データベースとデータのセットアップに応じて、メタデータが適用されるデータと同一のサーバーにメタデータが格納されない場合があります。この場合、データベースに対してバイナリXMLデータを読書きするためには、次の手順を実行する必要があります。

1. メタデータのコンテキスト・インスタンスを作成します。

2. このコンテキストを、データベース内のバイナリXMLデータにアクセスするために使用するデータ接続に関連付けます。データ接続は、専用接続(OCISvcCtx)でも接続プール(OCICPool)でもかまいません。

すると、アプリケーションがデータ接続上でバイナリXMLデータをエンコードまたはデコードする必要がある場合、それに必要なメタデータが自動的にフェッチされます。例14-2に示すように、一連の動作の全体は次のとおりです。

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データに対して操作します。

関連項目:

- 「XMLType記憶域モデル」

- 『Oracle XML Developer's Kitプログラマーズ・ガイド』

例14-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
static void checkerr(OCIError *errhp, sword status);
static sword create_env(OraText *user, ub2 user_len, OraText *pwd, ub2 pwd_len,
OCIEnv **envhp, OCISvcCtx **svchp, OCIError **errhp);
static sword run_example(OCIEnv *envhp, OCISvcCtx *svchp, OCIError *errhp,
OCIDuration dur);
static 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;
}

static 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;
}

static 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 */
. . .
}

14.7 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の検証もできます。

例14-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プログラマーズ・ガイド』を参照してください。

例14-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

14.8 Cでの一般的なXMLType操作

一般的なXML操作は、C API for XMLによって提供されます。

表14-2に、一般的なXML操作のXMLType関数を示します。

表14-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に関する項を参照してください。

例14-4では、DOMを使用して、発注された特定部品のインスタンスの数を判別する方法を示します。対象となる部品は、Id 37429158722です。ヘルパー関数exec_bind_xml、free_oci_handlesおよびinit_oci_handlesの定義は、 Oracleが提供するXML Schemaおよび例の例A-6を参照してください。

例14-4 DOMを使用した発注部品のカウント

#ifndef S_ORACLE
#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 */
static sword exec_bind_xml(OCISvcCtx *svchp,
OCIError *errhp,
OCIStmt *stmthp,
void *xml,
OCIType *xmltdo,
OraText *sqlstmt);

/* Helper function 2: Initialize OCI handles and connect */
static sword init_oci_handles(test_ctx *ctx);

/* Helper function 3: Free OCI handles and disconnect */
static 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

15 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 XML

- ODP.NETとのXMLTypeデータの使用

15.1 Oracle XML DBとODP.NET XML

ODP.NETでは、Oracle XML DBを介して、データベースでXMLデータがネイティブにサポートされます。

ODP.NET:

- XMLデータをXMLTypeとしてOracle Databaseにネイティブに格納します。

- Oracle DatabaseからMicrosoftの.NET環境まで、リレーショナル・データおよびオブジェクト・リレーショナル・データにXMLデータとしてアクセスし、Microsoftの.NET Frameworkを使用してXMLを処理します。

- XMLデータを使用して、変更内容をデータベース・サーバーに保存します。

- 次のXML固有のクラスが提供されます。

- OracleXmlType

- OracleXmlStream

- OracleXmlQueryProperties

- OracleXmlSaveProperties

- クラスOracleCommand、OracleConnectionおよびOracleDataReaderを拡張します。

15.2 ODP.NETとのXMLTypeデータの使用

データベースから.NETにXMLTypeデータを渡す例を示します。

例15-1では、データベースから.NETにXMLTypeデータが取り出され、結果が出力されます。

関連項目:

Oracle XML DBに対するOracle .NETサポートの詳細は、『Oracle Data Provider for .NET開発者ガイドfor Microsoft Windows』を参照してください。

例15-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);

第V部 XML Schemaとオブジェクト・リレーショナルXMLType

XML Schemaの使用方法とXMLTypeデータのオブジェクト・リレーショナル記憶域について説明します。

次の章で構成されています。XML Schemaの格納と問合せ: 基本

- XMLType記憶域および索引付けの選択

- XML Schemaの格納と問合せ: 基本

- オブジェクト・リレーショナル記憶域のXPathリライト

- XML Schemaの格納と問合せ: オブジェクト・リレーショナル記憶域

- XML Schemaの拡張

16 XMLType記憶域および索引付けの選択

アプリケーションの設計では、使用するXMLType記憶域モデルおよび使用する索引付けの方法を選択することも重要です。

- XMLType記憶域モデルと索引付けの方法の選択に関する概要

- XMLTypeのユースケースの範囲: データ中心からドキュメント中心

- XMLTypeとして格納されるXMLデータの一般的なユースケース

- XMLType記憶域オプション: 相対的なメリット

- XMLTypeの索引付けについての考慮事項

- XMLType記憶域オプション: 相対的なメリット

16.1 XMLType記憶域モデルと索引付けの方法の選択に関する概要

XMLTypeとは、XMLデータおよびその使用を最適にするための様々な記憶域モデルと索引付けモデルを提供する抽象SQLデータ型です。抽象データ型であるため、アプリケーションおよびデータベース問合せの柔軟性が増し、同じインタフェースをすべてのXMLType操作に使用できます。

アプリケーションが異なれば、XMLデータの使用方法も異なります。これは、リレーショナル・データソースから構築されることもあり、比較的構造化されています。これは抽出、変換およびロード(ETL)操作に使用されることもあり、その場合もきわめて構造化されます。書籍や記事のように、書式自由の文書(非構造化、または半構造化)に使用される場合もあります。

データの種類が異なれば、検索の方法も異なります。データ中心のユースケースでは固定の問合せセットを伴うことが多く、ドキュメント中心のユースケースでは任意の(非定型)問合せを伴う場合が多くなります。

XMLの使用方法は多岐にわたるため、どのようなユースケースでも最適なパフォーマンスと柔軟性が得られる万能の記憶域モデルはありません。Oracle XML DBには、XMLTypeに2つの記憶域モデルがあり、これらの記憶域モデルごとに適切な索引付け方法のアプローチがいくつかあります。パフォーマンスと機能は、使用しているXMLデータの種類とその使用方法に最も適するように調整できます。

したがって、どのXMLデータにどのXMLType記憶域モデルを使用するかということが、重要な決定事項の1つです。この章の内容は、特定のユースケースに最適な記憶域オプションを選択する際に役立ちます。

XMLType表および列は、次の方法で格納できます。

- バイナリXML記憶域 - これは、事後解析の永続性とも呼ばれます。これが、Oracle XML DBのデフォルトの記憶域モデルです。XMLデータに特化して設計された事後解析型のバイナリ形式です。バイナリXMLは、簡潔でXML Schema対応です。バイナリXML記憶域の最大の利点は、柔軟性です。XML Schemaに基づく文書にも、XML Schemaに基づかない文書にも使用できます。きわめて多様なデータを許可する、あるいは変化が激しい、または予測できないXML Schemaに対して使用できます。この記憶域モデルには、効率的な部分更新と、ストリーミング可能な問合せ評価の機能もあります。

- オブジェクト・リレーショナル記憶域 - これは、構造化記憶域、オブジェクトベースの永続性とも呼ばれます。この記憶域モデルは、エンティティ関連(ER)のXMLデータ分解を表します。既知で多かれ少なかれ固定の問合せセットを伴い、高度に構造化されたデータに対して最高のパフォーマンスを発揮します。問合せのパフォーマンスはリレーショナル・データのパフォーマンスに一致し、更新はインプレースで実行できます。

注意:

Oracle Database 12cリリース1 (12.1.0.1)以降、XMLType用の非構造化(CLOB)記憶域モデルは非推奨です。バイナリXML記憶域をかわりに使用してください。

CLOBデータとして格納されている既存のXMLTypeデータがある場合は、Oracle GoldenGateを使用して、それをバイナリXML記憶域の形式に移動することを検討してください。特定のXML文書について文書の再現性が重要な場合は、そのコピーをCLOB列に格納します。

Oracle XML DBは、XMLTypeデータに対して次の種類の索引をサポートします。

- オブジェクト・リレーショナル記憶域でのBツリー・ファンクション索引

- バイナリXML記憶域でのXML検索索引

- バイナリXML記憶域での構造化および非構造化コンポーネントを含むXMLIndex

- バイナリXML記憶域でXMLIndex (構造化および非構造化コンポーネントの両方)に対して自動的に作成されるセカンダリ表でのBツリー索引

ユースケースが異なれば、必要なXMLType記憶域モデルと索引の組合せも異なります。

関連項目:

- XMLTypeデータの索引

- 「XMLType記憶域オプション: 相対的なメリット」

16.2 XMLTypeのユースケースの範囲: データ中心からドキュメント中心

XMLType記憶域モデルを選択する際には、XMLデータの性質とその使用方法を検討します。ユースケースには、データ中心の程度が最も高いものからドキュメント中心の程度が最も高いものまでの範囲があります。

図16-1ではこのことについて説明しています。ここでは、データ中心の程度が最も高いケースを左端に、ドキュメント中心の程度が最も高いケースを右端に示しています。

図16-1 XMLのユースケースとXMLType記憶域モデル

データ中心データは高度に構造化されており、構造は比較的静的および予測可能で、アプリケーションはその構造を好材料として活用します。データはXML Schemaに準拠しています。

ドキュメント中心のデータは、次の2つの場合に分けられます。

- データは一般に構造がないか、可変構造を持っています。これには、構造化された部分と非構造化の部分が両方ある文書も含まれます。文書の構造が時間とともに変わる場合(拡張)や、テキスト・ノードと子要素の両方を含めて多数の要素があり、内容が混在する場合(半構造化)があります。多数のXML要素が欠落していたり、異なった順序で表示されたりすることがあります。ドキュメントはXML Schemaに準拠している場合もしていない場合もあります。

- データは比較的構造化されていますが、アプリケーションはその構造の長所を活用しません。つまり、構造がないかのようにデータを処理します。

16.3 XMLTypeとして格納されるXMLデータの一般的なユースケース

XMLTypeとして格納されるXMLデータの一般的なユースケースに対応するアプリケーション・ユースケースの推奨事項を示します。

ユースケースが一般的な場合、ここで説明されていなければ、この章の他の項で特殊なケースに関する情報を参照してください。

注意:

この項で扱うのは、XMLTypeとして永続的に保持されているXMLデータの一般的な使用方法です。XMLデータの一般的なユースケースの1つが、リレーショナル・データからのXMLデータの生成です。これはリレーショナル記憶域を伴い、生成されるXMLデータは必ずしも永続的に保持されないため、ここでは扱いません。

(生成されたXMLデータがXMLTypeとして永続的に保持される場合については、「XMLTypeのユースケース: ETLのステージを経たXMLデータ」を参照してください。)

関連項目:

- 「XMLTypeの索引付けについての考慮事項」

- XMLType記憶域オプション: 相対的なメリット

16.3.1 XMLTypeのユースケース: XMLフラグメントの更新または問合せがない

このユースケースでは、データベースに格納されているXMLデータのフラグメントを更新または問い合せる必要がありません。

このユースケースには、次のオプションがあります。

- バイナリXML記憶域を使用して、XMLTypeとして格納します。

- リレーショナルBLOBまたはCLOB列、可能であればSecureFiles LOBに格納します。

XMLデータをXMLTypeとしてではなくリレーショナルLOB列に格納する場合、Oracle Databaseではデータが解析されず、その妥当性を保証できません。(そのデータに対してXMLType操作は実行できません。)

16.3.2 XMLTypeのユースケース: 異なるXML Schemaを持つ多様なソースからのデータ統合

XMLデータが、異なるXML Schemaを使用する複数のデータソースから取得される場合は、バイナリXML記憶域を使用します。

このユースケースには、3つの下位ケースがあります。

- XMLデータに予測可能な構造化データのアイランドが含まれ、問合せが既知の場合には、構造化コンポーネントを含むXMLIndexを使用し、(これらのアイランドの周囲にあるのが非構造化データでも)構造化アイランドを索引付けします。構造化された索引コンポーネントに、使用する問合せが反映されます。このようなユースケースの例が、RSSニュース・アグリゲータです。

- このような構造化アイランドがない場合、または問合せが事前には未知である(非定型)場合、非構造化コンポーネントを含むXMLIndexを使用してください。

- 全文検索を伴う問合せを使用する場合は、XQueryプラグマora:no_schemaとともに、XML検索索引を使用します。

関連項目:

- 「XMLIndex構造化コンポーネント」

- 「XMLIndex非構造化コンポーネント」

- 「全文問合せ用のXMLデータの索引付け」および「Oracle XQuery拡張式プラグマ」

16.3.3 XMLTypeのユースケース: ETLのステージを経たXMLデータ

このユースケースでは、データが外部ソースから抽出され、操作のニーズに応じて変換され(通常はリレーショナル)、最後にデータベースにロードされます(抽出、変換、ロード(ETL))。特に、変換の際にはこのユースケースを利用します。

ETLのユースケースでは多くの場合、異なるソフトウェアやハードウェア・システムを使用する複数の当事者によって維持またはホストされている複数のアプリケーションからデータを統合します。抽出されたデータは、変換を担当する当事者または変換後に使用する当事者とは別の当事者が担当することが少なくありません。

これに伴うXMLデータは通常、高度に構造化されており、XML Schemaに準拠しています。このユースケースでは、XMLデータからのリレーショナル・データ生成も、リレーショナル・データからのXML生成も扱います。

ETLユースケースのサブセットでは、XMLデータの効率的な更新が必要です。更新には、XML文書全体の置換や、文書のフラグメントのみに対する変更(部分更新)が伴うことがあります。

このユースケースに適しているのは通常、XMLTypeデータのオブジェクト・リレーショナル記憶域です。

関連項目:

- XMLデータのリレーショナル・ビュー

- リレーショナル・データからのXMLデータの生成

16.3.4 XMLTypeのユースケース: 半構造化XMLデータ

このユースケースでは、XMLデータが可変フォームであるか、またはその大部分が明確に定義されていません。関連付けられているXML Schemaがない可能性もあれば、XML Schemaできわめて多様なデータを許可する、または変化が激しい、または予測できない可能性もあります。

このユースケースに適しているのは通常、XMLTypeデータのバイナリXML記憶域です。

問合せパスが既知の場合には構造化コンポーネントXMLIndexの索引付けを使用し、パスが事前に既知でない(非定型問合せ)場合にはパスサブセット化された非構造化コンポーネントXMLIndexの索引付けを使用します。XQuery全文問合せには、XML検索索引を使用します。

関連項目:

- 「XMLIndex構造化コンポーネント」

- 「XMLIndex非構造化コンポーネント」

- 「全文問合せ用のXMLデータの索引付け」

16.3.5 XMLTypeのユースケース: ビジネス・インテリジェンス問合せ

XMLデータに対するビジネス・インテリジェンス(BI)問合せを有効にするには、SQL/XML関数XMLTableを使用して、仮想表の列としてデータに含まれる値を予測します。次に、分析関数ウィンドウでSQL ORDER BYおよびGROUP BYを使用して、仮想表の列を操作します。

ビジネス・インテリジェンス問合せの場合、通常は次の操作をすべて実行します。

- XMLTypeデータをバイナリXMLとして格納する。

- 構造化コンポーネントが含まれるXMLIndex索引を使用する。

- SQL/XML関数XMLTableを使用してデータに対するリレーショナル・ビューを作成し、ビューでBIアプリケーションに関連する列をすべて予測する。

- これらのリレーショナル・ビューに対してアプリケーション問合せを記述する。

これらのビューに1対1対応でXMLIndex索引が作成される場合、そのビューに対する問合せはXMLIndex構造化コンポーネントのリレーショナル表に対する問合せに、Oracle Databaseによって自動的に変換され、リレーショナルのパフォーマンスが発揮されます。

仮想表の列に対して分析関数ウィンドウ、ORDER BYまたはGROUP BYを使用すると、これらの操作が構造化コンポーネントXMLIndex表で対応する物理的な列に対するウィンドウ、ORDER BYおよびGROUP BY操作に変換されます。

関連項目:

- 「XMLIndex構造化コンポーネント」

- XMLデータのリレーショナル・ビュー

16.3.6 XMLTypeのユースケース: 全文検索を伴うXML問合せ

アプリケーションでXMLデータに対する全文検索を実行する必要がある場合は、バイナリXML記憶域を使用して、問合せに対応するXML検索索引を作成します。

関連項目:

「全文問合せ用のXMLデータの索引付け」

16.4 XMLType記憶域モデルについての考慮事項

ほとんどのユースケースでXMLTypeのバイナリXML記憶域を使用することをお薦めします。オブジェクト・リレーショナル記憶域は特殊なケースに適しています。

次の条件がすべて満たされないかぎり、オブジェクト・リレーショナル記憶域は適しません。

- 特定のXMLType列または表に格納する予定であるXML文書すべての詳細なデータ形式を厳格に指定するXML Schemaがある。アプリケーションがデータ中心である。

- XML Schemaが、インプレースのスキーマ拡張を許可しない形で頻繁に拡張されない。

- データが特にスパースではない(空または欠落している要素を多数含んでいない)。

- XML文書をすべて同時に挿入または選択する必要がない。部分更新や部分選択が一般的である。

- 文書の再現性が必要とされない(DOM再現性で十分)。

表16-1に、この詳細を示します。XMLType記憶域モデルの選択に関してここで提示するガイドラインは独立したものではないため、各行は、条件列の条件が満たされるまで、示されている順序のとおりに適用してください。

表16-1 XMLType記憶域モデルについての考慮事項

条件

操作

1. 文書の再現性のプロパティが必要なため、元の空白をすべて維持する。

データベース用とXML処理用に、バイナリXML記憶域を使用します。ただし、元の文書のコピーもCLOB (リレーショナル)列に格納します。

(自身でデータを更新する場合、2つのバージョンの同期は自己責任です。)

2. XMLデータの一部のみを選択または更新する必要がほとんど皆無である。かわりに、通常はXML文書をすべて同時に挿入または選択する。

バイナリXML記憶域を使用します。

3. 同じXMLType表または列にある別のXML Schemaに準拠するXMLTypeインスタンスを格納する必要がある。

(Oracle XML DBがXML Schemaを使用してXML問合せやその他の処理を最適化できなくなるため、このような処理は一般的に推奨されません。)

バイナリXML記憶域を使用します。

4. データにXML Schemaがない。

バイナリXML記憶域を使用します。

XML Schemaの検証によってデータに利点があると考えられる場合には、スキーマ生成ツールを使用してXML Schemaを生成するかどうかを検討してください。

5. XML Schemaが頻繁に、または予測されない形で拡張され、インプレースのXML Schema拡張によるメリットを得られない。

インプレース拡張は通常、変更によって既存の文書が無効にならず、記憶域モデルの変更を伴わない場合にのみ許可されます。 XML Schemaの拡張を参照してください。

バイナリXML記憶域を使用します。

XML Schemaを更新するには、PL/SQLプロシージャDBMS_XMLSCHEMA.copyEvolveを使用します。

6. XMLデータが非常にスパースである。

バイナリXML記憶域を使用します。

7. XML Schemaが、要素anyやchoiceなどの構造体を使用せず、データ形式の詳細な仕様が提供されない。

(XML Schemaジェネレータを使用すると、生成されるスキーマにはこのような構造体が含まれることが多い。)

オブジェクト・リレーショナル記憶域を使用します。

8. XML Schemaを変更して、XMLデータ構造の厳格な定義を妨げるanyやchoiceなどの構造体を削除できる。

そのような構造体を削除し、オブジェクト・リレーショナル記憶域を使用します。

9. そのような構造体を削除できない。

バイナリXML記憶域を使用します。

16.5 XMLTypeの索引付けについての考慮事項

XMLTypeデータがオブジェクト・リレーショナル形式で格納されている場合は、リレーショナル・データの場合とまったく同じように、Bツリー・ビットマップ索引を作成します。バイナリXMLとして格納されているXMLTypeデータにはXMLIndex索引付けを使用します。

ドキュメント中心XMLデータの一般的な索引付けでは、非構造化コンポーネントとともにXMLIndexを使用します。これは、非定型(任意)の問合せに適しています。

データに、頻繁に問い合せる予測可能な部分が含まれる場合は、それらの部分に対して構造化コンポーネントを含むXMLIndexを使用します。このユースケースの例として、通常は書式自由だが著者、日付、タイトルについては固定フィールドを持つような仕様があります。

通常は構造化されていないコンテンツ内の構造のアイランドを処理するは、構造化および非構造化コンポーネントの両方を含む1つのXMLIndex索引を作成します。両方のコンポーネントを使用する可能性のあるユースケースとして、構造化データが存在するときは文書からXMLフラグメントを抽出するような問合せをサポートする場合などがあります。索引の構造化コンポーネントは、問合せで構造化データの有無を確認するWHERE句の条件に使用されます。非構造化コンポーネントは、フラグメントの抽出に使用されます。

表16-2に、バイナリXMLとして格納されているXMLTypeデータの索引付けの簡単なガイドラインを示します。これらのガイドラインは独立しているので、「条件」に書かれた条件が満たされる場合には、索引付けの方法を組み合せて使用できます。

表16-2 XMLTypeの索引付けについての考慮事項

条件

操作

データに予測可能な構造化データのアイランドが含まれている。

構造化アイランドのそれぞれに対する構造化コンポーネントを含むXMLIndexを使用します。

全文問合せをサポートする必要がある。

XML検索索引を使用します。

述語を含む非定型XML問合せをサポートする必要がある。

非構造化コンポーネントを含むXMLIndexの使用

16.6 XMLType記憶域オプション: 相対的なメリット

それぞれのXMLType記憶域モデルには、独自の長所と短所があります。

表16-3に、XMLTypeの各記憶域モデルの長所と短所をまとめます。(+)と(-)の記号は、それぞれ長所と短所を大まかに示しています。

表16-3 XMLType記憶域モデル: 相対的なメリット

品質

バイナリXML記憶域

オブジェクト・リレーショナル記憶域

スループット

(+)高いスループット。高速なDOMロード。バイナリ・エンコーダ/デコーダからのオーバーヘッドが多少発生します。

(-) XML分解では、XML文書のコンテンツ全体の収集または取出し時のスループットが低下する場合があります。

索引付けのサポート

XMLIndexとXML検索索引。

特定の要素または属性に対するBツリー索引、ビットマップ索引、およびOracle Text索引。

問合せ

(+) XMLIndexを使用するときに高速です。索引を使用できない問合せは、ストリーミングXPath評価を使用し、これも高速になります。

(++)リレーショナル問合せのパフォーマンス。基礎となるオブジェクト・リレーショナル列に対してBツリー索引を作成できます。

更新操作(DML)

(+)インプレースのピース単位更新(SecureFiles LOB記憶域の場合)。

(++)リレーショナル更新のパフォーマンス。列はインプレースで更新されます。

データの柔軟性

(+) XMLType列または表に格納可能なXML文書の構造に柔軟性があります。

(-)柔軟性は制限されます。XML Schemaに準拠する文書のみ格納できます。

XML Schemaの柔軟性

(++) XML Schemaに基づく文書とXML Schemaに基づかない文書のどちらも格納できます。登録されている任意のXML Schemaに準拠する文書を、同じXMLType表または列で格納できます。

(-)同じXML Schemaに準拠する文書のみを、特定のXMLType表または列に格納できます。

挿入時の検証

(++) XML Schemaに基づくデータは挿入時に完全に検証されますが、時間がかかります。

(+) XMLデータは挿入時に部分的に検証されます。

圧縮と暗号化

(+) SecureFiles LOB記憶域を持つバイナリXMLは、圧縮/暗号化が可能です。

(++)各XML要素/属性を個々に圧縮/暗号化できます。

17 XML Schemaの格納と問合せ: 基本

XML Schemaとは、XML文書のコンテンツおよび構造を記述するための標準です。Oracle XML DBで使用するXML Schemaは、登録、更新および削除できます。XML Schemaに基づくデータに使用する記憶域構造を定義し、XML Schemaデータ型をSQLデータ型にマッピングできます。

XML Schema勧告はXML文書のコンテンツおよび構造を記述するためにWorld Wide Web Consortium (W3C)で作成されました。これには既存のDocument Type Definitions (DTD)をXML Schemaに変換できるように、すべてのDTDの機能が含まれています。XML schemaにはDTDにはない追加機能があります。

- XML Schemaの概要

- Oracle XML DBにおけるXML Schemaの使用方法の概要

- Oracle XML DBへのXML Schemaの登録

- XML Schemaに基づくXMLType表および列の作成

- XML Schemaインスタンス・ドキュメントの識別方法

- XML Schemaデータ型のOracle XML DB記憶域へのマッピング

関連項目:

- Oracle XML DBでのXML Schemaの使用に関する高度な情報は、 XML Schemaの格納と問合せ: オブジェクト・リレーショナル記憶域を参照してください。

- Oracle XML DBでのXPath式の最適化の詳細は、 オブジェクト・リレーショナル記憶域のXPathリライトを参照してください。

- http://www.w3.org/TR/xmlschema-0/ - XML Schemaの概要

17.1 XML Schemaの概要

W3CのXML Schema勧告では、一連のXML文書の構造、コンテンツおよび特定のセマンティクスを指定するための標準化された言語が定義されています。XML Schemaは、XML文書のクラスを示すメタデータとみなすことができます。

XML Schema勧告については、http://www.w3.org/TR/xmlschema-0/を参照してください。

このドキュメントで、XML SchemaとはXML Schemaインスタンス定義を指します。

17.1.1 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文書です。

17.1.2 XML Schemaの機能

XML Schemaは、要素と属性の厳密な型指定のために、47のスカラー・データ型を定義しています。これは、オブジェクト指向の継承および拡張をサポートしているため、基本データ型から複合オブジェクトを持つXML Schemaを設計できます。これには、定義および順序付けの構造体、デフォルト値、必須コンテンツ、ネスト、セットの繰返しおよび再定義が含まれます。

Oracle XML DBは、XML Schemaで定義されたすべての構造体をサポートします(redefinesを除く)。

17.1.3 XMLインスタンス・ドキュメント

XML Schemaに準拠するドキュメントは、そのXML Schemaで定義されたクラスのインスタンスとみなすことができます。XML Schemaの一般的な用途は、指定されたそのようなインスタンス・ドキュメントがXML Schemaで定義されたルールに準拠していることを確認することです。

17.1.4 XML名前空間とXML Schema

XML Schemaには、targetNamespace属性を指定でき、その値にはURLを指定します。省略されている場合、スキーマにターゲット名前空間はありません。ターゲット名前空間は、XML Schemaで定義されているすべてのものの名前空間です。targetNamespace値は、通常、XML SchemaにアクセスできるURLです。

XMLインスタンス・ドキュメントには、ドキュメントのルート要素の名前空間(インスタンスが準拠しているXML Schemaのターゲット名前空間と同一)、およびこのルート要素を定義するXML Schemaの場所(URL)が指定されている必要があります。この情報は、属性xsi:schemaLocationで指定されます。XML Schemaにターゲットのネームスペースがない場合は、xsi:noNamespaceSchemaLocation属性を使用してXML Schema URLを指定します。

17.1.5 XML Schemaの編集の概要

XML Schemaは、任意の方法で作成および編集できます。

たとえば、次のいずれかを使用できます。

- Emacsやviなどの簡単なテキスト・エディタ

- Oracle JDeveloperに付属のXMLエディタなど、XML Schema対応のエディタ

- Altova社のXMLSpyなどの明示的なXML Schema作成ツール

図17-1は、発注書XML SchemaのXMLSpyでの編集を示しています。XMLSpyは、Altova社のグラフィカルなXMLツールで、XML SchemaおよびXML文書の作成と編集に使用できます。詳細は、http://www.altova.comを参照してください。脚注1

図17-1 XML Schema Purchase-OrderのXMLSpyによるグラフィカル表現

17.2 Oracle XML DBにおけるXML Schemaの使用方法の概要

Oracle XML DBは、XML Schemaの登録、XML Schemaに対する文書の検証、SQLオブジェクト型からのXML Schemaの生成、XML SchemaからSQLへのマッピング、XML Schemaに基づく表、ビューおよび列の作成および問合せ、およびXML Schemaに基づく文書がOracle XML DBリポジトリに挿入されたときのデータの自動挿入をサポートしています。

XML Schemaは、それらを参照するXML文書と同じように、XMLTypeインスタンスとしてOracle XML DBに格納されます。データベースに格納されるXMLデータとともにXML Schemaを使用するには、そのXML SchemaをOracle XML DBに登録する必要があります。

Oracle XML DBは、厳密な型指定などのXML Schemaの機能を利用して、XMLデータベース・データを安全かつ効率的に処理します。

Oracle XML DBに登録するには、XML SchemaがルートXML Schema、すなわちXDBSchema.xsdに準拠している必要があります。これは、Oracle XML DB XML SchemaのXML Schemaです。Oracle XML DBリポジトリの場所で、/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBSchema.xsdにあるXDBSchema.xsdにアクセスできます。

Oracle XML DBはメタデータとして注釈付きXML Schemaを使用します。標準XML Schema定義は、いくつかのOracle名前空間属性で定義された属性とともに使用されます。これらの属性は、データベースへのXMLインスタンス文書のマッピング方法を決定します。これらの属性は、XML Schemaの名前空間とは異なる名前空間に存在するため、注釈付きXML SchemaはXML Schema標準に準拠します。

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リポジトリに挿入される場合に行う、デフォルト表へのデータの自動挿入。

17.2.1 XML SchemaをOracle XML DBとともに使用する理由

XML Schemaを使用する一般的な理由は、検証、制約定義、記憶域の指定、および文書の挿入、格納およびアクセスの最適化などです。

- XML Schemaの最も一般的な用途は、XMLインスタンス・ドキュメントが指定のXML Schemaに準拠していることを確認する、つまりXMLデータがその意図された定義に準拠していることを確認するメカニズムとして使用することです。この定義にはデータ型、許容される項目の出現回数および項目の長さが含まれます。

- XML Schemaは、XMLType表または列の作成時に制約としても使用できます。たとえば、表または列を、XML Schemaで定義されたいずれかのグローバル要素に準拠するXML文書の格納用に制限できます。

- Oracle XML DBでは、XML Schemaを、XMLTypeインスタンスのコンテンツをデータベース内に格納する方法を定義するメカニズムとしても使用します。XMLTypeのバイナリXML記憶域モデルとオブジェクト・リレーショナル記憶域モデルは、いずれもXML Schemaの使用をサポートしています。XMLTypeデータをオブジェクト・リレーショナル形式で格納するとき、XML Schemaデータ型をSQLデータ型およびオブジェクト・リレーショナル形式の表および列に効率的にマップするためにXML Schemaが使用されます。

- プロトコルFTPおよびHTTP(S)を使用して、XML Schemaに基づく文書をOracle XML DBに格納する場合、XML Schema情報によって文書の挿入の効率も向上します。

- 事前情報なしにXMLインスタンスを処理しなければならない場合、XML Schemaを使用すると、最適な格納、再現性およびアクセスを予測できます。

関連項目:

「XMLType記憶域モデル」

17.2.2 ネーミング、マッピングおよび記憶域を制御するためのXML Schemaの注釈付けの概要

W3CのXML Schema勧告では、ベンダー固有の注釈をXML Schemaに追加できます。Oracle XML DBでは、注釈を使用して、XML Schemaと各種データベース・オプションの間のマッピングを制御します。注釈を使用して、XMLデータを格納する表を指定できます。注釈は、オブジェクト・リレーショナル記憶域で特に役立ちます。

Oracle XML DBでXML Schema注釈を使用すると、次の操作が可能です。

- XMLデータを格納するデータベース表の指定

- XML Schemaデータ型とSQLデータ型(オブジェクト・リレーショナル記憶域の場合)の間のデフォルト・マッピングの上書き

- XMLデータを格納するために作成されるデータベース・オブジェクトおよび属性の命名(オブジェクト・リレーショナル記憶域の場合)

例A-2に、注釈付き発注書XML Schemaを示します。これには、2つのXML名前空間が定義されています。

- http://www.w3c.org/2001/XMLSchema。これは、W3CによってSchema for Schemasのために予約されています。

- http://xmlns.oracle.com/xdb。これは、オラクル社によってOracle XML DBのスキーマ注釈用に予約されています。

XML Schemaに注釈を付けるには、最初にOracle XML DB名前空間を宣言する必要があります。Oracle XML DB名前空間は、http://xmlns.oracle.com/xdbです。例A-2では、名前空間接頭辞xdbを使用して、Oracle XML DB名前空間を短縮しています。

例A-2では、次のものを含めていくつかのXML Schema注釈を使用しています。

- PurchaseOrder要素内のdefaultTable注釈。このXML Schemaに準拠するXML文書をpurchaseorderというデータベース表に格納することを指定します。

- SQLType注釈。
SQLTypeの注釈が最初に出現したとき、complexType要素PurchaseOrderTypeから生成されたSQLデータ型の名前をpurchaseorder_tと指定します。

2番目の注釈SQLTypeでは、complexType要素LineItemTypeから生成されたSQLデータ型の名前をlineitem_tと指定します。

- SQLCollType注釈。これは、LineItem要素のコレクションを管理するSQL VARRAY型の名前がlineitem_vであることを指定します。

- SQLName注釈。purchaseorder_tの各SQLオブジェクト属性の明示的な名前を提供します。

図17-2に、XMLSpyの「Oracle」タブを示します。このタブを使用すると、グラフィカル・エディタでの作業中にOracle XML DBの注釈をXML Schemaに容易に追加できます。

図17-2 XMLSpyにおけるOracle XML DB Schema注釈のサポート

17.2.3 DOM再現性

DOM再現性は、XML文書内のすべての情報が、無意味な空白を除いて維持されていることを意味します。DOM再現性を使用すると、Oracle XML DBに格納されたXML文書の精度および整合性を保証できます。

ドキュメント・オブジェクト・モデル(DOM)の再現性とは、DOM検索のために、取得されたXML文書を元のXML文書と同じ構造に保持するという概念です。

DOM再現性がある場合、データベースから取得されたXMLデータは、無意味な空白のみを除いて、データベースに挿入される前と同一の情報を持ちます。「DOM再現性」という用語が使用されるのは、この種類の再現性はDOM検索で特に重要だからです。

XMLデータのバイナリXML記憶域では、重要な情報のすべてがバイナリXML形式にエンコードされ、DOM再現性を保証しています。

関連項目:

DOM再現性と、XMLデータのオブジェクト・リレーショナル記憶域の詳細は、「SYS_XDBPD$とオブジェクト・リレーショナル記憶域のDOM再現性」を参照してください。

17.2.4 XMLTypeのXML Schema関連メソッド

XML Schema操作のための最も重要なXMLTypeメソッドは、isSchemaBased()、getSchemaURL()、schemaValidate()、isSchemaValid()、isSchemaValidated()およびsetSchemaValidated()です。

表17-1 XMLTypeのXML Schema関連メソッド

XMLTypeのメソッド

説明

isSchemaBased()

XMLTypeインスタンスがXML Schemaに基づいている場合は、TRUEが戻されます。それ以外の場合は、FALSEが戻されます。

getSchemaURL()

XMLTypeインスタンスのXML Schema URL。

schemaValidate()
isSchemaValid()
isSchemaValidated()
setSchemaValidated()

登録されているXML Schemaに対するXMLTypeインスタンスの検証: 検証、検証ステータスのチェック、または記録された検証ステータスの設定。 XMLTypeデータの変換および検証を参照してください。

17.3 Oracle XML DBへのXML Schemaの登録

XML SchemaをOracle XML DBで使用するには、登録する必要があります。その後、これを使用して、XMLType表および列を作成したり、XML文書を検証することができます。スキーマ登録が失敗した場合、データベースは登録を試行する前の状態に復元されます。

すべてのDDL操作と同様に、XML Schema登録は、非トランザクション的なものです。しかし、登録は、次の意味において、アトミックです。

- 登録が正常に終了した場合、操作は自動コミットされます。

- 登録が失敗した場合、データベースは登録開始前の状態にロールバックされます。

XML Schemaの登録では、オブジェクト型および表が作成される可能性があるため、エラー・リカバリでは作成されたすべての型と表が削除されます。XML Schemaの登録プロセス全体はアトミックであることが保証されます。つまり、正常に終了するか、またはデータベースが登録の開始前の状態に復元されます。

XML SchemaをOracle XML DBに登録するには、次の2つの項目が必要です。

- XML Schema文書。

- Oracle Databaseに登録後、XML Schemaの一意の識別子として使用できる文字列。この一意の識別子は、XML Schemaで定義されたクラスのメンバーとしてXMLインスタンス・ドキュメントを識別するために使用されます。通常、識別子はURLの形式を取り、多くの場合、スキーマの場所を示すヒントまたは文書の場所を示すヒントとして参照されます。

注意:

XML Schemaを登録しても、Oracle XML DBリポジトリにすでにロードされておりXML Schemaを参照するインスタンス文書の状態には影響しません。

そのようなインスタンス・ドキュメントは、ロード時にXML Schemaに基づかないものとして扱われました。そのままの状態です。スキーマの登録後、XML Schemaに基づく文書を取得するには、そのような文書を削除して再ロードする必要があります。

17.3.1 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表および列を作成できます。

17.3.2 Oracle XML DBへのXML Schemaの登録

PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaを使用してXML Schemaを登録する例を示します。このプロシージャの主なパラメータは、スキーマURL、スキーマ・ソース・ドキュメント、ソース・ドキュメントのエンコーディングのキャラクタ・セットID、およびスキーマの登録方法を指定するオプションです。

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が使用されることを示します。もう1つのオプションはREGISTER_NT_AS_IOTで、これはOCTを索引構成表(IOT)として格納します。

関連項目:

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

例17-1では、例A-2の注釈付きXML Schemaを登録しています。

A-2では、XML Schemaの一意の識別子は次のとおりです。

http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd

XML Schema文書は、すでにOracle XML DBリポジトリ(/source/schemas/poSource/xsd/purchaseOrder.xsd)にロードされています。

XML Schemaの登録時に、PL/SQLコンストラクタXDBURITypeがリポジトリ内のXML Schema文書の場所に基づいてXML Schema文書のコンテンツにアクセスすることを、オプションSCHEMADOCで指定します。プロシージャregisterSchemaに渡される他のオプションによって、例A-2のスキーマをローカルXML Schema(オプションLOCAL)として登録する必要があること、SQLオブジェクト、および登録プロセス(オプションGENTABLES)で表を生成する必要があることが指定されます。

PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaは、次の操作を実行します。

- XML Schemaの解析および検証

- XML Schemaを記述するOracleデータ・ディクショナリ内の一連のエントリの作成

- XML Schemaで定義されたcomplexType要素に基づく一連のSQLオブジェクト定義の作成

- XML Schemaで定義された各グローバル要素のXMLType表の作成

デフォルトでは、XML Schemaが登録されると、Oracle XML DBは、インスタンス・ドキュメントの管理に必要なすべてのSQLオブジェクト型とXMLType表を自動的に生成します。XML Schemaは、グローバルまたはローカルとして登録できます。

関連項目:

- 「ローカルXML SchemaおよびグローバルXML Schema」

- 「XML Schema登録時のSQL型および表の作成」

- DBMS_XMLSCHEMA.registerSchemaの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

例17-1 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;
/

17.3.3 XML Schema登録時のSQL型および表の作成

XML Schemaの登録によって、オブジェクト型および表が作成されます。

例17-2では、例17-1の場合のように、XML Schemaの登録中に作成された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つずつあります。

例17-2 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

17.3.4 グローバル要素のデフォルト表

デフォルトでは、すべてのグローバル要素に対して、システム生成名を持つ表が作成されます。かわりに使用する名前を指定できます。特定の要素に対してデフォルト表が作成されないようにできます。このようにすることで、XML Schemaに多数のグローバル要素定義が含まれる場合は特に、使用されるプロセッサ時間と領域を削減できます。

デフォルトでは、XML Schemaがデータベースに登録するときに、Oracle XML DBは、XML Schemaにより定義される各グローバル要素に対してデフォルト表を生成します。

xdb:defaultTable属性を使用して、特定のグローバル要素に対するデフォルト表の名前を指定できます。指定するxdb:defaultTable属性値は、特定のデータベース・ユーザーにより登録されたすべてのスキーマ間で一意である必要があります。一部の要素に対して空でないデフォルト表名を指定しない場合、一意の名前が自動的に付けられます。

しかし実際には、ほとんどの場合、グローバル要素に対してデフォルト表を作成する必要はありません。XMLインスタンス・ドキュメントのルート要素として機能しない要素には、デフォルト表が使用されることはないため、デフォルト表は必要ありません。特に、XML Schemaに多数のグローバル要素定義が含まれている場合は、すべてのグローバル要素に対してデフォルト表を作成すると、プロセッサ時間に大量のオーバーヘッドが発生し、多くの領域が使用される可能性があります。

このため、一般に、どの文書内でもルート要素として使用されないことが確実なグローバル要素(または表外に格納されたローカル要素)に対しては、デフォルト表が作成されないようにすることができます。これを行うには、次のいずれかの方法を実行します。

- XMLインスタンス・ドキュメントのルート要素として表示されない各グローバル要素の定義に、注釈xdb:defaultTable = "" (空の文字列)を追加します。この方法を使用すると、通常はデフォルト表を自動的に作成し、必要な場合にxdb:defaultTable = ""を使用して明示的にデフォルト表の自動作成を禁止できます。

- XML Schemaの登録時にパラメータGENTABLESをFALSEに設定し、インスタンス・ドキュメントのルート要素として正当に表示できる各グローバル要素に対してデフォルト表を手動で作成します。この方法を使用すると、デフォルト表の自動作成は行われません。必要な表のみを手動で作成します。

17.3.5 登録されたXML Schemaに依存するデータベース・オブジェクト

いくつかの種類のデータベース・オブジェクト(表、ビュー、他のXML Schema、およびXML Schemaを参照するカーソル)を、登録済XML Schemaに依存させることができます。

正確には、次のようになります。

- XML Schemaの要素に準拠するXMLType列が含まれる表またはビュー。

- 定義の一部として指定のXML Schemaが含まれるか、またはインポートされるXML Schema。

- XML Schemaを参照するカーソル。これには、パッケージDBMS_XMLGENのファンクション内部の参照が含まれます。このようなカーソルは、一時オブジェクトです。

17.3.6 ローカル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は、それぞれプライベートおよびパブリックと呼ばれます。

17.3.6.1 ローカルXML Schema

デフォルトでは、XML SchemaをOracle XML DBに登録すると、XML Schemaがローカルになります。つまり、登録したユーザーのみがこのXML Schemaの所有者になります。XML Schema文書への参照は、Oracle XML DBリポジトリのユーザー(データベース・スキーマ)名の下に格納されます。

このようなXML Schemaは、ローカルとして参照されます。デフォルトでは、これらのスキーマは、所有者であるユーザーのみが使用できます。Oracle XML DBでは、ローカルXML Schemaのリソースは、フォルダ/sys/schemas/usernameに作成されます。残りのリポジトリのパス名は、スキーマのURLから導出されます。

たとえば、XML Schema purchaseOrder.xsdがユーザーQUINEによってローカル・スキーマとして登録された場合は、次のパス名が指定されます。

/sys/schemas/QUINE/xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd

データベース・ユーザーがXML SchemaをローカルXML Schemaとして登録するには、指定されたパス名でリソースを作成するための適切な権限およびアクセス制御リスト(ACL)が必要です。

関連項目:

リポジトリのアクセス制御

注意:

通常、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を使用して、他のユーザー(この場合は、ユーザーQUINE)が所有するXML Schemaを指定できます。

例17-3 ローカル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;
/

17.3.6.2 グローバルXML Schema

ローカルXML Schemaとは異なり、権限のあるユーザーは、DBMS_XMLSCHEMA登録ファンクションで引数を指定することにより、XML SchemaをグローバルXML Schemaとして登録できます。これは、すべてのユーザーが参照できます。これはOracle XML DBリポジトリのフォルダ/sys/schemas/PUBLIC/に格納されます。

注意:

フォルダ/sys/schemas/PUBLICへのアクセスはアクセス制御リスト(ACL)で制御されます。デフォルトでは、このフォルダにはデータベース管理者のみが書込み可能です。グローバルXMLスキーマを登録するには、このフォルダに対する書込み権限が必要です。このフォルダがデフォルトACLによって保護されている場合は、ロールXDBADMINによってこのディレクトリへの書込み権限も提供されます。 リポジトリのアクセス制御を参照してください。

ローカル・スキーマは、既存のグローバル・スキーマと同じURLに登録できます。ローカル・スキーマは、常に同じ名前(URL)を持つグローバル・スキーマを非表示にします。

例17-4に、グローバル・スキーマの登録を示します。

例17-4 グローバル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アクセス)が必要です。

17.3.7 完全修飾されたXML Schema URL

完全修飾されたXML Schema URLにより、特定のXML Schemaに対する明示的な参照が許可されます。URLの一部として、XML Schemaを所有するデータベース・ユーザーの名前が指定されます。完全修飾されたSchema URLは、Oracle XML DBの名前空間に属します。

デフォルトでは、XML Schema URLは、データベースの現行のユーザーの範囲内で参照されます。XML Schema URLは、まず現在のデータベース・ユーザーが所有するローカルのXML Schemaの名前として解決されます。

- 対応するXML Schemaがない場合、グローバルXML Schemaの名前として解決されます。

- 対応するグローバルXML Schemaもない場合、Oracle XML DBでエラーが発生します。

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」

17.3.8 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が指定されていて、XML Schemaにも依存している他の表にインスタンスがある場合、エラーが発生します。

プロシージャ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パッケージおよびタイプ・リファレンス』

例17-5はDELETE_CASCADE_FORCEの使用方法を示しています。

バイナリ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を参照しないように変換されていることを確認してください。そうしない場合、消去後にそれらの文書をデコードできなくなります。

例17-5 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;
/

17.3.9 登録されているすべてのXML Schemaのリスト

例では、Oracle XML DBに登録されているすべてのXML Schemaを示します。

例17-6に、PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaを使用してOracle XML DBで登録されているすべてのXML Schemaのリストを取得する方法を示します。ビューUSER_XML_SCHEMAS、ALL_XML_SCHEMAS、USER_XML_TABLESおよびALL_XML_TABLESも調べることができます。

例17-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://www.w3.org/2001/xml.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.

17.4 XML Schemaに基づくXMLType表および列の作成

XML Schemaによって定義されたグローバル要素に限定したXMLType表および列を作成できます。XMLType列を特定の要素および特定のスキーマに限定すると、以降はその要素のスキーマ定義に準拠している文書のみを含めることができます。

XMLType表の列は、CREATE TABLE操作に適切なXMLSCHEMAおよびELEMENT句を追加することで、特定の要素およびXML Schemaに制限されます。

図17-3から図17-6に、XMLType表を作成するための構文を示します。

関連項目:

object_propertiesのような構文要素を含むCREATE TABLEの詳しい説明は、『Oracle Database SQL言語リファレンス』。

注意:

各自のデータベース・スキーマと異なるデータベース・スキーマにXMLType表を作成するには、権限CREATE ANY TABLEだけでなく、権限CREATE ANY INDEXも必要です。これは、表の作成時に列OBJECT_IDに一意索引が作成されるためです。列OBJECT_IDには、システム生成のオブジェクト識別子が格納されます。

図17-3 XMLType表の作成: CREATE TABLEの構文

図17-4 XMLType表の作成: XMLType_tableの構文

図17-5 XMLType表の作成: table_propertiesの構文

図17-6 XMLType表の作成: XMLType_virtual_columnsの構文

注意:

- XMLType_virtual_columns句は、バイナリXMLとして格納されているXMLTypeデータに対してのみ使用できます。具体的には、オブジェクト・リレーショナル形式で格納されているデータに対して使用した場合に、パーティショニング句を使用すると、エラーが発生します。

- XMLデータの場合は、仮想列は主にSQLの制約のパーティション化や定義に使用されます。特定のXMLデータにリレーショナル形式でアクセスするためにそれを投影する必要がある場合、SQL/XML関数XMLTableまたはXMLIndexと構造化コンポーネントの使用を考慮してください。

関連項目:

- 「バイナリXMLとして格納されたXMLTypeデータでの仮想列の作成」

- 「Oracle XML DBのXMLTABLE SQL/XML関数」

- 「XMLIndex構造化コンポーネント」

XPointer表記法のサブセットを使用して、XML Schemaの場所および要素名を含む1つのURLを指定することもできます。 XMLデータの問合せと更新も参照してください。

例17-7は、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要素に限定されます。

XMLSchemaおよびElementを指定するには、次の2つの方法があります。

- XMLSchemaおよびElementを別の句として指定する方法

- XPointer表記法でElement句のみを使用する方法

XML Schemaに制限されるXMLType表または列に関連付けられているデータは、数種類の異なる方法で格納できます。

- オブジェクト・リレーショナル形式に分解して格納する方法

- 単一のXML列を使用してバイナリXML形式で格納する方法

例17-7 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";

17.4.1 XML Schemaに基づくデータのXMLType記憶域オプションの指定

XML Schemaを参照するXMLインスタンス・ドキュメントを格納する表を手動で作成する場合、使用する記憶域オプションを指定できます。特定のXMLType記憶域モデルを指定するには、CREATE TABLE文でSTORE AS句を使用します。

それ以外の場合は、XML Schemaの登録時に指定した記憶域モデルが使用されます。登録時に記憶域モデルが指定されなかった場合、オブジェクト・リレーショナル記憶域が使用されます。

XML Schemaに基づくデータの記憶域オプションの指定に加えて、XML Schema注釈を使用して、自動的に作成される表の記憶域オプションを指定することもできます。

関連項目:

- 「OracleでのXML Schemaの注釈」

- XMLType記憶域および索引付けの選択

17.4.1.1 XML Schemaに基づくデータのバイナリXML記憶域

STORE AS BINARY_XMLを指定すると、バイナリXML記憶域が使用されます。文書が準拠する必要があるXML Schemaを指定する場合、バイナリXMLとして格納されるXMLType表および列を作成するためにだけ、そのXML Schemaを使用できます。

同じXML Schemaを使用して、オブジェクト・リレーショナル形式で格納されるXMLType表および列を作成することはできません。

逆も成り立ちます。登録されたXML Schemaに対してオブジェクト・リレーショナル記憶域を使用する場合、そのXML Schemaを使用して作成できるのは、バイナリXMLとして格納される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表または列に挿入しようとすると、エラーが発生します。

可能なオプションについて表17-2にまとめます。

表17-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に基づくエンコーディングを使用してエンコードされます。

17.4.1.2 XML Schemaに基づくデータのオブジェクト・リレーショナル記憶域

XML Schemaを登録した後、そのXML Schemaに準拠する文書に対するオブジェクト・リレーショナルXMLType表または列を作成できます。オプションで、表または列に対してオブジェクト・リレーショナル記憶域オプションを指定できます。

URL http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsdによって識別される発注書XML Schemaを登録したと仮定します。次に、例17-8のように、XML Schemaの要素PurchaseOrderに準拠したインスタンスを格納するオブジェクト・リレーショナル形式のXMLType表、purchaseorder_as_tableを作成します。

これで、PurchaseOrder要素がマップされているデータベース・オブジェクト・タイプに対応する非表示の列が自動的に作成されます。また、ネームスペース宣言など、最上位インスタンスのデータを格納するためのXMLEXTRAオブジェクト列が作成されます。XMLEXTRAは、内部での使用に予約されています。

XML Schema purchaseOrder.xsdに、要素LineItemsが要素PurchaseOrderの子として定義されており、LineItemsがLineItem要素のコレクションであると仮定します。

オブジェクト・リレーショナル記憶域では、コレクションはSQL VARRAY値にマップされます。XMLのコレクションはXML Schemaによって定義される任意の要素であり、maxOccurs > 1であるため複数回出現できます。このようなVARRAYのコンテンツ全体は、デフォルトでOrdered Collection Table(OCT)内に一連の行として格納されます。

例17-9では、例17-8とは異なる表purchaseorder_as_tableを作成しています。ここでは、次のように追加の記憶域オプションを指定します。

- LineItemsコレクションのVARRAYは、表ではなくLOBとして格納されます。

- 表領域USERSは、要素Notesの格納に使用されます。

- 表は、オンライン・トランザクション処理(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句を使用する方法の代替策となる便利な方法です。例17-10に、これを示します。

STORE ALL VARRAYS ASを使用して指定した格納方式は、対応するXML Schemaで(非推奨の) XML Schema注釈xdb:storeVarrayAsTable脚注 2を使用して指定した格納方式よりも優先されます。

関連項目:

STORE ALL VARRAYS AS LOBSの使用方法の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

例17-8 デフォルト記憶域でのオブジェクト・リレーショナル形式のXMLType表の作成

CREATE TABLE purchaseorder_as_table OF XMLType
ELEMENT
"http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd#PurchaseOrder";

例17-9 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;

例17-10 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;

17.5 XML Schemaインスタンス・ドキュメントの識別方法

XML文書をXML Schemaに基づくXMLType表または列に挿入する前に、関連付けられているXML Schemaを識別する必要があります。表または列の作成時にこれを実行することも、XMLSchema-instanceを使用して、必要なスキーマ識別を明示的にXMLインスタンス・ドキュメントに追加することもできます。

XMLType表または列の作成時にXML Schemaを明示的に識別するには、XML Schemaの名前をXMLTypeコンストラクタに渡すか、またはXMLTypeのcreateSchemaBasedXML()メソッドを起動します。

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つまたは両方の属性が必要です。

17.5.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">
<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">

17.5.2 XML Schemaおよび複数の名前空間

XML Schemaに複数の名前空間で定義された要素が含まれるときは、各XML SchemaのschemaLocation属性でエントリを発生させる必要があります。各エントリは、名前空間宣言およびスキーマの場所を示すヒントで構成されています。

また、各エントリは1つ以上の空白文字で区切られています。

主要なXML Schemaでターゲットの名前空間が宣言されていない場合でも、主要なXML Schemaのスキーマの場所を示すヒントを指定するnoNamespaceSchemaLocation属性をXMLインスタンス・ドキュメントに含める必要があります。

17.6 XML Schemaデータ型のOracle XML DB記憶域へのマッピング

XML Schemaに準拠するデータは、XML Schemaデータ型を使用します。このXMLデータがOracle XML DBに格納される場合、その記憶域データ型はデフォルトのマッピングを使用して(およびオプションで、XML Schema注釈を使用して指定したマッピング情報を使用して)、XML Schemaデータ型から導かれます。

記憶域に対して使用するデータ型を指定しない場合、Oracle XML DBは登録時に、デフォルトのマッピングを使用して適切にXML Schemaに注釈を付けます。こうすると、登録されたXML Schemaに、データ型注釈の完全なセットが含まれます。

- オブジェクト・リレーショナル記憶域では、XML Schemaデータ型がSQLデータ型にマップされます。

- バイナリXML記憶域では、XML Schemaデータ型はOracle XML DBバイナリXMLエンコーディング型にマップされます。

関連項目:

「XML Schemaデータ型のSQLデータ型へのマッピング方法」

図17-7に、Oracle XML DBで、XML文書およびXML Schemaに指定されたマッピングを使用して、XML Schemaに基づくXMLType表を作成する方法を示します。XML Schemaで指定された格納方式に応じて、XMLインスタンス・ドキュメントは、バイナリXMLの値として単一のXMLType列に格納されるか、複数のオブジェクト・リレーショナル列を使用して格納されます。

図17-7 Oracle XML DBによるXML Schemaに基づくXMLType表のマッピング方法

脚注の凡例

脚注1:
XMLSpyは、WebDAVおよびFTPプロトコルもサポートしているため、それを使用して、Oracle XML DBリポジトリに格納されているコンテンツに直接アクセスして編集できます。

脚注2:
XML Schema注釈xdb:storeVarrayAsTableは、Oracle Database 12cリリース1 (12.1.0.1)から非推奨になりました。

18 XML Schemaの格納と問合せ: オブジェクト・リレーショナル記憶域

XML Schemaに基づくデータに対する高度なテクニックには、オブジェクト・リレーショナル記憶域の使用、XML Schemaの注釈付け、XML Schemaデータ型のSQLへのマッピング、complexTypeの拡張および制限の使用、XML Schemaに基づくデータの作成、XML Schemaに基づくデータに対するリレーショナル制約の指定およびXML Schemaに基づくデータのパーティション化、XMLTypeデータの表外格納、複雑または大規模なスキーマの操作、スキーマ登録のデバッグなどがあります。

- XML文書のオブジェクト・リレーショナル記憶域

- OracleでのXML Schemaの注釈

- XML Schemaデータ型のSQLデータ型へのマッピング方法

- Oracle XML DBでのcomplexTypeの拡張および制限

- XML Schemaに基づくXMLType列および表の作成

- オブジェクト・リレーショナル形式で格納されたXMLTypeの表および列のパーティション化の概要

- XMLType表および列に対するリレーショナル制約の指定

- XMLTypeデータの表外記憶域

- 複雑または大規模なXML Schemaの操作の考慮事項

- オブジェクト・リレーショナル形式で格納されたXMLデータのためのXML Schema登録のデバッグ

関連項目:

- Oracle XML DBでのXML Schemaの使用に関する基本情報は、XML Schemaの格納と問合せ: 基本を参照してください。

- Oracle XML DBでのXPath式の最適化の詳細は、 オブジェクト・リレーショナル記憶域のXPathリライトを参照してください。

- XML SchemaをOracle XML DBに登録した後で更新する方法の詳細は、 XML Schemaの拡張を参照してください。

- http://www.w3.org/TR/xmlschema-0/ - XML Schemaの概要

18.1 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文書が収集されると、XML Schemaにより定義された構造体は同等のSQL型に直接マップされます。これにより、Oracle XML DBでは、XMLを管理するときにOracle Databaseのすべての機能を使用でき、文書の格納に必要な容量を大幅に削減できます。また、XMLコンテンツの問合せおよび更新に必要なメモリーの量も削減できます。

18.1.1 オブジェクト・リレーショナル形式のXMLType記憶域の場合のコレクション格納方法

Ordered Collectionは、ヒープに基づく表(推奨)と索引構成表(IOT)のいずれかにすることができるOrdered Collection Table (OCT)のVARRAYとして格納できます。データに対するREFであるVARRAYエントリを使用して、実際のデータを表外に格納できます。

オブジェクト・リレーショナル形式で格納されるXMLTypeデータのXML Schemaを登録し、登録パラメータGENTABLESをTRUEに設定する場合、関連付けられたXMLインスタンス・ドキュメントを格納するためにデフォルト表が自動的に作成されます。

格納されるときに、XMLコレクション要素の順序は維持されます。結果はOrdered Collectionです。脚注 1データは次の方法でOrdered Collectionに格納できます。

- 表内のVARRAY。コレクション内の各要素は、SQLオブジェクトにマップされます。SQLオブジェクトのコレクションは、Ordered Collection Table (OCT)と呼ばれる表に、一連の行として格納されます。デフォルトでは、すべてのコレクションがOCTに格納されます。
このデフォルト動作は、XML Schema注釈xdb:storeVarrayAsTable = "true"(デフォルト値)に対応しています。脚注 2

- LOB内のVARRAY (非推奨)。コレクション内の各要素は、SQLオブジェクトにマップされます。SQLオブジェクトのコレクション全体が、VARRAYとしてシリアライズされてLOB列に格納されます。指定されたコレクションをLOB内のVARRAYとして格納するには、XML Schema注釈xdb:storeVarrayAsTable = "false"を使用します。脚注 2

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 Database 11gリリース1より前のリリースの場合:

- OCTはデフォルトでIOTとして格納されていました。

- xdb:storeVarrayAsTableのデフォルト値はfalseでした。

注意:

OracleからIOTの使用を明示的に指示された場合を除き、IOTでなく、ヒープに基づくOCTを使用してください。IOTの記憶域には、次のような大きな制限があります。

- コレクション表(IOT)のパーティショニングが無効化されます。

- 文書レベルのOracle Text索引しかサポートされません。要素に固有の索引や属性に固有の索引は無効になります。

関連項目: XMLデータでOracle Textを使用する方法の詳細は、「XQueryを使用しないXMLデータの全文検索」を参照してください。

関連項目:

- オブジェクト・リレーショナル記憶域を使用してXMLType表および列を手動で作成する場合のコレクション記憶域の詳細は、「XML文書のオブジェクト・リレーショナル記憶域」を参照してください。

- 「表外に格納するための注釈属性xdb:SQLInlineのfalse設定」

- オブジェクト・リレーショナル形式で格納されたXMLTypeの表および列のパーティション化の概要

18.1.2 オブジェクト・リレーショナル記憶域に対してXML Schema登録時に作成されるSQL型

オブジェクト・リレーショナル形式で格納されているXMLデータで使用するためにXML Schemaを登録する際は、パラメータGENTYPESの値にTRUEを使用します(TRUEがデフォルト値)。これにより、Oracle XML DBでは、準拠するXML文書のオブジェクト・リレーショナル記憶域に対応した適切なSQLオブジェクト型が作成されます。

デフォルトでは、SQLオブジェクト型はXML Schema登録者のデータベース・スキーマに作成されます。注釈xdb:defaultSchemaが使用されている場合は、Oracle XML DBによって、指定されたデータベース・スキーマを使用してオブジェクト型の作成が試行されます。現行のユーザーがこのオブジェクト型を作成するには、必要な権限を取得している必要があります。

例18-1に、XML Schema purchaseOrder.xsdがOracle XML DBで登録された場合に自動的に作成されるSQLデータ型を示します。

注意:

デフォルトでは、SQLオブジェクト型および属性の名前はシステム生成されます。例18-1がその例です。XML SchemaにSQLName属性が含まれていない場合、SQL名はXMLの名前から導出されます。XML Schema注釈を使用すると、ユーザー定義の名前を使用できます(詳細は、「OracleでのXML Schemaの注釈」を参照してください)。

例18-1 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

18.1.3 XML Schemaの登録時に作成されるデフォルト表

デフォルト表は、XML Schema登録の一部として作成できます。デフォルト表は、FTPやHTTP(S)など、表が指定されないAPIおよびプロトコルを介して文書が挿入される場合に非常に役立ちます。

この場合、XMLインスタンスはデフォルト表に挿入されます。

例18-2に、デフォルトのpurchase-order table表を示します。

属性xdb:defaultTableに値を指定すると、その名前でXMLType表が作成されます。それ以外の場合は、内部生成された名前で作成されます。

xdb:tablePropsおよびxdb:columnProps属性を使用して指定されたすべてのテキストが、生成されたCREATE TABLE文に追加されます。

例18-2 グローバル要素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"

18.1.4 XML Schemaの登録時に生成された内部構造体を使用しない

一般的に、XML Schemaの登録中に自動的に生成されたSQL構造体(データ型、ネストされた表、および表外の記憶域に関連付けられている表)は、Oracle XML DB内部にあります。これらをコードで使用しないことをお薦めします。

より正確には、生成されたSQLデータ型、ネストされた表、および表外の記憶域に関連付けられている表は、Oracleによっていつでも変更および再定義される、特定の内部のXML Schemaとオブジェクト型のマッピングに基づいています。一般的に次が成立します。

- 生成されたSQLデータ型は使用しないでください。

- 生成されたネストされた表または表外へのアクセスまたは変更は行わないでください。

ただし、生成された表のパーティション化などの記憶域オプションは変更できます。また、生成された表に対して索引または制約を作成することはできます。また、生成された構造体に名前を付ける注釈など、Oracle XML DBに付属するXML Schema注釈は自由に使用できます。

18.1.5 大/小文字が区別される生成名

XML Schemaの登録で生成されたSQL表、オブジェクト、属性の名前は、大/小文字が区別されます。

たとえば例18-2で、表PurchaseOrder1669_TABの名前は要素PurchaseOrderの名前から導出されているため、これも大/小文字が混在しています。このため、この表を参照する際に識別子に引用符を使用("PurchaseOrder1669_TAB")する必要があります。使用しないと、ORA-00942: 表またはビューが存在しませんなどの、オブジェクトが見つからないというエラーが発生します。

18.1.6 SYS_XDBPD$とオブジェクト・リレーショナル記憶域のDOM再現性

オブジェクト・リレーショナル形式で格納されているXMLデータのDOM再現性を示すために、Oracle XML DBは、システム定義のバイナリ・オブジェクト属性SYS_XDBPD$ (位置指定ディスクリプタ(PD))を使用して、他のオブジェクト属性に格納できないすべての情報をインスタンス・レベルのメタデータとして記録します。

XMLデータのオブジェクト・リレーショナル記憶域では、XML Schemaで宣言された要素および属性は、対応するSQLオブジェクト型の個別の属性にマップされます。ただし、XMLインスタンス・ドキュメント内の次の情報は、これらのオブジェクト属性に格納されません。

- 名前空間宣言

- コメント

- 接頭辞情報

オブジェクト・リレーショナル形式で格納されている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 Schema内のSQLType値のオーバーライド」

- 「要素を宣言する際のXML Schema内のSQLType値のオーバーライド」

- DOM再現性と、XMLデータのバイナリXML記憶域の詳細は、「DOM再現性」を参照してください

18.2 OracleでのXML Schemaの注釈

XML Schemaに注釈を付けることによって、XML Schema登録処理によって生成されるオブジェクトおよび表に影響を与えることができます。これを行うには、Oracle特有の属性を、XML Schemaによって宣言されるcomplexType、elementおよびattributeの定義に追加します。

このような注釈を手動で追加するには、XML Schema文書を編集するか、または注釈固有のPL/SQLサブプログラム(ほとんどの一般的な注釈に対応)を呼び出します。『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XMLSCHEMA_ANNOTATE」を参照してください。

Altova XMLSpyエディタを使用してXML Schemaを手動で編集する場合は、このエディタの「Oracle」タブを利用して、Oracle固有の注釈を追加および編集できます。図17-2を参照してください。

Oracle XML DBによって使用される大部分のXML属性は、名前空間http://xmlns.oracle.com/xdbに属します。XMLデータをバイナリXML形式でエンコードするために使用されるXML属性は、名前空間http://xmlns.oracle.com/2004/CSXに属します。XML Schemaの注釈の処理を単純化するために、名前空間接頭辞はXML Schemaのルート要素で宣言することをお薦めします。

18.2.1 XMLスキーマ注釈の一般的な使用

XML Schemaに注釈を付けてオブジェクト・リレーショナル表、オブジェクトおよびオブジェクト属性に名前を付けたり、XPath式の引数が再帰的なXMLデータをターゲットとしているときのXPathリライトを許可することができます。

XML Schemaに注釈を付ける一般的な理由は、次のとおりです。

- XMLTypeデータのオブジェクト・リレーショナル記憶域に対してPL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaで作成された表やオブジェクト、オブジェクト属性の名前が、わかりやすくすべてのアプリケーション・ネーミング標準に準拠することを保証するため。この場合は、パラメータGENTYPESまたはGENTABLESをTRUEに設定します(TRUEはこれらの各パラメータのデフォルト値)。

- 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、NVARCHAR2またはNCLOBは、SQLType注釈の値としては使用できません。

- xdb:SQLCollType - 要素のコレクションを管理するVARRAY型を指定するために使用します。

- xdb:maintainDOM - 指定されているcomplexType定義のDOM再現性を維持する必要があるかどうかを判断するために使用します。

これらの属性のいずれにも、値を指定する必要はありません。Oracle XML DBにより、デフォルトで、XML Schemaの登録プロセス中に適切な値が提供されます。ただし、オブジェクト・リレーショナル記憶域を使用する場合、少なくとも最上位のSQL型の名前を指定し、後で参照できるようにすることをお薦めします。

18.2.2 XML Schema注釈の例

XML Schemaの例に、最も重要なOracle XML DB注釈の一部を示します。

例18-3のXML Schemaは、例A-2のXML Schemaと似ていますが、ここではNotes要素とその型NotesTypeも定義しています。

- schema要素にはxdb名前空間の宣言が含まれます。

- グローバル要素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再現性を保持する必要がないことを指定します。

例18-4は、例18-3の注釈付きXML Schemaの登録で作成された表およびオブジェクトの一部を示しています。

次に、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)が作成されました。

例18-3 一般的なスキーマ注釈の使用

<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">
<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:simpleType name="NotesType">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="32767"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

例18-4 注釈付き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.

18.2.3 DBMS_XMLSCHEMA_ANNOTATEを使用したXML Schemaの注釈付け

PL/SQLパッケージDBMS_XMLSCHEMA_ANNOTATEはXML Schemaに注釈を付けるサブプログラムを備えています。これらのサブプログラムは通常、XML Schemaを手動で編集するよりも便利でエラーが発生しにくくなります。

特に、スクリプトでPL/SQLサブプログラムを使用すれば、必要に応じていつでも繰り返し実行できます。これは、大規模なXML Schema、標準またはサード・パーティのXML Schemaを使用しているため手動で編集したくない場合には特に有効です。

Oracle注釈ごとに固有のPL/SQLサブプログラムが用意されています。たとえば、xdb:defaultTable注釈の追加にはPL/SQLプロシージャsetDefaultTableを、xdb:defaultTable注釈の削除にはremoveDefaultTableをそれぞれ使用します。

注釈サブプログラムごとに次のものをパラメータとして保持しています。

- 注釈対象のXML Schema。このパラメータはIN OUTです。

- 注釈を追加または削除する対象のグローバル要素の名前。

- 注釈(XML属性)の値。

- 対応する既存の注釈を上書きするかどうかを示すブール・フラグ。デフォルトでは、上書きされます。

注釈対象の要素がグローバル要素以外の場合は、ローカル要素名を追加パラメータとして提供します。グローバル名とローカル名を組み合せてターゲット要素を特定します。ローカル名を持つ要素は、グローバル名を持つ要素の下位に位置する必要があります。

SQL*Plusを使用する場合、PL/SQLプロシージャDBMS_XMLSCHEMA_ANNOTATE.printWarningsを使用すれば、その他のDBMS_XMLSCHEMA_ANNOTATEサブプログラムを使用する際に、SQL*Plusの警告の出力を有効または無効にできます。デフォルトでは、警告は出力されません。たとえば、注釈サブプログラムに対して指定した名前の要素が存在しないため、XML Schemaに注釈を付けられないなどの警告があります。

例18-5では、PL/SQLパッケージDBMS_XMLSCHEMA_ANNOTATE内のサブプログラムを使用して、例18-3で示した注釈付きXML Schemaを生成します。

関連項目:

『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XMLSCHEMA_ANNOTATE」

例18-5 DBMS_XMLSCHEMA_ANNOTATEの使用

CREATE TABLE annotation_tab (id NUMBER, inp XMLType, out XMLType);
INSERT INTO annotation_tab VALUES (1, ... unannotated XML schema...);

DECLARE
schema XMLType;
BEGIN
SELECT t.inp INTO schema FROM annotation_tab t WHERE t.id = 1;

DBMS_XMLSCHEMA_ANNOTATE.setDefaultTable(schema, 'PurchaseOrder', 'PURCHASEORDER');
DBMS_XMLSCHEMA_ANNOTATE.setSQLType(schema, 'PurchaseOrderType', 'PURCHASEORDER_T');
DBMS_XMLSCHEMA_ANNOTATE.setSQLName(schema, 'complexType', 'PurchaseOrderType', 'element', 'Reference',
'REFERENCE');
DBMS_XMLSCHEMA_ANNOTATE.setSQLName(schema, 'complexType', 'PurchaseOrderType', 'element', 'Actions',
'ACTIONS_COLLECTION');
DBMS_XMLSCHEMA_ANNOTATE.setSQLName(schema, 'complexType', 'PurchaseOrderType', 'element', 'User', 'EMAIL');
DBMS_XMLSCHEMA_ANNOTATE.setSQLName(schema, 'complexType', 'PurchaseOrderType', 'element', 'LineItems',
'LINEITEM_COLLECTION');
DBMS_XMLSCHEMA_ANNOTATE.setSQLType(schema, 'complexType', 'PurchaseOrderType', 'element', 'Notes', 'CLOB');
DBMS_XMLSCHEMA_ANNOTATE.setSQLType(schema, 'LineItemsType', 'LINEITEMS_T');
DBMS_XMLSCHEMA_ANNOTATE.setSQLCollType(schema, 'complexType', 'LineItemsType', 'LineItem', 'LINEITEM_V');
DBMS_XMLSCHEMA_ANNOTATE.setSQLName(schema, 'complexType', 'LineItemsType', 'element', 'LineItem',
'LINEITEM_VARRAY');
DBMS_XMLSCHEMA_ANNOTATE.setSQLType(schema, 'LineItemType', 'LINEITEM_T');
DBMS_XMLSCHEMA_ANNOTATE.setSQLType(schema, 'PartType', 'PART_T');
DBMS_XMLSCHEMA_ANNOTATE.disableMaintainDom(schema, 'PartType');

UPDATE annotation_tab t SET t.out = schema WHERE t.id = 1;
END;
/

18.2.4 使用できるOracle XML DBのXML Schema注釈

要素と属性の宣言に指定できるOracle XML DB注釈を、その操作に使用可能な、パッケージDBMS_XMLSCHEMA_ANNOTATEのPL/SQLサブプログラムとともに説明します。

接頭辞csxがあるもの以外のすべての注釈は、オブジェクト・リレーショナル記憶域に対して登録されたXML Schemaに適用できます。

次の注釈は、バイナリXML記憶域に対して登録されたXML Schemaに適用されます。

- xdb:defaultTable

- xdb:defaultTableSchema (非推奨)

- xdb:tableProps

関連項目:

『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XMLSCHEMA_ANNOTATE」

表18-1 要素内の注釈

属性およびPL/SQL

値

デフォルト

説明

xdb:columnProps

適用可能なPL/SQLなし。

任意の列STORAGE句

NULL

デフォルトのCREATE TABLE文に挿入される列STORAGE句を指定します。主に、SQL表にマップされる要素(最上位の要素の宣言および表外の要素の宣言)に有効です。

xdb:defaultTable

PL/SQL:

setDefaultTable
removeDefaultTable
enableDefaultTableCreation
disableDefaultTableCreation

表の名前

要素名に基づきます。

このXML SchemaのXMLインスタンスを格納する必要があるSQL表の名前を指定します。これは、表の名前が指定されていないAPIおよびプロトコル(FTP、HTTP(S)など)を使用してXMLを挿入する場合に最も有効です。オブジェクト・リレーショナル記憶域およびバイナリXML記憶域に適用されます。

xdb:defaultTableSchemaFoot 3

非推奨。適用可能なPL/SQLなし。

任意のSQLユーザー名

XML Schemaを登録するユーザー

xdb:defaultTableによって指定された型を所有するデータベース・ユーザー(データベース・スキーマ)の名前を指定します。オブジェクト・リレーショナル記憶域およびバイナリXML記憶域に適用されます。

xdb:maintainDOM

PL/SQL:

enableMaintainDOM
disableMaintainDOM

true | false

true

trueの場合、この要素のインスタンスは出力でDOM再現性が保持されるように格納されます。これは、要素の順序の他に、すべてのコメント、処理命令、ネームスペース宣言などが保持されることを意味します。

falseの場合は、出力で入力と同じDOM操作が保持されない場合があります。

xdb:maintainOrderFootref 3

非推奨。適用可能なPL/SQLなし。

true | false

true

trueの場合(一般的に推奨、デフォルト値)、コレクションはVARRAYにマップされます(LOBまたはOrdered Collection Tableに格納されます)。

falseの場合、コレクションは順序付けられていない表にマップされ、ドキュメント内の順序は保持されません。

xdb:SQLCollSchemaFootref 3

非推奨。適用可能なPL/SQLなし。

任意のSQLユーザー名

XML Schemaを登録するユーザー

xdb:SQLCollTypeによって指定された型を所有するデータベース・ユーザー(データベース・スキーマ)の名前を指定します。

xdb:SQLCollType

PL/SQL:

setSQLCollType
removeSQLCollType

任意のSQLコレクション型

要素名から生成された名前

このXML要素に対応するSQLコレクション型の名前。XML要素は、maxOccurs > 1と指定されている必要があります。

xdb:SQLInline

PL/SQL:

setOutOfLine
removeOutOfLine

true | false

true

trueの場合、この要素は埋込みオブジェクト属性(maxOccurs > 1の場合はコレクション)として表内に格納されます。

falseの場合は、REF値(maxOccurs>1の場合はREF値のコレクション)が格納されます。SQLでインラインがサポートされない特定の状況(循環参照など)では、この属性は強制的にfalseになります。

xdb:SQLName

PL/SQL:

setSQLName
removeSQLName

SQL識別子

要素名

このXML要素にマップされるSQLオブジェクト内での属性の名前。

xdb:SQLSchemaFootref 3

非推奨。適用可能なPL/SQLなし。

任意のSQLユーザー名

XML Schemaを登録するユーザー

SQLTypeによって指定された型を所有するデータベース・ユーザー(データベース・スキーマ)の名前を指定します。

xdb:SQLType

PL/SQL:

setSQLType
removeSQLType

任意のSQLデータ型脚注 4,(NCHAR、NVARCHAR2およびNCLOBを除く)

要素名から生成された名前

このXML要素の宣言に対応するSQL型の名前。

xdb:tableProps

PL/SQL:

setTableProps
removeTableProps

任意の表STORAGE句

NULL

デフォルトのCREATE TABLE文に追加されるTABLE STORAGE句を指定します。主に、グローバルな要素および表外の要素に有効です。オブジェクト・リレーショナル記憶域およびバイナリXML記憶域に適用されます。

脚注 3

XML Schema注釈xdb:defaultTableSchema、xdb:maintainOrder、xdb:SQLCollSchemaおよびxdb:SQLSchemaは、Oracle Databaseリリース12c (12.1.0.1)から非推奨になりました。

脚注 4

XML Schemaデータ型のSQLデータ型へのマッピング方法

関連項目:

オブジェクト・リレーショナル記憶域のXMLType表を手動で作成する場合の記憶域オプションの指定の詳細は、「XML Schemaに基づくデータのオブジェクト・リレーショナル記憶域」を参照してください。

表18-2 グローバルなcomplexType要素を宣言する要素内の注釈

属性

値

デフォルト

説明

xdb:maintainDOM

PL/SQL:

enableMaintainDom
disableMaintainDom

true | false

true

trueの場合、この要素のインスタンスは出力でDOM再現性が保持されるように格納されます。これは、要素の順序の他に、すべてのコメント、処理命令、ネームスペース宣言などが保持されることを意味します。

falseの場合は、出力で入力と同じDOM操作が保持されない場合があります。

xdb:SQLSchemaFoot 5

非推奨。適用可能なPL/SQLなし。

任意のSQLユーザー名

XML Schemaを登録するユーザー

SQLTypeによって指定された型を所有するデータベース・ユーザー(データベース・スキーマ)の名前を指定します。

xdb:SQLType

PL/SQL:

setSQLType
removeSQLType

任意のSQLデータ型脚注 6(NCHAR、NVARCHAR2およびNCLOBを除く)

要素名から生成された名前

このXML要素の宣言に対応するSQL型の名前。

脚注 5

XML Schema注釈xdb:SQLSchemaは、Oracle Databaseリリース12c (12.1.0.1)から非推奨になりました。

脚注 6

XML Schemaデータ型のSQLデータ型へのマッピング方法

表18-3 XML Schema宣言内の注釈

属性

値

デフォルト

説明

xdb:mapUnboundedStringToLobFoot 7

適用可能なPL/SQLなし。

true | false

false

trueの場合は、デフォルトで、無制限の文字列がCLOBインスタンスにマップされます。同様に、デフォルトで、無制限のバイナリ・データがBLOB値にマップされます。

falseの場合は、無制限の文字列がVARCHAR2(4000)値にマップされ、無制限のバイナリ・コンポーネントがRAW(2000)値にマップされます。

xdb:storeVarrayAsTableFootref 7

非推奨。適用可能なPL/SQLなし。

true | false

true

trueの場合は、VARRAYが表(OCT)として格納されます。デフォルト値はtrueです。

falseの場合は、VARRAYがLOBに格納されます。

脚注7

XML Schema注釈xdb:mapUnboundedStringToLobおよびxdb:storeVarrayAsTableは、Oracle Database 12cリリース1 (12.1.0.1)から非推奨になりました。

18.2.5 オブジェクト・リレーショナル記憶域に対するXML Schema注釈のガイドライン

オブジェクト・リレーショナル形式で格納されるXMLTypeデータでは、パフォーマンスを最適化するために注意深い計画が求められます。エンティティ関連モデル、索引付け、データ型、表パーティションなどのリレーショナル・データについても、同様の点を考慮することが求められます。XPathリライトを有効にし、最適なパフォーマンスを達成するには、XML Schema注釈を使用してこのような多くの設計選択を実装します。

関連項目:

- 表18-1

- オブジェクト・リレーショナル記憶域のXPathリライト

18.2.5.1 未使用の最上位要素に不要な表作成の回避

対応するXMLインスタンスの最上位でXML Schemaの最上位の要素が使用されない場合は、注釈xdb:defaultTable = ""をXML Schemaの要素に追加することで、関連する表を作成せずに済みます。この属性の空の値により、デフォルト表の作成を回避できます。

XML Schema登録では、スキーマで定義される最上位の要素ごとに、デフォルトで、最上位の表が作成されます。そのような要素の中には、スキーマに準拠するXMLインスタンスで最上位で使用されるものもあります。たとえば、XML Schemaの要素は、REFターゲットとして使用するために最上位になることがあります。

PL/SQLプロシージャDBMS_XMLSCHEMA_ANNOTATE.disableDefaultTableCreationを使用して、空のxdb:defaultTable属性を、xdb:defaultTable属性を持たない最上位の各要素に追加できます。

注意:

任意のインスタンス・ドキュメントのルート要素として使用されるXML Schemaの最上位要素はすべて、空でないxdb:defaultTable属性を持つ必要があります。

関連項目:

PL/SQLプロシージャdisableDefaultTableCreationの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XMLSCHEMA_ANNOTATE」を参照してください。

18.2.5.2 デフォルト表に対する独自の名前の提供

チューニング用に、問合せの実行計画の出力を検証します。これは、オブジェクト・リレーショナル形式で格納されているXMLTypeデータの基礎となる表を参照します。これらの表には、システム生成された名前がデフォルトで含まれます。対象とする表の場合は特に、かわりに独自の表名を指定することをお薦めします。

これを行うには、注釈xdb:defaultTableを使用します。

関連項目:

「XML Schemaの登録時に作成されるデフォルト表」

18.2.5.3 不要な場合のDOM再現性の無効化

デフォルトでは、XML Schemaの登録で、DOM再現性を維持する表が生成されます。多くの場合、これはデータ中心のXMLデータのDOM再現性が必要でない場合です。かわりに、DOM再現性を維持しないオブジェクト・リレーショナル表を使用することで、格納、問合せおよびデータ変更のパフォーマンスを改善できます。

これを行うには、注釈xdb:maintainDOM = "false"を使用します。

関連項目:

「DOM再現性」

18.2.5.4 タイムスタンプ・データ型を使用した時間関連要素の注釈

アプリケーションとタイムゾーン・インジケータの連動が必要な場合は、xs:time型およびxs:dateTime型のXML Schema要素に、xdb:SQLType = "TIMESTAMP WITH TIME ZONE"の注釈を指定します。これによって、タイムゾーン・インジケータが含まれている値の格納、取出しおよび比較を実行できます。

18.2.5.5 表および列のプロパティの追加

オブジェクト・リレーショナルXMLTypeデータの基礎となる表または列に、パーティションや表領域、圧縮などの追加のプロパティを指定する必要がある場合は、注釈xdb:tablePropsまたはxdb:columnPropsを使用します。これを行うことにより、主キーや制約などを追加できます。

たとえば、オンライン・トランザクション処理(OLTP)のために表の圧縮を行うには、tableProps属性を使用してCOMPRESS FOR OLTPを追加します。

関連項目:

XMLType表および列を手動で作成する際のOLTP圧縮の指定の例は例17-9

18.2.5.6 大規模コレクションの表外格納

大規模コレクションがある場合は、注釈xdb:defaultTableおよびxdb:SQLInlineを使用して、そのコレクション要素を表外に格納するように指定する必要がある場合があります。

complexTypeで定義される要素と属性の最大数は、1000です。その型のインスタンスが格納される場合、生成されるSQLオブジェクトを管理できる単一の表を作成することはできません。大規模コレクションがある場合は、1つの表でこのような1000列の上限にぶつかる可能性があります。

注釈xdb:defaultTableおよびxdb:SQLInlineを使用すると、このようなコレクション要素を表外に格納するように指定できます。つまり、これらのデータは個別の表に格納され、主となるコレクション表に格納されるのは、その表の行の参照のみです。表外の表の名前を指定するには、xdb:defaultTableを使用します。表外に格納するには、大規模コレクションの各要素に注釈xdb:SQLInline = "false"を指定します。

注意:

XML Schema内の継承階層または置換グループごとに表が作成され、その列には、該当する階層または置換グループのコンテンツ・モデルが格納されます。これも、1000列の上限に達する原因になる場合があります。

関連項目:

- 「ORA-01792およびORA-04031: 大規模XML Schemaに関する問題」

- 「表外に格納するための注釈属性xdb:SQLInlineのfalse設定」

18.2.6 登録されたXML Schemaの問合せによる注釈の取得

データベース・ビューUSER_XML_SCHEMASおよびALL_XML_SCHEMASを問い合せると、登録されたXML Schemaとそれに附随するすべての注釈を取得できます。登録済のXML Schemaのバージョンには、Oracle XML DB注釈の完全なセットが含まれています。これらの注釈は、ユーザーが指定するか、XML Schemaの登録時にデフォルトで設定されます。

例18-6に、これを示します。XML SchemaがXMLTypeインスタンスとして戻されます。

例17-3および例17-4に示されているように、登録されているXML Schemaの場所は、XML Schemaがローカル・スキーマかグローバル・スキーマかによって異なります。特定の注釈情報をリレーショナル列に投影するには、RESOURCE_VIEWを問い合せることができます。例18-7に、これを示します。XMLTypeデータのオブジェクト・リレーショナル記憶域に対してXML Schemaで宣言されているグローバルなcomplexType定義、およびそれに対応するSQLオブジェクト型とDOM再現性値を取得します。

例18-6 登録されたXML Schemaを取得するビューUSER_XML_SCHEMASの問合せ

SELECT SCHEMA FROM USER_XML_SCHEMAS
WHERE SCHEMA_URL = 'http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd';

例18-7 登録された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.

18.2.6.1 あるXML Schemaから別のXML Schemaに適用可能な注釈

あるXML Schemaから別のXML Schemaに注釈を適用する必要が生じることがあります。たとえば、古いバージョンのスキーマから新しいバージョンに注釈を適用する場合などが一般的です。PL/SQLサブプログラムgetSchemaAnnotationsを使用して注釈を取得し、setSchemaAnnotationsを使用して注釈を設定できます。

PL/SQLファンクションgetSchemaAnnotationsにより、XML Schemaからすべての注釈が戻されます。PL/SQLプロシージャsetSchemaAnnotationsにより注釈が設定されます。これらのサブプログラムはPL/SQLパッケージDBMS_XMLSCHEMA_ANNOTATE内にあります。

関連項目:

PL/SQLサブプログラムgetSchemaAnnotationsおよびsetSchemaAnnotationsの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XMLSCHEMA_ANNOTATE」を参照してください。

18.3 DBMS_XMLSCHEMAを使用したXML Schemaデータ型のSQLデータ型へのマッピング

PL/SQLパッケージDBMS_XMLSCHEMAを使用して、XML Schema属性および要素のデータ型をSQLデータ型にマップします。

注意:

XML Schema登録時に、XML Schemaデータ型からマップされるSQLデータ型に直接アクセスしないでください。これらのSQL型はOracle XML DBの実装の一部です。ユーザーが使用できるように公開されたものではありません。オラクル社は製品パッチなどで、実装をいつでも変更する権利を留保します。オラクル社によるそうした変更は、XMLの抽象的概念に従うアプリケーションには影響しませんが、それらのデータ型に直接アクセスするアプリケーションには影響を与えることがあります。

18.3.1 XML Schemaデータ型のSQLへのマッピングの例

XML Schemaデータ型のSQLデータ型へのマッピングの例を示します。

例18-8では、属性SQLTypeを使用してデータ型のマッピングを指定します。また、属性SQLNameを使用して、様々なXML要素および属性に使用されるオブジェクト属性を指定します。

例18-8 属性SQLTypeを使用したXML Schemaデータ型のSQLデータ型へのマッピング

<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"/>
<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>

18.3.2 XML Schema属性データ型のSQLへのマッピング

XML属性の宣言で、基本型、ローカルなsimpleType、グローバルなsimpleType、またはグローバル属性に対する参照(ref="..")によって、そのXML Schemaデータ型を指定できます。SQLデータ型とその関連する情報は、基本XML Schema型から導出されます。

属性の宣言では、次のいずれかを使用してXML Schemaデータ型を指定できます。

- 基本型

- このXML Schemaまたは外部のXML Schema内で宣言されたグローバルなsimpleType

- このXML Schemaまたは外部のXML Schema内で宣言されたグローバル属性に対する参照(ref="..")

- ローカルなsimpleType

SQLデータ型および関連付けられた情報(長さおよび精度)、メモリーのマッピングの情報は、属性の基礎となるsimpleTypeから導出されます。

18.3.2.1 属性を宣言する際に実行できるXML Schema内のSQLType値のオーバーライド

XML Schemaに注釈としてSQLTypeの値を明示的に指定できます。指定するSQLデータ型はXML Schemaの検証で使用されて、デフォルトのSQLデータ型がオーバーライドされます。

このようなSQLデータ型の次の特定の形式のオーバーライドのみが可能です。

- デフォルトのSQLデータ型がSTRINGの場合、CHAR、VARCHARまたはCLOBでオーバーライドできます。

- デフォルトのSQLデータ型がRAWの場合は、RAWまたはBLOBでオーバーライドできます。

18.3.3 XML Schema要素データ型のSQLへのマッピング

XML要素の宣言で、基本型、ローカルまたはグローバルなsimpleType、ローカルまたはグローバルなcomplexType、またはグローバル要素に対する参照(ref="..")を使用して、そのXML Schemaデータ型を指定できます。SQLデータ型とその関連する情報は、基本XML Schema型から導出されます。

要素の宣言では、次のいずれかを使用してXML Schemaデータ型を指定できます。

- 属性の宣言に対して型を指定する方法のいずれか。「XML Schema属性データ型のSQLへのマッピング」を参照してください。

- このXML Schema文書または外部のXML Schema内で指定されたグローバルなcomplexType

- このXML Schema文書または外部のXML Schema内に存在するグローバル要素(ref="...")

- ローカルなcomplexType

18.3.3.1 要素を宣言する際の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"の場合は、デフォルト表が作成されます。デフォルト表の名前をユーザーが指定するか、そうしない場合は要素名から導出されます。

18.3.4 XML Schema simpleTypeのSQLへのマッピング

XML simpleTypeは、simpleTypeが定義された方法に応じて、様々な方法でSQLオブジェクト型にマップされます。

図18-1に、このようなマッピングの1つとして、XML文字列型のSQLのVARCHAR2またはCLOBへのマッピングを示します。

図18-1 simpleTypeのマッピング: XML文字列からSQLのVARCHAR2またはCLOB

表18-4から表18-7までに、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)データ型にマップされます。

表18-4 XML Schema文字列データ型のSQLへのマッピング

XML Schema文字列型

lengthまたはmaxLengthファセット

デフォルトSQLデータ型

互換性のあるSQLデータ型

string

n

n < 4000の場合はVARCHAR2(n)、それ以外の場合はVARCHAR2(4000)

CHAR、CLOB

string

-

mapUnboundedStringToLob = "false"の場合は、VARCHAR2(4000)、CLOB

CHAR、CLOB

表18-5 XML Schemaバイナリ・データ型(hexBinary/base64Binary)のSQLへのマッピング

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

表18-6 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

表18-7 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)

なし

表18-8 SQLへのその他のXML Schema基本および派生データ型のデフォルトのマッピング

XML Schema基本および派生型

デフォルトSQLデータ型

互換性のあるSQLデータ型

boolean

RAW(1)

VARCHAR2

language(string)

VARCHAR2(4000)

CLOB、CHAR

NMTOKEN(string)

VARCHAR2(4000)

CLOB、CHAR

NMTOKENS(string)

VARCHAR2(4000)

CLOB、CHAR

Name(string)

VARCHAR2(4000)

CLOB、CHAR

NCName(string)

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)

なし

18.3.4.1 SQLTypeでサポートされないNCHAR、NVARCHAR2およびNCLOBのSQLType値

Oracle XML DBでは、NCHAR、NVARCHAR2およびNCLOBは、属性SQLTypeの値としてサポートされません。XML要素または属性の型にNCHAR、NVARCHAR2またはNCLOBを指定できません。また、ユーザー独自のデータ型を提供する場合は、これらのデータ型を使用しないでください。

関連項目:

Oracle XML DBの制限

18.3.4.2 simpleType: SQLのVARCHAR2またはCLOBへのXML文字列のマッピング方法

XML Schemaで、データ型が、maxLengthが4000未満の文字列として指定されている場合、このデータ型は、指定された長さのVARCHAR2オブジェクト属性にマップされます。スキーマにmaxLengthが指定されていない場合、XML Schemaデータ型はLOBのみにマップできます。

これは、ほとんどの文字列の値が小さく、LOBを必要とする値がわずかである場合は、あまり効率的ではありません。

関連項目:

表18-4

18.3.4.3 XML SchemaのタイムゾーンのSQLへのマッピング方法

アプリケーションとタイムゾーン・インジケータの連動が必要な場合は、属性SQLTypeを使用して、SQL型をTIMESTAMP WITH TIME ZONEに指定してください。これによって、タイムゾーン・インジケータが含まれている値の適切な格納および取出しを実行できます。

次の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"/>

18.3.4.3.1 値の最後にZを使用したUTCタイムゾーンの指定

UTCタイムゾーンを表すために、XML Schemaのタイムゾーン・コンポーネントに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になります。

18.3.5 XML Schema complexTypeのSQLへのマッピング

XML complexTypeは、complexTypeが定義された方法に応じて、様々な方法でSQLオブジェクト型にマップされます。

XML Schemaを使用すると、次のようにcomplexTypeがSQLオブジェクト型にマップされます。

- complexType内で宣言されたXML属性は、SQLオブジェクト属性にマップされます。XML属性を定義するsimpleTypeによって、対応するオブジェクト属性のSQLデータ型が決定されます。

- complexType内で宣言されたXML要素も、SQLオブジェクト属性にマップされます。XML要素を定義するsimpleTypeまたはcomplexTypeによって、対応するオブジェクト属性のSQLデータ型が決定されます。

属性maxOccurs > 1でXML要素が宣言されると、それはSQLのcollection (オブジェクト)属性にマップされます。collectionは、VARRAY値(デフォルト、推奨)または順序付けられていない表(非推奨の属性xdb:maintainOrder脚注8をfalseに設定することによって、かわりにLOB記憶域を選択できます。

18.3.5.1 complexType XML Schema宣言での属性の指定

グローバルなcomplexTypeに基づく要素がある場合は、complexType宣言に属性SQLTypeが指定されている必要があります。要素の宣言内に同じSQLType属性を含めることもできます。

グローバルな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>

18.4 Oracle XML DBでのcomplexTypeの拡張および制限

XML Schemaでは、complexTypeの値はcomplexContentおよびsimpleContentに基づいて宣言されます。Oracle XML DBでは、complexTypeに対する様々な拡張および制限が定義されます。

- simpleContentは、simpleTypeの拡張として宣言されます。

- complexContentは、次のいずれかとして宣言されます。

- ベース型

- complexTypeの拡張

- complexTypeの制限

18.4.1 XML SchemaでのcomplexTypeの宣言: 継承の処理

complexTypeでは、Oracle XML DBが他の複合型を拡張する型と制限する型で異なるようにXML Schemaでの継承を処理します。

- 他の複合型を拡張するように宣言された拡張型の場合、ベース型に対応するSQL型が現在のSQL型のスーパータイプとして指定されます。サブcomplexTypeに宣言された追加属性および要素のみが、サブ・オブジェクト型に属性として追加されます。

- 他の複合型を制約するように宣言された拡張型の場合、サブ複合型に対するSQL型がそのベース型のSQL型と同じになるように設定されます。これは、SQLでは継承メカニズムを介したオブジェクト型の制限がサポートされないためです。すべての制約は、XML Schemaでの制限によるものです。

例18-9は、AddressというベースcomplexType、およびUSAddress、IntlAddressという2つの拡張を定義するXML Schemaの登録を示しています。

注意:

対応する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;

例18-10は、ベースのcomplexTypeのAddress、およびcountry属性を指定できないようにする制限型LocalAddressを定義するXML Schemaの登録を示しています。

SQLでの継承は制限の概念がサポートされないため、制限されたcomplexTypeに対応するSQLデータ型は、親オブジェクト型の空のサブタイプになります。例18-10の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;

例18-9 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;

例18-10 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;

18.4.2 simpleContentに基づくcomplexTypeのオブジェクト型へのマッピング

simpleContent宣言に基づく複合型は、XML属性に対応する属性および本体の値に対応する追加のSYS_XDBBODY$属性を持つオブジェクト型にマップされます。本体属性のデータ型は、本体の型を定義するsimpleTypeに基づきます。

例18-11のXML Schemaでは、Oracle XML DBによって次の型が生成されます。

CREATE TYPE obj_t AS OBJECT(SYS_XDBPD$ XDB.XDB$RAW_LIST_T,
SYS_XDBBODY$ VARCHAR2(4000));

例18-11 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;

18.4.3 anyおよびanyAttribute宣言のオブジェクト型属性へのマッピング

Oracle XML DBでは、要素の宣言であるanyおよび属性の宣言であるanyAttributeは、作成されたオブジェクト型のVARCHAR2属性(またはオプションでラージ・オブジェクト(LOB))にマップされます。オブジェクト属性によって、any宣言に一致するXMLフラグメントのテキストが格納されます。

- コンテンツが指定された名前空間に属するように、namespace属性を使用してコンテンツを制限できます。

- any要素宣言内のprocessContents属性は、any宣言に一致するコンテンツに必要な検証レベルを示します。

例18-12のコードでは、オブジェクト型obj_tで、any要素が宣言されて列SYS_XDBANY$にマップされます。また、属性processContentsがany宣言に一致するコンテンツを検証しないことも宣言されます。

例18-12の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));

例18-12 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;

18.5 XML Schemaに基づくXMLType列および表の作成

XML SchemaがOracle XML DBに登録された後は、XMLType表または列を定義するときにそれを参照できます。

XML Schemaに基づくデータを格納するXMLType表または列を作成する際に、記憶域モデルを指定しない場合、使用される記憶域モデルは、参照するXML Schemaの登録時に指定した記憶域モデルです。XML Schemaの登録時に記憶域モデルを指定しなかった場合は、オブジェクト・リレーショナル形式の記憶域が使用されます。

例18-13に、PurchaseOrder要素のデフォルト表である表purchaseorderを手動で作成する方法を示します。

例18-13のCREATE TABLE文は、XML Schema登録の際、パラメータGENTABLESをTRUEに設定すると、Oracle XML DBにより自動生成されるCREATE TABLE文と同等です。

例18-13で使用されているXML Schemaでは、表purchaseOrderがPurchaseOrder要素のデフォルト表であることが指定されています。XML Schemaに準拠するXML文書を、プロトコルまたはPL/SQLを使用してOracle XML DBリポジトリに挿入すると、その文書のコンテンツはpurchaseorder表に行として格納されます。

XML Schemaをグローバル・スキーマとして登録した場合は、デフォルト表に対する適切なアクセス権をデータベースのすべてのユーザーに付与する必要があります。これによって、ユーザーは、グローバルに登録したXML Schemaに準拠するインスタンス・ドキュメントを操作できるようになります。

関連項目:

「ローカルXML SchemaおよびグローバルXML Schema」

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$が自動的に含まれます。

デフォルトでは、(非推奨の) XML Schema注釈xdb:storeVarrayAsTable脚注 9の値はtrueで、XML Schema登録時に、コレクションに対してOrdered Collection Tables (OCT)を自動生成します。このOCTにはシステムが生成した、覚えにくい名前が付けられます。SQL文RENAME TABLEを使用して、わかりやすい名前を付けることができます。

例18-13のCREATE TABLE文は、単一レベルのネストが行われている発注書に対応しています。LineItem要素のコレクションを管理するVARRAYは、Ordered Collection Table、lineitem_tableです。

ここで、別のXML Schemaを想定し、Shipment要素のコレクションがShipments要素内にあり、この要素がLineItem要素内にあるとします。この場合は、例18-14に示すように、表を手動で作成できます。

例18-15に示すように、SQL*PlusのDESCRIBE文を使用すると、XMLType表に関する情報を表示できます。

例18-15のDESCRIBE文の出力には、purchaseorder表に関する次の情報が表示されます。

- 表はXMLType表です。

- 表は、XML Schema PurchaseOrderで定義されたPurchaseOrder文書の格納用に制限されます。

- この表の行は、データベースに一連のオブジェクトとして格納されます。

- SQL型purchaseorder_tは、この表のベース・オブジェクトです。

例18-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$)));

例18-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$))));

例18-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"

18.6 オブジェクト・リレーショナル形式で格納されたXMLTypeの表および列のパーティション化の概要

オブジェクト・リレーショナル形式のXMLType表またはオブジェクト・リレーショナル形式で格納されているXMLType列を含む表をパーティション化したり、リスト、レンジまたはハッシュのパーティション化を使用すると、デフォルトでデータ内のOrdered Collection Table (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'

関連項目:

キーワードGLOBALおよびLOCALを使用してパーティション付きの表を作成する方法の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

18.6.1 XMLTypeデータのパーティション化の例

XML Schemaの登録中または表の作成中に、オブジェクト・リレーショナルXMLTypeの実表のパーティション化情報を指定できます。ここでは、この例を示します。

- XML Schemaの登録時にXML Schema注釈xdb:tablePropsを使用

- 表の作成時にCREATE TABLEを使用

例18-16および例18-17に、これを示します。これら2つの例では、結果はまったく同じです。実表purchaseorderが、レンジを指定するためにReference要素を使用してパーティション化されます。明細項目の子表が、実表に対して同一レベルでパーティション化されます。

例18-16は、実表および明細項目の子表をパーティション化するように注釈が付けられた、発注書XML SchemaのPurchaseOrder要素を示します。

例18-17では、例18-16と同じパーティション化を、実表purchaseorderの作成時に指定しています。

また例18-16と例18-17は、個々の子表のパーティションのオブジェクト格納オプションを指定する方法も示しています。この場合は、STORAGE句で、子表の各パーティションごとに最初に14Mのエクステントを割り当てることを指定しています。

関連項目:

- 「例A-2」

- オブジェクト・リレーショナル形式のデータのパーティション化の詳細は、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照してください。

- パーティション化の詳細は、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照してください。

例18-16 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)))"/>

例18-17 表の作成時のパーティション化情報の指定

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)));

18.6.2 パーティション・メンテナンス

子表のパーティションの定義やメンテナンスは、手動で行う必要はありません。実表(親表)に対してパーティション・メンテナンスを実行すると、対応するメンテナンスが子表に対しても自動的に実行されます。

ただし、実表に対してのみパーティション・メンテナンスを実行するというのは一般的なルールで、例外もあります。次のような場合は、子表に対してメンテナンスを実行します。

- コレクション・パーティションのデフォルトの物理記憶域属性を変更する場合

- コレクション・パーティションの物理記憶域属性を変更する場合

- コレクション・パーティションを別のセグメント(または別の表領域のセグメント)に移動する場合

- コレクション・パーティションの名前を変更する場合

たとえば、実表の表領域を変更した場合、その変更はその子表パーティションにカスケード処理されません。子表の表領域を変更するには、子表パーティションに対して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パッケージおよびタイプ・リファレンス』を参照してください。

18.7 XMLType表および列に対するリレーショナル制約の指定

XMLTypeデータがオブジェクト・リレーショナル形式で格納されている場合は、XML文書内で1回のみ出現する要素および属性に対して、標準的なリレーショナル制約を指定できます。

例18-18では、標準データベース・スキーマOEにあるXMLType表purchaseorderに、一意性制約と外部キー制約を定義しています。

OE.purchaseorder表の場合のように、オブジェクト・リレーショナル形式で格納されているXMLTypeデータの場合、制約は、XMLコンテンツを管理するために使用されるSQLデータ型のオブジェクト属性によって指定される必要があります。

例18-18は、バイナリXML表に一意性制約を定義している例3-8に似ています。ただし例18-18では、各OE.purchaseorder文書の要素Userが、標準データベース・スキーマHRの表employeesに含まれる従業員の電子メール・アドレスである必要があるという外部キー制約も追加して定義されています。

例3-8と同様に、例18-18の一意性制約reference_is_uniqueが要素Referenceの、表に格納されたすべてのドキュメントを通じての一意性を保証しています。外部キー制約user_is_validは、ここで要素Userの値がHR.employees表のemail列の値に対応することを保証しています。

XML文書DuplicateReference.xmlの要素Referenceに関連付けられたテキスト・ノードに、XML文書PurchaseOrder.xml内の対応するノードと同じ値が含まれています。したがって、両方の文書をOracle XML DBに格納しようとすると、制約reference_is_uniqueに違反します。

また、XML文書InvalidUser.xmlの要素Userに関連付けられたテキスト・ノードには、値HACKERが含まれています。表HR.employeesには、email列の値がHACKERのエントリはありません。この文書をOracle XML DBに格納しようとすると、外部キー制約user_is_validに違反します。

関連項目:

- 「SQL制約を使用した参照整合性の規定」、特に例3-8を参照してください。

- バイナリXMLとして格納されるXMLTypeデータに対する制約の定義の詳細は、「データベースを使用したXMLデータ整合性の規定」を参照してください。

- 「属性の親要素への一意制約の追加」

例18-18 オブジェクト・リレーショナル形式で格納されている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

18.7.1 属性の親要素への一意制約の追加

複数回出現する要素に制約を作成するには、VARRAYをOrdered Collection Table(OCT)として格納します。したがって、OCTに対して制約を作成できます。たとえば、自己循環する要素(コレクション)の属性に基づいて一意キーを作成することが考えられます。

例18-19に示すXML Schemaを使用すると、要素<PhoneNumber>の属性Noが複数回出現します。この例は、指定のインスタンス・ドキュメント内で同一の電話番号を繰り返せないことを保証する一意制約を追加する方法を示しています。

この例の制約は、個々のコレクションに対して適用され、すべてのインスタンスには適用されません。制約は、コレクションID列を持つ連結索引を作成することで適用されます。全インスタンス・ドキュメントのコレクションすべてに制約を適用するには、コレクションID列を省略します。

注意:

バイナリXMLとして格納されたXMLTypeデータに対する一意キーまたは外部キーの制約としてのみ、機能上の制約を作成できます。

例18-19 属性の親要素への一意制約の追加

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

18.8 XMLTypeデータの表外記憶域

デフォルトでは、XMLTypeデータがオブジェクト・リレーショナル形式で格納される場合、子要素は埋込みSQLオブジェクト属性にマップされます。ときには、XMLTypeデータの一部を表外に格納することによってパフォーマンスが向上する場合があります。XML Schema注釈xdb:SQLInlineを使用してこれを実行します。

18.8.1 表外に格納するための注釈属性xdb:SQLInlineのfalse設定

XMLフラグメントを表外に格納するには、XML Schema注釈xdb:SQLInlineをfalseに設定します。この要素は、表外に格納されるXMLフラグメントに対応するXMLTypeの他のインスタンスを指す、埋込みREF属性を持つSQLオブジェクト型にマップされます。

デフォルトでは、XMLTypeデータがオブジェクト・リレーショナル形式で格納される場合、子XML要素は埋込みSQLオブジェクト属性にマップされます。ただし、表外に格納することによってパフォーマンスが向上する場合もあります。そのような場合は、XML Schema注釈(属性)xdb:SQLInlineをfalseに設定すると、REF属性が埋め込まれたSQLオブジェクト型がOracle XML DBによって生成されます。REFは、表外に格納されるXMLフラグメントに対応するXMLTypeの他のインスタンスを指します。また、デフォルトのXMLType表が作成され、この表に表外のフラグメントが格納されます。

図18-2に、表外に格納するためのSQLへのcomplexTypeのマッピングを示します。

図18-2 表外に格納するためのSQLへのcomplexTypeのマッピング

注意:

Oracle Database 11gリリース2(11.2.0.2)以降では、結果がan out-of-line tableとなるXML Schemaを使用するXMLType表を1つだけ作成できます。同じXML Schemaを使用する2つめの表を作成しようとすると、エラーが発生します。

例18-20では、要素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によって、例18-21の型およびXMLType表が生成されます。

表emp_tabには全従業員の情報が格納され、表外の、表addr_tabに格納されている住所情報を指すオブジェクト参照が含まれています。

このモデルのメリットは、表外の表(addr_tab)を直接問い合せ、住所情報を参照できることです。例18-22は、全従業員について固有の都市情報を取得するために、表addr_tabを直接問い合せる場合を示しています。

この格納モデルのデメリットは、Employee要素全体を取得するために、住所に関する別の表にアクセスする必要がある点です。

例18-20 表外に格納するための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;
/

例18-21 生成された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)

例18-22 表外の表の問合せ

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

18.8.2 表外の表へのコレクションの格納

表外にコレクション項目を格納できます。親要素には、単一のREF列ではなく、コレクションのメンバーを指すREF値のVARRAYが挿入されます。

たとえば、各従業員の住所リストがあり、そのリストが例18-23に示すように表外の記憶域にマップされているとします。

このXML Schemaの登録中に、Oracle XML DBでは例18-20に示すように、表emp_tabおよびaddr_tab、型emp_tおよびaddr_tが生成されます。しかし、このときは、例18-24に示すように、型emp_tには単一のREF属性ではなく、住所を指すREF値のVARRAYが含まれます。

デフォルトでは、(非推奨の) XML Schema属性xdb:storeVarrayAsTable脚注 10は値trueを持ち、これはREF値のVARRAYが表外の中間表に格納されることを意味します。XML Schemaの登録では、取り上げた表および型の作成に加えて、REF値のリストを格納する中間表も作成されるということです。この表にはシステムが生成した名前が付けられますが変更することができます。これは索引を作成する場合などに役立つことがあります。

例18-26は、サンフランシスコを拠点とする全従業員の名前と居住している町を選択する問合せを示しています。この例では、City要素で住所表を問い合せ、従業員表を使用して逆方向に結合します。示されている実行計画の断片は、表emp_tab_reflistとemp_tabの間の結合を示しています。

パフォーマンスを向上するには、REF値の索引を中間表emp_tab_reflistに作成します。これによって、Oracle XML DBは、住所表を問い合せて、関連する行へのオブジェクト参照(REF)を取得し、そのオブジェクト参照をREF値のリストが格納されている中間表に結合し、従業員表を使用してその中間表を逆方向に結合することができます。

REFに範囲指定または参照制約がある場合にのみ、REF値に索引を作成できます。範囲指定されたREF列には、特定の表内のオブジェクトへのポインタのみが格納されます。表emp_tab_reflistのREF値は、表addr_tab内のオブジェクトのみを参照するので、例18-27に示すように、REF列に有効範囲制約および索引を作成できます。

例18-23 コレクションの表外格納

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;
/

例18-24 生成された表外のコレクション型

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

例18-25 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

例18-26 表外のコレクションの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 |

例18-27 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);

例18-26と同じ問合せの実行計画の断片は、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 |

18.9 複雑または大規模なXML Schemaの操作の考慮事項

XML Schemaは複雑になることがあります。複雑なスキーマの例として、再帰的なスキーマや循環参照を含むスキーマなどがあります。複雑または大規模なXML Schemaの操作は困難で、いくつかの点を考慮する必要があります。

18.9.1 XML Schema間での循環依存

W3C XML Schema勧告では、complexTypesおよびグローバル要素に再帰的参照を挿入できます。この種の構造では、対象の要素が再帰的階層で無限に出現する可能性があるインスタンス・ドキュメントを使用できます。

たとえば、complexType定義に、同じcomplexTypeに基づく要素を含めることができます。またはグローバル要素に自己参照を含めることができます。いずれの場合も、直接または間接的な参照にできます。

例18-28 循環依存を使用した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>

例18-28のXML Schemaには、循環依存が含まれています。complexType personTypeは、personName属性およびdescendant要素のコレクションで構成されます。descendant要素は、personTypeの実体として定義されます。

18.9.1.1 XML Schemaの循環依存のためのパラメータGenTablesのTRUE設定

Oracle XML DBでは、循環スキーマ依存を含むXML Schemaをサポートしています。循環を検出して使用不可にし、XML Schema登録時に作成された別々のXMLType表に再帰的要素を行として格納することで、このサポートを実現しています。

したがって、この種の構造を定義するXML Schemaを登録する場合は、パラメータgenTablesがTRUEに設定されていることが重要です。再帰的要素の格納に使用する表の名前は、XML Schemaにxdb:defaultTable注釈を追加することで指定できます。

18.9.1.2 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では、複合型の定義間に循環を設定できます。図18-3にこれを示します。複合型CT1の定義は別の複合型CT2を参照でき、CT2の定義は最初の型CT1を参照します。

XML Schemaでは、複合型の定義間に循環を設定できます。例18-29では、長さが2の循環が作成されます。

SQL型では、型の定義で循環を使用できません。ただし、REF(参照)オブジェクト属性を伴う循環など、弱い循環はサポートされます。必要に応じて強制的にSQLInline="false"を設定することで循環を回避し、循環するXML Schema定義はSQLオブジェクト型にマップされます。これによって、弱いSQL循環が作成されます。

例18-29の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;

図18-3 同じXML Schemaの異なるcomplexType間での相互参照

循環する複合型に、自己参照する複合型の宣言が含まれる場合があります。例18-30では、SectionT型が自己参照しています。

例18-30のXML Schemaでは、Oracle XML DBによって次の型が生成されます。

CREATE TYPE body_coll AS VARRAY(32767Footref 11);
CREATE TYPE section_t AS OBJECT (SYS_XDBPD$  XDB.XDB$RAW_LIST_T,
"title"     VARCHAR2(32767Footref 11),
"body"      BODY_COLL,
"section"   XDB.XDB$REF_LIST_T) NOT FINAL;

注意:

例18-30では、オブジェクト属性sectionはXMLTypeインスタンスへのREF参照のVARRAYとして宣言されます。埋込みセクションが複数存在する可能性があるので、属性はVARRAYになります。これはSQLオブジェクトの循環が構成されないようにするためにも、属性はXMLTypeインスタンスのREF参照のVARRAYになります。

図18-4に、スキーマでのcomplexTypeの自己参照の方法を示します。

図18-4 XML Schema内での複合型の自己参照

関連項目:

「XML Schema間での循環参照」

例18-29 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;

例18-30 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;

18.9.1.3 XML Schema間での循環参照

XML Schemaどうしを、通常の方法で逐次的に登録できないように、相互に依存させることができます。

これを図18-5に示します。

図の上半分は、3つのXML Schema間の間接循環参照の例を示しています。

図の下半分は、2つのXML Schema間の循環依存の例を示しています。最初に、この簡単な例の詳細を説明します。

図18-5 XML Schema間での循環参照

他のXML Schemaを含むXML Schemaは、その含まれるXML Schemaが存在しない場合には作成できません。xm40a.xsdが存在しない場合、例18-31のXML Schema xm40.xsdの登録は失敗します。

ただし、例18-32に示すように、オプションFORCE => TRUEを指定した場合は、XML Schema xm40.xsdを作成できます。

ただし、例18-33のように、XML Schema xm40.xsdを使用しようとすると失敗します。

例18-34に示すように、FORCEオプションを使用してxm40a.xsdも登録すると、CREATE TABLE文で示されるように、両方のXML Schemaを使用できます。

したがって、相互に依存するこれらの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が有効になります。

例18-31 存在しない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;
/

例18-32 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;
/

例18-33 循環するXML Schemaを使用した表作成の試行

CREATE TABLE foo OF XMLType XMLSCHEMA "xm40.xsd" ELEMENT "Emp";

例18-34 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";

18.9.2 再帰的スキーマのサポート

表外の表の再帰構造に対するREFにより、コンパイル時に構造の深さがわからなくなるため、XPath問合せのリライトが困難になる場合があります。XPathリライトを可能にするには、再帰構造でDOCID列がルート文書を指すようにします。

これにより、一部のXPath問合せで表外の表を直接使用して、この列を使用して後戻り結合できるようになります。

文書が相互に関連する再帰的な問合せは、'//'を含むXPath式またはXQuery式、およびXMLTypeインスタンスを受け入れるSQL関数を使用する問合せです。文書が相互に関連する再帰的な問合せは、次の条件の両方を満たすことが問合せのコンパイル時に決定できる場合は、リライトできます。

- XPath式またはXQuery式のターゲットとなるXMLTypeインスタンスのすべてのフラグメントが単一の表外の表に存在すること。

- XMLTypeインスタンスの他のフラグメントが同じ表外の表に存在しないこと。

リライトされた問合せは、DOCID列に基づいて表外の表と結合されます。

'//'を持つその他の問合せもリライトできます。たとえば、スキーマの異なるセクションにある、すべて同じ型のaddress要素がいくつかある場合に、ドキュメント内の場所を特定せずに'//'を持つすべてのaddress要素を頻繁に問合せする場合は、リライトが発生する可能性があります。

スキーマの登録中に、追加のDOCID列が表外のXMLType表に生成されます。この列には文書のOID (Object Identifier Values)つまりルート要素が格納されます。この列はデータが表に挿入されると自動的に移入されます。DOCID列を含む表をエクスポートし、後でそれをインポートできます。

例18-35 再帰的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>

18.9.2.1 一般的な表外の要素間で共有されるdefaultTable

同じ修飾名(名前空間およびローカル名)と同じ型の表外の要素は、同じデフォルト表に格納されます。特殊な場合として、循環型要素構造のルート要素を、サブ要素と同じ表の表外に格納できます。

デフォルト表を共有する両方の要素は表外の要素である必要があります。つまり、表外の要素のデフォルト表は最上位要素の表と同じにできません。同じにするには、両方の要素にxdb:SQLInline = "false"を指定し、両方の要素に同じ値を持つ明示的なxdb:defaultTable属性を指定します。

例18-36は、表外の表がABCSECTIONTABに格納されているXML Schemaを示しています。

例18-36の表外のAbcSection要素は、両方とも同じデフォルト表ABCSECTIONTABを共有しています。

ただし、例18-37は、デフォルト表の無効な共有を示しており、再帰的要素(XyZSection)は同じ表外の表を共有しません。

次の問合せはリライトできません。

SELECT XMLQuery('//XyzSection' PASSING OBJECT_VALUE RETURNING CONTENT)
FROM xyzcode;

例18-36 表外の表

<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>

例18-37 デフォルト表の無効な共有

<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>

18.9.2.2 DOCIDが存在する場合の問合せのリライト

// XPath式を処理する前に、同じ要素が複数回出現していないか確認します。//の下にあるすべての出現が同じdefaultTableを共有する場合、DOCIDを使用した表に対して問合せをリライトできます。

//の下ではなく、その表を共有しているルートの下に、同じ要素の出現が他にある場合、問合せはリライトできません。

たとえば、次の要素構造を考えます。

<Book>が<Chapter>および<Part>を含む。<Part>が<Chapter>を含む。

両方の<Chapter>要素が表外に格納されており、同じデフォルト表を共有しているとします。/Book//Chapterという問合せは、<Book>の下にあるすべての<Chapter>要素は同じデフォルト表を共有するので、<Chapter>要素のデフォルト表に対してリライトできます。このため、このXPath問合せは、文書が相互に関連する再帰的なXPath問合せです。

ただし、<Part>の下にあるすべての<Chapter>要素が同じ表を共有している場合でも、/Book/Part//Chapterのような問合せはリライトできません。その理由は、<Book>(同様にその表を共有しているドキュメント・ルート)の下に別の<Chapter>があるからです。

例18-36の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がその他とともに表外に格納されていない場合、問合せをリライトできます。

18.9.2.3 DOCID列の作成の無効化

DBMS_XMLSCHEMA.registerSchemaを呼び出す際、OPTIONSパラメータを指定することで、DOCID列の作成を無効化できます。これにより、スキーマ登録時に生成されるすべてのXMLType表でDOCIDの作成が無効化されます。

OPTIONSは、データ型PLS_INTEGERの入力パラメータです。デフォルト値は0で、この場合オプションは使用されません。列DOCIDの生成を継承するには、パラメータOPTIONSをDBMS_XMLSCHEMA.REGISTER_NODOCID (つまり1)に設定してください。

関連項目:

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

18.9.3 ラージ・オブジェクト(LOB)にマップできるXMLフラグメント

複合要素をCLOBまたはBLOBとして使用できるように、SQLデータ型を指定できます。

たとえば、図18-6では、XMLフラグメント全体がLOB属性に格納されます。

例18-38では、注釈SQLType = "CLOB"を使用して、XML Schemaで要素Addrを定義しています。

図18-6 CLOBインスタンスへのcomplexTypeのXMLフラグメントのマッピング

例18-38 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);

18.9.4 ORA-01792およびORA-04031: 大規模XML Schemaに関する問題

大規模または複雑なXML Schemaを操作すると、エラーORA-01792およびORA-04031が発生することがあります。これらは、XML Schemaを登録する際、またはXML Schemaによって定義されたグローバル要素に基づく表を作成する際に発生することがあります。

- ORA-01792: 表またはビューに指定できる最大列数は1000です。

- ORA-04031: 共有メモリーのstringバイトを割当てできません("string","string","string","string")

これらのエラーは、大多数の要素および属性の定義を含むcomplexTypeとしてグローバル要素が定義されているときに、グローバル要素に基づいてXMLType表または列を作成しようすると発生します。

これらは、オブジェクト・リレーショナル記憶域を使用する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を使用します。

いずれの方法を使用するかは、アプリケーション、およびデータに対して実行される問合せと更新のタイプによって決まります。

18.9.5 コレクションでの大規模な文書のロードおよび取得の考慮事項

Oracle XML DB構成ファイルxdbconfig.xmlには、ロード操作で使用されるメモリー量を制御するパラメータ(xdbcore-loadableunit-sizeおよびxdbcore-xobmem-bound)があります。

これにより、次の条件が満たされた場合は、ロード処理を最適化できます。

- 文書は次のいずれかの方法でロードされます。

- プロトコル(FTP、HTTP(S)、DAV)

- PL/SQL関数DBMS_XDB_REPOS.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により制御されます(デフォルト値は16KB)。文書に割り当てるメモリーの量は、パラメータxdbcore-xobmem-boundで指定できます(デフォルト値は1MB)。これらのパラメータの値はKBで指定します。つまり、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

18.9.5.1 構成パラメータxdbcore-loadableunit-sizeおよびxdbcore-xobmem-boundのガイドライン

PGAサイズと試行錯誤により、構成パラメータxdbcore-loadableunit-sizeおよびxdbcore-xobmem-boundの最適な値を特定します。

一般に、アドレス指定可能な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と等しい場合は、さらにパフォーマンスを向上させるために両方のパラメータ値を大きくします。

18.10 オブジェクト・リレーショナル形式で格納されたXMLデータのためのXML Schema登録のデバッグ

オブジェクト・リレーショナル形式で格納されるXMLデータの場合、PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaを起動する前にイベント31098を設定することで、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の登録中の問題を診断するために役立ちます。

脚注の凡例

脚注1:
XML Schema注釈xdb:maintainOrderは、Oracle Database 12cリリース1 (12.1.0.1)から非推奨になりました。xdb:maintainOrder = "false"を使用すると、Ordered Collectionでなく、Unordered Collectionが使用されます。XMLデータの場合、ドキュメント内の順序を保持するために、Ordered Collection (xdb:maintainOrder = "true")を使用することをお薦めします。デフォルトで、属性xdb:maintainOrderはtrueです。

脚注2:
XML Schema注釈xdb:storeVarrayAsTableは、Oracle Database 12cリリース1 (12.1.0.1)から非推奨になりました。

脚注8:
XML Schema注釈xdb:maintainOrderおよびxdb:storeVarrayAsTableは、Oracle Database 12cリリース1 (12.1.0.1)から非推奨になりました。

脚注9:
XML Schema注釈xdb:storeVarrayAsTableは、Oracle Database 12cリリース1 (12.1.0.1)から非推奨になりました。

脚注10:
XML Schema注釈xdb:storeVarrayAsTableは、Oracle Database 12cリリース1 (12.1.0.1)から非推奨になりました。

脚注11:
この値(32767)は、初期化パラメータMAX_STRING_SIZEがEXTENDEDであることを前提としています。『Oracle Database SQL言語リファレンス』を参照してください。

19 オブジェクト・リレーショナル記憶域のXPathリライト

オブジェクト・リレーショナル形式で格納されたXMLTypeデータの場合、様々なSQL関数のXPath式引数に関する問合せは、基礎となるSQL表に対する問合せに自動的にリライトされることによって、高度に最適化されます。

- オブジェクト・リレーショナル記憶域のXPathリライトの概要

- リライトされるXPath式の例

- XPath問合せを解析および最適化する実行計画を使用する場合のガイドライン

関連項目:

「XQuery用のパフォーマンス・チューニング」

19.1 オブジェクト・リレーショナル記憶域のXPathリライトの概要

Oracle XML DBでは、XPath式を使用する問合せ(たとえば、XPath (XQuery)式を引数として取るXMLQuery、XMLTable、XMLExistsなどのSQL関数を使用する問合せ)を最適化できることがよくあります。XPath式はXML文書に対して評価されますが、このときメモリー内でそのXML文書が構成されることはありません。

この最適化をXPathリライトと呼びます。これはXML問合せの最適化の適切なサブセットで、XPath式でないXQuery式(FLWOR式など)の最適化も行われます。また列に索引が存在する場合、XPathリライトによって、オプティマイザによる問合せの評価にその索引を使用できるようになります。

Oracle XML DBによってリライトできるXPath式は、Oracle XML DBでサポートされているXPath式の適切なサブセットです。機能性を損わずにXPath式をリライトできる場合は、リライト可能なXPath式を使用してください。

XPathリライトは、次のような状況(またはこれらの状況の組合せ)で可能です。

- XMLTypeデータがオブジェクト・リレーショナル形式の列または表に格納されている場合、またはリレーショナル・データに基づいてXMLTypeビューが構築されている場合。

関連項目:

- XMLデータのリレーショナル・ビュー

- XMLTypeビュー

- 「オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け」

- XMLIndex索引を使用する場合。

関連項目:

「XMLIndex」

ここでは、第1のケースである、オブジェクト・リレーショナルXMLデータまたはXMLTypeビューを使用する問合せのリライトについて説明します。XMLTypeビューは、XML Schemaに基づくビューでも、XML Schemaに基づかないビューでもかまいません。XMLTypeデータのオブジェクト・リレーショナル記憶域は常に、XML Schemaに基づいています。この章の例は、XML Schemaに基づく表に関するものです。

オブジェクト・リレーショナルXMLデータでXPathリライトが可能な場合、データベース・オプティマイザは従来の関係代数に基づいて実行計画を導出できます。これはまた、Oracle XML DBが、データベースのすべての機能を使用でき、XQuery式やXPath式を含むSQL文がパフォーマンスの高い効率的な方法で実行されることが保証されることを意味します。このリライトによるオーバーヘッドはほとんどないため、Oracle XML DBは、リレーショナルSQL文とほぼ同じ速度でXQueryベースおよびXPathベースの問合せを実行できます。

XPathリライトを実行できない場合もあります。これは、通常、XPath式に対して同等のSQLがない場合に発生します。この場合、Oracle XML DBはXPath式の機能評価を実行し、一般に、処理する文書数が多い場合は特に、コストが増加します。

例19-1は、XPath式を使用する単純な問合せのXPathリライトを示しています。

関連項目:

「オブジェクト・リレーショナル記憶域に対するXML Schema注釈のガイドライン」

例19-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';

19.2 リライトされる一般的なXPath式

XPathリライト中にリライトされる最も一般的なXPath式について説明します。

表19-1に説明を示します。

表19-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用のパフォーマンス・チューニング」を参照してください。

19.3 表外の表に対するXPathリライト

表外に格納されている要素を含むXPath式は自動的にリライトできます。リライトされた問合せでは、表外の表との結合が行われます。

例19-2に、このような問合せを示します。XQuery式はSQL EXISTS副問合せにリライトされています。これは表addr_tabを問い合せ、表addr_tab内のオブジェクト識別子列を使用して表emp_tabと結合します。オプティマイザは表emp_tabおよびaddr_tabの全表スキャンを使用します。addr_tabに多数のエントリがある場合、例19-3に示すように、cityに索引を作成することで、この問合せの効率を高めることができます。例19-2と同じ問合せの実行計画の断片は、cityの索引が取得されることを示しています。

注意:

オブジェクト・リレーショナルに格納されているXMLType表でオプティマイザの統計を収集する場合、XML Schemaで定義されたすべての表、つまりUSER_XML_TABLES内のすべての表で統計を収集することをお薦めします。そのためには、プロシージャDBMS_STATS.gather_schema_statsを使用するか、対象の各表に対してDBMS_STATS.gather_table_statsを使用します。これによりオプティマイザは、XMLTypeデータを格納するために使用されているすべての依存表について情報を取得できます。

例19-2 表外の表の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.

例19-3 表外の表での索引の使用

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 |

19.4 XPath問合せを解析および最適化する実行計画を使用する場合のガイドライン

実行計画を使用して、問合せの実行を分析して、(a) XPathリライトが発生したかどうかを確認し、(b) 2次索引を使用して問合せの実行を最適化するガイドラインを示します。これらのガイドラインは、オブジェクト・リレーショナル形式で格納されるXMLTypeデータにのみ適用されます。

これらのガイドラインを一緒に使用し、適用されるすべての事項を考慮します。

オブジェクト・リレーショナル記憶域のXPathリライトとは、XPath式で定義されるXMLフラグメントを選択する問合せが、基礎となるオブジェクト・リレーショナル表および列のSQL SELECT文にリライトされることです。基礎となるこれらの表には、表外の表を含めることができます。

PL/SQLプロシージャDBMS_XMLSTORAGE_MANAGE.XPath2TabColMappingを使用すると、指定されたXPath式に対応する基礎となる表および列の名前を検索できます。

関連項目:

- 「表外の表に対するXPathリライト」

- プロシージャXPath2TabColMappingの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

19.4.1 ガイドライン: 実行計画内のXML関数に対する基礎となる表の検索

リライトされた問合せの実行計画は、問合せ対象のXMLTypeデータの基礎となるオブジェクト・リレーショナル表および列の名前を参照します。これらの名前は、XML要素または属性名から導出された場合、またはXML Schema注釈xdb:defaultTableが使用された場合に、意味を持つ場合があります。

そうでない場合、名前はシステムにより生成され、明確な意味を持ちません。これらの名前には、対応するXML要素または属性の名前はを反映されません。

また、システム生成の列の一部は、通常は非表示です。SQL describeコマンドを使用すると、それらは表示できません。その場合でも実行計画には表示されます。

リライトされていない問合せの計画には、実表の名前のみが表示され、通常は、XMLExistsなどのユーザー・レベルXML関数を参照します。問合せが最適化されているかどうかを判断するには、この違いを調べてください。実行計画に表示されるXML関数名は、実際には内部名(XMLEXISTS2など)で、ユーザー・レベルの名前と多少異なることがあります。

例19-4に、Oracle XML DBがXPathリライトを実行できない場合に生成される実行計画の出力の種類を示します。ここでの計画はSQL/XML関数XMLExistsを使用する問合せに対するものです。計画の出力に、対応する内部関数XMLExists2があり、これは問合せがリライトされないことを示します。

この場合、Oracle XML DBは、問合せのWHERE句で指定した他の条件に基いて、事前フィルタされた結果セットを構成します。次に、この潜在的な結果セットの行をフィルタして、結果セットに属する行を決定します。フィルタリングでは、各文書でDOMが構築され、DOM APIにより定義されたメソッドを使用して機能評価が実行され、各文書が結果セットのメンバーかどうかが判断されます。

例19-4 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)

19.4.2 ガイドライン: 実行計画で認識するためのオブジェクト・リレーショナル表の名前付け

XML Schemaを設計する場合は、注釈xdb:defaultTableを使用して、基礎となる表に名前を付けます。この表はパフォーマンスが重要な問合せで選択する要素に対応します。これにより、実行計画でそれらを容易に識別できるようになり、問合せがリライトされたかどうかがわかります。

コレクション表には、対応するXML Schema注釈がありません。コレクション表にわかりやすい名前を付けるには、最初にXML Schemaを登録する必要があります。その後で、PL/SQLプロシージャDBMS_XMLSTORAGE_MANAGE.renameCollectionTableを使用すると、登録時に作成された表の名前(システムで生成された名前)を変更できます。

関連項目:

プロシージャrenameCollectionTableの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

19.4.3 ガイドライン: 述語でターゲットとなっている列に対する索引の作成

SQL述語のターゲットとなる列に適用される索引を作成して、そのSQL述語を含むようにリライトされる問合せのパフォーマンスを向上できる場合があります。

XPathリライトから生成された問合せには、SQL述語(WHERE句)が含まれる場合があります。これは、元の問合せでXPath述語が使用されない場合や、元の問合せにSQL WHERE句がない場合でも発生することがあります。

この場合は、SQL述語のターゲットとなる列に対して索引を作成したり、その列の関数適用に対して索引を作成することで、パフォーマンスを向上できる場合があります。

例19-1は、WHERE句を含む問合せのXPathリライトを示しています。例19-5は、この問合せの実行計画からの述語情報を示しています。

述語情報では、発注書SYS_NC0021$の要求者情報が格納される、基礎となるリレーショナル列のSQL関数castの使用に合せて、XMLCast(XMLQuery...))式がリライトされることを示します。この列名はシステム生成されます。適用されるXML Schemaでは、注釈SQLNameを使用してこの列REQUESTORに名前を付けますが、実行計画では、システム生成されたこの名前を参照します。

これらの2つの名前(ユーザー定義およびシステム生成)は同じ列を参照するため、いずれかの名前を使用して、この列に対してBツリー索引を作成できます。また、extractValueショートカットを使用し、発注書の要求者データをターゲットとするXPath式を指定することで索引を作成することもできます。

プロシージャDBMS_XMLSTORAGE_MANAGE.XPath2TabColMappingを使用すると、指定されたXPath式に対応する基礎となる表および列の名前を取得できます。例19-6は、例19-1のWHERE句で使用されているXPath式/PurchaseOrder/Requestorで、これを説明しています。

ワイルドカードまたは子孫軸を含むXPath式を指定する場合、複数の表および列が選択されます。その場合、プロシージャXPath2TabColMappingでは、複数の<Mapping>要素(表と列のペアごとに1つずつ)を戻します。

その後、この方法で取得した表名および列名をCREATE INDEX文で使用すれば、XPath式に対応する索引を作成できます。例19-7は、述語でターゲットとなっている列に対してBツリー索引を作成する3つの同等の方法を示しています。

ただし、この問合せでは、リライトされた問合せの式に一致するファンクション式を使用してファンクション索引を作成することをお薦めします。例19-8に、これを示します。

例19-9は、索引が取り出されることを示す実行計画を示しています。

この問合せの場合では、元のファンクション式によってXMLCastがXMLQueryに適用され、単一要素のRequestorがターゲットになります。これは、CREATE INDEX文でこうしたファンクション式をショートカットとして直接使用できる特殊なケースです。基礎となるスカラー・データ上に索引を作成するように、その文がリライトされます。例19-10はXPath式をターゲットとしており、対応するオブジェクト・リレーショナル列をターゲットとする例19-8と同じ結果になります。

関連項目:

- XMLQueryに適用されるXMLCastのショートカットおよび単一のデータに索引付けするためのextractValueショートカットの使用方法の詳細は、「繰り返し使用しないテキスト・ノードまたは属性値の索引付け」を参照してください

- プロシージャXPath2TabColMappingの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

例19-5 実行計画の分析による列と索引の対応の特定

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)

例19-6 DBMS_XMLSTORAGE_MANAGE.XPATH2TABCOLMAPPINGの使用

SELECT DBMS_XMLSTORAGE_MANAGE.XPath2TabColMapping(USER,
'PURCHASEORDER',
'',
'/PurchaseOrder/Requestor',
'')
FROM  DUAL;

DBMS_XMLSTORAGE_MANAGE.XPath2TabColMapping(US
---------------------------------------------
<Result>
<Mapping TableName="PURCHASEORDER" ColumnName="SYS_NC00021$"/>
</Result>

例19-7 述語でターゲットとなっている列に対する索引の作成

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'));

例19-8 述語でターゲットとなっている列に対するファンクション索引の作成

CREATE INDEX requestor_index ON purchaseorder
(cast("XMLDATA"."REQUESTOR" AS VARCHAR2(128)));

例19-9 索引が取得されていることを示す実行計画

-----------------------------------------------------------------------------------------------
| 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')

例19-10 述語でターゲットとなっている列に対するファンクション索引の作成

CREATE INDEX requestor_index
ON purchaseorder po
(XMLCast(XMLQuery('$p/PurchaseOrder/Requestor' PASSING po.OBJECT_VALUE AS "p"
RETURNING CONTENT)
AS VARCHAR2(128)));

19.4.4 ガイドライン: Ordered Collection表に対する索引の作成

Ordered Collection Table (OCT)またはXMLTypeインスタンスとしてコレクションが格納されている場合は、コレクションのメンバーに直接アクセスできます。各メンバーは表の行になるため、SQLで直接アクセスできます。このようなコレクション・メンバーに索引付けすることによって、パフォーマンスを向上できます。

これを実行するには、コレクションXML要素またはその属性、および疑似NESTED_TABLE_IDに対応するオブジェクト属性に対して、コンポジット索引を作成します。

例19-11では、部品番号717951002372 (Id属性の値が717951002372のPart要素)の発注を含む文書からReference要素を検索する問合せの実行計画を示します。LineItem要素のコレクションは、Ordered Collection Table、lineitem_tableに行として格納されています。

注意:

例19-11では、サンプル・データベース・スキーマOEのpurchaseorder表を使用しません。これは、コレクション要素LineItemのlineitem_tableという名前のOrdered Collection Table (OCT)を使用するpurchaseorder表を使用します。

実行計画は、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にマップされています。これらの情報に基づいて、例19-12に示すように、属性part_numberおよび疑似列NESTED_TABLE_IDに対するコンポジット索引を作成できます。この索引によって、必要な部品を参照するLineItem要素が含まれた発注書に直接アクセスできます。

例19-11 コレクション要素の選択の実行計画

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             |                        |    21 |  2352 |    20  (10)| 00:00:01 |
|*  1 |  HASH JOIN RIGHT SEMI        |                        |    21 |  2352 |    20  (10)| 00:00:01 |
|   2 |   JOIN FILTER CREATE         | :BF0000                |    22 |   880 |    14   (8)| 00:00:01 |
|*  3 |    TABLE ACCESS FULL         | LINEITEM_TABLE         |    22 |   880 |    14   (8)| 00:00:01 |
|   4 |   JOIN FILTER USE            | :BF0000                |   132 |  9504 |     5   (0)| 00:00:01 |
|*  5 |    TABLE ACCESS FULL         | PURCHASEORDER          |   132 |  9504 |     5   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("NESTED_TABLE_ID"="PURCHASEORDER"."SYS_NC0003400035$")
3 - filter("SYS_NC00011$"='717951002372')
5 - filter(SYS_OP_BLOOM_FILTER(:BF0000,"PURCHASEORDER","SYS_NC0003400035$"))

例19-12 Ordered Collection Tableに直接アクセスするための索引の作成

CREATE INDEX lineitem_part_index ON lineitem_table l (l.part.part_number, l.NESTED_TABLE_ID);

19.4.5 ガイドライン: XMLOptimizationCheckを使用した、問合せがリライトされない理由の特定

問合せが最適化されていない場合、システム変数XMLOptimizationCheckを使用して理由を特定できます。

関連項目:

「XQueryの最適化の診断: XMLOptimizationCheck」

脚注の凡例

脚注1:
この例では、サンプルのデータベース・スキーマOEとその表purchaseorderを使用しています。この表のXML Schemaには、REQUESTORなどのSQLオブジェクト属性名を指定するために、属性SQLNameで注釈が付けられています(例A-2を参照)。このような注釈を使用しないと、例では、p."XMLDATA".".REQUESTOR"ではなくp."XMLDATA"."Requestor"が使用されます。

20 XML Schemaの拡張

XML Schemaの拡張を使用すると、XML SchemaをOracle XML DBに登録した後に更新できます。

- XML Schemaの拡張の概要

- コピーに基づくスキーマの拡張

- インプレースXML Schemaの拡張

Oracle XML DBでは、W3C XML Schema勧告をサポートしています。XML Schemaに準拠するXMLインスタンス・ドキュメントは、SQLおよびプロトコル(FTP、HTTP(S)、WebDAVなど)を使用して格納および取得できます。XML Schemaは、XML文書の構造指定に加え、XMLとオブジェクト・リレーショナル記憶域間のマッピングを判断します。

関連項目:

XML Schemaの格納と問合せ: 基本

20.1 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プロシージャがそれぞれ用意されています。この章では、各プロシージャの使用方法について説明し、それに関連するスキーマの拡張方法のガイドラインを提示します。

20.2 コピーに基づくスキーマの拡張

PL/SQLプロシージャDBMS_XMLSCHEMA.copyEvolveを使用して、コピーに基づくXML Schemaの拡張を実行します。これにより、既存のインスタンス・ドキュメントが一時XMLType表にバックアップされて、古いバージョンのXML Schemaが削除されて(関連インスタンス・ドキュメントも削除されます)、新しいバージョンが登録されて、バックアップしたインスタンス・ドキュメントが新規XMLType表にコピーされます。

問題が発生した場合、バックアップ・コピーはリストアされます。「プロシージャDBMS_XMLSCHEMA.COPYEVOLVEでのエラー発生時のロールバック」を参照してください。

プロシージャcopyEvolveを使用すると、既存のXMLインスタンス・ドキュメントの有効性を保持しながら、登録されたXML Schemaを拡張できます。

20.2.1 コピーに基づく拡張の使用例

拡張されたバージョンの発注書XML Schemaを示します。これは、コピーに基づくXML Schemaの拡張の使用方法を示す例で使用されます。

例20-1は、例A-2の発注書XML Schemaの修正バージョンのリストの一部を示します。完全な修正スキーマのリストは、例A-3を参照してください。この例では、太字のテキストが新規部分、または元のスキーマと異なる部分です。

例20-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>

20.2.2 COPYEVOLVEパラメータおよびエラー

PL/SQLプロシージャDBMS_XMLSCHEMA.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);

表20-1に、各パラメータについて説明します。表20-2に、このプロシージャに関連するエラーについて説明します。

表20-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を含む新規の表または列を記憶域モデルとして作成します。

表20-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の警告: 一時表がクリーンアップされていません

スキーマが拡張された後、一時表のクリーンアップでエラーが発生しました。スキーマの拡張は正常に終了しています。

一時表を削除する必要がある場合は、マッピング表を使用して一時表の名前を取得し、その一時表を削除します。

20.2.3 プロシージャCOPYEVOLVEの制限事項

PL/SQLプロシージャ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オブジェクト属性を処理しないことに注意してください。そのような場合はエラーが発生します。

20.2.4 プロシージャCOPYEVOLVEの使用時のガイドライン

PL/SQLプロシージャDBMS_XMLSCHEMA.copyEvolveを使用するための一般的なガイドラインと、特定のコンテキストに固有のガイドラインを示します。

次の一般的なガイドラインが、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、新しいスキーマおよび変換スタイルシートを指定します。

20.2.4.1 最上位要素名の変更

PL/SQLプロシージャDBMS_XMLSCHEMA.copyEvolveでは、新しいスキーマの最上位要素は削除されていないこと、およびその名前が変更されていないことを前提としています。そのような変更がある場合、文書のバックアップ・コピーを使用できるように、パラメータgenerateTablesをFALSEに、パラメータpreserveOldDocsをTRUEに設定して、プロシージャcopyEvolveをコールします。

これらのパラメータ値を使用すると、新しい表は生成されず、古いドキュメント(バックアップ・コピー)を保持する一時表はプロシージャの最後に削除されません。その場合、古いドキュメントを適切な形式で格納し、一時表を削除できます。これらのパラメータの使用の詳細は、「COPYEVOLVEパラメータおよびエラー」を参照してください。

20.2.4.2 デフォルト表以外の表のユーザー作成の仮想列

デフォルト表でない表では、コピーに基づく拡張では作成した仮想列は再作成されません。このような列が必要な場合、copyEvolveパラメータpreserveOldDocsをTRUEに設定して表を作成し、プロシージャcopyEvolveが完了した後に古いドキュメントをコピーします。

20.2.4.3 XML Schemaとその依存が同時セッションで使用されないようにする方法

XML Schemaの拡張処理中は、拡張するXML Schemaとその依存を同時セッションで使用しないようにしてください。

拡張処理の開始時に、他の同時セッションがこのスキーマに対する共有ロックを保持していた場合、プロシージャDBMS_XMLSCHEMA.copyEvolveは、排他ロックを取得できるように、これらのセッションによるロックのリリースを待機します。ただし、このロックは、残りの処理を継続できるようにただちにリリースされます。

20.2.4.4 プロシージャDBMS_XMLSCHEMA.COPYEVOLVEでのエラー発生時のロールバック

プロシージャDBMS_XMLSCHEMA.copyEvolveは、完全に成功するか、エラーが発生するかのいずれかです。エラーが発生した場合は、可能なかぎり多くの操作のロールバックを試行します。

XML Schemaの拡張には、多くのデータベースDDL文が含まれます。エラーが発生した場合、補正DDL文が実行され、その地点までに実行されたすべての手順を取り消します。古い表またはスキーマが削除された場合、再作成されますが、表、列、記憶域のプロパティおよび表や列に関連する補助構造(索引、トリガー、制約およびRLSポリシーなど)は失われます。

20.2.4.5 不十分な権限に起因するロールバックの失敗

場合によっては、コピーに基づく拡張の操作はロールバックできません。たとえば、新規XML Schemaに関係のない理由で表の作成に失敗した場合は、ロールバックする方法がありません。

その理由には、不十分な権限による失敗などがあります。一時表はpreserveOldDocsがFALSEに設定されている場合にも削除されないため、データはリカバリできます。mapTabNameパラメータがNULLの場合、マッピング表はXDB$MAPTABの後に順序番号が続く名前となります。正確な表名は、次の問合せを使用して確認できます。

SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME LIKE 'XDB$MAPTAB%';

20.2.4.6 XML Schemaの拡張に必要な権限

コピーに基づくXML Schemaの拡張を実行するには、いくつかのデータベース権限が必要になる場合があります。

コピーに基づくXML Schemaの拡張にはSQLデータ型の削除または作成が伴う場合があるため、DROP TYPE、CREATE TYPEおよびALTER TYPEなどの型に関連する権限が必要です。スキーマを拡張するには、拡張に関係するXML Schemaを削除および登録する権限が必要です。拡張するスキーマに準拠するXMLType表に対するすべての権限が必要です。XMLType列については、対応する表に対するALTER TABLE権限が必要です。他のデータベース・スキーマ内にXML Schemaに基づくXMLType表または列が存在する場合は、次のような権限が必要です。

- CREATE ANY TABLE

- CREATE ANY INDEX

- SELECT ANY TABLE

- READ ANY TABLE

- UPDATE ANY TABLE

- INSERT ANY TABLE

- DELETE ANY TABLE

- DROP ANY TABLE

- ALTER ANY TABLE

- DROP ANY INDEX

他のデータベース・スキーマに属するXML Schemaに基づくXMLType表または列がある場合は、これらのすべての権限をデータベース・スキーマ所有者に付与しなくてすむように、データベース管理者が拡張を実行することをお薦めします。

20.2.5 XSLTスタイルシートを使用した既存のXMLインスタンス・ドキュメントの更新

登録済XML Schemaを変更した後は、そのXML Schemaを使用する既存のXMLインスタンス・ドキュメントも更新する必要があります。更新するには、各インスタンス・ドキュメントにXSLTスタイルシートを適用します。このスタイルシートは、古いXML Schemaと新しいXML Schemaの差分を表します。

例20-2はファイルevolvePurchaseOrder.xsl内のXSLTスタイルシートを示しています。これによって、古いXML Schemaを使用していた既存の発注書が新しいXML Schemaを使用するように変換されます。

例20-2 evolvePurchaseOrder.xsl: インスタンス・ドキュメントを更新するXSLTスタイルシート

<?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>

20.2.6 プロシージャCOPYEVOLVEの使用時の例

PL/SQLプロシージャDBMS_XMLSCHEMA.copyEvolveを使用してXML Schemaを更新する例をいくつか示します。(プロシージャを使用する前に、必ず、すべての登録済XML Schemaとそれを参照するXML文書をバックアップしてください。)

例20-3では、修正されたXML Schemaおよび拡張XSLスタイルシートをOracle XML DBリポジトリにロードします。

例20-4は、プロシージャDBMS_XMLSCHEMA.copyEvolveを使用し、XSLTスタイルシートevolvePurchaseOrder.xslによってXML Schema purchaseOrder.xsdをrevisedPurchaseOrder.xsdに拡張する方法を示しています。

プロシージャ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表には、表20-3で示すような列が一時表に存在します。

表20-3 XML Schemaの拡張: XMLType表の一時表の列

名前

型

コメント

Data

CLOB

CLOB形式の古い表からのXML文書。

OID

RAW(16)

古い表で対応する行のOID。

ACLOID

RAW(16)

この列は、古い表が階層に対応している場合のみ存在します。古い表で対応する行のACLOID。

OWNERID

RAW(16)

この列は、古い表が階層に対応している場合のみ存在します。古い表で対応する行のOWNERID。

XMLType列には、表20-4で示すような列が一時表に存在します。

表20-4 XML Schemaの拡張: XMLType列の一時表の列

名前

型

コメント

Data

CLOB

CLOB形式の古い列からのXML文書。

RID

ROWID

この列が含まれる表の対応する行のROWID。

プロシージャCopyEvolveは、古い表または列名から、mapTabNameパラメータで指定された個別の表に対応する一時表名へのマッピングに関する情報を格納します。preserveOldDocsがTRUEの場合、mapTabNameパラメータは、NULL以外の値であり、かつ現行ユーザーのスキーマに存在しない表名である必要があります。マッピング表の各行には、古い表または列の1つに関する情報が含まれます。表20-5に、マッピング表の列を示します。

表20-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言語リファレンス』を参照してください。

例20-3 修正されたXML SchemaおよびXSLTスタイルシートのロード

DECLARE
res BOOLEAN;
BEGIN
res := DBMS_XDB_REPOS.createResource(         -- Load revised XML schema
'/source/schemas/poSource/revisedPurchaseOrder.xsd',
bfilename('XMLDIR', 'revisedPurchaseOrder.xsd'),
nls_charset_id('AL32UTF8'));
res := DBMS_XDB_REPOS.createResource(         -- Load revised XSL stylesheet
'/source/schemas/poSource/evolvePurchaseOrder.xsl',
bfilename('XMLDIR', 'evolvePurchaseOrder.xsl'),
nls_charset_id('AL32UTF8'));
END;/

例20-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>

20.3 インプレース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が妥当なスキーマでなかった場合、インプレースの拡張は失敗します。

20.3.1 インプレースのXML Schemaの拡張の制限

インプレースのXML Schemaの拡張ではデータをコピーしないため、XML Schemaへの任意の変更は許可されません。インプレース拡張を使用する際の主要な制限は一般に、指定されたXML Schemaが、下位互換にのみインプレース拡張できることという要件として記述できます。

インプレースの拡張でサポートされている変更の完全なリストは、インプレースのXML Schema拡張でサポートされる操作を参照してください。

つまり、下位互換とは、指定のXML Schemaに対して検証される可能性のあるすべてのインスタンス・ドキュメントは、そのXML Schemaの将来の(拡張)バージョンでも同様に検証される必要があります。これは既存のインスタンス・ドキュメントに限らず、すべての可能な準拠インスタンス・ドキュメントに適用されます。バイナリXMLとして格納されたXMLデータの場合、下位互換性は、バイナリXML処理に影響を与えるXML Schema注釈は拡張中に変更できないことも意味します。下位互換性の詳細は、下位互換性の制約で説明します。

この一般的な下位互換性制限に加え、インプレースの拡張には他の制約もあります。それについては項「インプレース拡張のその他の制限」で説明します。

20.3.1.1 下位互換性の制約

説明するインプレースXML Schemaの拡張の制限により、拡張されたスキーマの下位互換性が保証されるため、以前のXML Schemaを満足させる可能なインスタンス・ドキュメントはすべて、新しいスキーマを満足させます。

20.3.1.1.1 ディスク上のデータ・レイアウトの変更

XML Schemaへの一定の変更は、関連付けられるディスク上のインスタンス・ドキュメントのレイアウトが変更されるため許可されていません。これはオブジェクト・リレーショナル記憶域の場合と同様、記憶域のレイヤーがXML Schemaから導出された情報と密に統合されている場合に一般的な状況です。

そのような例の1つは、オブジェクト・リレーショナル記憶域のマッピングとして登録されたXML Schemaで、1つの複合型を2つの複合型に分割することで拡張されます。例20-5では、複合型ShippingInstructionsTypeが2つの複合型Person-NameとContact-Infoに分割され、ShippingInstructionsType複合型は削除されます。

このXML Schemaに関連付けられているインスタンス・ドキュメントがないため、データのコピーが不要な場合でも、今後のインスタンス・ドキュメントに対応するために既存の表のレイアウトを変更する必要があります。

例20-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>

20.3.1.1.2 XML Schema構造体の再順序付け

XMLインスタンス・ドキュメントのDOM再現性に影響を及ぼすような方法では、XML Schema要素の再順序付けにインプレースの拡張を使用できません。たとえば、複合型定義での<sequence>要素内の要素の順序は変更できません。

具体的には、複合型ShippingInstructionsTypeでその子要素をname、address、telephoneの順にする必要がある場合、順序をname、telephone、addressに変更するためにインプレースの拡張は使用できません。

20.3.1.1.3 コレクションから非コレクションへの変更

コレクションから非コレクションへの変更に、インプレースの拡張は使用できません。例としては、1より大きいmaxOccursから1であるmaxOccursへの変更が考えられます。そのため、削除でコレクションから非コレクションへの拡張が必要となる場合、インプレースの拡張では複合型から要素は削除できません。

20.3.1.1.4 複合型要素内のモデルの変更

モデルは、group、choice、sequenceまたはallの要素です。complexType要素内では、インプレース拡張を使用して、新しいモデルを追加することや既存のモデルを別の型のモデルで置き換える(たとえば、choice要素をsequence要素で置き換える)ことはできません。

しかし、グローバルgroup要素を追加、つまりcomplexType要素以外のgroup要素を追加できます。

20.3.1.2 インプレース拡張のその他の制限

いくつかのインプレースXML Schemaの拡張の制限は、拡張されたXML Schemaの下位互換性以外の理由で必要になります。

20.3.1.2.1 xdb名前空間の属性の変更

属性xdb:defaultTableを除き、名前空間http://xmlns.oracle.com/xdbのどの属性(事前定義された接頭辞xdbを持つもの)の変更にもインプレースの拡張は使用できません。

20.3.1.2.2 非コレクションからコレクションへの変更

オブジェクト・リレーショナルXMLTypeデータの場合、インプレースの拡張を使用して非コレクション・オブジェクト型をコレクション・オブジェクト型に変更することはできません。たとえば、複合型へ既存の要素と同じ要素を追加する(または、継承によって関連する型へ追加する)などです。

20.3.2 インプレースの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属性は変更できません。

- グローバル・グループまたはattributeGroupの追加または削除: 常に許可されます。たとえば、型定義への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名前空間内の他の属性に対する変更は許可されません。

- コメントまたは処理命令の追加、変更、削除:常に許可されます。

20.3.3 インプレースのXML Schema拡張の使用時のガイドライン

インプレースXML Schemaの拡張に適用されるガイドラインを示します。(インプレースのスキーマ拡張を実行する前に、必ずデータをバックアップしてください。)

- インプレースXML Schemaの拡張を実行する前に、次のことを行います。

- 拡張されるXML Schemaのすべての既存データ(インスタンス・ドキュメント)をバックアップします。

注意:

結果が想定外になる場合に備えて、インプレースのXML Schema拡張を実行する前に、必ずデータをバックアップしてください。インプレース拡張の後は、ロールバックできません。拡張時にエラーが発生した場合や、大きな失敗があり操作全体の再実行が必要な場合、元のデータのバックアップ・コピーに戻せる必要があります。

- トレースのみを使用してドライ・ランを実行します。実際にXML Schemaが拡張されたり、インスタンス文書が更新されたりすることなく、拡張時に実行される更新操作のトレースが生成されます。これを実行するには、flagパラメータ値をINPLACE_TRACEにのみ設定します。INPLACE_EVOLVEは使用しないでください。
予行演習を実行した後でトレース・ファイルをチェックし、リストされたDDL操作が本当に意図したとおりであることを確認します。

- インプレースXML Schemaの拡張を実行した後で、次のことを行います。
データをキャッシュするクライアントを使用してデータベースにアクセスしている場合、または当てはまるかどうか不明な場合は、クライアントを再起動します。そうしないと、引き続き拡張前のバージョンのXML Schemaがローカルに使用され、予想外の結果になる可能性があります。

関連項目:

トレース・ファイルの使用の詳細は、『Oracle Database管理者ガイド』を参照してください。

20.3.4 inPlaceEvolveパラメータ

PL/SQLプロシージャDBMS_XMLSCHEMA.inPlaceEvolveのパラメータと、このプロシージャに関連するエラーを説明します。

プロシージャDBMS_XMLSCHEMA.inPlaceEvolveのシグネチャは、次のとおりです。

procedure inPlaceEvolve(schemaURL IN VARCHAR2,
diffXML   IN XMLType,
flags     IN NUMBER);

表20-6に、各パラメータについて説明します。

表20-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表に関連する索引オブジェクトが不安定な状態にあり、その原因がパーティション管理操作の可能性がある場合。

20.3.5 diffXMLパラメータのドキュメント

プロシージャDBMS_XMLSCHEMA.inPlaceEvolveのパラメータdiffXMLの値は、インプレースの拡張においてXML Schemaに適用される変更を指定した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言語リファレンス』を参照してください。

20.3.5.1 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>とともに使用し、既存のノードを変更できます。

例20-6は、次の変更を指定するdiffXMLパラメータのXML文書を示しています。

- 複合型PartTypeの削除。

- 最大長28での複合型PartTypeの追加。

- ShippingInstructions要素の前へのコメントの追加。

- 必須要素shipmethodのShippingInstructions要素への追加。

例20-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>

第VI部 Oracle XML DBリポジトリ

Oracle XML DBリポジトリでは、データをバージョニングしたり、セキュリティを実装および管理したり、APIを使用してリポジトリ・リソースにアクセスして操作することができます。

- Oracle XML DBリポジトリのデータへのアクセス

- Oracle XML DBリポジトリの構成

- Oracle XML DBでのXLinkおよびXIncludeの使用方法

- RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス

- リソース・バージョン

- Oracle XML DBリポジトリへのPL/SQLアクセス

- リポジトリのアクセス制御

- プロトコルを使用したリポジトリへのアクセス

- ユーザー定義のリポジトリ・メタデータ

- Oracle XML DBリポジトリ・イベント

- Oracle XML DB Content Connector

- JavaでのOracle XML DBアプリケーションの作成方法

- URIを使用したデータ・アクセス

- ネイティブなOracle XML DB Webサービス

21 Oracle XML DBリポジトリ・データへのアクセス

Oracle XML DBリポジトリ・データにアクセスして操作するには、FTPやHTTP(S)/WebDAVなどの標準プロトコルを使用する、Oracle XML DB Resource Application Program Interface (API)を使用する、リポジトリ・ビューRESOURCE_VIEWとPATH_VIEWを使用するなどのいくつかの方法があります。

- Oracle XML DBリポジトリの概要

- リポジトリの用語と提供されているリソース

- Oracle XML DBリポジトリ・リソース

- リポジトリ・リソースへのナビゲーショナル・アクセスまたはパス・アクセス

- リポジトリ・リソースへの問合せベースのアクセス

- リポジトリ・リソースへのサーブレット・アクセス

- リポジトリ・リソースに対する操作

- SQLを使用したリポジトリ・リソースのコンテンツへのアクセス

- XML Schemaに基づく文書のコンテンツへのアクセス

- リポジトリの文書のコンテンツの更新

- RESOURCE_VIEWおよびPATH_VIEW内のリソースの問合せ

- Oracle XML DBの階層リポジトリ索引

21.1 Oracle XML DBリポジトリの概要

Oracle XML DBリポジトリを使用すると、従来のリレーショナル・データベース構造ではなく、階層構造のデータベースにコンテンツを格納できます。このリポジトリでは、あらゆる種類のコンテンツを管理できますが、XMLコンテンツを持つリソースの管理に関連する特別な機能と最適化機能が用意されています。

従来、リレーショナル・データベースは、階層構造の管理や、パスまたはURLの検索には適していません。Oracle XML DBリポジトリを使用すると、データベース内のXMLコンテンツを階層構造に整理できます。ファイルやフォルダを使用して整理した場合と同様の問合せおよび管理が可能になります。

リレーショナル表/行/列隠喩は、高度に構造化されたデータの管理に効果的なモデルです。ドキュメント指向のXMLデータなど、半構造化されたデータまたは構造化されていないデータの管理には、あまり効果的ではない可能性があります。

たとえば、1冊の本を表の一連の行として表すのは容易ではありません。本は冊-章-節-段落のような階層として表すのが一般的で、その階層は一連のフォルダおよびサブフォルダとして表すことができます。

階層リポジトリ索引によって、フォルダとパスの検索が高速化されます。Oracle XML DBには、特許を取得した階層索引が含まれており、この階層索引によってOracle XML DBリポジトリ内のフォルダとパスの検索が高速化されます。階層リポジトリ索引はエンド・ユーザーに対して透過的で、Oracle XML DBでは、従来のファイル・システムと同等以上の速度でフォルダとパスの検索を実行できます。

図21-1に、典型的なツリーとして表示されるOracle XML DBリポジトリのフォルダおよびファイルの階層構造の例を示します。ツリーの上部は、ルート・フォルダ(/)です。

図21-1 リポジトリの階層構造を示すフォルダ・ツリー

注意:

フォルダ/sysは、Oracle XML DBによって、システム定義のXML Schemaやアクセス制御リスト(ACL)などをメンテナンスするために使用されます。フォルダ/sysのデータを変更したり追加したりしないでください。

Oracle XML DBリポジトリ内の内容には、SQL、PL/SQL、Java、Cの各言語に加えて、FTP、HTTP(S)、WebDAVなど標準の接続アクセス・プロトコルを使用してアプリケーションからアクセスできます。Oracle XML DBでは、文書中心の操作のために設計されたこれらのプロトコルに対するネイティブ・サポートがOracle Databaseに追加されます。これらのプロトコルをサポートすることにより、Oracle XML DBでは、Microsoft Windows Explorer、Microsoft Office、およびAltovaやAdobeなどのベンダーからの製品が、リポジトリに格納されたXMLコンテンツを直接操作できます。

リポジトリを使用すると、ファイル・システムに格納されているかのように、Oracle Databaseに格納されているXMLコンテンツに直接アクセスできます。リポジトリのファイルおよびフォルダに対するアクセス制御権限を設定できます。

こうした機能を使用できるのは、HTTPプロトコルに対する一連の拡張機能を定義しているIETF標準であるWebDAV上でリポジトリがモデル化されているためです。WebDAVによりHTTPサーバーはDAV対応クライアントに対するファイル・サーバーとして機能できます。たとえば、WebDAV対応エディタは、HTTP/WebDAVサーバーがファイル・システムであるかのように対話できます。

DAV標準では、ファイルやフォルダを示すためにリソースという用語が使用されます。WebDAVサーバーにより管理される各リソースは、URLで識別されます。リソースには、コンテンツの他に関連のメタデータがあります。

次のトピックでは、標準プロトコルを使用して、Oracle XML DBリポジトリ・フォルダのデータにアクセスする方法について説明します。Java、SQLおよびPL/SQLを使用してリポジトリ・オブジェクト階層にアクセスするために使用できるAPIについて説明します。

関連項目:

- RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス

- Oracle XML DBリポジトリへのPL/SQLアクセス

- リポジトリのアクセス制御

- プロトコルを使用したリポジトリへのアクセス

21.1.1 Oracle XML DBで提供される名前レベル・ロック

Oracle XML DBリポジトリの主要なメリットの1つは、論理トランザクションでのリポジトリ操作でSQLを使用できることです。アプリケーションによって、複数のフォルダの更新を含む、実行時間の長いトランザクションが作成される場合があります。このリポジトリでは、高いレベルの同時実行性を実現するために、フォルダ・レベル・ロックではなく名前レベル・ロックを使用します

リレーショナル・データベースを使用して階層フォルダ構造を保持する場合、フォルダに対して項目を追加または削除するときに高度な同時実行性を保証することは重要な問題です。従来のファイル・システムでは、トランザクションの概念はありません。各操作(ファイルの追加、サブフォルダの作成、ファイル名の変更、ファイルの削除など)は、基本トランザクションとして処理されます。操作が完了すると、ファイル・システムのすべてのユーザーに対して変更がすぐに反映されます。

この場合、更新されたフォルダまたはディレクトリ・ツリーに排他ロックを設定する従来のロック方針では、同時実行性に関する重大な問題がすぐに発生します。Oracle XML DBでは、フォルダ・レベル・ロックではなく名前レベル・ロックを提供して、これを解決します。サブフォルダまたはファイルの作成、名前の変更、移動、削除などのリポジトリ操作では、ターゲット・フォルダに対する排他書込みロックの付与は必要はありません。リポジトリは、フォルダ自体ではなくフォルダ内の名前をロックして、フォルダに対する同時操作を管理します。名前および変更タイプは、キューに入れられます。

トランザクションがコミットされた場合にのみ、フォルダがロックされてそのコンテンツが変更されます。したがって、Oracle XML DBでは、1つのフォルダのコンテンツに対して複数のアプリケーションが同時に更新を実行できます。また、キューを使用すると、2つのアプリケーションによる同じ名前のオブジェクトの作成を回避できるため、フォルダの同時実行性を管理できます。

同じトランザクションで1つのフォルダに対して複数の変更が行われる場合は、コミット時までフォルダの変更をキューに入れて、I/Oを最小限にすることもできます。これは、短時間の間に複数のアプリケーションが同じディレクトリ内にファイルを生成する場合に役立ちます。たとえば、トレース・ファイルやログ・ファイルを生成する場合、印刷または電子メール配信用にスプール・ディレクトリを保持する場合などです。

注意:

データベースによって適用されるトランザクション・セマンティクスの結果として、SQL文を使用して作成されたフォルダは、トランザクションがコミットされるまで他のデータベース・ユーザーから参照されません。Oracle XML DBリポジトリへの同時アクセスは、Oracle Databaseの同時実行性の制御に使用されるのと同じメカニズムを使用して制御されます。リポジトリのOracle Databaseとの統合により、XMLコンテンツに対する強力な管理オプションが提供されます。

21.1.2 Oracle XML DBリポジトリ・リソースにアクセスする2つの方法

Oracle XML DBリポジトリ・リソースにアクセスして操作するには、特別なビューでSQLを使用するか、階層索引を使用してパスにナビゲートします。

- SQLアクセス。リソースのプロパティおよびパス名を公開し、階層アクセス演算子をOracle XML DB Schemaへマップする特別のビューを使用することにより行います。「リポジトリ・リソースへの問合せベースのアクセス」を参照してください。

- ナビゲーションベースまたはパスベースのアクセス。リソースの階層索引が使用されます。各リソースは、階層内の場所を反映する、1つ以上の一意のパス名を持ちます。XPath式を使用して、任意のリポジトリ・リソースへナビゲートできます。
リポジトリ・リソースは、データベース内の既存のXMLTypeオブジェクトへの参照として作成できます。このようなデータベース・オブジェクトには、XPathを使用してナビゲートできます。「リポジトリ・リソースへのナビゲーショナル・アクセスまたはパス・アクセス」を参照してください。

関連項目:

- アクセス方法の選択の詳細は、「Oracle XML DBリポジトリへのアクセス」を参照してください。

- アクセス方法の比較の概要は、表21-3を参照してください。

Uniform Resource Locator(URL)を使用して、Oracle XML DBリソースにアクセスできます。URLには、オブジェクトのホスト名、プロトコル情報、パス名およびリソース名が含まれます。

21.1.3 データベース・スキーマ(ユーザー・アカウント) XDBおよびOracle XML DBリポジトリ

データベース・スキーマ(ユーザー・アカウント) XDBはXMLType表XDB$RESOURCEを所有し、これには、Oracle XML DBリポジトリ内のすべてのリソース(ファイルおよびフォルダ)が含まれます。また、リポジトリを管理するためのすべてのメタデータも含まれます。

データベース・スキーマXDBは、Oracle XML DBのインストール中に作成されます。このスキーマのプライマリ表はXDB$RESOURCEというXMLType表で、これには、Oracle XML DBリポジトリ内のリソース(ファイルまたはフォルダ)ごとに1行が含まれます。この表内の文書はリソース・ドキュメントと呼ばれます。Oracle XML DBのリソース・ドキュメントの構造を定義するXML Schemaは、URL http://xmlns.oracle.com/xdb/XDBResource.xsdに登録されています。

データベース・スキーマ(ユーザー)XDBが所有する表は内部です。次が推奨されます。

- ユーザーXDB (およびOracle XML DBリポジトリ)のみが使用する専用の表領域を作成します。表領域が読取り専用でないことを確認してください。

- ユーザーXDBが所有する表またはデータを直接操作することはできません。たとえば、それらを圧縮または圧縮解除しないでください。
XDBが所有する表またはデータを操作するには、Oracle XML DBが提供しているPL/SQLサブプログラムおよびデータベース・ビューのみを使用します。

- どのような場合でも、ユーザーXDBは絶対にロック解除しないでください。

関連項目:

- ユーザーXDBおよびリポジトリ専用の表領域の作成の詳細は、「パッケージDBMS_XDB_ADMIN」を参照してください。

- データベース・スキーマXDBの詳細は、『Oracle Database 2日でセキュリティ・ガイド』を参照してください。

21.2 リポジトリの用語と提供されているリソース

Oracle XML DBリポジトリは、ファイルではなくデータベース・オブジェクトのファイル・システムとして考えることができます。これは、すべてのXML Schemaおよびデータベース・スキーマをまたぐ、階層化された一連のデータベース・オブジェクトです。これらのデータベース・オブジェクトはパス名にマップされます。

このリポジトリは、単一のルート・ノード(/)を持つ、連結された有向非循環脚注1グラフです。図式内の各リソースは、関連付けられた1つ以上のパス名を持ちます。リポジトリは、指定されたリソースへの複数のリンクをサポートします。

21.2.1 リポジトリの用語

Oracle XML DBリポジトリで使用される用語には、リソース、リソース名、リソース・コンテンツ、フォルダまたはディレクトリ、パス名、パス要素、リンク名、アクセス制御リスト(ACL)およびXDBBinary要素があります。これらの用語の一部には、他のコンテキストでの共通の同義語が存在します。

- リソース: リポジトリ階層内のオブジェクトまたはノード。リソースは、オブジェクトのパス名とリソース名を含むUniform Resource Locator (URL)によって識別されます。

関連項目:

- 「Oracle XML DBリポジトリ: 概要」

- 「Oracle XML DBリポジトリ・リソース」

- フォルダ: 他のリソースを含むことができるリソース。ディレクトリと呼ばれることもあります。

- パス名: リソースへの絶対パスを表す階層形式の名前。リポジトリのルートを表すスラッシュ(/)と、それに続くスラッシュで区切られたゼロ個以上のパス要素で構成されています。「.」または「..」のみをパス要素とできませんが、それ以外の形であれば、ピリオド(.)をパス要素で使用できます。パス要素は、データベース・キャラクタ・セットの任意の文字で構成されますが、スラッシュ(/)およびバックスラッシュ(\)の他、構成パラメータ/xdbconfig/sysconfig/invalid-pathname-charsを使用したOracle XML DBの構成ファイル/xdbconfig.xmlに指定された文字は除きます。

- リソース名(またはリンク名) - その親フォルダ内のリソースの名前。この名前が、パス名の中で最も右端のパス要素となります。リソース名は、それらを直接含むフォルダ内で一意である必要があり、大/小文字は区別されます。

- リソース・コンテンツ: リソースの本体、つまりデータ。これは、リソースをファイルとして処理してそのコンテンツを要求したときに取得されるものです。型は常にXMLTypeです。

- アクセス制御リスト (ACL) - プリンシパル(ユーザーまたはロール)に対するアクセス権限を1つ以上のリポジトリ・リソースに指定する、順序付けられたルールのリスト。

関連項目:

リポジトリのアクセス制御

- XDBBinary要素: バイナリデータを含むXML要素。Oracle XML DB XML Schemaで定義されています。XDBBinary要素は、非構造化バイナリ・データがOracle XML DBにアップロードされたときに、リポジトリに格納されます。

表21-1に示すとおり、Oracle XML DBで使用される多くの用語には、他のコンテキストでの共通の同義語が存在します。

表21-1 Oracle XML DBリポジトリの用語の同義語

同義語

リポジトリの用語

用途

コレクション

フォルダ

WebDAV

ディレクトリ

フォルダ

オペレーティング・システム

権限

権限

権限

権利

権限

様々

WebDAVフォルダ

フォルダ

Webフォルダ

ロール

グループ

アクセス制御

リリース

バージョン

RCS、CVS

ファイル・システム

リポジトリ

オペレーティング・システム

階層

リポジトリ

様々

ファイル

リソース

オペレーティング・システム

バインド

リンク

WebDAV

21.2.2 事前定義されたリポジトリのファイルおよびフォルダ

Oracle XML DBリポジトリでは、特定のファイルおよびフォルダが事前定義されています。独自に使用するために追加のものを作成できます。

事前定義されたOracle XML DBリポジトリのファイルおよびフォルダを次に示します。

/dbfsFoot 2
/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/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/stats.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/xdbconfig.xsd
/xdbconfig.xml

21.3 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名前空間外のすべての要素を含むことができます。任意のインスタンス定義のプロパティをリソースと関連付けることができます。

21.3.1 リポジトリ・データが格納される場所

Oracle XML DBは、Oracle XML DBリポジトリのデータを、アクセス可能な一連の表および索引に格納します。

XML Schemaを登録し、Oracle XML DBによって表が生成されるように要求した場合、表はユーザーのデータベース・スキーマに作成されます。このため、それらを参照または変更することができます。他のユーザーは、表を参照する権限を付与されないかぎり、その表を参照できません。

21.3.1.1 生成された表の名前

生成された表の名前は、Oracle XML DBによって割り当てられます。これらは、ユーザーのXML Schema文書(またはデフォルトのXML Schema文書)のxdb:defaultTable属性を検索することによって取得できます。

XML Schemaを登録する場合、Oracle XML DBによって作成されたデフォルト名でなく、ユーザー独自の表名を指定することもできます。表でXML記憶域が指定されている場合、文書はXML形式にエンコードされてから表内に格納されます。

関連項目:

「XML Schemaの登録時に作成されるデフォルト表」

21.3.1.2 リポジトリ・リソース用のオブジェクト・リレーショナル記憶域の定義方法

リポジトリ・リソース用のオブジェクト・リレーショナル記憶域を定義するには、登録済のXML Schemaに準拠するデータをサブクラス化するか、格納します。

リポジトリ・リソース用のオブジェクト・リレーショナル記憶域を定義する必要があるアプリケーションでは、次のいずれかの方法で行います。

- Oracle XML DBリソース・タイプをサブクラス化します。Oracle XML DBリソースのサブクラス化には、XDB$RESOURCE表に対する権限が必要です。

- 参照可能な登録済XML Schemaに準拠するデータを格納します。

関連項目:

XML Schemaの格納と問合せ: 基本

21.3.1.3 Oracle ASM仮想フォルダ

Oracle Automatic Storage Management (Oracle ASM)の仮想フォルダ/sys/asmのコンテンツは、Oracle ASMにより自動管理されるOracle ASMファイルおよびフォルダです。

関連項目:

- 「プロトコルおよびリソースAPIを使用したOracle ASMファイルへのアクセス (DBAの場合)」

- 『Oracle Automatic Storage Management管理者ガイド』

21.3.2 Oracle XML DBリポジトリへの文書の格納方法

登録されたXML Schemaに基づくXML文書がリポジトリにロードされると、文書が解析され、スキーマに従って一連のSQLオブジェクトに分解されます。ソースXML文書にリポジトリ・アクセスを提供するために、対応するリソース・ドキュメントが作成されます。

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が含まれます。

21.3.3 リポジトリ・データ・アクセス制御

アクセス制御エントリ(ACE)で構成されるアクセス制御リスト(ACL)を使用すると、Oracle XML DBリポジトリ内のリソースへのアクセスを制御できます。ACEは、特定のプリンシパルに対する一連の権限を付与または拒否します。

プリンシパルとは、データベース・ユーザー、データベース・ロール、LDAPユーザー、LDAPグループ、またはリソースの所有者である特別なプリンシパルDAV::ownerです。リポジトリ内の各リソースは、ACLによって保護されます。ACLによって、ユーザーがリソースに対して持つ権限(read-propertiesやupdateなど)が決まります。各リポジトリ操作には、現行ユーザーがその操作の実行を許可されているかどうかを判断するために、ACLの確認が含まれています。

デフォルトでは、新規のリソースはその親フォルダのACLを継承します。ただし、PL/SQLプロシージャDBMS_XDB_REPOS.setACLを使用してリソースのACLを設定することもできます。Oracle XML DBのリソースのセキュリティの詳細は、 リポジトリのアクセス制御を参照してください。

次の例で、現行ユーザーは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

21.3.4 リポジトリのパス名の解決

フォルダをそのフォルダの内容に関連付けるデータは、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の定義用)

21.3.5 リンク・タイプ

Oracle XML DBにおけるリンクは、リポジトリ・リンクまたはドキュメント・リンクのいずれかです。リポジトリ・リンクには、ハード・リンクおよび弱いリンクがあります。ドキュメント・リンクについても、それらのターゲットがリポジトリ・リソースの場合は、ハード・リンクおよび弱いリンクがあります。

21.3.5.1 リポジトリ・リンクとドキュメント・リンク

リソースの他に、フォルダ・リソースは他のリソース(ファイルまたはフォルダ)へのリンクも含むことができます。これらのリポジトリ・リンクは、リポジトリの階層関係を表しています。一方、ドキュメント・リンクはXML文書間の任意のリンクで、必ずしもリポジトリ・リソースではありません。

リポジトリ・リンクは、フォルダ・リンクと呼ばれることもあります。これは、ドキュメント・リンクとは異なり、XLink標準およびXInclude標準で提供されるリンクに相当し、Oracle XML DBでもサポートされます。リポジトリ・リンクは、フォルダと子の間をナビゲートするためのリポジトリ・リソース間のリンクです。ドキュメント・リンクは、リポジトリ・リソースとは限らないドキュメント間の任意のリンクです。

リポジトリ・リンクは、リポジトリの階層関係を表しています。一方ドキュメント・リンクは、それらを使用するアプリケーションによりセマンティクスが派生する任意の関係を表しています。リポジトリ・リンクは、リポジトリの階層関係を表しているため、ファイル・システムに関連するプロトコルを使用してナビゲートできます。ドキュメント・リンクではこのようなことはできません。ドキュメント・リンクは、任意の関係を表すことができるため、リポジトリの関係も表すことが可能です。このようにリソースをターゲットとしているドキュメント・リンクはさらに、ハード・リンクおよび弱いリンクに分けることができます。

関連項目:

ドキュメント・リンクの詳細は、Oracle XML DBでのXLinkおよびXIncludeの使用方法を参照してください。

21.3.5.2 ハード・リンクおよび弱いリンク

リポジトリ・リソースをターゲットとするリンクには、ハード・リンクと弱いリンクがあります。ハード・リンクと弱いリンクでは、ターゲットとしているリソースに関する依存関係が異なります。ハード・リンクは、祖先のフォルダをターゲットにできませんが、弱いリンクはできます。リポジトリ・リンク・タイプを判断するためにリポジトリ・パス・ビューPATH_VIEWに問い合せることができます。

ハード・リンクおよび弱いリンクはともに、物理データへの参照(またはポインタ)であり、(内部的な)リポジトリ・リソースの識別子です。他のリンクのシンボリック名やパスを指すものではありません。これらのターゲットは、リンクが作成される時点で解決されます。ハード・リンクおよび弱いリンクは、リソースの識別子を直接指すので、ターゲットは必ず必要です。そのかわり、ターゲットの移動や名前の変更が行われても、有効性は保持されます。ハード・リンクおよび弱いリンクの作成や削除には、同じ権限が必要です。

ハード・リンクと弱いリンクの違いは、ターゲット・リソースの削除に関連するものです。ターゲット・リソースは、ハード・リンクに対して従属関係にあります。つまり、ハード・リンクのターゲットである間は削除できません。ハード・リンクを削除すると、次のいずれも成り立つ場合、リンクのターゲットであるリソースも削除されます。

- リソースがバージョニングされていません。

- 削除するハード・リンクがそのリソースに対する最後の(したがって唯一の)ハード・リンクです。

弱いリンクには、リソースに対するこうした拘束力はありません。つまり、弱いリンクのターゲットであるリソースは(ハード・リンクのターゲットでないかぎり)削除できます。このため弱いリンクは、アクセスの頻度が高いリソースへのショートカットとして使用でき、それらのリソースの削除に影響しません。

ただし、弱いリンクには逆方向の依存性があります。弱いリンク(1つ以上)のターゲットになっているリソースを削除すると、それらの弱いリンクも自動的に削除されます。この意味でも、弱いリンクは参照先を失います。ハード・リンクおよび弱いリンクはいずれも、参照整合性を伴っています。つまり、リンクが存在すれば、そのターゲットも存在します。

ハード・リンクおよび弱いリンクには、この他にも違いがあります。祖先のフォルダへのハード・リンクは、循環を導入するため、許可されません。弱いリンクにはこのような制約はありません。弱いリンクは任意のフォルダをターゲットとでき、場合によっては循環が作成されます。Oracle XML DBリポジトリの(非環式)構造は、一連のハード・リンクによって定義されます。弱いリンクが表しているのは、その基本構造の上に追加されたマッピングです。

リポジトリ・リンク・タイプを判断するためにリポジトリ・パス・ビューPATH_VIEWに問合せを行うことができます。リンク・タイプはリンク情報に含まれています。ルート要素LINKの子要素LinkTypeに含まれるこの情報は、PATH_VIEWのXMLType列LINKに表示されます。例21-1に、これを示します。また、イベント・ハンドラ(LinkIn、LinkTo、UnlinkIn、またはUnlinkFrom)でコールバックgetLink()を使用して、リポジトリ・リンク・タイプを判断できます。

関連項目:

- 「リポジトリ・リソースの削除: 例」

- PATH_VIEWの詳細は、「リポジトリ・リソースへの問合せベースのアクセス」を参照してください。

- PL/SQLファンクションgetLinkの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

例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

21.3.5.3 フォルダ階層の情報がない状況での弱いリンクの作成

弱いリンクは、ハード・リンクによって決定されるリポジトリ構造の上のマッピングを表しています。リソースへの弱いリンクは、そのパスではなくOIDを使用して作成できます。弱いリンクを使用すると、リソースを含むフォルダにアクセスせずにリソースにアクセスできます。

ある同僚が所有しているファイル・リソースを閲覧するとします。そのリソースにアクセスしそれを閲覧できるようにする場合、そのファイルの祖先のフォルダすべてに関して権限<xdb:resolve>が付与されていないかぎり、そのリソースへのハード・リンクの作成はできません。この権限が付与されていれば、その同僚が所有するフォルダの名前、およびそのターゲット・リソースまでの階層構造をすべて知ることができます。

ただし、弱いリンクは基本的に、一連のハード・リンクによって定義されている実際のリポジトリ構造の上に追加されたマッピングを表しているため、リソースに対して、そのOIDを使用すれば、完全な名前のパス(URL)がなくても弱いリンクを作成できます。つまり、同僚が決めたファイルへのOIDパスを名前のパスのかわりに受け取れば、そのOIDパスを使用してドキュメントへの弱いリンクを作成できます。例21-2および例21-3に、これを示します。

例21-2は、ファイル・リソース/home/QUINE/purchaseOrder.xmlのOIDパスを出力したものです。ユーザーquineはこれを使用してリソースへのOIDパスを取得し、そのパスをユーザーcurryへ送信できます。またユーザーcurryは、リソースへの弱いリンクを作成できます(例21-3)。

例21-3では、ユーザーcurryが、quinePurchaseOrder.xmlという名前の弱いリンクをフォルダ/home/CURRY内に作成します。リンクのターゲットは、URL /home/QUINE/purchaseOrder.xmlに対応するOIDパスです。ユーザーcurryは、ユーザーquineには参照可能なリポジトリの構造を認識する必要はありません。

例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_REPOS.createOIDPath(resoid);
DBMS_OUTPUT.put_line(oidpath);
END;

例21-3 OIDパスを使用した弱いリンクの作成

CALL DBMS_XDB_REPOS.link(/sys/oid/1BDCB46477B59C20E040578CCE0623D3
'/home/CURRY', 'quinePurchaseOrder.xml',
DBMS_XDB_REPOS.LINK_TYPE_WEAK);

21.3.5.4 複数のハード・リンクを回避する方法およびタイミング

ハード・リンクの作成を制限し、フォルダまたはファイル(またはその両方)への複数のハード・リンクを許可しないようにできます。ファイル・リソースへの複数のハード・リンクを許可し、フォルダ・リソースへの複数のハード・リンクを許可しないことで、UNIXやLinuxなどのファイル・システムに近い動作を実現できます。

これにより、事実上、各ファイル・リソースに対して正規のハード・リンクのパスが一意に作成され、アプリケーションの設計を単純化できます。さらに、リソースに対して複数のハード・リンクを作成しないことで、問合せのパフォーマンスを向上できます。

構成ファイルxdbconfig.xmlで次のブール型パラメータを使用して、複数のハード・リンクの作成を回避するよう構成できます。各パラメータのデフォルト値はtrueで、複数のハード・リンクを作成できます。

- folder-hard-links - falseの場合、フォルダ・リソースへの複数のハード・リンクの作成を回避します。

- non-folder-hard-links - falseの場合、ファイル・リソースへの複数のハード・リンクの作成を回避します。

関連項目:

「xdbconfig.xmlを使用したOracle XML DBの構成」

21.4 リポジトリ・リソースへのナビゲーショナル・アクセスまたはパス・アクセス

Oracle XML DBリポジトリのフォルダは、多くのオペレーティング・システムにより使用されている標準的なプロトコルをサポートしています。これによって、リポジトリ・フォルダは、サポートされているオペレーティング・システム環境で、ネイティブ・フォルダ(ディレクトリ)と同様に機能します。

次に例を示します。

- 図21-2のように、ファイル・システムで他のファイルやフォルダにアクセスするときと同じように、Windows Explorerを使用してリポジトリのファイルおよびフォルダ(リソース)を開き、それにアクセスすることができます。

- 図21-3および図21-4に示すように、WebブラウザからHTTP(S)/WebDAVを使用してリポジトリ・データにアクセスします。
図21-3は、URL http://xdbdemo:8080/にアクセスしたときのブラウザを示しています。接続先のサーバーがxdbdemo、HTTPポート番号が8080です。

図21-4は、データベースに格納されているXML文書(XSLスタイルシート)にHTTPを使用してアクセスしたときのブラウザを示しています。URLはhttp://localhost:8080/home/SCOTT/poSource/xsl/purchaseOrder.xslです。

図21-2 WindowsエクスプローラでのOracle XML DBのフォルダ

図21-3 HTTPやWebDAVおよびWebブラウザを使用したリポジトリ・データへのアクセス

図21-4 HTTPとURLを使用したパスベースのアクセス

21.4.1 インターネット・プロトコルを使用したOracle XML DBリソースへのアクセス

Oracle Net Servicesでは、データベース・リソースのアクセス方法が提供されます。インターネット・プロトコルをサポートしているOracle XML DBでは、データベース・リソースにアクセスする別の方法が提供されます。

21.4.1.1 Oracle XML DBのプロトコル・アクセスを使用できる場所

Oracle Net Servicesは、レコード指向のデータに対して最適化されています。インターネット・プロトコルは、バイナリ・ファイルやXMLテキスト・ドキュメントなどのストリーム指向のデータ用に設計されています。特定のシナリオでは、Net ServicesよりOracle XML DBのプロトコル・アクセスを使用することをお薦めします。

- ファイル・システムのようなデータベースを使用した、ファイル指向アプリケーションからデータベースへの直接アクセス

- 均一なデータ・アクセス方法(MS SQL Server、Exchange、Notes、多くのXMLデータベース、株価情報サービス、ニュース配信を含む多くのデータ・サーバーによってサポートされているHTTPを介したXMLなど)を必要とする異機種間アプリケーション・サーバー環境

- XMLテキスト形式のデータを必要とするアプリケーション・サーバー環境

- 多くのアプリケーション処理を必要とせずに、クライアント側のXSLを使用して、データグラムをフォーマットするWebアプリケーション

- データベース内で実行するJavaサーブレットを使用するWebアプリケーション

- XML指向のストアド・プロシージャに対するWebアクセス

21.4.1.2 Oracle XML DBへのプロトコル・アクセスの概要

Oracle XML DBへのプロトコル・アクセスには、接続、ユーザー認証、リクエスト解析およびJavaサーブレットの起動が含まれます。

プロトコルを使用したOracle XML DBリソースへのアクセスは次のように行われます。

1. 接続オブジェクトが確立されます。また、プロトコルによってリクエストの一部が読み取られる場合があります。

2. プロトコルによって、認証済のユーザーが既存のセッションを再利用できるか、または接続を再認証する必要があるか(通常はこちら)が決定されます。

3. 既存のセッションがセッション・プールから取り出されるか、または新しいセッションが作成されます。

4. 認証が行われず、リクエストがHTTPのgetまたはheadの場合、セッションはANONYMOUSユーザーとして実行されます。セッションがすでにANONYMOUSユーザーとして認証されている場合は、そのまま既存のセッションを再利用できます。認証が行われている場合は、データベースの再認証ルーチンを使用して、接続が認証されます。

5. リクエストが解析されます。

6. (HTTPのみ)要求されたパス名がサーブレットにマップされる場合、サーブレットはJava仮想マシン(JVM)を使用して起動されます。サーブレット・コードがレスポンス・ストリームに対するレスポンスを書き出すか、またはXMLTypeインスタンスにレスポンスを書き出すように要求します。

21.4.1.3 Oracle XML DBリソースの取得

プロトコルがリソースの取得を示した場合、リソースがXMLデータまたはRAWフォームとしてストリームされることによって、リソースへのパス名が解決され、リソースがフェッチされます。

フェッチされるリソースは、XMLデータとしてストリームされます。ただし、XMLバイナリ・データ型であるXDBBinary要素を含むリソースで、そのコンテンツがRAWフォームでストリームされるものは除きます。

21.4.1.4 Oracle XML DBリソースの格納

プロトコルが、XML文書であるリソースを格納することを示した場合、その関連付けられているXML Schema (存在する場合)は、文書を格納するデフォルト表を決定するために参照されます。

Oracle XML DBは、文書のファイル名の拡張子が.xml、.xsl、.xsdなどであることを確認します。文書がXMLである場合、事前解析が実行されます。その場合、文書のルート要素のXML schemaLocationおよびnamespaceを判断するために十分なリソースが読み取られます。登録されたスキーマが、schemaLocation URLに配置されていて、現在の文書のルート要素に対する定義を持っている場合、その要素に対して指定されたデフォルト表を使用して、リソースのコンテンツが格納されます。

21.4.1.5 インターネット・プロトコルおよびXMLType: ストリームへのXMLTypeの直接書込み

Oracle XML DBは、Java XMLTypeメソッドwriteToStream()を使用することによって、XMLTypeレベルでインターネット・プロトコルをサポートします。このメソッドはネイティブに実装され、XMLTypeデータをプロトコルのリクエスト・ストリームに直接書き込みます。

これによって、Javaデータ型を介したデータベース・データの変換およびJavaオブジェクトの作成に伴うJava VMの実行コストとオーバーヘッドが回避され、パフォーマンスが大幅に向上します。パフォーマンスをさらに向上させるには、Javaコードが多くのリーフ要素を検索せずにルートに近いXML要素ツリーのみを処理し、作成するJavaオブジェクトの数が相対的に少なくなるようにします。

関連項目:

プロトコルを使用したリポジトリへのアクセス

21.4.2 プロトコルおよびリソースAPIを使用したOracle ASMファイルへのアクセス (DBAの場合)

Oracle Automatic Storage Management (Oracle ASM)を使用すると、データベース・ファイルはディスク・グループに整理され、管理、データベースのミラー化およびI/Oバランシングが簡単になります。仮想リポジトリ・フォルダ/sys/asmのOracle 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-5に示します。ただし、図を簡潔にするために、エイリアス用に作成されるディレクトリは省略しています。

図21-5 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管理者ガイド』を参照してください。

21.5 リポジトリ・リソースへの問合せベースのアクセス

PL/SQLパッケージDBMS_XDB_REPOSには、Oracle XML DBリポジトリ・リソースを操作するサブプログラムが用意されています。このAPIは、パブリック・ビューRESOURCE_VIEWとPATH_VIEWに基づいており、FTPやHTTP(S)/WebDAVなどのプロトコルを介してSQLによるリポジトリ・データへのアクセスを可能にします。

- PATH_VIEW - 一意のリポジトリ・パスごとに1つの行が存在します。

- RESOURCE_VIEW - リソースごとに1つの行が存在します。

リポジトリに格納された文書のメタデータおよびコンテンツはいずれも、これらのビューを介してアクセスして更新できます。ビューに対する操作では、XDB$RESOURCEなどの基礎となるリポジトリ表を使用します。

各ビューには仮想列RESがあります。列RESを使用すると、リポジトリ・パス表記法に対応するSQL文を使用して、リソース・ドキュメントにアクセスして更新できます。

RESOURCE_VIEWビューには列ANY_PATHがあります。列ANY_PATHには、リソースのコンテンツにアクセスするために現行ユーザーがPL/SQLコンストラクタXDBURITypeに渡すことができる有効なURLが含まれます。このコンテンツがバイナリ・データでない場合、リソースそのものにもコンテンツが含まれます。

表21-2に、ビューの相違点をまとめています。

表21-2 PATH_VIEWとRESOURCE_VIEWの違い

PATH_VIEW

RESOURCE_VIEW

リンク・プロパティを含みます。

リンク・プロパティを含みません。

リポジトリの一意の各パスに1つの行を持ちます。

リポジトリの各リソースに1つの行を持ちます。

これらのビューの行のデータ型は、XMLTypeです。RESOURCE_VIEWでは、リソースに関連付けられる単一のパスは、そのリソースを参照している可能なパスの中から任意に選択されます。Oracle XML DBにはunder_pathなどのSQL関数が用意されており、アプリケーションから特定のフォルダ内に(再帰的に)含まれているリソースを検索したり、リソースの深さを取得したりできます。

リポジトリ・ビュー上でDMLコードを使用すると、リソースのプロパティおよびコンテンツの挿入、名前の変更、削除および更新ができます。その他の操作(既存のリソースへのリンクの作成など)に対しては、プログラムAPIを使用する必要があります。

Oracle XML DBは、リンクの概念をサポートしています。リンクによって、指定した文書への複数のパスを定義できます。リンク・プロパティ文書と呼ばれる各XML文書では、(リソース固有ではなく)パス固有のメタデータ・プロパティが保持されます。リソースが作成されるたびに、最初のリンクも作成されます。

PATH_VIEWは、リンク・プロパティ文書を公開します。PATH_VIEWには、文書に対してアクセス可能なパスごとに1つのエントリがあります。PATH_VIEWの列RESには、このリンクの参照先のリソース・ドキュメントが含まれます。列PATHには、リンクがリソースへのアクセスに使用できるパスが含まれます。列LINKには、このPATHのリンク・プロパティ文書(メタデータ)が含まれます。

関連項目:

- 「リンク・タイプ」

- RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス

- リポジトリのアクセス制御

- ビューPATH_VIEWの詳細は、『Oracle Databaseリファレンス』を参照してください。

- ビューRESOURCE_VIEWの詳細は、『Oracle Databaseリファレンス』を参照してください。

21.6 リポジトリ・リソースへのサーブレット・アクセス

Oracle XML DBは、JavaサーブレットAPIバージョン2.2を実装します。

サポートは、次の制限事項によって限定されます。

- すべてのサーブレットが配布可能である必要があります。これらのサーブレットは、異なる仮想マシンで実行可能である必要があります。

- WARおよびweb.xmlファイルはサポートされていません。Oracle XML DBはこのファイルのXML構成のサブセットをサポートしています。XSLTスタイルシートをweb.xmlに適用して、サーブレットの定義を生成できます。外部ツールを使用して、web.xmlファイルに定義されたサーブレットのデータベース・ロールを作成する必要があります。

- JavaServer Pages(JSP)サポートをサーブレットとしてインストールし、手動で構成できます。

- HTTPSessionおよび関連するクラスはサポートされません。

- 1つのサーブレット・コンテキスト(1つのWebアプリケーション)のみがサポートされます。

関連項目:

JavaでのOracle XML DBアプリケーションの作成方法

21.7 リポジトリ・リソースに対する操作

Oracle XML DBリポジトリ・リソースに格納されているデータを操作するには、Java、PL/SQL、インターネット・プロトコルおよびOracle XML DB Content Connectorを使用します。最も一般的な操作およびこれらの使用に必要なデータベース権限について説明します。

次のいずれかの方法でリポジトリ・データにアクセスできます。

- 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は、各操作に必要なリソース権限も示しています。

表21-3 Oracle XML DBリポジトリへのアクセス: APIオプション

データ・アクセス

SQLおよびPL/SQL

プロトコル

必要なリソース権限

JCRのサポート

リソースの作成

DBMS_XDB_REPOS.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 =
XMLQuery(
'declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
copy $i := $p1 modify
(for $j in $i/Resource/Contents/text
return replace value of node $j with $p2)
return $i'
PASSING RES AS "p1", 'NEW text' AS "p2"
RETURNING CONTENT)
WHERE equals_path(RES, '/public/T1/copy1.txt') = 1

HTTP: PUT;

FTP: PUT

リソースに対するxdb:write-content

サポート

リソース・プロトコルの更新

UPDATE RESOURCE_VIEW
SET RES =
XMLQuery(
'declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
copy $i := $p1 modify
(for $j in $i/Resource/DisplayName
return replace value of node $j with $p2)
return $i'
PASSING RES AS "p1", 'NewName1.txt' AS "p2" RETURNING CONTENT)
WHERE equals_path(RES, '/public/T1/copy1.txt') = 1;

WebDAV:

PROPPATCH;

リソースに対するDAV::write-properties

サポート

リソースACLの更新

EXEC DBMS_XDB_REPOS.setACL(
'/public/T1/copy1.txt',
'/sys/acls/all_owner_acl.xml');

適用なし

リソースに対するDAV::write-acl

非サポート

リソースのリンク解除(最新のリンクの削除)

EXEC DBMS_XDB_REPOS.deleteResource()

または

DELETE FROM RESOURCE_VIEW
WHERE equals_path(RES, path) > 0

HTTP:

DELETE;

FTP:delete

親フォルダに対するDAV::unbind

リソースに対するxdb:unlink-from

サポート

リソースへのすべてのリンクの強制削除

DBMS_XDB_REPOS.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

リソース

すべての親フォルダに対する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_REPOS.link('/public/T1/copy3.txt',
'/public/T1',
'myhardlink');

適用なし

親フォルダに対するDAV::bind

リソースに対するxdb:link-to

非サポート

既存リソースへの弱いリンクの作成

EXEC DBMS_XDB_REPOS.link(
'/public/T1/copy3.txt',
'/public/T1',
'myweaklink',
DBMS_XDB_REPOS.LINK_TYPE_WEAK);

適用なし

親フォルダに対するDAV::bind

リソースに対するxdb:link-to

非サポート

リソースの所有者の変更

UPDATE RESOURCE_VIEW
SET RES =
XMLQuery(
'copy $i := $p1 modify
(for $j in $i/Resource/Owner
return replace value of node $j with $p2)
return $i'
PASSING RES AS "p1", 'U2' AS "p2" RETURNING CONTENT)
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_REPOS.createFolder('/public/T2');

WebDAV:

MKCOL;

FTP: mkdir

親フォルダに対するDAV::bind

サポート

フォルダのリンク解除

DBMS_XDB_REPOS.deleteResource('/public/T2')

HTTP:

DELETE;

FTP: rmdir

親フォルダに対するDAV::unbind

リソースに対するxdb:unlink-from

サポート

フォルダおよびそのフォルダに対するすべてのリンクの強制削除

DBMS_XDB_REPOS.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_REPOS.LockResource(
'/public/T1/res.xml',
TRUE,
TRUE);

WebDAV:

LOCK;

FTP:

quote lock

リソースに対するDAV::write-properties

非サポート

WebDAVロックの削除

DECLARE...

BEGIN
DBMS_XDB_REPOS.GetLockToken('/public/T1/res.xml',
locktoken);
DBMS_XDB_REPOS.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;

適用なし

適用なし

サポート

表21-3にリストされている権限に加え、操作により影響を受ける各リソースに対しては権限xdb:read-propertiesが必要です。また、その操作のターゲットとなるリソースに加え、リソースの親フォルダに影響を与える操作を実行するには、その親フォルダに対しても権限xdb:read-propertiesが必要です。たとえば、あるリソースに対する削除操作は、削除するリソースおよびその親フォルダに影響を及ぼします。したがってこの場合は、対象のリソースおよびその親フォルダに対して権限xdb:read-propertiesが必要です。

関連項目:

- RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス

- Oracle XML DBリポジトリへのPL/SQLアクセス

- プロトコルを使用したリポジトリへのアクセス

- Oracle XML DB Content Connector

- PL/SQLパッケージDBMS_XDB_REPOSの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

- 新規PL/SQLパッケージDBMS_XDB_VERSIONの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- 新規PL/SQLパッケージDBMS_XEVENTの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

21.8 SQLを使用したリポジトリ・リソースのコンテンツへのアクセス

SQLでは、Oracle XML DBリポジトリの文書のコンテンツにアクセスするには、PL/SQLコンストラクタXDBURITypeを使用するか、RESOURCE_VIEWおよび対応するリソース・ドキュメントを使用します。

最も簡単な方法は、XDBURITypeを使用することです。このコンストラクタにURLを渡し、アクセスするリソースを指定します。このURLは、リポジトリのルートから始まると想定されます。オブジェクト型XDBURITypeには、リソースに関連付けることのできる様々な種類のコンテンツにアクセスするためのメソッドgetBLOB()、getCLOB()およびgetXML()が用意されています。

例21-4では、コンストラクタXDBURITypeを使用してテキスト・ドキュメントのコンテンツにアクセスします。

文書のコンテンツには、RESOURCE_VIEWおよび対応するリソース・ドキュメントを使用してもアクセスできます。例21-5では、これを実行してテキスト・ドキュメントのコンテンツにアクセスします。

XML文書(XML Schemaに基づくまたはXML Schemaに基づかない)のコンテンツには、この方法でもアクセスできます。例21-6では、XML文書のノードおよび対応するリソース・ドキュメントのノードが含まれたXPath式を使用して、PurchaseOrder文書のコンテンツにアクセスします。

例21-6では、名前空間接頭辞rを使用し、リソースの名前空間のメンバーであるノードをXPath式から識別しています。名前空間接頭辞rは、SQL/XML関数XMLTableのXMLNAMESPACES句を使用して定義されます。発注書XML Schemaで名前空間が定義されておらず、名前空間接頭辞をPurchaseOrder文書のノードに適用できないため、ここでは名前空間の宣言が必要になります。

関連項目:

XMLTableのXMLNAMESPACES句の詳細は、XQueryとOracle XML DBを参照してください。

例21-4 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.

例21-5 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.

例21-6 リソースと名前空間接頭辞を使用した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.

21.9 XML Schemaに基づく文書のコンテンツへのアクセス

XML Schemaに基づく文書のコンテンツにアクセスするには、スキーマに基づかない文書の場合と同様、対応するリソース・ドキュメントを使用します。または、XML SchemaをOracle XML DBに登録したときに定義したデフォルト表の行としてアクセスします。

最初の場合は、RESOURCE_VIEWを使用して、XML Schemaに基づく様々な種類の文書を1つのSQL文で問い合せることができます。

21.9.1 結合でXMLRef要素を使用した、リソース・コンテンツへのアクセス

リソース・ドキュメントの要素XMLRefは、SQL文で単一の操作の一部としてメタデータおよびコンテンツにアクセスまたは更新する必要があるときに必要な結合キーを提供します。

ここでの例は、要素XMLRefの値に基づく結合を使用して、リソース・コンテンツにアクセスする問合せを示しています。

例21-7では、Oracle XML DBリポジトリのパスに基づいて、defaultTableの行を検索します。SQL関数refは、リソース・ドキュメントRES内のXMLRef要素の値に基づいて、デフォルト表内のターゲットの行を検索します。

例21-8では、メタデータ、パスおよびコンテンツに基づいて、XML文書からフラグメントを選択する方法を示します。この問合せは、/home/QUINE/PurchaseOrders/2002/Marの下にあり、部品番号715515009058の発注が含まれる文書に対して、要素Referenceの値を戻します。

通常、XML Schemaに基づくXML文書のコンテンツにアクセスするときは、RESOURCE_VIEWまたはPATH_VIEWを単独で使用するよりも、RESOURCE_VIEWまたはPATH_VIEWをデフォルト表と結合して使用した方が効率的です。リソース・ドキュメントとデフォルト表を明示的に結合することによって、Oracle XML DBは、SQL文が1種類のXML文書に対してのみ機能することを認識します。したがって、XPathのリライトを使用すれば、デフォルト表およびリソースに対する操作を最適化できます。

例21-7 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.

例21-8 メタデータ、パスおよびコンテンツに基づく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.

21.10 リポジトリの文書のコンテンツの更新

Oracle XML DBリポジトリに格納された文書のコンテンツは、インターネット・プロトコルまたはSQLを使用して更新できます。

21.10.1 インターネット・プロトコルを使用したリポジトリのコンテンツの更新

最も一般的なコンテンツ作成ツールは、HTTP、FTPおよびWebDAVプロトコルをサポートしています。適切なアクセス権限が付与されている場合、Oracle XML DBリポジトリに格納されたコンテンツにアクセスして編集するには、更新する文書をターゲットとする簡単なURLのみが必要です。

一般的なコンテンツ作成ツールでは、URLが指定されたHTTP動詞getを使用して文書のコンテンツにアクセスでき、HTTP動詞putを使用して、更新されたコンテンツを保存できます。

図21-6に、Microsoft WordのWebDAVサポートを使用して、Oracle XML DBリポジトリに格納された文書をMicrosoft Wordで更新および編集する方法を示します。

図21-6 Microsoft Wordを使用した、Oracle XML DBに格納されたコンテンツの更新および編集

Microsoft Wordなどの編集アプリケーションを使用してOracle XML DBに格納されたXML文書を更新すると、データベースは、文書の新しいコンテンツを含む入力ストリームを受け取ります。ただし、文書にどのような変更が加えられたかについて、WordなどのアプリケーションからOracle XML DBに伝達する方法はありません。このため、部分的に更新することはできません。文書全体を再度解析し、元の文書から導出されたすべてのオブジェクトを、新しいコンテンツから導出されたオブジェクトに置き換える必要があります。

21.10.2 SQLを使用したリポジトリのコンテンツの更新

XQuery Updateを使用すると、Oracle XML DBリポジトリに格納された文書のコンテンツを更新できます。文書のコンテンツを変更するには、リソース・ドキュメントまたは文書のコンテンツを保持するデフォルト表を更新します。

21.10.2.1 リソース・ドキュメントの更新によるリポジトリ内の文書の更新

ドキュメントのコンテンツを更新するには、SQL UPDATE文およびSQL関数XMLQueryとXQuery Updateを使用します。XQuery式が更新操作のターゲットとしてXMLQueryに渡されます。

例21-9では、簡単なテキスト・ドキュメントのコンテンツを更新します。更新操作のターゲットとしてXMLQueryに渡されたXQuery式により、要素/Resource/Contents/textに属するテキスト・ノードが識別されます。

関連するリソースの更新によって文書のコンテンツを更新する方法のメリットは、Oracle XML DBリポジトリに格納されたあらゆる種類の文書を更新できることです。

例21-10では、対応するリソース・ドキュメントでSQL UPDATE操作を実行して、XML文書のノードを更新します。ここでは、XQuery Updateを使用して、要素Userに関連付けられたテキスト・ノードの値を変更します。

例21-9 リソースでUPDATEとXQuery Updateを使用したテキスト・ドキュメントの更新

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 =
XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
copy $i := $p1 modify
(for $j in $i/Resource/Contents/text
return replace value of node $j with $p2)
return $i'
PASSING RES AS "p1", contents AS "p2" RETURNING CONTENT)
WHERE equals_path(res, '/home/QUINE/NurseryRhyme.txt') = 1;
DBMS_LOB.freeTemporary(contents);
END;
/

例21-10 リソースでUPDATEとXQuery Updateを使用したXMLノードの更新

UPDATE RESOURCE_VIEW
SET RES =
XMLQuery('declare namespace r="http://xmlns.oracle.com/xdb/XDBResource.xsd";
copy $i := $p1 modify
(for $j in $i/r:Resource/r:Contents/PurchaseOrder/User
return replace value of node $j with $p2)
return $i'
PASSING RES AS "p1", 'SKING' AS "p2" RETURNING CONTENT)
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.

21.10.2.2 デフォルト表の更新によるリポジトリ内のXML Schemaに基づく文書の更新

文書のコンテンツを管理するために使用するデフォルト表に対して更新操作を直接実行することによって、XML Schemaに基づく文書を更新できます。

メタデータに基づくパスまたは条件が含まれたWHERE句を使用して文書を配置する必要がある場合、SQL UPDATE文では、リソースとデフォルト表の間の結合を使用する必要があります。

一般に、XML Schemaに基づく文書のコンテンツを更新する場合は、RESOURCE_VIEWまたはPATH_VIEWを単独で使用するよりも、RESOURCE_VIEWまたはPATH_VIEWをデフォルト表と結合して使用するほうが効率的です。リソース・ドキュメントとデフォルト表を明示的に結合することによって、Oracle XML DBは、SQL文が1種類のXML文書に対してのみ機能することを認識します。これによって、デフォルト表およびリソースで部分更新を使用できます。

例21-11では、ターゲットの行をパスによって識別し、デフォルト表に対してXQuery Updateを使用します。更新される行は、REFによって識別されます。REFは、Oracle SQL関数equals_pathを使用して、リポジトリ・パスによって識別されます。これにより、更新対象は、指定されたパスで識別されるリソースに対応する行のみに制限されます。

例21-11 リポジトリ内のXML Schemaに基づく文書の更新

UPDATE purchaseorder p
SET p.OBJECT_VALUE =
XMLQuery('copy $i := $p1 modify
(for $j in $i/PurchaseOrder/User
return replace value of node $j with $p2)
return $i'
PASSING p.OBJECT_VALUE AS "p1", 'SBELL' AS "p2" RETURNING CONTENT)
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

21.11 RESOURCE_VIEWおよびPATH_VIEW内のリソースの問合せ

ここでの例は、RESOURCE_VIEWおよびPATH_VIEWと、Oracle SQL関数equals_pathおよびunder_pathを使用したリポジトリのフォルダ限定の問合せを示しています。

Oracle XML DBには、フォルダ限定の問合せを実行するために使用できるOracle SQL関数equals_pathおよびunder_pathの2つが用意されています。このような問合せは、RESOURCE_VIEWまたはPATH_VIEWを操作するSQL文を、Oracle XML DBのフォルダ階層内の特定の場所にある文書に制限します。

関数equals_pathは、SQL文を、指定したパスで識別される単一の文書に制限します。関数under_pathは、SQL文を、階層内の特定の場所より下位に存在する文書に制限します。

ここでの例は、RESOURCE_VIEWおよびPATH_VIEWに格納されたリソース・ドキュメントに対する簡単なフォルダ限定の問合せを示しています。

例21-12の問合せでは、SQL関数equals_pathとRESOURCE_VIEWを使用してリソースにアクセスしています。問い合せるリソースは、例21-9の更新操作で得られた結果です。例21-4と例21-5に示す元のリソースのテキストが、別の童謡「Hickory Dickory Dock...」の歌詞に置き換えられています。

例21-12に示すように、リソース・ドキュメントは、DAV標準で定義された一連のメタデータを取得するXML文書です。メタデータには、CreationDate、Creator、Owner、ModificationDate、DisplayNameなどの情報が含まれています。リソース・ドキュメントのコンテンツは、SQL/XMLアクセスおよび問合せ関数を使用して、他のXML文書と同様の方法で問合せおよび更新ができます。

例21-13の問合せにより、Oracle XML DBリポジトリに格納された各XSLスタイルシートへのパスを検索します。これは.xslで終わるDisplayNameの検索を実行します。

例21-14の問合せでは、パス/home/QUINE/PurchaseOrdersの下に存在するリソース(ファイルおよびフォルダ)の数をカウントします。PATH_VIEWではなくRESOURCE_VIEWを使用すると、複数リンクのターゲットであるリソースは1回のみカウントされます。SQL関数under_pathを使用すると、結果セットは、/home/QUINE/PurchaseOrdersで始まるパスを使用してアクセス可能な文書に制限されます。

例21-15の問合せは、パス/home/QUINE/PurchaseOrders/2002/Aprで識別されるフォルダのコンテンツをリストします。この問合せによって、フォルダ内のディレクトリのリストを効率的に作成できます。

例21-16の問合せは、パス/home/QUINE/PurchaseOrders/2002/Aprで識別されるフォルダに含まれる、関連するリソースのDisplayName要素がSで始まる一連のリンクをリストします。

例21-17の問合せにより、PurchaseOrder文書を含む、Oracle XML DBリポジトリの各リソースへのパスを検索します。文書はXML Schema URLおよびリポジトリに格納されたスキーマに基づくXMLデータのグローバル要素を識別する、メタデータ・プロパティSchemaElementに基づき識別されます。

例21-12 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.

例21-13 リポジトリに格納されたXSLTスタイルシートへのパスの判別

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
-------------------------------------------
/home/MDSYS/epsg/sdoepsggrid2nadcon.xsl
/home/MDSYS/epsg/sdoepsggrid2ntv2/xsl
/source/schemas/poSource/xsl/empdept.xsl
/source/schemas/poSource/xsl/purchaseOrder.xsl

4 rows selected.

例21-14 パスの下に存在するリソースのカウント

SELECT count(*)
FROM RESOURCE_VIEW
WHERE under_path(RES, '/home/QUINE/PurchaseOrders') = 1;

COUNT(*)
----------
145

1 row selected.

例21-15 パス内のフォルダのコンテンツのリスト

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.

例21-16 フォルダに含まれているリンクのリスト

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.

例21-17 発注書の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.

21.12 Oracle XML DBの階層リポジトリ索引

Oracle XML DBでは、Oracle XML DBリポジトリの階層索引を使用して、リポジトリのパスに基づく問合せと、フォルダ限定の問合せのパフォーマンスを最適化します。これは、Oracleドメイン索引として実装されます。

従来のリレーショナル・データベースでは、パスベースのアクセスおよびフォルダ限定の問合せはCONNECT BY操作を使用して実装します。このような問合せはコストがかかるため、パスベースのアクセスおよびフォルダ限定の問合せは、文書の数やフォルダ階層の深さが増すにつれて効率が下がる可能性があります。

この問題に対処するために、Oracle XML DBでは階層リポジトリ索引という新しい索引タイプが導入されました。これを使用すると、CONNECT BY操作を使用しなくても、データベースでフォルダ限定の問合せを解決できます。したがって、Oracle XML DBでは、パスベースおよびフォルダ限定の問合せを効率的に実行できます。階層リポジトリ索引は、Oracleのドメイン索引として実装されます。これは、Oracle Text索引のサポートおよび他の多数の高度な索引タイプをデータベースに追加する場合の方法と同じです。

例21-18では、フォルダ限定の問合せで生成された実行計画の出力を示します。次に示すように、階層リポジトリ索引(XDBHI_IDX)を使用して問合せを解決します。

例21-18 フォルダ限定の問合せの実行計画の出力

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.

脚注の凡例

脚注1:
このグラフは、リポジトリ構造を定義するハード・リンクによって定義され、ハード・リンクを使用した循環は許可されません。ただし弱いリンクを使用して循環を導入できます。「ハード・リンクおよび弱いリンク」を参照してください。

脚注2:
リポジトリの/dbfsフォルダでは、DBFSコンテンツにプロトコルでアクセスできます。DBFSの詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照してください。

22 Oracle XML DBリポジトリの構成

Oracle XML DBリポジトリの構成全体が、すべてのリポジトリ・リソースに適用されます。これには、イベント処理やXLinkおよびXInclude処理の管理に関するパラメータの構成は含まれていません。リソース構成ファイルを使用して、リソースを構成します。

- リソースを構成するリソース構成ファイル

- リソースの構成

- 共通の構成パラメータ

関連項目:

- 「Oracle XML DBプロトコル・サーバーの構成管理」

- 「リポジトリ・イベントの構成」

- 「XLinkおよびXIncludeのリポジトリ・リソースの構成」

- 「XDBResource.xsd: Oracle XML DBリソースのためのXML Schema」

- 「XDBResConfig.xsd: リソース構成のためのXML Schema」

- リポジトリ専用の表領域の使用方法の詳細は、「パッケージDBMS_XDB_ADMIN」を参照してください。

22.1 リソースを構成するリソース構成ファイル

Oracle XML DBリポジトリ・リソースは、リソースについて構成可能なパラメータを定義するリソース構成ファイルと関連付けて、あらゆる目的で構成します。リソース構成ファイル自体が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で定義されているため、変更できません。

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およびconfiguration」

22.2 リソースの構成

Oracle XML DBリポジトリ・リソースの構成には、構成ファイルを作成し、そのファイルを構成リソースとしてリポジトリに追加し、および構成リソースをそれが構成するリソースまたはリポジトリ全体にマッピングすることが含まれます。

個々のリソースまたはリポジトリ全体(すべてのリソース)を構成するには、次の手順に従ってください。

1. 構成を定義するリソース構成ファイルを作成します。このXMLファイルは、XML Schema XDBResConfig.xsdに準拠している必要があります。

2. リソース構成ファイルを、それ自体をリソースである構成リソースとしてリポジトリに追加します。これを行うには、PL/SQL関数DBMS_XDB_REPOS.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パッケージおよびタイプ・リファレンス』を参照してください。

22.3 共通の構成パラメータ

共通で使用される構成パラメータ、つまり構成ファイル内の要素について説明します。

特定の構成の型に固有のパラメータについては、他の項で説明します。

22.3.1 構成要素ResConfig

リソース構成ファイルの最上位要素はResConfigです。これを使用すると、リソース構成ファイルを無効または有効にできます。

要素ResConfigには、namespace属性およびschemaLocation属性の他に、オプションとしてenable属性を含めることができます。属性の値をenableからfalseに設定し、リソース構成ファイルを無効にします。これにより、そのファイルにマップされたリソースには影響がなくなります。これは、アプリケーションの無効化やデバッグには便利です。enableのデフォルト値はtrueで、属性が存在しない場合に使用されます。

22.3.2 構成要素defaultChildConfigおよびconfiguration

構成要素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>

22.3.3 構成要素applicationData

要素applicationDataはアプリケーション固有のデータを格納します。通常、アプリケーションは、ハンドラが動作している場合はこのデータをイベント・ハンドラに渡します。要素applicationData内で必要な任意のXMLコンテンツを使用できます。

イベント・ハンドラは、PL/SQL関数DBMS_XEVENT.getApplicationDataまたはJava関数oracle.xdb.XMLType.getApplicationDataを使用して、イベント・リスナーのリソース構成ファイルのapplicationDataにあるデータにアクセスします。

例22-2に、Oracle Spatial and Graphアプリケーションで使用するapplicationData要素を示します。

関連項目:

- PL/SQL関数DBMS_XEVENT.getApplicationDataの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- Java関数oracle.xdb.XMLType.getApplicationDataの詳細は、『Oracle Database XML Java API Reference』のXDBRepositoryEventクラスに関する項を参照してください。

- イベント・リスナー用のリソース構成ファイルの例は、例30-1を参照してください。

例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>

23 Oracle XML DBでのXLinkおよびXIncludeの使用

XLinkおよびXIncludeは、Oracle XML DBリポジトリのリソースで使用できます。

- XLinkおよびXIncludeの概要

- XLinkおよびXIncludeのリンク・タイプ

- XInclude: 複合ドキュメント

- Oracle XML DBのXLinkサポート

- Oracle XML DBのXIncludeサポート

- DOCUMENT_LINKSビューを使用したXLinkリンクおよびXIncludeリンクの調査

- XLinkおよびXIncludeのリポジトリ・リソースの構成

- DBMS_XDB_REPOS.processLinksを使用したXLinkリンクおよびXIncludeリンクの管理

23.1 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を参照してください。

23.2 XLinkおよびXIncludeのリンク・タイプ

XLinkおよびXIncludeのリンク・タイプ、およびそれらのリンクとOracle XML DBリポジトリのリンクとの関係について説明します。XLinkリンクは、リポジトリ・リンクよりも一般的です。XLinkリンクには、単純リンクと拡張リンクがあります。Oracle XML DBでは単純XLinkリンクのみがサポートされており、拡張XLinkリンクはサポートされていません。

23.2.1 XLinkリンクおよびXIncludeリンクによるドキュメント間関係のモデル化

XLinkリンクおよびXIncludeリンクを使用すると、ドキュメント間の任意の関係がモデル化されます。関係の意味と動作は、リンクを使用するアプリケーションに依存します。リンク自体によっては決定されません。XLinkリンクおよびXIncludeリンクは、Oracle XML DBのドキュメント・リンクにマップできます。

Oracle XML DBリポジトリのリソースをターゲットとするドキュメント・リンクは、(構成オプションに応じて)ハード・リンクか弱いリンクかのいずれかになります。この点については、リポジトリ・リンクと同様です。ただし、リポジトリ・リンクはFTPやHTTPなどのファイル・システムに関連するプロトコルによってナビゲートできるのに対し、ドキュメント・リンクはこうしたプロトコルではナビゲートできません。ドキュメント・リンクをナビゲートするには、XPath 2.0関数fn:docを使用します。

関連項目:

「ハード・リンクおよび弱いリンク」

23.2.2 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により表されています。

23.3 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には、章を表す別のドキュメントが含まれています。

XIncludeには、その他に次の機能もあります。

- プレーン・テキストの包含: 属性parseに値textを指定したparse = "text"を使用し、未解析の非XMLテキストを含めることができます。

- XMLフラグメントの包含: xi:include要素のxpointer属性を使用し、ドキュメント全体ではなくXMLフラグメントを指定して、それを含めることができます。

- フォールバック処理: 含まれたドキュメントのURIにアクセスできないエラー、xi:include構文エラー、xpointer参照がNULLを戻すエラーなどが発生した場合、XIncludeでは、xi:fallback要素に指定されている処理が実行されます。通常は、含まれる代替要素を指定します。この代替要素では、他ドキュメントを含めるために、これ自体がxi:includeを使用します。

例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>

23.4 Oracle XML DBのXLinkサポート

XLinkリンクを無視したり、XLinkリンクをOracle XML DBのドキュメント・リンクにマップするように、Oracle XML DBリポジトリ・リソースを構成できます。

Oracle XML DBでは単純XLinkリンクのみサポートしており、拡張XLinkリンクはサポートされていません。

XLinkの属性を含むXML文書が、リソース・コンテンツまたはユーザー定義のリソース・メタデータとしてOracle XML DBリポジトリに追加された場合は、リポジトリまたは個々のリポジトリ・リソースの構成に基づいて特殊な処理が実行される場合があります。この処理は、リソース構成ドキュメントXDBResConfig.xsdの要素XLinkConfigによって指定されます。

XLinkリンクがOracle XML DBドキュメント・リンクにマップされるようにリソースを構成する場合、ドキュメント・リンクをハード・リンクにするか弱いリンクにするかを指定できます。ハード・ドキュメント・リンクおよび弱いドキュメント・リンクにはそれぞれ、ハード・リポジトリ・リンクおよび弱いリポジトリ・リンクと同じプロパティがあります。

ドキュメント・リンクの作成や更新に必要な権限は、リポジトリ・リンクの作成や更新に必要な権限と同じです。ドキュメントを部分的に更新する場合でも、ドキュメント全体の削除や再挿入を行う場合と同じ権限が必要です。たとえばドキュメント・リンクを1つしか更新しない場合でも、そのリンクを含むドキュメントにリンクされている各ドキュメントの削除権限と挿入権限が必要です。

構成によりXLinkリンクがドキュメント・リンクにマップされている場合は、XLinkリンクを含むドキュメントがリポジトリに追加されるたびに、XLink情報が抽出され、システム・リンク表に格納されます。リンクのターゲット(リンク先)の場所は、リソースOIDに基づくダイレクト・パスに置き換えられます。構成では、ドキュメント取得の際にOIDパスを名前付きパス(URL)に置き換えるかどうかも指定できます。名前付きパスのかわりにOIDパスを使用すると、通常は、リソース・コンテンツを取得する場合も含め、リンク処理の際のパフォーマンスが向上します。

XLinkは、リソース・コンテンツ内では使用できますが、リソース・メタデータ内では使用できません。

関連項目:

- 「DOCUMENT_LINKSビューを使用したXLinkリンクおよびXIncludeリンクの調査」

- ユーザー定義のリポジトリ・メタデータ

- 「ハード・リンクおよび弱いリンク」

- 「XLinkおよびXIncludeのリポジトリ・リソースの構成」

- 「XDBResConfig.xsd: リソース構成のためのXML Schema」

23.5 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リンクの調査」

23.5.1 複合ドキュメントにおける包含の展開

Oracle XML DBリポジトリから複合ドキュメントを取得する場合、オプションで、xi:include要素をそのターゲットで展開できます。

複合ドキュメントを取得するときには、次の選択肢があります。

- 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-8のリソースbookfile.xmlと、それに含まれているリソースchap1.xmlおよびchap2.xmlに対応するものです。)

関連項目:

- 展開時のアクセス制御の詳細は、「複合ドキュメントのバージョニング、ロックおよびアクセス制御」を参照してください。

- XDBURITypeの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

例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.5.2 複合ドキュメントの検証

複合ドキュメントの検証は、XML文書の検証と同じ方法で行います。ただし、複合ドキュメントの検証は、xi:include要素をそのまま使用するか、ターゲットに置き換えた形で行うかを選択できます。

また、展開されていない形での検証と展開された形での検証に、別々のXML Schemaを使用するように選択できます。たとえば、あるXML Schemaを使用して、最初は記憶域構造を設定できるよう展開せずに検証を行い、次に展開したドキュメントの格納後に、別のXML Schemaを使用して検証できます。

23.5.3 複合ドキュメントの更新

複合ドキュメントは、リソースと同じ方法で更新できます。その場合、リソースが新規の値で置き換えられます。

したがって、リソースを削除し、リソースを挿入する処理に相当します。つまり、元のリソース内のxi:include要素は削除されます。置換後の(挿入された)ドキュメント内のxi:include要素は、挿入時に定義された構成に従って通常どおり処理されます。

23.5.4 複合ドキュメントのバージョニング、ロックおよびアクセス制御

複合ドキュメントは、それぞれ個別のリソースで構成されます。したがって、このようなリソースのバージョンニング、ロックおよびアクセス制御も、それぞれ個別に行われます。

- バージョン管理されたリソース(VCR)へのドキュメント・リンクは、常にターゲット・リソースの最新バージョン、または現在のワークスペース内で選択されたバージョンに解決されます。ただし、OIDベースのパスでターゲット・リソースを識別すると、特定のバージョンを明示的に参照できます。

- xi:include要素を含むドキュメントをロックしても、含まれているドキュメントはロックされません。また、含まれているドキュメントをロックしても、それを含むドキュメントはロックされません。

- 展開した形で複合ドキュメントを取得する場合は、常に各参照ドキュメントのアクセス制御リスト(ACL)がチェックされます。このチェックには、現行ユーザーの権限(起動者の権限)を使用します。含まれているドキュメントのいずれかについて権限が不十分な場合、展開はキャンセルされエラーが発生します。

関連項目:

- 「複合ドキュメントにおける包含の展開」

- VCRの詳細は、 リソース・バージョンを参照してください。

- リソースのACLの詳細は、 リポジトリのアクセス制御を参照してください。

23.6 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リファレンス』を参照してください。

23.6.1 XLink情報に関するDOCUMENT_LINKSへの問合せ

指定されたリソースを含むフォルダが、XLinkリンクをハード・ドキュメント・リンクにマップするように構成されている場合、パブリック・ビューDOCUMENT_LINKSを問い合せて、ドキュメント・リンクに関するシステム情報を取得できます。

例23-3は、リソース作成時にXLinkリンクを処理する方法、およびドキュメント・リンクに関するシステム情報をビューDOCUMENT_LINKSから取得する方法を示したものです。リソースが格納されているフォルダは、XLinkリンクをハード・ドキュメント・リンクにマップするように構成されているとみなされます。

関連項目:

XLinkをハード・リンクにマップするようにフォルダを構成する例は、「例23-5」を参照してください。

例23-3 XLinkリンクからマップされたドキュメント・リンクの問合せ

DECLARE
b BOOLEAN;
BEGIN
b := DBMS_XDB_REPOS.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_REPOS.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

23.6.2 XInclude情報に関するDOCUMENT_LINKSへの問合せ

ビューDOCUMENT_LINKSを問い合せて、XIncludeリンクからマップされたドキュメント・リンクを表示できます。

例23-4は、すべてのドキュメント・リンクを表示するビューDOCUMENT_LINKSに対する問合せを示します。

例23-4 XIncludeリンクからマップされたドキュメント・リンクの問合せ

DECLARE
ret BOOLEAN;
BEGIN
ret := DBMS_XDB_REPOS.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

23.7 XLinkおよびXIncludeのリポジトリ・リソースの構成

他のリソースのXLinkおよびXInclude処理を構成する場合にリソースとして使用するリソース構成ファイルについて説明します。

リソース構成ファイルを使用して、リポジトリ・リソースの他の処理と同様に、Oracle XML DBリポジトリ・リソースの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_REPOS.processLinksを使用します。

関連項目:

- 「DBMS_XDB_REPOS.processLinksを使用したXLinkリンクおよびXIncludeリンクの管理」

- Oracle XML DBリポジトリの構成

23.7.1 未解決リンクの処理の構成: UnresolvedLink属性

LinkConfig要素には、Error (デフォルト値)またはSkipの値のUnresolvedLink属性を使用できます。これは、ドキュメントをリポジトリに挿入する(リソースを作成する)際、XLinkリンクまたはXIncludeリンクを解決できない場合の処理を指定します。

Errorを指定すると、エラーが発生し、現在の操作がロールバックされます。Skipを指定すると、XLinkリンクまたはXIncludeリンクの処理がスキップされます。処理がスキップされると、対応するドキュメント・リンクを含まずにリソースが作成され、そのリソースのHasUnresolvedLinks属性がtrueに設定されます。これは、リソースに未解決リンクが含まれていることを表すものです。

弱いリンクの循環を含むリソースを作成する場合は特に、属性UnresolvedLinkの値としてSkipを指定すると便利です。この値を指定しない場合は、リソース作成中に未解決リンクのエラーが発生します。スキップされたリンクは、リソースおよびそれにリンクするすべてのリソースが作成された後に、PL/SQLプロシージャDBMS_XDB_REPOS.processLinksを使用して処理できます。このプロシージャによってすべてのXLinkリンクおよびXIncludeリンクが解決されると、属性HasUnresolvedLinksはfalseに設定されます。

削除済リソースへの弱いリンクのあるリソースには、リソース要素HasUnresolvedLinksもtrueに設定されます。このため、リソースを削除すると、そのリソースに対する弱いリンクも事実上削除されます。特に、リソースへの最後のハード・リンクを削除した場合は、リソースそのものも削除され、削除されたリソースを弱いリンクで示すすべてのリソースで、属性HasUnresolvedLinksがtrueに設定されます。

関連項目:

- 「ハード・リンクおよび弱いリンク」

- 「DBMS_XDB_REPOS.processLinksを使用したXLinkリンクおよびXIncludeリンクの管理」

23.7.2 作成するドキュメント・リンクのタイプの構成: LinkType要素

リソース構成ファイルのLinkType要素を使用して、ドキュメントのOracle XML DBリポジトリへの格納の際、XLinkリンクまたはXIncludeリンクが検出された場合に作成されるドキュメント・リンクのタイプを指定します。LinkType要素に指定できる値(要素のコンテンツ)は次のとおりです。

- None(デフォルト): XLinkリンクおよびXIncludeリンクが無視され、対応するドキュメント・リンクは作成されません。

- Hard: XLinkリンクまたはXIncludeリンクが、リポジトリ・ドキュメント内のハード・ドキュメント・リンクにマップされます。

- Weak: XLinkリンクまたはXIncludeリンクが、リポジトリ・ドキュメント内の弱いドキュメント・リンクにマップされます。

関連項目:

- 例23-5

- 例23-6

23.7.3 取得に使用するパス形式の構成: 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

23.7.4 XIncludeに関する競合解決の構成: ConflictRule要素

リソース構成ファイルのConflictRule要素を使用して、構成要素ドキュメントに対して計算済のパスがすでにOracle XML DBリポジトリ内にある場合に使用する競合解決ルールを指定します。ConflictRule要素に指定できる値(要素のコンテンツ)は次のとおりです。

- Error(デフォルト): エラーが発生します。

- Overwrite: 既存のリポジトリ・パスのターゲットとなっているドキュメントを、含まれているドキュメントに置き換えると更新されます。既存のドキュメントがバージョン管理されたリソースであれば、バージョニングが自動的に行われる場合を除いて、事前にチェックアウトされます。そうでない場合は、エラーが発生します。

- Syspath: 含まれているドキュメントへのパスが、新規システム定義のパスに変更されます。

関連項目:

バージョン管理されたリソースの詳細は、 リソース・バージョンを参照してください。

23.7.5 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

- 例23-8

23.7.6 XLinkおよびXIncludeの構成例

XLinkおよびXIncludeとOracle XML DBリポジトリのリソースおよびリンクとの関連の例を示します。

例23-5は、XInclude処理を構成する構成ファイルのセクションを示します。ここではXInclude属性をOracle XML DBリポジトリのハード・ドキュメント・リンクにマップします。取得したリソース内のリポジトリ・パスは、リソースのOIDに基づいて構成されます。

例23-6は、XLinkリンクをリポジトリ内の弱いドキュメント・リンクにマップするためのXLinkConfigセクションを示したものです。この場合、ドキュメントの取得には名前付きパス(URL)が使用されます。

例23-7は、入力ドキュメントをOracle XML DBリポジトリに追加する際、入力ドキュメントの各Chapter要素が別々のリポジトリ・ファイルになるように指定するSectionConfigセクションを示します。作成されたファイルのリポジトリ・パスは、構成要素documentPathによって指定され、このパスは、例23-6のリソース構成ファイルの場所に対する相対パスです。

この例の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にこれを示します。

関連項目:

- Oracle XML DBリポジトリの構成

- XDBResConfig.xsd: リソース構成のためのXML Schema

- 「XIncludeを使用したドキュメントの分解の構成: SectionConfig要素」

例23-5 OIDによる取得時のXIncludeリンクからハード・ドキュメント・リンクへのマッピング

<ResConfig>
. . .
<XIncludeConfig UnresolvedLink="Skip">
<LinkType>Hard</LinkType>
<PathFormat>OID</PathFormat>
</XIncludeConfig>
. . .
</ResConfig>

例23-6 名前付きパスによる取得時のXLinkリンクから弱いリンクへのマッピング

<ResConfig>
. . .
<XLinkConfig UnresolvedLink="Skip">
<LinkType>Weak</LinkType>
<PathFormat>Named</PathFormat>
</XLinkConfig>
. . .
</ResConfig>

例23-7 XIncludeを使用したドキュメントの分解の構成

<ResConfig>
. . .
<SectionConfig>
<Section type = "Document">
<sectionPath>//Chapter</sectionPath>
<documentPath>concat("chap", @id, ".xml")</documentPath>
</Section>
</SectionConfig>
. . .
</ResConfig>

例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>

23.8 DBMS_XDB_REPOS.processLinksを使用したXLinkリンクおよびXIncludeリンクの管理

PL/SQLプロシージャDBMS_XDB_REPOS.processLinksを使用して、単一ドキュメント内、または1つのフォルダに格納された全ドキュメント内のXLinkリンクおよびXIncludeリンクをすべて手動で処理できます。

ハード・リンクされたすべてのサブフォルダを再帰的に処理する場合は、RECURSIVEをモード引数としてこのプロシージャに渡します。すべてのXLinkリンクおよびXIncludeリンクは、対応する構成パラメータに従って処理されます。リソース内のいずれかのリンクを解決できない場合は、そのリソースのHasUnresolvedLinks属性がtrueに設定され、リソースに未解決リンクが含まれていることが示されます。属性HasUnresolvedLinksのデフォルト値はfalseです。

関連項目:

「未解決リンクの処理の構成: UnresolvedLink属性」

24 RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリへのアクセス

事前定義されたパブリック・ビューRESOURCE_VIEWおよびPATH_VIEWは、Oracle XML DBリポジトリ・データへのアクセスを提供します。Oracle SQL関数under_pathおよびequals_pathを使用すると、リソースのパス名に基づいてリソースを問い合せることができ、関数pathとdepthを使用すると、リソース・パス名と深さを戻すことができます。

- Oracle XML DBのRESOURCE_VIEWとPATH_VIEWの概要

- RESOURCE_VIEWおよびPATH_VIEWを使用するOracle SQL関数

- リポジトリ・データ・パス、リソースおよびリンクへのアクセス: 例

- リポジトリ・リソースの削除: 例

- リポジトリ・リソースの更新例

- 複数のOracle XML DBリソースの操作

- Oracle XML DBリポジトリ操作のパフォーマンス・ガイドライン

- Oracle Textを使用したリソースの検索

関連項目:

- ビューPATH_VIEWの詳細は、『Oracle Databaseリファレンス』を参照してください。

- ビューRESOURCE_VIEWの詳細は、『Oracle Databaseリファレンス』を参照してください。

24.1 Oracle XML DBのRESOURCE_VIEWとPATH_VIEWの概要

パブリック・ビューRESOURCE_VIEWおよびPATH_VIEWでは、SQLを使用してOracle XML DBリポジトリに格納されたデータにアクセスするためのメカニズムが提供されます。これらのビューを使用すると、FTPやWebDAVなどのインターネット・プロトコルまたはApplication Program Interface (API)を使用して、リポジトリに格納されたデータにアクセスできます。

図24-1では、これを説明しています。

RESOURCE_VIEWは、リソース名を含むリソース(それ自体はXMLTypeインスタンス)、ACLおよびプロパティ(静的または拡張可能)で構成されます。

- リソースのコンテンツがXMLType表またはビュー内に格納されているXMLデータである場合、RESOURCE_VIEWはそのコンテンツを格納するXMLType行を指します。

- リソースのコンテンツがXMLデータではない場合、RESOURCE_VIEWはそのコンテンツをLOBとして格納します。

注意:

Oracle Database リリース11.2.0.1.0以降では、表内にLOBとして格納されるリポジトリ・コンテンツは、SecureFiles LOB記憶域を使用します。それより前は、BasicFiles LOB記憶域を使用していました。

フォルダ間の親子関係は、リポジトリの階層索引を使用して効率的に保持および検索されます。テキスト索引はリソースのプロパティの検索に使用でき、名前およびACLに対する内部Bツリー索引によって、リソースXMLTypeデータのこれらの属性に対するアクセスが高速化されます。

RESOURCE_VIEWとPATH_VIEWをPL/SQLパッケージDBMS_XDB_REPOSとともに使用すると、Oracle XML DBへの問合せベースのアクセス、およびAPIを使用して利用可能なすべてのDML機能が提供されます。

RESOURCE_VIEWの実表はXDB.XDB$RESOURCEです。この表にアクセスするには、RESOURCE_VIEWまたはPL/SQLパッケージDBMS_XDB_REPOSのみを使用してください。

関連項目:

Oracle XML DBの使用方法の概要

図24-1 RESOURCE_VIEWおよびPATH_VIEWを使用したリポジトリ・リソースへのアクセス

図24-2にRESOURCE_VIEWとPATH_VIEWの構造を示します。

図24-2 RESOURCE_VIEWとPATH_VIEWの構造

注意:

ルート・フォルダ(/)リソースは、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は戻しません。

24.1.1 RESOURCE_VIEWの定義および構造

パブリック・ビューRESOURCE_VIEWには、Oracle XML DBリポジトリの各リソースに対して1つの行が含まれます(ルート・フォルダ・リソースを除く)。

表24-1では、RESOURCE_VIEWの構造について説明します。

表24-1 RESOURCE_VIEWの構造

列

データ型

説明

RES

XMLType

リポジトリ内のリソース(ルート・フォルダ・リソースを除く)

ANY_PATH

VARCHAR2

リソースへの(絶対)パス

RESID

RAW

リソースのOID。リソースの一意のハンドル。

24.1.2 PATH_VIEWの定義および構造

パブリック・ビューPATH_VIEWには、Oracle XML DBリポジトリのリソースにアクセスする一意のパスごとに1行が含まれます(ルート・フォルダ・リソースを除く)。各リソースには、リンクとも呼ばれる複数のパスが含まれる場合があります。

表24-2では、PATH_VIEWの構造について説明します。

表24-2 PATH_VIEWの構造

列

データ型

説明

PATH

VARCHAR2

リポジトリ・リソースRESへの(絶対)パス

RES

XMLType

列PATHにより参照されるリソース

LINK

XMLType

リンクのプロパティ

RESID

RAW

リソースOID

24.1.3 RESOURCE_VIEWとPATH_VIEWとの違い

PATH_VIEWには、特定のリソースに対するすべてのパス名が含まれます。RESOURCE_VIEWには、リソースに対する可能なパス名のうちの1つが含まれます。PATH_VIEWには、リンク・プロパティも含まれます。パフォーマンスを高めるには、可能なかぎりPATH_VIEWではなくRESOURCE_VIEWを使用します。

図24-3に、この違いを示します。

多くのインターネット・アプリケーションでは1つのURLがあればリソースにアクセスできるため、RESOURCE_VIEWは広範囲に適用できます。

PATH_VIEWには、リンク・プロパティとリソース・プロパティの両方が含まれますが、RESOURCE_VIEWには、リソース・プロパティのみが含まれます。

PATH_VIEWを使用すると、複数のパスの情報が処理されるため、アクセスに時間がかかることがあります。RESOURCE_VIEWを使用すると、データベースでは、必要なパスが1つのみであるという事実を活用して、使用可能なすべてのパスを索引で判断する作業を軽減できます。

注意:

RESOURCE_VIEWを使用するとき、関数under_pathまたはequals_pathを使用してパスを指定した場合は、指定されたパスが、そのリソースに対してRESOURCE_VIEWを使用した場合に通常表示するものとして選択した任意のパスであるかどうかに関係なく、関数によってリソースが検索されます。

図24-3 RESOURCE_VIEWとPATH_VIEWの解説

24.1.4 UNDER_PATHおよびEQUALS_PATHを使用して実行できる操作

Oracle SQL関数under_pathおよびequals_pathを使用して、リソースまたはそのOIDを取得したり、リソースを作成、削除または更新したり、パス名に対応するディレクトリをリストできます。

- パス名を指定した場合、次のことができます。

- リソースまたはそのOIDの取得

- パス名で指定されたディレクトリのリスト

- リソースの作成

- リソースの削除

- リソースの更新

- under_pathまたは他のSQL関数を使用する条件を指定した場合、次のことができます。

- リソースの更新

- リソースの削除

- 複数のリソースまたはそのOIDの取得

24.2 RESOURCE_VIEWおよびPATH_VIEWを使用するOracle SQL関数

パブリック・ビューRESOURCE_VIEWおよびPATH_VIEWで使用されるOracle SQL関数には、under_path、equals_path、pathおよびdepthが含まれます。

24.2.1 UNDER_PATH SQL関数

Oracle SQL関数under_pathは、Oracle XML DBリポジトリの階層索引を使用して、特定のパスの下に存在するすべてのハード・リンクのパスを戻します。この索引は、(最も一般的な用途である)パスの検索の際、高速にアクセスできるように設計されています。

ただし、問合せ述語の他の部分の選択性が高い場合、リポジトリを下から上に検索するunder_pathの機能実装を選択できます。この場合、検索が必要なリンクの数が少なくなるため、より効率的です。図24-4にunder_pathの構文を示します。

図24-4 UNDER_PATHの構文

表24-3にOracle SQL関数under_pathのシグネチャに関する詳細を示します。

表24-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)に関連付けるために使用できる整数。

戻されるリソースのpathname引数の下には、そのリソースにアクセス可能なパスが1つしか必要ないことに注意してください。このようなパスが引数pathnameの下にない場合は、NULL値が戻されます。

注意:

このような検索は循環する場合があるため、関数under_pathが弱いリンクの後に続くことはありません。under_pathに対する弱いリンクの引数は正しく解決されますが、そのパスのリソースを検索する場合、弱いリンクの後に続くことはありません。

24.2.2 EQUALS_PATH SQL関数

Oracle SQL関数equals_pathを使用して、指定されたパス名を含むリソースを検索します。これはunder_pathの深さの制約がゼロの場合と機能的に同等です。

equals_path(resource_column, pathname);

パラメータは次のとおりです。

- resource_columnはPATH_VIEWまたはRESOURCE_VIEWのRESOURCE列の列名または列の別名です。

- pathnameは、解決する(絶対)パス名です。このパス名には、ハード・リソース・リンクまたは弱いリソース・リンクが構成要素として含まれます。

図24-5に、equals_pathの完全な構文を示します。

図24-5 EQUALS_PATHの構文

注意:

- Oracle SQL関数equals_pathを使用して、リソースパスの等価テストequals_path('/my/path') = 1を行ってください。絶対パスについては、ANY_PATHの等価テストANY_PATH = '/my/path'は行わないでください。

- ハードコードされた文字列ではなく、バインド変数をequals_pathとともに使用してください。

24.2.3 PATH SQL関数

Oracle SQL関数pathは、指定されたpathname引数の下にあるリソースの相対パス名を、関数under_pathまたはequal_pathに戻します。

RESOURCE_VIEWのパス列には、常にリソースの絶対パスが含まれます。関数pathの構文は、次のとおりです。

path(correlation);

パラメータは次のとおりです。

- correlationは、pathをunder_pathまたはequals_pathに関連付けるために使用できる整数です。

図24-6に、関数pathの構文を示します。

図24-6 PATHの構文

24.2.4 DEPTH SQL関数

Oracle SQL関数depthは指定された起動パスの下にあるリソースのフォルダ階層を戻します。

depth(correlation);

パラメータは次のとおりです。

correlationは、depthをunder_pathまたはequals_pathを持つpathに関連付けるために使用できる整数です。

24.3 リポジトリ・データ・パス、リソースおよびリンクへのアクセス: 例

ここでの例は、Oracle XML DBリポジトリ・パス、リソースおよびリンク・プロパティにアクセスする方法を示しています。

初めの方の例では、次のパスで指定されたリソースを使用します。

/a/b/c
/a/b/c/d
/a/e/c
/a/e/c/d

例24-1では、Oracle SQL関数pathを使用してパス/a/bの下の相対パスを取得します。

例24-2では、ANY_PATHを使用してパス/a/bの下の絶対パスを取得します。

例24-3は例24-2と同じ例ですが、等しい(=)ものでなく等しくない(!=)ものを選び出している点が異なります。例24-3の問合せでは、リポジトリ内でパス/a/bの下にないすべてのパスを検索します。

例24-4に、リポジトリのa/bフォルダおよび/a/eフォルダの下位の相対パスをそれぞれ示します。式path(1)は、a/bフォルダを指定している式under_path(RES, '/a/b', 1)と同じcorrelation番号1を使用しているので、a/bフォルダの下位のパスを表します。path(2)と/a/eフォルダについても同様です。式ANY_PATHは、対応する絶対パスを戻します。

例24-1 あるパスの下にあるパスの判別: 相対

SELECT path(1) FROM RESOURCE_VIEW WHERE under_path(RES, '/a/b', 1) = 1;

PATH(1)
-------
c
c/d

2 rows selected.

例24-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.

例24-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.

例24-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.

例24-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.

例24-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.

例24-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
. . .

例24-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.

例24-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.

例24-10 EQUALS_PATHを使用したリポジトリ・パスの特定

SELECT ANY_PATH FROM RESOURCE_VIEW WHERE equals_path(RES, '/sys') > 0;

ANY_PATH
--------
/sys

1 row selected.

例24-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.

例24-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.

例24-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.

例24-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.

24.4 リポジトリ・リソースの削除: 例

ここでの例は、Oracle XML DBリポジトリのリソースおよびパスを削除する方法を示しています。

リーフ・リソースのみを削除するには、例24-15のようにDELETE FROM RESOURCE_VIEWを使用します。

同じリソースへの複数のリンクの場合、RESOURCE_VIEWから削除すると、リソースはそのリンクすべてとともに削除されます。PATH_VIEWから削除すると、指定したパスのリンクのみが削除されます。

例24-16に、これを示します。

例24-15 リソースの削除

DELETE FROM RESOURCE_VIEW WHERE equals_path(RES, '/public/myfile') = 1';

例24-16 リソースへのリンクの削除

たとえば、'/home/myfile1'が'/public/myfile'へのリンクだとします。

CALL DBMS_XDB_REPOS.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;

24.4.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);

例24-17は、空でないフォルダの削除方法を示しています。この例では、フォルダexampleが、サブフォルダexample1とともに削除されています。

注意:

この場合も、複数の行に対して操作を行う場合、同時トランザクションでのデッドロックが発生しないように注意する必要があります。

例24-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

24.5 リポジトリ・リソースの更新例

ここでの例は、Oracle XML DBリポジトリのリソースおよびパスを更新する方法を示しています。

例24-18は、パス/test/HR/example/paperのリソースを変更します。

関連項目:

リソース・メタデータの更新のその他の例は、 ユーザー定義のリポジトリ・メタデータを参照してください。

デフォルトでは、DisplayName要素のコンテンツpaperは、リソース・パス/test/HR/example/paperの最後のロケーション・ステップと同じテキストだったことに注意してください。ただし、これはデフォルト値にすぎません。DisplayNameはリソース・パスからは独立なので、更新してもパスは変わりません。

要素DisplayNameはWebDAV標準によって定義されていて、WebDAVアプリケーションにより認識されています。FTPクライアントなど、WebDAVベースでないアプリケーションは、リソースのDisplayNameを認識しません。FTPクライアントは、UPDATE操作の後であっても、(たとえばFTPコマンドlsを使用して)リソースをpaperとしてリストします。

例24-19では、リソースのパスを/test/HR/example/paperから/test/myexampleへと変更します。これはUNIXまたはLinuxコマンドmv /test/HR/example/paper /test/myexampleの使用に類似しています。

関連項目:

RESOURCE_VIEWおよびPATH_VIEWに適用されるSQL関数を使用するその他の例は、表21-3を参照してください。

例24-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 =
XMLQuery('copy $i := $p1 modify
(for $j in $i/Resource/DisplayName
return replace value of node $j with $p2)
return $i'
PASSING r.RES AS "p1", 'My New Paper' AS "p2"
RETURNING CONTENT)
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.

例24-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.

24.6 複数のOracle XML DBリソースの操作

複数のOracle XML DBリソースに対して操作を実行するか、または特定の一連の基準を満たす1つ以上のOracle XML DBリソースを検索するには、SQLでRESOURCE_VIEWおよびPATH_VIEWを使用します。

たとえば、次の操作を実行できます。

- 属性に基づいたリソースの更新 - 例24-20を参照

- フォルダ内のリソースの検索 - 例24-21を参照

- 一連のOracle XML DBリソースのコピー - 例24-22を参照

例24-22のSQL DML文では、フォルダpublic内のすべてのリソースをフォルダnewlocationにコピーします。これはUNIXまたはLinuxコマンドcp /public/* /newlocationに類似しています。ターゲット・フォルダnewlocationはコピーの前に存在している必要があります。

例24-20 属性に基づいたリソースの更新

UPDATE RESOURCE_VIEW
SET RES =
XMLQuery('copy $i := $p1 modify
(for $j in $i/Resource/DisplayName
return replace value of node $j with $p2)
return $i'
PASSING RES AS "p1", 'My New Paper' AS "p2"
RETURNING CONTENT)
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.

例24-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/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/xdblog.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/stats.xsd
/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/xdbconfig.xsd

12 rows selected.

例24-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.

24.7 Oracle XML DBリポジトリ操作のパフォーマンス・ガイドライン

リソースの作成や問合せなど、リポジトリ操作のパフォーマンスを高めるためのガイドラインを示します。

フォルダに多数のリソースが含まれる場合、特に多数のリソースを作成または削除するときに、並行性が低下することがあります。一般的に、フォルダに含めるリソースは10,000以下に抑えてください。経験的限界は、データベース・ブロック・サイズとファイル名の平均長によって決まります。

リソースを一括で作成する場合は、少なくとも1,000リソースに1回ずつCOMMIT操作を実行してください。コミットの頻度が高すぎる場合も、1,000リソースの作成ごとに1回より頻度が低い場合も、パフォーマンスが低下することがあります。

既知のXML Schemaに基づく文書であるファイル・リソースを作成する場合、PL/SQLファンクションDBMS_XDB_REPOS.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です。ドキュメントがこの数値を超えると、一部のロード可能ユニット(パーティション)のスワッピングが行われます。

関連項目:

- Oracle XML DBの管理

- PL/SQLファンクションDBMS_XDB_REPOS.createResourceの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

24.8 Oracle Textを使用したリソースの検索

データベース・スキーマXDBの表XDB$RESOURCEは、リポジトリ・リソースに対応するメタデータおよびデータを格納します。RESOURCE_VIEWまたはPATH_VIEWでOracle SQL関数containsを使用して、特定のキーワードを含むリソースを検索できます。

このような問合せを評価するには、まずXDB$RESOURCE表にConText索引を作成する必要があります。Oracle XML DBに格納されたドキュメント・タイプに応じて次のいずれかのオプションを選択して、ConText索引を作成します。

- Oracle XML DBにXML文書のみが含まれる場合、つまりバイナリ・データが含まれない場合は、通常のContext索引をXDB$RESOURCE表に作成できます。例24-24がその例です。

CREATE INDEX xdb$resource_ctx_i ON XDB.XDB$RESOURCE(OBJECT_VALUE)
INDEXTYPE IS CTXSYS.CONTEXT;

関連項目:

「XMLデータの問合せと更新」および「XQueryを使用しない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パッケージおよびタイプ・リファレンス』を参照してください。

- 「PL/SQL API for XMLType: リファレンス」

パッケージDBMS_XDBTには、索引の同期と最適化に使用するプロシージャも含まれています。プロシージャconfigureAutoSync()を使用し、ジョブ・キューを使用して索引を自動的に同期化できます。

例24-23 「Paper」を含むすべてのリソースの検索

SELECT PATH FROM PATH_VIEW WHERE contains(RES, 'Paper') > 0;

PATH
-----------------------
/newlocation/myexample
/test/myexample

2 rows selected.

例24-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.

25 リソース・バージョン

Oracle XML DBリポジトリ・リソースはバージョニングできます。バージョン管理されたリソースに対するすべての変更の記録が保持されます。

- Oracle XML DBバージョニングの概要

- リソース・バージョンおよびリソースID

- リソース・バージョンおよびACL

- リソースのバージョニングの例

25.1 Oracle XML DBリポジトリ・リソースのバージョニングの概要

様々なバージョンのリポジトリ・リソースを作成および管理できます。バージョン管理されたリソースに対するすべての変更の記録が保持されます。バージョン管理されたリソースを更新すると、更新前のコンテンツは、異なるリソース・バージョン(履歴レコードのスナップショット)として格納されます。

バージョニング機能には次のものが含まれます。

- リソースのバージョン管理。
Oracle XML DBリポジトリ・リソースのバージョン管理を有効または無効にするオプションがあります。

- バージョン管理されたリソースの更新。
Oracle XML DBは、バージョン管理されたリソースを更新するときに、リソースの新しいバージョンを作成します。この新しいバージョンは、バージョン管理されたリソースを削除しても、データベースから削除されません。

- バージョン管理されたリソースへのアクセス。
バージョン管理されたリソースには、他のリソースへのアクセスと同じ方法でアクセスできます。

- リソース・バージョンへのアクセス。
リソースの特定のバージョンにアクセスするには、そのバージョンのリソースIDを使用します。リソースIDは、リソース・バージョン履歴またはバージョン管理されたリソース自身から取得できます。「リソース・バージョンおよびリソースID」を参照してください。

表25-1に、この章で使用する用語について示します。

表25-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つを問い合せる場合は、その問合せで複数のバージョンのリソースからデータを戻すことができることにも注意してください。これは、行ごとに異なるリソース・バージョンのデータが基礎となる同じ表に格納されるためです。

25.2 PL/SQLパッケージDBMS_XDB_VERSIONの概要

Oracle XML DBリポジトリのリソース・バージョンを操作するには、PL/SQLパッケージDBMS_XDB_VERSIONを使用します。

表25-2に、主要なDBMS_XDB_VERSIONサブプログラムをまとめます。

表25-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_VERSION.RESID_TYPE;

チェックアウトしたリソースをチェックインします。

引数はチェックアウトしたリソースのパス名です。

リソースがチェックアウトされる前にバージョンのリソースIDを戻します。これは、自動コミットのSQL操作ではありません。チェックアウトに使用したパス名と同じパス名を使用する必要はありません。しかし、unCheckOutのパス名とチェックアウトのパス名は同じリソースを参照する必要があります。そうでない場合は、予期しない結果になります。

リソースの名前が変更された場合は、unCheckOutに新しい名前を使用する必要があります。パス名で参照するリソースがないと、エラーが発生します。

getPredecessors(pathname VARCHAR2) RETURN RESID_LIST_TYPE;

getPredsByRESID(resid DBMS_XDB_VERSION.RESID_TYPE) RETURN RESID_LIST_TYPE;

バージョン・リソースまたはバージョン管理されたリソースを参照するパス名を指定すると、先行のリソースが戻されます。

ファンクションgetPredsByRESIDを使用して先行のリソースをリソースIDで取り出すことは、ファンクションgetPredecessorsを使用してパス名で取り出す方法よりも効率的です。

戻される先行リソースのリストに含まれる要素(親)は1つのみです。Oracle XML DBでは、ブランチがサポートされていません。

getSuccessors(pathname VARCHAR2) RETURN RESID_LIST_TYPE;

getSuccsByRESID(resid DBMS_XDB_VERSION.RESID_TYPE) RETURN RESID_LIST_TYPE;

指定されたバージョン・リソースまたはバージョン管理されたリソースで、後続のリソースを戻します。

ファンクションgetSuccsByRESIDを使用して後続のリソースをリソースIDで取り出すことは、ファンクションgetSuccessorsを使用してパス名で取り出す方法よりも効率的です。

戻される後続リソースに含まれる要素(親)は1つのみです。Oracle XML DBでは、ブランチがサポートされていません。

getResourceByRESID(resid DBMS_XDB_VERSION.RESID_TYPE) RETURN XMLType;

指定されたリソースIDで、リソースをXMLTypeインスタンスとして戻します。

25.3 リソース・バージョンおよびリソースID

リソース・オブジェクトID (リソースID)は、リソースに一意のシステム生成された定数のIDです。各リソースにはそれぞれリソース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: リソース・ハンドルまたはパス名が無効です)が発生します。バージョン管理されたリソースを削除すると、そのバージョンにはアクセスできません。

25.4 リソース・バージョンおよびACL

バージョン・リソースは不変です。これはリソースのコンテンツおよびメタデータのスナップショットで、リソースIDと、スナップショットおよびIDの両方は静的です。同様に、バージョン・リソースのアクセス制御リスト(ACL)は変更できません。

バージョン管理されたリソースをチェックアウトすると、そのACLを変更することはできません。ACLをチェックインすると、変更されたACLには引き続き現在(最新)のバージョンのリソースが関連付けられ、前のバージョン(新しく作成されたバージョン・リソース)は、変更前のACLに関連付けられます。つまり、前のバージョンは前のACLに関連付けられ、現在のバージョンは更新済のACLに関連付けられます。

注意する重要な点は次のとおりです。

- リソースのバージョンごとに異なるACLを関連付けることができます。

- 現在のバージョンに関連付けられたACLは、リソースのチェックアウト後に変更できます。

- チェックインすると、新しく作成されたバージョン・リソース(リソースの前のバージョン)にチェックアウト前のACLが関連付けられます。

- 指定されたバージョンに関連付けられたACLは同じままです。

25.5 リソースのバージョニングの例

ここでは、バージョン管理されたリソースの作成、そのリソースIDを使用したリソースのコンテンツの取出し、バージョン管理されたリソースのチェックアウト(すべてのユーザー対象)、リソースのコンテンツの更新、リソースのチェックイン、様々なバージョンのリソースのコンテンツとメタデータの取出しおよびリソースのチェックアウトのキャンセルを行う例を示します。

- リソースのバージョン管理への配置 - 例25-2

- そのリソースIDを使用したリソースのコンテンツの取出し - 例25-3

- バージョン管理されたリソースのチェックアウト(すべてのユーザー対象) - 例25-4

- リソースのコンテンツの更新 - 例25-5

- リソースのチェックイン - 例25-6

- 様々なバージョンのリソースのコンテンツとメタデータの取出し - 例25-7、例25-8、例25-9

- リソースのチェックアウトのキャンセル - 例25-10

例25-3では、Oracle XML DBリポジトリ・リソースをリポジトリ・パス/public/t1.txtで作成します。リソースにはコンテンツとしてテキストMary had a little lambが含まれます。この例では、SQL*PlusコマンドVARIABLEを使用して、この項の別の例で使用されているバインド変数targetPath、current_RESIDおよびprevious_RESIDを宣言します。

新しいリソースはバージョン管理されません。例25-2では、PL/SQL関数DBMS_XDB_VERSION.makeVersionedを使用して、バージョン管理の対象にします。この関数は、バージョン管理されたリソースの最初のバージョン・リソースのリソースIDを戻します。この関数では自動コミットは行われません。明示的にCOMMITを使用する必要があります。

例25-2では、新しいバージョン・リソースのリソースIDをバインド変数current_RESIDにコピーします。例25-3に、PL/SQLコンストラクタXDBUritypeとPL/SQL関数createOIDPathを使用し、リソースIDを参照してリソース・コンテンツを取り出す方法を示します。

例25-4では、バージョン管理されたリソースをチェックアウトして(コミットし)、このリソースを変更できるようにします。チェックアウトされたリソースは変更できません。

例25-5では、チェックアウトしたリソースのコンテンツを更新します。(LOB)コンテンツを更新する前に、リソースをロックする必要があります。この例では、リソースの表示名(スカラー属性)のダミー更新を使用して、この操作を実行します。

例25-5では、LOBロケータを使用してLOBコンテンツを取得します。これは要素/ns:Resource/ns:XMLLobです。これにより既存のコンテンツは空になり、パッケージDBMS_LOB内のPL/SQLプロシージャtrimおよびappendを使用して、新しいコンテンツが追加されます。コンテンツの変更がコミットされます。

関連項目:

LOBの更新の詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照してください。

この時点でコンテンツは変更されていますが、この変更はバージョン・シリーズに記録されていません。例25-6では、リソースをチェックインし、チェックインをコミットします。

PL/SQL関数checkInは現在のバージョンのリソースIDを戻し、これはcurrent_RESIDと同じです。例25-6では、この値をPL/SQL関数getPredsByRESIDに渡します。この関数は、引数の直前のリソースの、リソースIDのリストを戻します。脚注 1 例25-6では、このリストの最初(かつ唯一)の要素をバインド変数previous_RESIDに割り当てます。

この時点で、current_RESIDの値は現在のバージョンのリソースIDで、previous_RESIDの値は前のバージョンのリソースIDです。

リソースのコンテンツまたはメタデータは、次の方法を使用して取り出すことができます。

- PL/SQLコンストラクタXDBURITypeとPL/SQLファンクションDBMS_XDB_REPOS.createOIDPath: コンテンツを取り出します。例25-3および例25-7を参照してください。

- PL/SQLファンクションDBMS_XDB_VERSION.getContentsCLOBByRESID: コンテンツを取り出します。例25-8を参照してください。

- PL/SQLファンクションDBMS_XDB_VERSION.getResourceByRESID: メタデータを取り出します。例25-9を参照してください。

コンストラクタXDBURITypeと関数createOIDPathを使用すると、プロトコルを使用してリソース・コンテンツにアクセスできます。たとえば、createOIDPathによって戻される値にHTML IMAGEタグのHREFを設定し、様々なバージョンのWebページ用グラフィック・イメージ・ファイルのリソースをOracle XML DBで提供できます。

例25-7から例25-9では、それぞれ異なる方法を使用して、バインド変数current_RESIDおよびprevious_RESIDで指定されるリソースの2つのバージョンをチェックイン後に取り出します。

PL/SQLファンクションDBMS_XDB_VERSION.unCheckOutを使用すると、チェックアウトをキャンセルできます。例25-10に、これを示します。

例25-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_REPOS.existsResource(:targetPath))
THEN DBMS_XDB_REPOS.deleteResource(:targetPath);
END IF;
res := DBMS_XDB_REPOS.createResource(:targetPath, 'Mary had a little lamb');
END;
/

例25-2 バージョン管理されたリソースの作成

DECLARE
resid DBMS_XDB_VERSION.RESID_TYPE;
BEGIN
resid := DBMS_XDB_VERSION.makeVersioned(:targetPath);
:current_RESID := resid;
COMMIT;
END;
/

例25-3 リソースIDの参照によるリソース・コンテンツの取出し

SELECT XDBURIType(DBMS_XDB_REPOS.createOIDPath(:current_RESID)).getClob()
FROM DUAL;

XDBURITYPE(DBMS_XDB_REPOS.CREATEOIDPATH(:CURRENT_RESID)).GETCLOB()
------------------------------------------------------------------
Mary had a little lamb

1 row selected.

例25-4 バージョン管理されたリソースのチェックアウト

BEGIN
DBMS_XDB_VERSION.checkOut(:targetPath);
COMMIT;
END;
/

例25-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 =
XMLQuery('copy $i := $p1 modify
(for $j in $i/Resource/DisplayName
return replace value of node $j with $p2)
return $i'
PASSING
RES AS "p1",
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)) AS "p2"
RETURNING CONTENT)
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;
/

例25-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;
/

例25-7 XDBURITYPEおよびCREATEOIDPATHを使用したリソース・バージョン・コンテンツの取出し

SELECT XDBURIType(DBMS_XDB_REPOS.createOIDPath(:current_RESID)).getClob()
FROM DUAL;

XDBURITYPE(DBMS_XDB_REPOS.CREATEOIDPATH(:CURRENT_RESID)).GETCLOB()
------------------------------------------------------------------
Mary had a little lamb

1 row selected.

SELECT XDBURIType(DBMS_XDB_REPOS.createOIDPath(:previous_RESID)).getClob()
FROM DUAL;

XDBURITYPE(DBMS_XDB_REPOS.CREATEOIDPATH(:PREVIOUS_RESID)).GETCLOB()
-------------------------------------------------------------------
Hickory dickory dock, the mouse ran up the clock

1 row selected.

例25-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.

例25-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.

例25-10 UNCHECKOUTを使用したチェックアウトのキャンセル

DECLARE
resid DBMS_XDB_VERSION.RESID_TYPE;
BEGIN
resid := DBMS_XDB_VERSION.unCheckOut(:targetPath);
END;
/

脚注の凡例

脚注1:
Oracle XML DBでは、バージョン・リソースは、常に、単一の先行リソース(その直前の単一のバージョン)を持ちます。WebDAV標準では、複数の先行リソースの選択肢が用意されます。

26 Oracle XML DBリポジトリへのPL/SQLアクセス

PL/SQLパッケージDBMS_XDB_CONFIGおよびDBMS_XDB_REPOSは、ともに、Oracle XML DBリソースのPL/SQL用アプリケーション・プログラム・インタフェース(API)を提供します。前者を使用して、Oracle XML DBとそのリポジトリを構成します。後者を使用して、リポジトリでのその他の非構成操作を実行します。

- DBMS_XDB_REPOS: リポジトリ・リソースのアクセスと管理

- DBMS_XDB_REPOS: ACLベースのセキュリティ管理

- DBMS_XDB_CONFIG: 構成管理

関連項目:

- 「PL/SQL API for XMLType: リファレンス」

- 「パッケージDBMS_XDB_ADMIN」

26.1 DBMS_XDB_REPOS: リポジトリ・リソースのアクセスと管理

PL/SQLパッケージDBMS_XDB_REPOSを使用すると、Oracle XML DBリポジトリ内のリソースにアクセスして管理できます。また、アクセス制御リスト(ACL)に基づいたリソースのセキュリティ管理も可能です。ACLは、どのリソースへのアクセス権をどのプリンシパル(ユーザーまたはロール)が持つかを決定するアクセス制御エントリ(ACE)のリストです。

関連項目:

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

表26-1に、パッケージDBMS_XDB_REPOSのファンクションおよびプロシージャの概要を示します。

表26-1 DBMS_XDB_REPOSのリソース・アクセスおよび管理サブプログラム

ファンクションおよびプロシージャ

説明

addResource

指定された文字列を内容として持つ新規ファイル・リソースを階層に挿入します。

appendResourceMetadata

ユーザー定義のメタデータをリソースに追加します。

createFolder

新しいフォルダ・リソースを作成します。

createOIDPath

オブジェクト識別子(OID)に基づいてリソースへの仮想パスを作成します。

createResource

新しいファイル・リソースを作成します。

deleteResource

リポジトリからリソースを削除します。

deleteResourceMetadata

指定したユーザー定義のメタデータをリソースから削除します。

existsResource

絶対パスを指定されたリソースが存在するかどうかを示します。

getContentBLOB

リソースのコンテンツをBLOBインスタンスとして戻します。

getContentVARCHAR2

リソースのコンテンツをVARCHAR2値として戻します。

getContentXMLRef

リソースのコンテンツをXMLTypeインスタンスへの参照として戻します。

getContentXMLType

リソースのコンテンツをXMLTypeインスタンスとして戻します。

getLockToken

指定されたリソースのパスを使用して、現行のユーザーに対するリソースのロック・トークンを戻します。

getResOID

絶対パスで指定したリソースのオブジェクト識別子(OID)を戻します。

getResource

リポジトリ内の指定された場所で見つかったクラスDBMS_XDBRESOURCE.XDBResourceのインスタンスを戻します。

getXDB_tablespace

データベース・スキーマ(ユーザー・アカウント)XDBの現行の表領域を戻します。

hasBLOBContent

指定されたリソースにBLOBコンテンツがある場合はTRUEを戻します。

hasCharContent

指定されたリソースに文字コンテンツがある場合はTRUEを戻します。

hasXMLContent

指定されたリソースにXMLTypeコンテンツがある場合はTRUEを戻します。

hasXMLReference

指定されたリソースにXMLTypeコンテンツへの参照がある場合はTRUEを戻します。

isFolder

指定されたリソースがフォルダの場合はTRUEを戻します。

link

既存のリソースへのリンクを作成します。

lockResource

指定されたリソースのパスを使用して、WebDAV形式のロックを取得します。

processLinks

文書またはフォルダ内のすべてのXLinkおよびXIncludeリンクを処理します。

purgeResourceMetadata

すべてのユーザー定義のメタデータを指定されたリソースから削除します。

refreshContentSize

指定されたリソースのコンテンツ・サイズを再計算します。

renameResource

指定されたリソースの名前を変更します。

touchResource

最終更新時刻を現在の時刻に変更します。

unlockResource

ロック・トークンとパスで指定したリソースのロックを解除します。

updateResourceMetadata

ユーザー定義のリソース・メタデータを変更します。

例26-1では、パッケージDBMS_XDB_REPOSを使用してリポジトリ・リソースを管理します。次のものが作成されます。

- フォルダ/publicの下のフォルダmydocs

- 2つのファイル・リソースemp_selby.xmlおよびemp_david.xml

- ファイル・リソースperson_selby.xmlおよびperson_david.xmlへの2つのリンク

続いて、新しく作成されたリソースとリンクが削除されます。フォルダを削除する前にフォルダの内容が削除されます。

関連項目:

appendResourceMetadataおよびdeleteResourceMetadataを使用した例は、 ユーザー定義のリポジトリ・メタデータを参照してください。

例26-1 DBMS_XDB_REPOSを使用したリソースの管理

DECLARE
retb BOOLEAN;
BEGIN
retb := DBMS_XDB_REPOS.createfolder('/public/mydocs');
retb := DBMS_XDB_REPOS.createresource('/public/mydocs/emp_selby.xml',
'<emp_name>selby</emp_name>');
retb := DBMS_XDB_REPOS.createresource('/public/mydocs/emp_david.xml',
'<emp_name>david</emp_name>');
END;
/
PL/SQL procedure successfully completed.

CALL DBMS_XDB_REPOS.link('/public/mydocs/emp_selby.xml',
'/public/mydocs',
'person_selby.xml');
Call completed.

CALL DBMS_XDB_REPOS.link('/public/mydocs/emp_david.xml',
'/public/mydocs',
'person_david.xml');
Call completed.

CALL DBMS_XDB_REPOS.deleteresource('/public/mydocs/emp_selby.xml');
Call completed.

CALL DBMS_XDB_REPOS.deleteresource('/public/mydocs/person_selby.xml');
Call completed.

CALL DBMS_XDB_REPOS.deleteresource('/public/mydocs/emp_david.xml');
Call completed.

CALL DBMS_XDB_REPOS.deleteresource('/public/mydocs/person_david.xml');
Call completed.

CALL DBMS_XDB_REPOS.deleteresource('/public/mydocs');
Call completed.

26.2 DBMS_XDB_REPOS: ACLベースのセキュリティ管理

PL/SQLパッケージDBMS_XDB_REPOSには、Oracle XML DBのACLベースのセキュリティ管理ファンクションおよびプロシージャが用意されています。

表26-2 DBMS_XDB_REPOS: セキュリティ管理サブプログラム

ファンクションおよびプロシージャ

説明

ACLCheckPrivileges

現行のユーザーに付与されたすべてのアクセス権限をACLで確認します。

changeOwner

指定されたリソースの所有者を指定ユーザーに変更します。

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-3では、システム管理者がプロシージャsetACLに接続して、所有者(データベース・スキーマHR)に、例26-2で作成されたファイル・リソースにおけるすべての権限を付与しています。プロシージャgetACLDocumentは、続いて<principal>ユーザーが所有者(HR)であるdav:ownerであることを示しています。

例26-4では、ユーザーHRがファンクションchangePrivilegesに接続して、新しいアクセス制御エントリ(ACE)をACLに追加して、リソースemp_selby.xmlにおけるすべての権限をユーザーoeに付与しています。プロシージャgetACLDocumentは、新しいACEがACLに追加されたことを示します。

例26-5では、ユーザーoeは接続してDBMS_XDB_REPOS.getPrivilegesをコールし、リソースemp_selby.xmlでユーザーoeに付与されたすべての権限を表示します。

例26-2 DBMS_XDB_REPOS.GETACLDOCUMENTの使用

CONNECT hr
Enter password: password

Connected.

DECLARE
retb BOOLEAN;
BEGIN
retb := DBMS_XDB_REPOS.createFolder('/public/mydocs');
retb := DBMS_XDB_REPOS.createResource('/public/mydocs/emp_selby.xml',
'<emp_name>selby</emp_name>');
END;
/
PL/SQL procedure successfully completed.

SELECT XMLSerialize(DOCUMENT
DBMS_XDB_REPOS.getACLDocument('/public/mydocs/emp_selby.xml')
AS CLOB)
FROM DUAL;

XMLSERIALIZE(DOCUMENTDBMS_XDB_REPOS.GETACLDOCUMENT('/PUBLIC/MYDOCS/EMP_SELBY.XML
--------------------------------------------------------------------------------
<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 DBMS_XDB_REPOS.SETACLの使用

CONNECT SYSTEM
Enter password: password

Connected.

-- Give all privileges to owner, HR.
CALL DBMS_XDB_REPOS.setACL('/public/mydocs/emp_selby.xml',
'/sys/acls/all_owner_acl.xml');
Call completed.
COMMIT;
Commit complete.

SELECT XMLSerialize(DOCUMENT
DBMS_XDB_REPOS.getACLDocument('/public/mydocs/emp_selby.xml')
AS CLOB)
FROM DUAL;

XMLSERIALIZE(DOCUMENTDBMS_XDB_REPOS.GETACLDOCUMENT('/PUBLIC/MYDOCS/EMP_SELBY.XML
--------------------------------------------------------------------------------
<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 DBMS_XDB_REPOS.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_REPOS.changePrivileges('/public/mydocs/emp_selby.xml', ace);
END;
/

PL/SQL procedure successfully completed.

COMMIT;

SELECT XMLSerialize(DOCUMENT
DBMS_XDB_REPOS.getACLDocument('/public/mydocs/emp_selby.xml')
AS CLOB)
FROM DUAL;

XMLSERIALIZE(DOCUMENTDBMS_XDB_REPOS.GETACLDOCUMENT('/PUBLIC/MYDOCS/EMP_SELBY.XML
--------------------------------------------------------------------------------
<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 DBMS_XDB_REPOS.GETPRIVILEGESの使用

CONNECT oe
Enter password: password

Connected.

SELECT XMLSerialize(DOCUMENT
DBMS_XDB_REPOS.getPrivileges('/public/mydocs/emp_selby.xml')
AS CLOB)
FROM DUAL;

XMLSERIALIZE(DOCUMENTDBMS_XDB_REPOS.GETPRIVILEGES('/PUBLIC/MYDOCS/EMP_SELBY.XML'
--------------------------------------------------------------------------------
<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.

26.3 DBMS_XDB_CONFIG: 構成管理

PL/SQLパッケージDBMS_XDB_CONFIGには、Oracle XML DBの構成管理用ファンクションおよびプロシージャが用意されています。

表26-3 DBMS_XDB_CONFIG: 構成管理サブプログラム

ファンクションおよびプロシージャ

説明

addHTTPExpireMapping

有効期限に対するURLパターンのマッピングを表XDB$CONFIGに追加します。マッピングでは、パターンと一致するURLのExpireヘッダーを制御します。

addMIMEMapping

MIMEマッピングを表XDB$CONFIGに追加します。

addSchemaLocMapping

スキーマの場所のマッピングを表XDB$CONFIGに追加します。

addServlet

サーブレットを表XDB$CONFIGに追加します。

addServletMapping

サーブレット・マッピングを表XDB$CONFIGに追加します。

addServletSecRole

セキュリティ・ロール参照をサーブレットに追加します。

addXMLExtension

XML拡張機能を表XDB$CONFIGに追加します。

CFG_Get

現行セッションの構成情報を戻します。

CFG_Refresh

現行のOracle XML DB構成ファイルxdbconfig.xmlを使用してセッションの構成情報をリフレッシュします。

cfg_update

Oracle XML DB構成情報を更新します。構成ファイルxdbconfig.xmlが書き込まれます。

deleteHTTPExpireMapping

有効期限に対する指定されたURLパターンのすべてのマッピングを表XDB$CONFIGから削除します。

deleteMIMEMapping

MIMEマッピングを表XDB$CONFIGから削除します。

deleteSchemaLocMapping

スキーマの場所のマッピングを表XDB$CONFIGから削除します。

deleteServlet

サーブレットを表XDB$CONFIGから削除します。

deleteServletMapping

サーブレット・マッピングを表XDB$CONFIGから削除します。

deleteServletSecRole

セキュリティ・ロール参照をサーブレットから削除します。

deleteXMLExtension

XML拡張機能を表XDB$CONFIGから削除します。

enableDigestAuthentication

Digest認証を有効にします。

getFTPPort

現行のFTPポート番号を戻します。

getHTTPConfigRealm

HTTP構成レルムを戻します。

getHTTPPort

現行のHTTPポート番号を戻します。

getListenerEndPoint

HTTPサーバーに対するリスナーのエンド・ポイントのパラメータを戻します。

setFTPPort

Oracle XML DB FTPポートを、指定したポート番号に設定します。

setHTTPConfigRealm

HTTP構成レルムを設定します。

setHTTPPort

Oracle XML DB HTTPポートを、指定したポート番号に設定します。

setListenerEndPoint

HTTPサーバーに対するリスナーのエンド・ポイントのパラメータを設定します。

setListenerLocalAccess

すべてのリスナーのエンド・ポイントを、(a) localhostインタフェースでのみリスニングするように制限するか、(b) localhostインタフェースと非localhostインタフェースの両方でリスニングできるようにします。

usedPort

同じマルチテナント・コンテナ・データベース(CDB)内のプラガブル・データベース(PDB)によって使用されるポートを戻します。戻り値は、各PDBをID番号別に、関連付けられたポートをタイプおよび番号別にリストするXMLTypeインスタンスです。

関連項目:

『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』の「DBMS_XDB_CONFIG」

例26-6では、ファンクションcfg_getを使用して、Oracle XML DB構成ファイルxdbconfig.xmlを取得しています。

例26-7は、プロシージャcfg_updateの使用方法を説明しています。現行の構成がXMLTypeインスタンスとして取得され、変更されます。続いてcfg_updateを使用してリライトされます。

例26-6 DBMS_XDB_CONFIG.CFG_GETの使用

CONNECT SYSTEM
Enter password: password

Connected.

SELECT DBMS_XDB_CONFIG.cfg_get() FROM DUAL;

DBMS_XDB_CONFIG.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 DBMS_XDB_CONFIG.CFG_UPDATEの使用

DECLARE
configxml    SYS.XMLType;
configxml2   SYS.XMLType;
BEGIN
-- Get the current configuration
configxml := DBMS_XDB_CONFIG.cfg_get();

-- Modify the configuration
SELECT XMLQuery(
'declare default element namespace
"http://xmlns.oracle.com/xdb/xdbconfig.xsd"; (: :)
copy $i := $p1 modify
(for $j in $i/xdbconfig/sysconfig/protocolconfig/httpconfig/http-port
return replace value of node $j with $p2)
return $i'
PASSING CONFIGXML AS "p1", '8000' AS "p2" RETURNING CONTENT)
INTO configxml2 FROM DUAL;

-- Update the configuration to use the modified version
DBMS_XDB_CONFIG.cfg_update(configxml2);
END;
/

PL/SQL procedure successfully completed.

SELECT DBMS_XDB_CONFIG.cfg_get() FROM DUAL;

DBMS_XDB_CONFIG.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およびACE

- アクセス制御リスト(ACL)の使用の概要

- ACLキャッシング

- リポジトリ・リソースおよびデータベース表のセキュリティ

- Oracle XML DBのLDAPとの統合

関連項目:

- WebDAVの詳細は、 プロトコルを使用したリポジトリへのアクセスを参照してください。

- リソース・セキュリティの構成と管理の詳細は、 Oracle XML DBの管理を参照してください。

- リソース・セキュリティの管理に使用できるPL/SQL APIの詳細は、「PL/SQL API for XMLType: リファレンス」を参照してください。

27.1 アクセス制御の概念

アクセス制御の用語および概念について説明します。アクセス制御エンティティ(ユーザー、ロール、プリンシパル、権限、アクセス制御リスト(ACL)およびアクセス制御エントリ(ACE))はそれぞれ、XML文書またはフラグメントとして宣言的に実装されます。

セキュアな認可を行うためには、どのユーザー、アプリケーションまたは関数が、どのような種類の操作を実行するために、どのデータにアクセスできるかを定義することが必要です。つまり、(1)どのユーザーが(2)どの操作を(3)どのデータに対して実行できるか、という3つの局面があります。この3つの局面をそれぞれ、(1)プリンシパル、(2)権限、(3)オブジェクトと呼びます。プリンシパルは、ユーザーまたはロールです。

プリンシパルと権限(局面1と2)は、アクセス制御リストを定義することにより、宣言的に関連付けられます。その後、これらは3番目の局面であるデータに、様々な方法で宣言的または手続き的に関連付けられます。たとえば、Oracle XML DBリポジトリのリソースまたは表データを保護するには、PL/SQLプロシージャDBMS_XDB_REPOS.setACLを使用して、それを制御するACLを設定します。

27.1.1 認証と認可

認証とは、何かのアイデンティティ(ユーザー、デバイス、アプリケーションなど)を検証することです。認可とは、認証されたものが別の何か(データベース表やWebDAVリソースなど)に対するアクセスを許可されているかどうかを検証することです。

Oracle XML DBリポジトリ・リソースにアクセスする場合、様々な種類のプリンシパルを認可できます。アプリケーション固有のプリンシパルを認証できます。

関連項目:

- プリンシパルの詳細は、「プリンシパル: ユーザーまたはロール」を参照してください

- アプリケーション固有のプリンシパルの認証および認可の詳細は、「アプリケーションによるカスタム認証とカスタム認可」(27‐31ページ)を参照してください。

27.1.2 プリンシパル: ユーザーまたはロール

ファイングレイン・データベース・アクセス制御のコンテキストにおいては、プリンシパルは、最終的にデータベース内の情報にアクセスする1人以上の個人または1つ以上のアプリケーションのセットです。プリンシパルには、データベースのユーザーやロールまたはLDAPのユーザーやグループを指定できます。

プリンシパルはユーザーまたはロールです。ユーザーは、データベース内の情報にアクセスする個人またはアプリケーションです。ロールは、ユーザーまたは他のロールで構成されますが、この再帰は循環型にできません。最終的には、各ロール(つまり各プリンシパル)はユーザーのセットに対応します。

ユーザーは、アクセス制御の目的で要素userを持つXMLフラグメントで表されます。ロールは、要素roleを持つフラグメントで表されます。

Oracle Databaseでは、プリンシパルとして次のものをサポートしています。

- データベース・ユーザーおよびデータベース・ロール。データベース・ユーザーは、データベース・スキーマまたはユーザー・アカウントと呼ばれることもあります。個人またはアプリケーションはデータベースにログオンするとき、データベース・ユーザー(スキーマ)およびパスワードを使用します。データベース・ロールは、データベース・ユーザー、アプリケーションまたは他のデータベース・ロールに付与できるデータベース権限のセットに対応しています。データベース・ロールおよびACLによる権限のユーザーへのマップを参照してください。

- LDAPユーザーおよびLDAPユーザー・グループ。LDAPプリンシパルの使用の詳細は、「Oracle XML DBのLDAPとの統合」を参照してください。

ここで「ユーザー」または「ロール」のように何も付かない語が使用されている場合、それはすべてのタイプのユーザーまたはロールに適用されます。タイプを区別することが重要な場合は、「データベース」または「LDAP」という語が付いています。

27.1.2.1 データベース・ロールおよびACLによる権限のユーザーへのマップ

データベース・ロールは、ユーザーに権限をマップします。ファイングレイン・アクセス制御のコンテキストにおいては、権限はACLによってユーザーにマップされ、ロールは単なる一連のユーザーです。

データベース・ユーザーに権限を付与できるのと同様、データベース・ロールにも権限が付与されます。データベース・ロールは、データベース権限をデータベース・ユーザー(およびアプリケーション)にマップするための媒介として機能します。つまり、ロールに権限が付与されてから、そのロールがユーザーに付与されます(それによりユーザーに権限が付与されます)。

ユーザーのグループと、それらのユーザーに付与された権限のグループとの違いは、データベース・ロールの概念においては少しあいまいです。データベース・ロールによって、ユーザーにマップされた権限をグループ化したり、権限がマップされたユーザーをグループ化したりすることもできるためです。マッピングは、ロールを定義してユーザーに付与することにより行われます。従来のデータベース用語では、ロールを、それに割り当てられた権限のセットと同じものとして考えます。

ファイングレイン・アクセス制御の関連においては、別のメカニズムであるアクセス制御リスト(ACL)が、権限をユーザーにマップする媒介として使用されます。ロールは単なるユーザーのセットです。この場合、権限をユーザーおよびロールに関連付ける操作はデータベース権限ではありません。この操作は、ACLのランタイム評価やACL競合の解消とともに、宣言的なACLエントリです。

混同しないように、この用語の違いに注意してください。権限をユーザーにマップする手段として、アクセス制御では(1)プリンシパル、(2)権限、(3)ACLとして分類されている機能のいくつかは、データベース・ロールではまとめられています。アクセス制御の用語においては、ロールはユーザーとともにプリンシパルとして分類されます。これに対し、従来のデータベース用語においては、ロールは権限のセットとして分類されます。

27.1.2.2 プリンシパルDAV::owner

プリンシパルDAV::ownerを使用して、指定したリポジトリ・リソースの所有者を参照できます。リソースの所有者は、リソースのプロパティの1つです。通常、リソースの所有者は特別な権限を持っているため、プリンシパルDAV::ownerを使用すると、プリンシパル間でのACLの共有が簡単になります。

27.1.3 権限

権限とは、プリンシパルに対して付与または拒否される特定の権限です。権限は、集約権限または基本権限になります。集約権限にはその他の権限が含まれますが、基本権限には含まれません。

- 集約権限: 他の権限が含まれる権限。

- 基本権限: 他の権限は含まれない権限。それ以上分割できません。

集約権限は、権限の数が多くなった場合の操作性を簡略化し、ACLクライアント間の相互運用性を高めます。「権限」を参照してください。

集約権限はそのまま保持され、対応する基本(リーフ)権限に分割されません。WebDAVの用語において、Oracle Databaseの集約権限は抽象的でありません。つまり、集約権限は、それらのコンポーネントのコピーではなく、そのコンポーネント権限へのポインタのセットとして機能します。したがって、コンポーネントの定義が変更された場合でも、集約権限は常に最新の状態を保持します。

プリンシパルに付与された権限のセットによって、プリンシパルが保護するデータに対して特定の操作を実行できるかどうかが制御されます。たとえば、プリンシパル(データベース・ユーザー)HRが特定のリソースに対してread操作を実行するには、読取り操作の前にHRに読取り権限が付与されている必要があります。

27.1.4 アクセス制御エントリ(ACE)

アクセス制御エントリ(ACE)とは、アクセス制御リスト(ACL)内のエントリであるXML要素(ace)のことです。ACEは、特定のプリンシパルによるリポジトリ・リソースまたはその他のデータベース・データへのアクセスを許可または拒否します。

ACE自身は、保護対象のデータを指定しません。この指定はACEおよびACLの外側で、ACLをターゲット・データに関連付けることによって行われます。その関連付けを行う方法として、PL/SQLプロシージャDBMS_XDB_REPOS.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属性。

例27-1に、プリンシパルDAV::ownerに権限DAV::allを付与する単純なACEを示します。つまり、ACLが適用されるリソースの所有者にすべての権限を付与します。

例27-1 権限を付与する単純なアクセス制御エントリ(ACE)

<ace>
<grant>true</grant>
<principal>DAV::owner</principal>
<privilege>
<DAV::all/>
</privilege>
</ace>

27.1.5 アクセス制御リスト(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.2 リポジトリ操作のためのデータベース権限

Oracle XML DBリポジトリのリソースに対する一般的な操作に必要なデータベース権限について説明します。

表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のインストールのアップグレードまたはダウングレード」を参照してください。

27.3 権限

Oracle Databaseに提供される権限には、標準のWebDAV権限とOracle固有の権限があります。

標準のWebDAV権限では、WebDAV名前空間DAV:脚注1を使用します。Oracle固有の権限では、事前定義された接頭辞xdbを含むOracle XML DB ACL名前空間(http://xmlns.oracle.com/xdb/acl.xsd)を使用します。

関連項目:

RFC 3744: 2004年5月の「Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol」の「IETF Network Working Group Request For Comments #3744」を参照してください。

27.3.1 基本権限

基本権限には、他の権限は含まれません。リポジトリ操作に使用可能な基本権限について説明し、そのデータベースでの操作をリストします。

表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.2 集約権限

集約権限には、他の権限(基本または集約)が含まれます。リポジトリ操作に使用可能な集約権限をそのコンポーネントの基本権限とともにリストします。

表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

27.4 ACLおよびACE

ACLは、リソースを保護するために使用されます。Oracle Databaseの場合、Oracle XML DBリポジトリ内のリソース(ファイルおよびフォルダ)です。ACLはACEで構成されます。

アクセス制御リスト(ACL)は、Javaなどの言語やMicrosoft Windowsなどのオペレーティング・システムで使用される、標準のセキュリティ・メカニズムです。ACLは、WebDAV標準の一部でもあります。

リポジトリのリソースには、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については、 Oracleが提供するXML Schemaおよび例を参照してください。

- データベース・スキーマXDBの詳細は、『Oracle Database 2日でセキュリティ・ガイド』を参照してください。

27.4.1 システムACL

事前定義され、Oracle Databaseで提供されているシステム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」

27.4.2 ACLおよびACEの評価

プリンシパルが、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のインストールのアップグレードまたはダウングレード」を参照してください。

27.4.3 ACL検証

ACLは作成されると、ACL用のXML Schemaに基づいて検証され、いくつかの正確性テスト(ACEの開始日と終了日が時間的に矛盾していないことの確認など)が実行されます。ACLの作成時に、ACL間のリレーションについての完全チェックは行われません。

このようなACLの正確性に関する完全なチェックをACL妥当性チェックと呼びます。これをXML Schemaの妥当性と混同しないでください。ACLが(ACLとして)有効になるためには、同時にXML Schemaでも有効である必要がありますが、その逆は言えません。

プリンシパルに操作を行うための適切な権限があるかどうかをチェックするためにACLが評価されるたびに、完全なACL妥当性チェックが実行時に行われます。このチェックによりACLが無効であると判断された場合、そのACLが指定されたプリンシパルに付与するすべての権限は拒否されます。

27.4.4 要素invert: ACEでのプリンシパルの補完

別のプリンシパル・セットを補完することによりプリンシパル・セットを定義するほうが便利な場合もあります。ACE要素invertは、この目的で使用します。追加するプリンシパルをすべてリストするのではなく、要素invertを使用して、除外するプリンシパルのリストを囲みます。

例27-3の最初のACEは、IntranetUsers以外のすべてのプリンシパルに対して権限privilege1を拒否しています。(デフォルトで)ACEは出現順に考慮されるため、後続のACEはすべて最初のACEによりオーバーライドされます。このため、プリンシパルNonIntraNetUserは明示的に権限を付与されているにもかかわらず、権限privilege1を拒否されます。

例27-3 要素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>

27.5 アクセス制御リスト(ACL)の使用の概要

Oracle Databaseのアクセス制御リスト(ACL)はそれ自身がOracle XML DBリポジトリ内のリソースなので、リポジトリのリソースを操作するメソッドはすべてACLにも適用されます。さらに、PL/SQLパッケージDBMS_XDB_REPOSのACLに固有のAPIもいくつかあります。

これらのACLプロシージャや関数を使用すると、PL/SQLを使用してOracle XML DBのセキュリティ・メカニズムにアクセスし、特定のACLに基づいてユーザーの権限を確認して、特定のACLやリソースに対して現行ユーザーが所有している権限のセットをリストできます。

関連項目:

Oracle XML DBの管理

27.5.1 DBMS_XDB_REPOS.CREATERESOURCEを使用したACLの作成

DBMS_XDB_REPOS.createResourceを使用してACLを作成する例を示します。

例27-4では、ACLをファイル・リソース/TESTUSER/acl1.xmlとして作成します。リソースに適用されると、このACLはすべての権限をリソースの所有者に付与します。

注意:

現在のトランザクション中に作成されたACLファイル・リソースを使用する操作を実行する前に、COMMIT操作を実行する必要があります。それまでは、ACLファイルを使用するたびにORA-22881エラー「REFの参照先がありません」が発生します。

例27-4 CREATERESOURCEを使用したACLの作成

DECLARE
b BOOLEAN;
BEGIN
b := DBMS_XDB_REPOS.createFolder('/TESTUSER');
b := DBMS_XDB_REPOS.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;

27.5.2 リポジトリのパスがある場合のACL文書の取得

ACL文書のOracle XML DBリポジトリ内の場所がわかっている場合にACL文書を取得する例を示します。

例27-5 リポジトリのパスがある場合の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>

27.5.3 リソースのACLの設定

PL/SQLプロシージャDBMS_XDB_REPOS.setACLを使用して、リソースのACLを設定する例を示します。

例27-6では、リソース/TESTUSER/po1.xmlを作成し、PL/SQLプロシージャDBMS_XDB_REPOS.setACLを使用してそのACLを/TESTUSER/acl1.xmlに設定します。

例27-6 リソースのACLの設定

DECLARE
b BOOLEAN;
BEGIN
b := DBMS_XDB_REPOS_REPOS.createResource('/TESTUSER/po1.xml', 'Hello');
END;
/

CALL DBMS_XDB_REPOS_REPOS.setACL('/TESTUSER/po1.xml', '/TESTUSER/acl1.xml');

27.5.4 ACLの削除

PL/SQLプロシージャDBMS_XDB_REPOS.deleteResourceを使用して、ACLを削除する例を示します。

例27-7では、例27-4で作成したACLを削除します。

リソースが削除するACLによって保護されている場合は、ACLを削除する前にそのリソースのACLを変更してください。

例27-7 ACLの削除

CALL DBMS_XDB_REPOS_REPOS.deleteResource('/TESTUSER/acl1.xml');

27.5.5 ACLの更新

ACLの更新は、リソースを更新するための標準メソッドを使用して実行できます。特にACLはXML文書なので、ACLの操作にはOracle SQL/XML関数XMLQueryとXQuery Updateを使用できます。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を更新できます。これらのプロトコルの使用方法の詳細は、 プロトコルを使用したリポジトリへのアクセスを参照してください。RESOURCE_VIEWを使用して、ACLの更新や、アクセス制御エントリ(ACE)の変更を行えます。

例27-8では、SQL/XML関数XMLQueryをXQuery Updateとともに使用して、ACL /TESTUSER/acl1.xmlを完全に置換することによって更新しています。その結果、プリンシパル値DAV::ownerがTESTUSERで置換されます。置換ACLの他の部分は以前と同じだからです。

例27-9では、XQuery Updateを使用して、既存のACLにACEを追加しています。このACEは、ユーザーHRに、権限read-propertiesおよびread-contentsを付与します。

例27-10では、Oracle SQL関数deleteXMLを使用して、既存のACLからACEを削除しています。最初のACEは削除されます。

例27-8 アクセス制御リストの更新(置換)

UPDATE RESOURCE_VIEW r
SET r.RES =
XMLQuery(
'declare namespace r="http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
declare namespace a="http://xmlns.oracle.com/xdb/acl.xsd"; (: :)
copy $i := $p1 modify
(for $j in $i/r:Resource/r:Contents/a:acl
return replace node $j with $p2)
return $i'
PASSING r.RES AS "p1",
'<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>' AS "p2"
RETURNING CONTENT)
WHERE equals_path(r.RES, '/TESTUSER/acl1.xml') = 1;

例27-9 アクセス制御リストへのACEの追加

UPDATE RESOURCE_VIEW r
SET r.RES =
XMLQuery('declare namespace r="http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
declare namespace a="http://xmlns.oracle.com/xdb/acl.xsd"; (: :)
copy $i := $p1 modify
(for $j in $i/r:Resource/r:Contents/a:acl
return insert nodes $p2 as last into $j)
return $i'
PASSING r.RES AS "p1",
XMLType('<ace xmlns="http://xmlns.oracle.com/xdb/acl.xsd">
<grant>true</grant>
<principal>HR</principal>
<privilege>
<read-properties/>
<read-contents/>
</privilege>
</ace>') as "p2"
RETURNING CONTENT)
WHERE equals_path(r.RES, '/TESTUSER/acl1.xml') = 1;

例27-10 アクセス制御リストからのACEの削除

UPDATE RESOURCE_VIEW r
SET r.RES =
XMLQuery('declare namespace r="http://xmlns.oracle.com/xdb/XDBResource.xsd"; (: :)
declare namespace a="http://xmlns.oracle.com/xdb/acl.xsd"; (: :)
copy $i := $p modify delete nodes $i/r:Resource/r:Contents/a:acl/a:ace[1]
return $i'
PASSING r.RES AS "p" RETURNING CONTENT)
WHERE equals_path(r.RES, '/TESTUSER/acl1.xml') = 1;

27.5.6 指定されたリソースを保護するACL文書の取得

PL/SQLファンクションDBMS_XDB_REPOS.getACLDocumentを使用して、指定されたリソースを保護するACL文書を取得する例を示します。

関連項目:

例26-2

例27-11 リソースのACL文書の取得

SELECT XMLSerialize(DOCUMENT DBMS_XDB_REPOS.getACLDocument('/TESTUSER/po1.xml')
AS CLOB)
FROM DUAL;

XMLSERIALIZE(DOCUMENTDBMS_XDB_REPOS.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.

27.5.7 特定のリソースに対して現行ユーザーに付与された権限の取得

PL/SQLファンクションDBMS_XDB_REPOS.getPrivilegesを使用して、現行ユーザーに付与された権限を取得する例を示します。

例27-12 特定のリソースに対して現行ユーザーに付与された権限の取得

SELECT XMLSerialize(DOCUMENT DBMS_XDB_REPOS.getPrivileges('/TESTUSER/po1.xml')
AS CLOB)
FROM DUAL;

XMLSERIALIZE(DOCUMENTDBMS_XDB_REPOS.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.5.8 現行ユーザーがリソースに対する権限を所有しているかどうかの確認

PL/SQLファンクションDBMS_XDB_REPOS.checkPrivilegesを使用して、現行ユーザーがリソースに対する特定の権限セットを所有しているかどうかを確認する例を示します。ユーザーがその権限を所有している場合、この関数は、ゼロ以外の値を戻します。

例27-13では、リソース/TESTUSER/po1.xmlに対するアクセス権限read-contentsおよびread-propertiesが、現行ユーザーに付与されているかどうかを確認しています。戻り値が正の整数であれば、ユーザーがその権限を持っていることを示しています。

例27-13 あるリソースに対してユーザーが特定の権限を所有しているかどうかの確認

SELECT DBMS_XDB_REPOS.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_REPOS.CHECKPRIVILEGES('/TESTUSER/PO1.XML',
---------------------------------------------------
1

1 row selected.

27.5.9 ユーザーがACLおよびリソース所有者を使用する権限を所有しているかどうかの確認

ファンクションDBMS_XDB_REPOS.ACLCheckPrivileges は、通常、ユーザーによる操作の実行を許可する前に、独自にACLの評価を実行する必要のあるアプリケーションによって使用されます。

例27-14では、ACL /TESTUSER/acl1.xmlにより、権限read-contentsおよびread-propertiesが、現行ユーザーshに付与されているかどうかを確認しています。2番目の引数TESTUSERは、確認時にACLのDAV::ownerに置き換えられたユーザーです。ユーザーshは、指定された権限を付与されたユーザーのいずれにも一致しないため、戻り値はゼロです。

例27-14 ACLCheckPrivilegesを使用したユーザー権限の確認

CONNECT sh
Enter password: <password>

Connected.

SELECT DBMS_XDB_REPOS.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_REPOS.ACLCHECKPRIVILEGES('/TESTUSER/ACL1.XML','TESTUSER',
------------------------------------------------------------------
0

1 row selected.

27.5.10 指定されたリソースを保護するACLのパスの取得

RESOURCE_VIEW問合せを使用して、指定されたリソースを保護するACLのパスを取得する例を示します。この問合せでは、リソースの要素XMLRefおよびACLOIDが、ACLとリソースをリンクしていることを前提として使用しています。

例27-15は、ACLによって保護されたリソースの指定を受けて、ACLへのパスを取得しています。保護されたリソース(r)のACLOIDには、それを保護しているACLリソース(a)のOIDが格納されています。ACLリソースのREFは、保護されたリソースACLOIDにより識別されるオブジェクトのものと同じです。

リソースACLOIDのREFは、Oracle SQL関数make_refを使用して取得できます。指定されたOIDを持つオブジェクト行へのREFが戻されます。

例27-15では、make_refは、リソース/TESTUSER/po1.xmlに対して、OIDが/Resource/ACLOIDである表XDB$ACLの行へのREFを戻しています。内部問合せがリソースのACLOIDを取得します。外部問合せが、対応するACLへのパスを戻します。

例27-15 特定のリソースを保護する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.5.11 指定されたACLによって保護されるすべてのリソースのパスの取得

指定されたACLによって保護されるすべてのリソースのパスを取得する例を示します。

例27-16では、パスが/TESTUSER/acl1.xmlであるACLリソースのREFに対してACLOID REFが一致しているリソースへのパスを取得します。ファンクションmake_refはリソースACLOID REFを戻します。

内部問合せは、指定されたACLのREFを取得します。外部問合せは、ACLOID REFが指定されたACLのREFに一致するリソースのパスを選択します。

例27-16 特定の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.6 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サーバーからそのグループのネストされたメンバーシップを取得します。そのため、可能なかぎりメンバーとネスト・レベルの少ないグループを使用することをお薦めします。

27.7 リポジトリ・リソースおよびデータベース表のセキュリティ

REFベースのリポジトリ・リソースの格納に使用される表の階層を有効にすることによって、これらのリソースへのアクセスに均一なセキュリティ・メカニズムが提供されます。特定のリソースについてACLベースのセキュリティが必要ない場合は、PL/SQLプロシージャDBMS_XDBZ.disable_hierarchyを使用してACLチェックを無効にすることによってそれらのアクセスを最適化できます。

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セキュリティによって保護されません。

27.7.1 最適化: 必要でない場合に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権限があることを確認します。

DBMS_XDBZ.disable_hierarchyをコールすると、同じ問合せの実行計画では、フィルタにSYS_CHECKACLが表示されません。

関連項目:

プロシージャDBMS_XDBZ.disable_hierarchyの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

27.8 Oracle XML DBのLDAPとの統合

Lightweight Directory Access Protocol (LDAP)ユーザーにOracle XML DB機能(ACLを含む)の使用を許可できます。

典型的なシナリオでは、単一の共有データベース・スキーマ(ユーザー)に、複数のLDAPユーザーがマップされています。このマッピングは、Oracle Internet Directoryで維持されています。エンド・ユーザーは、LDAPユーザー名およびパスワードを使用して、データベースにログインできます。ログインすると、対応する共有データベース・スキーマに自動的にマップされます。(ログインには、SQLまたはOracle XML DBでサポートされている任意のプロトコルを使用できます。)暗黙的なACL解決は、現行のLDAPユーザーおよび対応するLDAPグループのメンバーシップ情報に基づいています。

Oracle XML DB ACLのプリンシパルとしてLDAPユーザーおよびLDAPグループ(LDAPロールとも呼ばれる)を使用する場合は、その前に次の条件を満たす必要があります。

- Oracle Internet Directoryが設定され、データベースがそれに登録されている必要があります。

- SSL認証がデータベースとOracle Internet Directoryの間に設定されている必要があります。

- 共有データベース・スキーマに対応するデータベース・ユーザーが作成されている必要があります。

- Oracle Internet DirectoryでLDAPユーザーが作成され、共有データベース・スキーマにマップされる必要があります。

- LDAPグループが作成され、そのメンバーが指定されている必要があります。

- LDAPグループやLDAPユーザーに対してACLが定義され、それを使用してLDAPユーザーがアクセスするリポジトリ・リソースが保護される必要があります。

関連項目:

- 『Oracle Fusion Middleware Oracle Internet Directory管理者ガイド』

- SSL認証の設定の詳細は、『Oracle Databaseセキュリティ・ガイド』を参照してください。

- エンタープライズ(LDAP)ユーザーのための共有データベース・スキーマの使用方法の詳細は、『Oracle Databaseエンタープライズ・ユーザー・セキュリティ管理者ガイド』を参照してください。

例27-17は、LDAPユーザーのACLを示しています。要素<principal>にはLDAPユーザーの完全識別名(この場合cn=user1,ou=Americas,o=oracle,l=redwoodshores,st=CA,c=US)が含まれています。

関連項目:

LDAPユーザーの識別名の形式の詳細は、『Oracle Fusion Middleware Oracle Internet Directory管理者ガイド』を参照してください。

例27-18は、LDAPグループのACLを示しています。要素<principal>には、LDAPグループの完全識別名が含まれています。

関連項目:

LDAPグループの識別名の形式の詳細は、『Oracle Fusion Middleware Oracle Internet Directory管理者ガイド』を参照してください。

例27-17 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>

例27-18 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>

脚注の凡例

脚注1:
コロン(:)は名前空間名の一部です。DAV:は、接頭辞ではなく、名前空間そのものです。名前空間DAV:に広く使用される接頭辞はdavですが、これは慣例的なものにすぎません。davは、Oracle XML DBで事前定義されている接頭辞ではありません。

28 プロトコルを使用したリポジトリへのアクセス

Oracle XML DBリポジトリ・データには、FTPおよびHTTP(S)/WebDAVプロトコルを使用してアクセスできます。

- Oracle XML DBプロトコル・サーバーの概要

- Oracle XML DBプロトコル・サーバーの構成管理

- FTPおよびOracle XML DBプロトコル・サーバー

- HTTP(S)およびOracle XML DBプロトコル・サーバー

- WebDAVとOracle XML DB

28.1 Oracle XML DBプロトコル・サーバーの概要

Oracle XML DBは、Oracle XML DBプロトコル・サーバーも提供します。Oracle XML DBは、その階層リポジトリまたはファイル・システムにアクセスするための標準インターネット・プロトコルであるFTP、WebDAVおよびHTTP(S)をサポートします。HTTPSはOracle XML DBリポジトリへのセキュアなアクセスを提供します。

多くのユーザーは、これらのプロトコルによって、追加のソフトウェアをインストールせずに、Oracle XML DBに直接アクセスできます。プロトコルで使用するユーザー名およびパスワードは、SQL*Plusで使用するものと同じです。エンタープライズ・ユーザーもサポートされています。データベース管理者は、これらのプロトコルと、DBMS_XDB_REPOSなどのリソースAPIを使用して、リポジトリの仮想フォルダ/sys/asmにあるOracle Automatic Storage Management(Oracle ASM)のファイルとフォルダにアクセスすることができます。

Oracle XML DBを使用する前におよびOracle XML DBリポジトリ・データへのアクセスで説明したとおり、Oracle XML DBリポジトリは、XML用に設計された階層データ・リポジトリをデータベース内に提供します。Oracle XML DBリポジトリは、XMLTypeのデータベース・オブジェクトにパス名(またはURL)をマップし、これらのオブジェクトの管理機能を提供します。

関連項目:

リポジトリ情報へのアクセスとその場合の制限事項の詳細は、Oracle XML DBリポジトリ・データへのアクセスを参照してください。

注意:

- Oracle XML DBプロトコルを使用して仮想フォルダ/sys/asmにアクセスする場合は、ロールDBAの権限を持っているSYS以外のユーザーとしてログインする必要があります。

- Oracle XML DBのプロトコルは、EBCDICプラットフォームではサポートされません。

28.1.1 セッション・プーリング

Oracle XML DBプロトコル・サーバーは、セッションの共有プールを保持します。各プロトコル接続は、このプールの1つのセッションに関連付けられます。接続のクローズ後、セッションは共有プールに戻され、その後の接続で使用できます。

セッション・プーリングでは、特に、リクエストごとに新しい接続が作成されるHTTP 1.0を使用する場合、セッション状態を再作成するコストが削減され、HTTP(S)のパフォーマンスが向上します。たとえば、データベース・セッションを作成する必要がある場合に、既存のHTTP/1.1接続でいくつかの小さいファイルを取り出すことができます。Oracle XML DBの構成ファイルxdbconfig.xmlでセッション・プール・サイズを設定することによってセッション数を調整したり、このプール・サイズを0 (ゼロ)に設定することによってセッションを使用禁止にできます。

セッション・プーリングは、Javaサーブレットを作成するユーザーに影響する可能性があります。これは、他のユーザーが別のユーザーの別のリクエストによって初期化されたセッションの状態を参照できるためです。そのため、サーブレットの作成者は、Java静的変数などのセッション・メモリーのみを使用して、特定のユーザーではなくアプリケーション全体に対するデータを保持する必要があります。セッションが1人のユーザーに対してのみ存在すると想定するのではなく、ユーザーごとの状態をデータベースまたは参照表に格納する必要があります。

関連項目:

JavaでのOracle XML DBアプリケーションの作成方法

図28-1に、Oracle XML DB プロトコル・サーバーのコンポーネント、およびそれらを使用してOracle XML DBリポジトリのファイルおよび他のデータにアクセスする方法を示します。この図では、リポジトリの関連するコンポーネントのみを示します。

図28-1 Oracle XML DBのアーキテクチャ: プロトコル・サーバー

28.2 Oracle XML DBプロトコル・サーバーの構成管理

Oracle XML DBプロトコル・サーバーでは、ファイルxdbconfig.xmlに格納された構成パラメータを使用して、起動状態を初期化したり、セッション・レベルの構成を管理します。セッション・プール・サイズおよびタイムアウト・パラメータは動的に変更できません。変更内容を有効にするためには、データベースを再起動する必要があります。

関連項目:

「xdbconfig.xmlを使用したOracle XML DBの構成」

28.2.1 プロトコル・サーバー・パラメータの構成

Oracle XML DBプロトコルの構成パラメータについて説明します。これには、すべてのプロトコルに共通するもの、FTPに固有のものおよびHTTP(S)/WebDAVに固有のものが含まれます。

図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の詳細は、 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サーバーの不正使用は禁じられており、民事および刑事訴追の対象となる場合があります。)というデフォルト・ウェルカム・メッセージが表示されます。

host-name

ホスト・システムへのアクセスに使用する名前。値は、IPアドレスまたはホスト・ネーミング(例: Linuxの場合は/etc/hostsファイル)を使用してIPアドレスにマップされる名前です。デフォルトでは、オペレーティング・システムが戻したIPアドレスを使用します。

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リポジトリへの匿名アクセス」を参照してください。

authentication

HTTP認証メカニズムを使用できます。「HTTPの認証メカニズムの構成および管理」を参照してください"

expire

URLの期限切れ日時を指定するHTTPヘッダー。「URL有効期限の制御」を参照してください。

28.2.2 セキュアHTTP(HTTPS)の構成

リポジトリによるセキュアHTTP接続(HTTPS)の使用を有効にするには、データベース管理者(DBA)がデータベースを適切に構成する必要があります。パラメータhttp2-portおよびhttp2-protocolを構成し、HTTPリスナーでSSLを使用できるようにして、TCPS Dispatcherの起動を有効にします。次に、DBAはデータベースとリスナーを停止および再起動する必要があります。

関連項目:

Oracle XML DBパラメータの構成の詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください

28.2.2.1 HTTP ListenerによるSSLの使用の有効化

SSLに対してHTTPリスナーを構成するには、データベース管理者(DBA)はサーバー用のウォレットを作成して証明書をインポートし、サーバーにウォレットの場所を指定して、クライアント認証を無効にし、SSL_DH_anon暗号スイートをSSL_CIPHER_SUITESに追加して、TCP/IPをSSLで使用するリスニング・エンド・ポイントを作成する必要があります。

つまり、DBAは次の手順を実行して、SSLに対してHTTPリスナーを構成する必要があります。

1. サーバー用のウォレットを作成し、証明書をインポートします。Oracle Wallet Managerを使用して次の操作を行います。

a. サーバー用のウォレットを作成します。

b. サーバーの識別名(DN)を持つ有効な証明書がない場合は、証明書リクエストを作成して認証局に送信します。有効な証明書を認証局から取得します。

c. サーバーの識別名(DN)を持つ有効な証明書をサーバーにインポートします。

d. 新しいウォレットを不明瞭化した形式で保存し、パスワードなしで開けるようにします。

関連項目:

ウォレットの作成方法の詳細は、『Oracle Databaseエンタープライズ・ユーザー・セキュリティ管理者ガイド』を参照してください。

2. ウォレットの場所をサーバーに対して指定します。Oracle Net Managerで行います。構成がディスクに保存されたことを確認します。この手順により、ファイルsqlnet.oraおよびlistener.oraが更新されます。

3. サーバー側でのクライアント認証を無効にします。大部分のWebクライアントには証明書がないからです。Oracle Net Managerを使用します。この手順により、ファイルsqlnet.oraが更新されます。

4. SSL_DH_anon暗号スイートをSSL_CIPHER_SUITESに追加します(次のいずれかを使用してください)。

- SSL_DH_anon_WITH_3DES_EDE_CBC_SHA

- SSL_DH_anon_WITH_RC4_128_MD5

- SSL_DH_anon_WITH_DES_CBC_SHA

この手順により、ファイルsqlnet.oraが更新されます。

5. TCP/IPをSSLで使用するリスニング・エンド・ポイントを作成します。Oracle Net Managerを使用します。この手順により、ファイルlistener.oraが更新されます。

関連項目:

手順1から5の詳細は、『Oracle Databaseセキュリティ・ガイド』を参照してください。

28.2.2.2 TCPS Dispatcherの有効化

データベース起動中のTCPS Dispatcherの起動を有効にするには、データベース管理者(DBA)はデータベースpfileを編集する必要があります。

pfileに次の行を追加する必要があります。ここで、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

28.2.3 リスナー・ステータスを使用したポート構成の確認

TNS Listenerコマンドlsnrctl statusを使用して、HTTP(S)およびFTPサポートが有効かどうかを検証できます。このことの例を示します。

関連項目:

プロトコルを使用したリポジトリへのアクセス

例28-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.2.4 データベース統合後のプロトコル・ポート・パラメータの構成

マルチテナント・コンテナ・データベース(CDB)では、プロトコル・サーバーのポート番号によって、接続されたプラガブル・データベース(PDB)を識別します。そのため、このようなデータベースにはそれぞれ一意のポート番号が必要です。データベース管理者(DBA)は、PDBで使用される各ポート番号が一意であることを確認する必要があります。

ポートの競合を避け、統合によって発生する可能性のあるポートの競合を解決するには、データベース管理者は次の手順を実行する必要があります。

1. PL/SQL関数DBMS_XDB_CONFIG.usedPortを使用して、同じCDB内で別のPDBが使用しているポート番号を取得します。

2. PL/SQLサブプログラムDBMS_XDB_CONFIG.setFTPPortまたはDBMS_XDB_CONFIG.setHTTPPortを(必要に応じて)使用し、競合しているポート番号をそれぞれ一意の番号に変更します。

注意:

PDBのプラグインまたはクローン操作後、Oracle XML DBが完全に初期化されるまでの間、構成ファイルxdbconfig.xmlのポート・パラメータ設定は未定義となる可能性があります。DBMS_XDB_CONFIGサブプログラムgetFTPPort、getHTTPPort、getHTTPSPort、setFTPPort、setHTTPPortまたはsetHTTPSPortを使用して、ポート値を取得または変更することをお薦めします。

28.2.5 HTTPの認証メカニズムの構成および管理

構成ファイルxdbconfig.xmlに要素authentication (要素httpconfigの子)を設定することにより、Oracle XML DBリポジトリへのHTTPアクセスを許可するよう、認証メカニズムを構成します。

12c リリース1 (12.1.0.1)以降、Oracle Databaseでは、Basic認証だけでなくDigestアクセス認証もサポートしています。

ユーザーの資格証明では、大/小文字が区別されます。具体的には、認証を受けるにはユーザー名が作成された名前と正確に一致する必要があります(デフォルトでは、すべて大文字)。

Digestアクセス認証(Digest認証とも呼ばれる)では、完全なデータ暗号化に伴うオーバーヘッドを発生させることなく、ユーザーの資格証明(ユーザー名、パスワードなど)の暗号化を行います。

使用する認証メカニズムは、構成ファイルxdbconfig.xmlに要素authentication(要素httpconfigの子)を設定することにより構成できます。要素authenticationはオプションです。存在しない場合は、Basic認証のみが使用されます。

要素authenticationには、次の2つの子要素を使用できます。

- 要素allow-mechanismでは、使用可能なメカニズム(basic、digestまたはcustom)を指定します。許可するメカニズムごとに、個別のallow-mechanism要素を指定してください。

- 要素digest-authはオプションです。Digestメカニズムの情報を指定します。子要素nonce-timeoutでは、指定されたnonceの有効期限を秒数で指定します。デフォルト値は300秒です。
digestが指定されたallow-mechanismはあるがdigest-auth要素がない場合は、デフォルト値が使用されます。digestが指定されたallow-mechanismがない場合、digest-auth要素は無視されます。

HTTPリクエストは、指定されたallow-mechanismごとに受け付けられます。認証チャレンジは、指定されたallow-mechanismタイプの順に提示されます。たとえば、digestとbasicの両方がこの順番で存在する場合は、Digestチャレンジ、Basicチャレンジの順に提示されます。常に強力な認証を弱い認証よりも優先させることをお薦めします(Digest認証はBasic認証よりも強力)。

関連項目:

- インストール、アップグレードおよびダウングレードの考慮事項は、「既存のOracle XML DBのインストールのアップグレードまたはダウングレード」を参照してください

- RFC2617、HTTP認証方式: Basicアクセス認証とDigestアクセス認証(http://tools.ietf.org/html/rfc2617)

28.2.5.1 Digest認証のnonce

Digest認証では、unauthorizedレスポンスが発行されるたびに、サーバーによりnonceが生成されます。クライアントでは、サーバーへのリクエストにnonceを含めます。サーバーでは、クライアントから受信したnonceをチェックし、クライアント認証を拒否する必要があるかどうかを確認します。クライアントでは、同じ方法でサーバーを認証できます。

nonceは、サーバーがHTTPレスポンス401 (unauthorized)を発行するたびに生成される一意の文字列です。クライアントでは、サーバーに送信する後続のリクエストにnonceを含めます。サーバーでは、クライアントから受信したnonceを確認します。不正であったり、nonce-timeoutの期限が切れている場合、サーバーはただちに認証を拒否できます

(クライアントは独自のnonceを生成できるので、サーバーの認証に同じメカニズムの使用が可能です。クライアントとサーバーの両方がこのクライアント側のnonceを使用することで、特定のプレーン・テキスト攻撃を防止できます)。

サーバーがクライアントにDigestチャレンジを送信するたびに、新しいnonceが生成されます。nonceはnonceキーに基づいています。最初のnonceキーは、データベースのインストールまたはアップグレード時にランダムに生成されます。

Digest認証を使用する場合は、新しいnonceキーを定期的に作成して、キーの整合性を確保することもお薦めします。これを行うには、PL/SQLプロシージャDBMS_XDB_ADMIN.createNonceKeyを使用します。

28.2.6 Oracle XML DBリポジトリおよびファイルシステムのリソース

プロトコル仕様のRFC 959 (FTP)、RFC 2616 (HTTP)およびRFC 2518 (WebDAV)では、暗黙的にサーバー側の抽象的な階層ファイル・システムを想定しています。これはOracle XML DBリポジトリにマッピングされます。リポジトリでは、名前解決、ACLベースのセキュリティおよび任意のコンテンツを格納したり取得する機能が提供されます。

リポジトリは、FTPを介したバイナリ・データ入力と、XML Schemaに基づく文書を格納できます。

関連項目:

- http://www.ietf.org/rfc/rfc959.txt

- http://www.ietf.org/rfc/rfc2616.txt

- http://www.ietf.org/rfc/rfc2518.txt

28.2.7 プロトコル・サーバーによるXML Schemaに基づくXML文書または基づかないXML文書の処理

Oracle XML DBプロトコル・サーバーでは、常に、挿入される文書が、Oracle XML DBリポジトリで登録されているXML Schemaに基づいているかどうかがチェックされます。基づいている場合、使用するXMLType記憶域モデルは、該当するXML Schemaによって決定されます。基づいていない場合、文書はBLOBとして格納されます。

28.2.8 イベントベース・ロギング

プロトコル・サーバーによって受信されたリクエストと送信されたレスポンスをログに記録するには、イベント番号31098をレベル2に設定します。

このイベントを設定するには、次の行をinit.oraファイルに追加し、データベースを再起動します。

event="31098 trace name context forever, level 2"

28.3 FTPおよびOracle XML DBプロトコル・サーバー

RFC959で規定されているファイル転送プロトコル(FTP)は、最も古く、最も一般的なプロトコルの1つです。これにより、異機種間のファイル・システムへの均一な方法でのアクセスが可能となります。FTPを使用すると、Oracle XML DBリポジトリに格納されたデータにアクセスして更新できます。

28.3.1 Oracle XML DBプロトコル・サーバー: FTP機能

ファイル転送プロトコル(FTP)は、オペレーティング・システムの専用クライアント、ファイル・システムのエクスプローラ・クライアントおよびブラウザで実装されています。FTPは、一般的にセッション指向であり、明示的なログインによってユーザー・セッションが作成され、ファイルまたはディレクトリがダウンロードおよび参照された後、接続がクローズされます。

1回の接続でコマンド・メッセージの転送とステータスの取得が実行されます。ただし、データ転送用に、クライアントとサーバー間で新しい接続がオープンされます。一方、HTTP(S)を使用すると、1回の接続でコマンドとデータが転送されます。

注意:

セキュリティ上の理由のため、FTPはデフォルトでOracle Databaseに対して無効になっています。IETF FTPプロトコルの仕様ではパスワードをクリアテキストで送信することが要求されているためです。無効化は、FTPサーバーのポートをゼロ(0)にすることで実現しています。FTPを有効にするには、ftp-portパラメータを、使用するFTPポート(2100など)に設定します。

関連項目:

- RFC 959: FTPプロトコル仕様 - http://www.ietf.org/rfc/rfc959.txt

- 構成パラメータの詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください

28.3.1.1 サポートされていないFTPの機能

Oracle XML DBでサポートされていないFTP機能には、レコード指向のファイルや追加、割当て、アカウントおよび中断の操作があります。

Oracle XML DBは、RFC 959で定義されたFTPを実装しますが、次のオプション機能は除きます。

- レコード指向のファイル、たとえば、STRUメソッドは、FILE構造のみサポートされています。これは、ファイルの転送に最も広範囲に使用されている構造です。これは、仕様で指定されているデフォルトでもあります。構造マウントはサポートされません。

- 追加。

- 割当て。ファイル転送の前に領域を事前に割り当てます。

- アカウント。安全性の低いTelnetプロトコルを使用します。

- 強制終了。

28.3.1.2 サポートされているFTPクライアント・メソッド

Oracle XML DBでは、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の使用」を参照してください。

28.3.1.3 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キャラクタ・セットが使用されます。

28.3.1.4 FTPを使用したOracle XML DBリポジトリへのコンテンツのアップロード

標準のコマンドラインFTPツールで文書をOracle XML DBリポジトリにロードするときに発行されるコマンドと、生成された出力の例を示します。

図28-3および例28-2で示されている要点は、Windows ExplorerおよびFTPツールのいずれもがOracle XML DBの操作を認識していないことです。このようなツールおよびOracle XML DBの両方でオープン・インターネット・プロトコルがサポートされているため、最初から相互に使用できます。

WebDAVまたはFTPプロトコルを認識するツールを使用すると、Oracle XML DBリポジトリで管理されるコンテンツを作成できます。クライアントまたは中間層に追加のソフトウェアをインストールする必要はありません。

Windows ExplorerやFTPなどのツールを使用してフォルダのコンテンツを表示すると、そのフォルダに格納されたXML Schemaに基づく文書のサイズはゼロ(0)バイトと表示されます。このように設計されているのは、次の2つの理由からです。

- 文書のサイズが明確でありません。文書に関連するサイズには、文書を出力して生成されたCLOBインスタンスのサイズ、文書をデータベース内に永続的に保持するために使用するオブジェクトの格納に必要なバイト数などがあります。

- 選択された定義に関係なく、この情報を計算して保持するにはコストがかかります。

例28-2 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.
$

28.3.1.5 Oracle ASMファイルに対するFTPの使用

Oracle Automatic Storage Management(Oracle ASM)を使用すると、データベース・ファイルはディスク・グループに整理され、管理が簡潔になるとともに、データベースのミラー化やI/Oバランシングなどの利用が可能になります。プロトコルおよびリソースAPIを使用して、リポジトリのvirtual folder /sys/asm内のOracle ASMファイルにアクセスできます。/sys/asmにあるファイルはすべてバイナリです。

一般的な用途は、Oracle ASMのファイルやフォルダに対するリスト表示、コピー、移動、作成、および削除です。例28-3はOracle ASMの仮想フォルダのナビゲートとサブフォルダ内のファイルのリスト表示の例です。

Oracle ASM仮想フォルダ/sys/asmの構造は、Oracle XML DBリポジトリ・データへのアクセスで説明しています。例28-3では、ディスク・グループがDATAおよびRECOVERY、データベース名がMFG、エイリアス用に作成されたディレクトリがdbsおよびtmpです。この例はサブフォルダにナビゲートし、ファイルをリストし、ファイルの1つをローカルのファイル・システムにコピーしています。

例28-3では、データベース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-4は2つのデータベース間でのコピーを示しています。この場合、proxy FTPクライアント・メソッドを使用できます。proxyメソッドを使用すると、2つの異なるリモートFTPサーバーに直接接続できます。

例28-4では、Oracle ASMファイルをデータベース間でコピーしています。接尾辞1が付いた語はデータベースserver1に対応しています。接尾辞2が付いた語はデータベースserver2に対応しています。一部のFTPクライアントでは、入力したパスワードが画面に表示されることがあります。パスワードが他人の目に触れないよう、十分注意してください。

例28-4の内容:

- 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にコピーします。

例28-3 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-4 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.3.1.6 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_CONFIG.setFTPPortを使用して、Oracle XML DB構成ファイルxdbconfig.xmlでFTPポート番号を21に設定します。

SQL> exec DBMS_XDB_CONFIG.setFTPPort(21);

6. 次のSQL文を使用してデータベースが必ずリスナーとともに登録されるようにします。

SQL> ALTER SYSTEM REGISTER;

7. このシェル・コマンドを使用して、リスナーが適切に構成されていることを確認します。

% lsnrctl status

関連項目:

- リスナーのパラメータおよびファイルlistener.oraの詳細は『Oracle Database Net Servicesリファレンス』を参照してください。

- 特権ポートの詳細は『Oracle Database Net Servicesリファレンス』の、ポート番号の制限に関する項を参照してください。

28.3.1.7 FTPでのIPv6 IPアドレスの使用

11gリリース2 (11.2)以降のOracle Databaseでは、(Internet Protocol Version 4に加えて) Internet Protocol Version 6 (IPv6)がサポートされています。

例28-5に、FTPでIPv6アドレス2001::0db8:ffff:ffff:ffffに接続する方法を示します。

関連項目:

IPv6の詳細は、『Oracle Database Net Servicesリファレンス』を参照してください。

例28-5 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>

28.3.1.8 FTPサーバーのセッション管理

Oracle XML DBプロトコル・サーバーでは、FTPのセッション管理も提供します。FTPは、新しいコマンドの入力をショート・ウェイトした後、プロトコル・レイヤーに戻ります。

このショート・ウェイト時間は、Oracle XML DB構成ファイルのcall-timeoutパラメータを変更することによって構成できます。通信量が多いサイトでは、call-timeoutを短くし、より多くの接続を確立できるようにする必要があります。接続で新しいデータが受信されると、FTPサーバーは最新のデータを使用して再起動されます。そのため、FTPが長時間実行する性質を持っていても、プロトコル・サーバーに確立可能な接続の数には影響しません。

関連項目:

Oracle XML DBパラメータの構成の詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください

28.3.1.9 エラーの処理421。FTPセッションのデフォルトのタイムアウト値の変更

頻繁にサーバーから切断され、次の操作を実行する前に、再接続してディレクトリ全体を検索する必要がある場合は、FTPセッションに対するデフォルトのタイムアウト値を変更する必要がある可能性があります。この時間の経過後もセッションがアイドル状態である場合、そのセッションは切断されます。

タイムアウトの値(デフォルト= 6000センチセカンド)を大きくするには、次のように構成ドキュメントを変更した後、データベースを再起動します。

例28-6 FTPセッションのデフォルトのタイムアウト値の変更

DECLARE
newconfig XMLType;
BEGIN
SELECT XMLQuery('copy $i := $p1 modify
(for $j in $i/xdbconfig/sysconfig/protocolconfig/ftpconfig/session-timeout
return replace value of node $j with $p2)
return $i'
PASSING DBMS_XDB_CONFIG.cfg_get() AS "p1", 123456789 AS "p2" RETURNING CONTENT)
INTO newconfig FROM DUAL;
DBMS_XDB_CONFIG.cfg_update(newconfig);
END;/
COMMIT;

28.3.1.10 パッシブ・モードでの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から導出)をクライアントに渡すためで、これによりクライアントはサーバーでなく自分自身に接続しようとしてしまいます。

28.4 HTTP(S)およびOracle XML DBプロトコル・サーバー

Oracle XML DBは、RFC2616仕様に定義されているHyperText Transfer Protocol(HTTP)のHTTP 1.1を実装します。

28.4.1 Oracle XML DBプロトコル・サーバー: HTTP(S)機能

Oracle XML DBプロトコル・サーバーのOracle XML DB HTTP(S)コンポーネントは、いくつかのオプション機能を除いて、RFC2616仕様を実装します。

サポートされていないオプションのHTTP(S)機能は、次のとおりです。

- gzipおよび圧縮転送エンコーディング

- バイト範囲ヘッダー

- TRACEメソッド(プロキシ・エラーのデバッグに使用します。)

- キャッシュ制御ディレクティブ(コンテンツの期限日を指定する必要があります。一般には使用されません。)

- TE、Trailer、VaryおよびWarningヘッダー

- 弱いエンティティ・タグ

- Web共通ログ・フォーマット

- マルチホームWebサーバー

関連項目:

RFC 2616、HTTP 1.1プロトコル仕様(http://www.ietf.org/rfc/rfc2616.txt)

28.4.1.1 サポートされているHTTP(S)クライアント・メソッド

Oracle XML DBでは、Oracle XML DBリポジトリにアクセスするための複数のHTTP(S)クライアント・メソッドがサポートされています。

- OPTIONS - 利用できる通信オプションについての情報を取得します。

- GET - 文書/データ(ヘッダーとも)を取得します。

- HEAD - 文書の本文なしで、ヘッダーのみを取得します。

- PUT - データをリソースに格納します。

- DELETE - リソースを削除します。

これらのHTTP(S)メソッドのセマンティクスはWebDAVに従っています。サーブレットとWebサービスは、POSTなどこの他のHTTP(S)メソッドをサポートする場合があります。

関連項目:

WebDAVに関係する、サポートされているHTTP(S)クライアント・メソッドは、「Oracle XML DBによってサポートされるWebDAVクライアント・メソッド」を参照してください。

28.4.1.2 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_CONFIG.setHTTPPortを使用して、Oracle XML DB構成ファイルxdbconfig.xmlでHTTP(S)ポート番号をport_numberに設定します(ここでport_numberは、80 (HTTP)または443 (HTTPS)です)。

SQL> exec DBMS_XDB_CONFIG.setHTTPPort(port_number);

6. 次のSQL文を使用してデータベースが必ずリスナーとともに登録されるようにします。

SQL> ALTER SYSTEM REGISTER;

7. リスナーが正しく構成されていることを確認します。

% lsnrctl status

関連項目:

- リスナーのパラメータおよびファイルlistener.oraの詳細は『Oracle Database Net Servicesリファレンス』を参照してください。

- 特権ポートの詳細は『Oracle Database Net Servicesリファレンス』の、ポート番号の制限に関する項を参照してください。

28.4.1.3 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リファレンス』を参照してください。

28.4.1.4 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を参照してください。

28.4.1.5 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を指定することはできません。

28.4.1.6 HTTPを使用したOracle XML DBリポジトリへの匿名アクセス

オプションの構成パラメータallow-repository-anonymous-accessは、ロック解除されたANONYMOUSユーザー・アカウントを使用した、Oracle XML DBリポジトリ・データへの匿名HTTPアクセスが許容されるかどうかを示します。デフォルト値はfalseで、これはリポジトリ・データへの非認証アクセスがブロックされることを意味します。

リポジトリへのHTTPアクセスを許可するには、このパラメータをtrueに設置して、ANONYMOUSユーザー・アカウントをロック解除する必要があります。

注意:

リポジトリへの匿名アクセスを許可することには、潜在的なセキュリティ・リスクがあります。

パラメータallow-repository-anonymous-accessは、サーブレットを使用したリポジトリへの匿名アクセスは制御しません。各サーブレットには、アクセスを制御する独自のsecurity-role-refパラメータ値があります。

注意:

ユーザー・アカウントANONYMOUSがマルチテナント・コンテナ・データベース(CDB)に対してロックされている場合、そのCDBにプラグインされているプラガブル・データベース(PDB)に対してANONYMOUSをロックまたはロック解除しても、ANONYMOUSによるPDBへのアクセスには、影響を及ぼしません。

関連項目:

- パラメータallow-repository-anonymous-accessの詳細は、表28-3を参照してください。

- Oracle XML DBパラメータの構成の詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください

- security-role-refパラメータの詳細は、「Oracle XML DBサーブレットの構成」を参照してください。

28.4.1.7 HTTP(S)によるJavaサーブレットの使用

Oracle XML DBでは、Javaサーブレットの使用がサポートされています。その動作をカスタマイズするパラメータとともに、Oracle XML DBの構成ファイルに一意の名前でそれぞれ登録する必要があります。それをコンパイルして、データベースにロードする必要があります。そのサーブレット名をパターンに関連付ける必要があります。

このパターンは、JavaサーブレットApplication Program Interface (API)バージョン2.2に記述されているとおり、*.jspなどの拡張子または/a/b/cや/sys/*などのパス名になります。

HTTP(S)リクエストの処理中、そのリクエストに対するパス名は登録済のパターンと照合されます。一致する場合、プロトコル・サーバーは適切な初期化パラメータを使用して対応するサーブレットを起動します。Java仮想マシン(JVM)が起動され、これによりJavaメソッドが起動されて、サーブレットの初期化、レスポンス・オブジェクトとリクエスト・オブジェクトの作成、サーブレットへのこれらの受渡しが行われて、サーブレットが実行されます。

関連項目:

JavaでのOracle XML DBアプリケーションの作成方法

28.4.1.8 埋込みPL/SQLゲートウェイ

PL/SQLゲートウェイを使用して、WebアプリケーションをPL/SQLに完全に実装できます。PL/SQLゲートウェイの実装には、mod_plsqlと埋込みゲートウェイの2つがあります。

- mod_plsql: HTTP(S)を使用してPL/SQLストアド・プロシージャを起動できる、Oracle HTTP Serverのプラグインです。Oracle HTTP Serverは、Oracle Fusion Middlewareにも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での埋込みゲートウェイの構成定義の詳細は、 Oracle XML DBの管理を参照してください。

- PL/SQLゲートウェイの使用に関する概念的な情報は、『Oracle Fusion Middleware Oracle HTTP Server管理者ガイド』を参照してください。

- mod_plsqlの詳細は、『Oracle Fusion Middleware mod_plsqlユーザーズ・ガイド』を参照してください。

28.4.1.9 クライアントからのマルチバイト・データの送信

クライアントが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の構成」を参照してください

28.4.1.10 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の構成」を参照してください

28.4.1.11 HTTP(S)のキャラクタ・セット

HTTP(S)を使用して転送されるデータで使用されるキャラクタ・セットを制御できます。

28.4.1.11.1 HTTP(S)リクエストのキャラクタ・セット

HTTP(S) Request Bodyのキャラクタ・セットは、簡単ですが多少複雑なアルゴリズムを使用して決定されます。

1. Content-Typeヘッダーを評価します。Content-Typeヘッダーにcharset値が指定されている場合は、指定されたcharsetを使用します。

2. ドキュメントのMIMEタイプを次のように評価します。

a. MIMEタイプが*/xmlの場合、キャラクタ・セットは次のように決定されます。

i. BOMもエンコーディング宣言も存在しない場合は、UTF-8を使用します。

ii. BOMが存在する場合は、UTF-16を使用します。

iii. エンコーディング宣言が存在する場合は、指定されたエンコーディングを使用します。

b. MIMEタイプがtextの場合は、ISO8859-1を使用します。

c. MIMEタイプが、*/xmlでもtextでもない場合は、データベース・キャラクタ・セットを使用します。

HTTP(S)とSQL間またはHTTP(S)とFTP間では処理が異なります。テキスト・ドキュメントの場合、IETF.org RFC 2616: HTTP 1.1プロトコル仕様で指定されているとおり、デフォルトはISO8859-1です。

28.4.1.11.2 HTTP(S)レスポンスのキャラクタ・セット

Oracle XML DB HTTP Serverで生成されるレスポンスは、リクエストのAccept-Charsetフィールドに指定されているキャラクタ・セットです。

Accept-Charsetには、キャラクタ・セットのリストを指定できます。Oracle XML DBは、q値に基づいて、変換が不要なキャラクタ・セットのいずれかを選択します。選択されるキャラクタ・セットが、最大のq値を持つキャラクタ・セットではない場合があります。変換が不要なものが見つからない場合、Oracle XML DBでは、最大のq値に基づいて変換を行います。

28.5 WebDAVとOracle XML DB

Web Distributed Authoring and Versioning (WebDAV)は、インターネットを経由したOracle XML Repositoryへのファイル・システム・インタフェースをユーザーに提供するために、Oracle XML DBによって使用されるIETF標準のプロトコルです。WebDAVサーバー・フォルダにアクセスする最も一般的な方法は、Microsoft Windowsを使用して「Webフォルダ」を使用する方法です。

WebDAVはHTTP 1.1プロトコルの拡張で、HTTPサーバーをファイル・サーバーとして使用することを可能にします。WebDAVを使用すると、クライアントは、メソッド、ヘッダー、Request BodyフォーマットおよびResponse Bodyフォーマットの一貫したセットを介して、リモートWebコンテンツのオーサリングを実行できます。たとえば、DAV対応のエディタは、ファイル・システムとまったく同様にHTTP/WebDAVサーバーと対話できます。WebDAVは、リソースの格納および取出し、リソース・コレクションのコンテンツの作成およびリスト、同時アクセスに対するリソースの調整式ロックおよびリソース・プロパティの設定および取出しを行う操作を提供します。

28.5.1 Oracle XML DB WebDAVの機能

Oracle XML DBでは、WebDAVのフォルダリングおよびアクセス制御機能がサポートされます。フォルダリングはRFC2518で規定されています。

WebDAVは、HTTP(S)プロトコルへの拡張機能のセットで、リモートWebサーバーのファイルを共有、編集および管理できます。

関連項目:

RFC 2518: WebDAVプロトコル仕様(http://www.ietf.org/rfc/rfc2518.txt)

28.5.1.1 Oracle XML DBによってサポートされないWebDAV機能

Oracle XML DBでは、いくつかの機能を除いてRFC2518仕様がサポートされます。メソッドCOPY、MOVEおよびDELETEについては、RFC5842仕様で説明するように、リソースのバインディングもサポートされます。

Oracle XML DBでサポートされないRFC2518からのWebDAV機能は、次のとおりです。

- 書込みがロックされたnullリソース(ロックnullリソース)の名前をフォルダ名として使用すると、ファイル・システムで長さがゼロのリソースとして表現されるため、このようにすることはサポートされていません。これはオプション機能です。

- メソッドLOCKについては、深さに無限を指定して、リソースとそのすべての子孫を同時にロックすることはできません。この機能はオプションではありませんが、Oracle XML DBではサポートされていません。

さらに、メソッドCOPY、MOVEおよびDELETEについては、RFC5842のセクション2、「Binding Extensions to Web Distributed Authoring and Versioning (WebDAV)」で説明されているように、Oracle XML DBでリソースのバインディングがサポートされます。バインディングは、指定されたフォルダのリソースに対するURIのマッピングです。

関連項目:

- ロックnullリソースの詳細は、RFC2518仕様のセクション7.4 (http://www.webdav.org/specs/rfc2518.html#rfc.section.7.4)を参照してください。

- 深さが無限のロックの詳細は、RFC2518仕様のセクション9.2 (http://www.webdav.org/specs/rfc2518.html#rfc.section.9.2)を参照してください。

- リソース・バインディングの詳細は、RFC5842仕様のセクション2 (https://tools.ietf.org/html/rfc5842#section-2)を参照してください。

28.5.1.2 Oracle XML DBによってサポートされるWebDAVクライアント・メソッド

Oracle XML DBでは、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を使用したメタデータの追加」

28.5.2 WebDAVとMicrosoft Windows XP SP2

Microsoft Windows XP Service 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)の構成」

28.5.3 Oracle XML DBリポジトリで使用するためのMicrosoft WindowsでのWebフォルダの作成

Windows 2000でWebフォルダを作成して、Oracle XML DBリポジトリで使用します。

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フォルダの作成

28.5.3.1 ファイルをOracle XML DBリポジトリにコピーする際のWindows ExplorerでのWebDAVの使用

Windows Explorerを使用して、ローカルのハード・ドライブからOracle Databaseにフォルダを挿入できます。

図28-3では、これを説明しています。

Windows Explorerは、WebDAVプロトコルをサポートしています。WebDAVはHTTP標準の拡張で、HTTPサーバーがファイル・サーバーとして機能できる動詞が追加されています。

Windows Explorerのコピー操作やFTPの入力コマンドを使用して、多数の文書をOracle XML DBリポジトリに転送する場合、それぞれのputまたはpostコマンドは、個別の基本操作として扱われます。これにより、ファイル転送のうちのいずれかが失敗してもクライアントに混乱が生じません。また、プロトコルを介して文書に加えられた変更は、リクエストが処理されるとすぐに、他のユーザーも参照できます。

図28-3 Oracle XML DBリポジトリへのファイルのコピー

脚注の凡例

脚注1:
BOMとは、後続のバイト・ストリームの順序を示すUnicode標準のシグネチャです。

29 ユーザー定義のリポジトリ・メタデータ

Oracle XML DBリポジトリに格納されたXMLデータに関連付ける独自のメタデータを作成できます。

- メタデータとXMLの概要

- XML Schemaを使用したリソース・メタデータの定義

- リソース・メタデータの追加、変更および削除

- XML Schemaに基づくリソース・メタデータの問合せ

- バイナリ・イメージ・メタデータからのXMLイメージ・メタデータ

- XML Schemaに基づかないリソース・メタデータの追加

- リソース・メタデータに影響するPL/SQLプロシージャ

29.1 メタデータとXMLの概要

使用するデータが、コンテンツの一部ではない追加情報に関連付けられていることがよくあります。データを様々な方法で処理するには、この種のメタデータをデータのグループ化や分類に使用します。

たとえば、多数の写真に対して、カラー合成、焦点長などの写真の特性や、場所、被写体の種類(風景か人物か)などの付随情報といったメタデータをそれぞれの写真に関連付けたい場合があります。

Oracle XML DBリポジトリのリソースは、メタデータとデータの両方を含むXML文書です。データは、要素Contentsのコンテンツです。リソース内の他のすべての要素にはメタデータが含まれます。リソースのデータはXMLでなくてもかまいません。

Oracle XML DBリポジトリを、ユーザーが定義したメタデータに関連付けることができます。こうしたユーザー定義のメタデータの他に、各リポジトリ・リソースにも、Oracle XML DBにより自動作成され、リソース管理に(透過的に)使用されている関連のメタデータがあります。こうしたシステム定義のメタデータには、各リソースの所有者や作成日などのプロパティが含まれています。

システム定義のメタデータを除き、リソース情報のいずれをデータ、いずれをメタデータとみなすかはユーザーの判断です。写真リソースの場合、写真に関する付随情報は通常、バイナリ・イメージである写真データの一部とはみなされません。しかしテキストの場合は、特定の情報をリソースのコンテンツ(データ)に含めるか、別扱いにして、メタデータとしてコンテンツに関連付けるかを選択できる場合があります。こうした選択は、多くの場合、データを使用または作成するアプリケーションに左右されます。

29.1.1 メタデータの種類 - 用語の用法

メタデータという用語は、XMLのコンテキストにおいて様々な方法で使用され、ここには、XML Schema定義、XMLタグ、およびリソース・コンテンツを補完するOracle XML DBリポジトリ・リソース情報などが含まれます。

リソース・メタデータ(システム定義またはユーザー定義)の他に、「メタデータ」という語は次のものを指すことがあります。

- XML Schemaは、XML文書のクラスを示すメタデータです。

- XMLタグ(要素名または属性名)は、要素のコンテンツや属性値に名前を付けたり整理したりするのに使用されるメタデータです。

次のようにして、メタデータをリポジトリ・リソースのコンテンツであるXML文書に関連付けることができます。

- メタデータ情報を含む追加のXML要素をリソースのコンテンツに追加することができます。たとえば、デジタル・イメージ・データを、写真に関する説明を要素として含むXML文書の中に入れることもできます。この場合、データとそのメタデータは、同じリソースのコンテンツであることによって関連付けられています。それらを分離したり、正しく関連させたりする処理はアプリケーションが担当します。

- 特定のリソースのメタデータをリポジトリに、別のリソースのコンテンツとして追加することもできます。この場合、このリソースをメタデータとして処理し、データに関連付けるのはアプリケーションが担当します。

- リソースのメタデータ情報を、リポジトリのリソース・メタデータとして追加できます。この場合、Oracle XML DBはメタデータをそのままの形で認識します。アプリケーションは、リポジトリに問い合せることによってこのメタデータを検出します。アプリケーションは、メタデータが存在するかどうかや、データとの関連付けについて独自に知っている必要はありません。

関連項目:

「Oracle XML DBリポジトリ・リソース」

29.1.2 ユーザー定義のリソース・メタデータ

ユーザー定義のリソース・メタデータは、それ自身XMLで表現されています。他のXMLデータに関連付けられたXMLデータであり、その説明や、補足情報、関連情報を提供します。

リソースのユーザー定義のメタデータはXML Schemaに基づいている場合も、そうでない場合もあります。

- XML Schemaに基づくリソース・メタデータは別個の(オンラインでない)表に格納されます。これらはリソースOIDによってリソース表に関連付けられており、メタデータ表の非表示のオブジェクト列RESIDに格納されます。

- XML Schemaに基づかないリソース・メタデータは、リソース文書の一部としてリソース表のXDB.XDB$RESOURCEに格納されます。

XML Schemaに基づくメタデータは、リソースに対して問合せやDML操作を効率的に実行する際に有効です。この章では、XML Schemaに基づくリソース・メタデータに関する次のタスクの実行方法を説明します。

- 特定の種類のリソースに対してメタデータを定義するXML Schemaの作成と登録。

- リポジトリ・リソースへのメタデータの追加とその更新(変更)。

- 関連付けられているコンテンツを検索するためのリソース・メタデータの問合せ。

- リソースに関連付けられているメタデータの削除と、リソースに関連付けられているすべてのメタデータの消去。

この他、XML Schemaに基づかないメタデータをリソースに追加する方法も説明します。

一般に、ユーザー定義のリソース・メタデータはリソース・データを使用する場合と同様に使用できます。バージョニングとアクセス制御については特にそれが成り立ちます。

リソース・メタデータの典型的な使用方法には、ワークフロー・アプリケーション、ユーザー権限の強制管理、リソース所有権の追跡、リソース有効期間の管理などがあります。

29.1.3 シナリオ: 写真コレクションのメタデータ

XML Schemaに基づくリソース・メタデータの使用方法を説明するために、次のシナリオでは、リポジトリ・リソースに格納されている写真のイメージ・ファイルに関連付けられているメタデータを使用します。必要なだけ多くの種類のメタデータを作成して、同じリソースに関連付けることができます。

イメージ・ファイルの例では、(1)写真の技術的な側面、および(2)写真のテーマや用途に関する情報のメタデータを作成します。この2種類の関連メタデータを使用して写真リソースを問い合せます。

29.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-2のXML Schemaは写真イメージ・ファイルの分類に使用するメタデータを定義します。この簡単な例では、分類用のCategoryという名前の、単一の汎用プロパティを定義します。

メタデータのXML Schema定義には、その情報を任意の特定の種類のデータへの関連付けに制限するものはないということに注意してください。任意の型のメタデータを任意の型のリソースに、自由に関連付けできます。同一のリソースに複数の型のメタデータを関連付けることもできます。

また、XML Schemaは、それ自身では、関連付けられているデータをメタデータであると定義してはいません。そうした特徴付けは、enableHierarchyの値ENABLE_HIERARCHY_RESMETADATAを介するスキーマ登録によって行われます。enableHierarchyの値ENABLE_HIERARCHY_CONTENTS(デフォルト値)に同じスキーマが登録されると、リソースに対応するメタデータでなく、同じ情報を持つリソース・コンテンツが定義されます。同一のXML Schemaを、同じ名前で複数回登録することはできません。

注意:

デフォルトでは、ユーザー・メタデータは、XML Schemaに基づく場合にはオブジェクト・リレーショナル形式で格納され、XML Schemaに基づかない場合にはCLOBインスタンスとして格納されます。また、XML Schema登録のためのOPTIONSパラメータをREGISTER_BINARYXMLに設定することにより、かわりにバイナリXMLとしても格納できます。

例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の登録

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;
/

29.3 リソース・メタデータの追加、変更および削除

ユーザー定義のリソース・メタデータを追加、更新および削除するには、パッケージDBMS_XDB_REPOS内のPL/SQLプロシージャ、SQL DML文INSERT、UPDATEおよびDELETEまたはWebDAVプロトコル・メソッドPROPPATCHを使用します。

ユーザー定義のリソース・メタデータの追加、更新、および削除は、次のいずれかの方法で行うことができます。

- パッケージDBMS_XDB_REPOS内の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_REPOS内の各種PL/SQLプロシージャの使用方法はよく似ています。いずれも、XML Schemaに基づいている、またはXML Schemaに基づかないメタデータとともに使用できます。一部のプロシージャのいくつかの形式(シグネチャ)は、XML Schemaに基づくメタデータにのみ適用されます。ここでは、プロシージャappendResourceMetadataおよびdeleteResourceMetadataについて、例を使用して説明します。

関連項目:

PL/SQLパッケージDBMS_XDB_REPOSのプロシージャの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

29.3.1 APPENDRESOURCEMETADATAを使用したメタデータの追加

プロシージャDBMS_XDB_REPOS.appendResourceMetadataを使用して、ユーザー定義のメタデータをリソースに追加できます。

例29-3では、写真リソースを作成し、型がImgTechMetadataの、XML Schemaに基づくメタデータを追加することにより、写真に関する技術情報を記録しています。

例29-4では、型がImgTechMetadataのメタデータを例29-3と同じリソースに追加することにより、写真をいずれかのユーザー定義のコンテンツ・カテゴリに分類しています。

例29-3 メタデータのリソースへの追加 - 写真の技術情報

DECLARE
returnbool BOOLEAN;
BEGIN
returnbool := DBMS_XDB_REPOS.createResource(
'/public/horse_with_pig.jpg',
bfilename('MYDIR', 'horse_with_pig.jpg'));
DBMS_XDB_REPOS.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 メタデータのリソースへの追加 - 写真のコンテンツ・カテゴリ

BEGIN
DBMS_XDB_REPOS.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.

29.3.2 DELETERESOURCEMETADATAを使用したメタデータの削除

プロシージャDBMS_XDB_REPOS.deleteResourceMetadataを使用して、リソースに関連付けられている特定のメタデータを削除できます。あるリソースに関連付けられているメタデータをすべて削除するには、プロシージャDBMS_XDB_REPOS.purgeResourceMetadataを使用します。

例29-5では、例29-4で写真リソースに追加されたカテゴリ・メタデータを削除しています。デフォルトでは、メタデータへのリソース・リンク(REF)と、そのリンクにより識別されるメタデータ表の両方が削除されます。リンクのみを削除するように指定するオプションのパラメータを使用できます。その場合、メタデータ表はそのまま残りますが、リソースへの関連性はなくなります。この例では、デフォルトの動作が使用されています。

例29-5 リソースからの特定のメタデータの削除

BEGIN
DBMS_XDB_REPOS.deleteResourceMetadata('/public/horse_with_pig.jpg',
'cnamespace',
'ImgCatMetadata');
END;
/

PL/SQL procedure successfully completed.

SELECT * FROM imgcatmetadatatable;

no rows selected

29.3.3 SQL DMLを使用したメタデータの追加

プロシージャDBMS_XDB_REPOS.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.

29.3.4 WebDAV PROPPATCHを使用したメタデータの追加

プロシージャDBMS_XDB_REPOS.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>

29.4 XML Schemaに基づくリソース・メタデータの問合せ

リソース・メタデータを問い合せる際に、メタデータ列RESIDを使用して、メタデータを関連のデータに結合できます。

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.

29.5 バイナリ・イメージ・メタデータからのXMLイメージ・メタデータ

デジタル・カメラには、生成されるイメージ・ファイルの一部としてイメージ・メタデータが含まれます。Oracle Multimediaでは、このバイナリ・メタデータを抽出してXMLに変換するためのツールが提供されています。Oracle Multimedia 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 Multimediaでイメージ・メタデータを使用する際にサポートされているXML Schemaの詳細は、『Oracle Multimediaリファレンス』を参照してください。

29.6 XML Schemaに基づかないリソース・メタデータの追加

XML Schemaに基づかないユーザー定義のリソース・メタデータは、CLOBインスタンスとして、関連付けられているリソースのResource要素に格納します。

リソースのデフォルトのXML Schemaでは最上位要素がany (maxOccurs= "unbounded"で宣言)なので、任意の有効なXMLデータをリソース表XDB.XDB$RESOURCEのリソース・ドキュメントに含めることができます。

次のスケルトンは、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_REPOS.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.

29.7 リソース・メタデータに影響するPL/SQLプロシージャ

PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchema、DBMS_XDBZ.enable_hierarchy、DBMS_XDBZ.disable_hierarchy、DBMS_XDBZ.is_hierarchy_enabled、DBMS_XDB_REPOS.appendResourceMetadata、DBMS_XDB_REPOS.deleteResourceMetadata、DBMS_XDB_REPOS.purgeResourceMetadataおよびDBMS_XDB_REPOS.updateResourceMetadataを使用して、リソース・メタデータ操作を実行できます。

- 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_REPOS.appendResourceMetadata - リソースにメタデータを追加します。

- DBMS_XDB_REPOS.deleteResourceMetadata - リソースから特定のメタデータを削除します。

- DBMS_XDB_REPOS.purgeResourceMetadata - ユーザー定義のメタデータをすべてリソースから削除します。XML Schemaに基づくリソースの場合、オプションのパラメータDELETE_OPTIONを使用して、メタデータ情報を単にリンク解除するだけでなく、削除するかどうかを指定できます。

- DBMS_XDB_REPOS.updateResourceMetadata - リソースのメタデータを更新します。

関連項目:

PL/SQLプロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

30 Oracle XML DBリポジトリ・イベント

Oracle XML DBリポジトリを使用して、あらゆるリポジトリ・リソース形式のデータを格納、またはデータにアクセスできます。リポジトリ・データには、任意のアプリケーションからアクセスできます。特定のリポジトリ操作が発生するたびに、アプリケーションによる特定のアクションの実行が必要な場合があります。リポジトリ・イベントを使用してこれを行うことができます。

- リポジトリ・イベントの概要

- 可能なリポジトリ・イベント

- リポジトリ操作とイベント

- リポジトリ・イベント・ハンドラの考慮事項

- リポジトリ・イベントの構成

関連項目:

リポジトリ・リソースの構成の詳細は、 Oracle XML DBリポジトリの構成を参照してください。

30.1 リポジトリ・イベントの概要

リポジトリ操作に関連するイベントが発生した場合、アプリケーションで特定のアクションを実行できます。たとえば、リソースを削除するたびに、ごみ箱への移動やバックアップ操作を実行する場合があります。

リポジトリ・リソース操作には、作成、削除、ロック、ロック解除、レンダリング、リンク付け、リンク解除、バージョン管理、チェックイン、チェックアウト、チェックアウト解除(チェックアウトされたバージョンの回復)、オープン、更新があります。

30.1.1 リポジトリ・イベント: ユースケース

リポジトリ・イベントを使用できる場合の例として、ごみ箱へのリソースの移動やMIMEタイプに基づくリソースの分類などがあります。

- ごみ箱– UnLink前処理イベント・ハンドラを使用して、リソースを削除するのではなく、効率的にごみ箱に移動できます。つまり、元のリンクを削除する前にごみ箱フォルダにリンクを作成します。ごみ箱のリンクにより、リソースは削除されません。その後、削除されたリソースをごみ箱から元に戻す場合、元のリンクが再作成され、ごみ箱のリンクが削除されます。特定のパスのリソースは、そのパスから複数回リンク解除できるため、ごみ箱のリンク名は、削除されるリンク名と異なるリンク名にできます。ごみ箱には、そのパスに対応する、リンク・プロパティが異なり、それぞれ別のリソースを指している可能性のあるリンクが複数存在します。

- カテゴリ分け: アプリケーションにより、管理するリソースがMIMEタイプや他のプロパティに基づいて分類される場合があります。リポジトリ・フォルダ/my-app/gif、/my-app/txt、および/my-app/xmlからGIFファイル、テキスト・ファイル、およびXMLファイルのリンクが保持され、そのファイルが追跡されることがあります。ここでは、LinkIn、UnlinkIn、Updateの3つの後処理イベント・ハンドラを使用できます。LinkIn後処理イベント・ハンドラはリソースを調べ、リソースがまだ存在しない場合は、適切なカテゴリ・フォルダにリンクを作成します。UnlinkIn後処理イベント・ハンドラは、カテゴリ・フォルダからリンクを削除します。Update後処理イベント・ハンドラは、そのカテゴリが変更された場合に、1つのカテゴリ・フォルダから別のカテゴリ・フォルダへリソースを効率的に移動します。

30.1.2 リポジトリ・イベントとデータベース・トリガー

データベース・トリガーは、アプリケーションによるリポジトリ操作への反応には使用できません。指定のリポジトリ操作は、複数の基礎となる内部表において、複数のデータベース操作で構成されている場合があります。これらの基礎となる表はOracle XML DB内部にあるため、特定のリポジトリ操作に簡単にはマップできません。

たとえば、内部表XDB$H_INDEXは、(ACLが変更された場合は)データベース更新操作、またはリンク操作により更新されます。データベース・トリガーによって同様の操作が可能な場合でも、これを使用しません。リポジトリ・イベントとは、基礎となる表の一連のデータベース・トリガーより高いレベルの抽象的概念です。

リポジトリ・イベントが発生すると、使用されているリソース・パスなど、その操作に関連した情報が対応するイベント・ハンドラに渡されます。このような情報は、データベース・トリガーを使用した場合はすぐに使用できません。

リポジトリ・イベントとデータベース・トリガーは両方ともXMLデータに適用できます。たとえば、トリガーはXMLType表で使用できます。ただし、XMLType表も(階層対応の)リポジトリ表である場合は、表に適用されるトリガー・コードをイベント・ハンドラでコピーしないでください。コピーした場合、そのコードは2回実行されます。

30.1.3 リポジトリ・イベント・リスナーとイベント・ハンドラ

各リポジトリ操作は、イベントに関連付けられています。アプリケーションは、イベント・リスナーを特定のリソース、またはリポジトリ全体に対して構成できます。リスナーは、ノードが存在することという前提条件によって制限できます。リスナーは、それぞれが単一のイベントを処理する、一連のPL/SQLまたはJavaハンドラです。

リポジトリ・イベント・リスナーはJavaクラス、PL/SQLパッケージまたはオブジェクト型です。このリポジトリは一連のPL/SQLプロシージャまたはJavaメソッドで構成され、それぞれがイベント・ハンドラと呼ばれます。

リソース構成ファイルをリソースとマップして、リポジトリ・イベント・リスナーとリソースを関連付けます。PL/SQLパッケージDBMS_RESCONFIGを使用して、リソース構成ファイルとそれを構成するリソースと関連付けるなど、リソース構成ファイルを操作します。特に、PL/SQLファンクションDBMS_RESCONFIG.getListenersには、特定のリソースのすべてのイベント・リスナーが一覧されています。

30.1.4 リポジトリ・イベント構成

リポジトリ・イベント構成には、リソース構成ファイルの定義と、その処理順序の定義が含まれます。ファイルは、イベント・リスナーを定義します。このような構成は、個々のリソースのイベントとリポジトリ全体のイベントに適用されます。

複数のリソース構成ファイルにより、特定のリソースが構成されます。これらはリソース構成リストに格納されており、リストに記載された順番で処理されます。リポジトリ全体のイベントも複数のリソース構成ファイルで構成される場合があります。同様に、リポジトリにもリソース構成リストがあります。リポジトリ全体について構成されるイベント処理は、任意のリソース固有のイベント処理前に有効になります。つまり、リポジトリ全体に渡る当該イベントはすべて、リソース固有のイベント前に処理されます。

指定のリソース構成ファイルによって構成するリソースの複数のイベント・リスナーが定義され、各イベント・リスナーによって複数のイベント・ハンドラが定義されます。

関連項目:

- 「リポジトリ・イベントの構成」

- リソース構成およびリソース構成リストの詳細は、「リソースを構成するリソース構成ファイル」を参照してください

30.2 可能なリポジトリ・イベント

リポジトリ操作は、事前定義されたイベントに関連付けられます。レンダリング操作を除いて、イベントは事前と事後のペアで発生します。

レンダリング操作は、単一のリポジトリ・イベントと関連付けられています。レンダリングを除き、すべてのリポジトリ操作は、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_VERSION.MakeVersioned()は複数回コールできますが、バージョン履歴は初回コール時のみ作成されます。それ以降のコールによる影響はなく、VersionControlイベントは発生しません。

リソースのバージョン履歴作成前

リソースの最初のバージョン作成後

簡単にするため、一般的にこのドキュメントでは、イベント型pre-link-inおよびpost-link-inの略記としてLinkInイベント型を参照するなど、リポジトリ・イベント・ペアの両方のメンバーを扱います。同様に、ここで使用するイベント型名は、JavaインタフェースXDBRepositoryEventListenerから接頭辞handlePreおよびhandlePostを削除して導出されたものです。

関連項目:

PL/SQLリポジトリ・イベント型は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

30.3 リポジトリ操作とイベント

異なる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を参照してください。

30.4 リポジトリ・イベント・ハンドラの考慮事項

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に関する項を参照してください。

- 起動者権限によるリポジトリ・イベント・ハンドラの定義の詳細は、「リポジトリ・イベントの構成」を参照してください

30.5 リポジトリ・イベントの構成

リソース構成ファイルでは、要素ResConfigの子である要素event-listenersを使用して、Oracle XML DBリポジトリ・イベント処理を構成します。

リポジトリ・リソースの他の処理を構成するように、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を使用してリポジトリ・イベント処理を構成します。

関連項目:

リポジトリ・リソースの構成の詳細は、 Oracle XML DBリポジトリの構成を参照してください。

30.5.1 構成要素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要素の順に実行時に処理されます。

30.5.2 構成要素listener

要素listenerは要素event-listenersの子で、個々のリポジトリ・イベント・リスナーを構成します。

各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およびconfigurationを参照してください。

- events: Render、Pre-Createなど一意のリポジトリ・イベント型名のシーケンスです。リスナーには、これらの型のリポジトリ・イベントのハンドラのみ有効化されています。可能なリポジトリ・イベント型のリストは、「可能なリポジトリ・イベント」を参照してください。要素eventsが存在しない場合、すべての型のリポジトリ・イベントのハンドラがリスナーに有効になり、無駄になります。重要性の低いリポジトリ・イベントのハンドラの起動を削減するため、要素eventsを提供します。

30.5.3 リポジトリ・イベント構成の例

リポジトリ・イベントの構成の例を示します。リソース構成ファイルにより、前提条件のあるJavaイベント・リスナーと前提条件のないPL/SQLイベント・リスナーが定義されます。例では、MIMEタイプに応じてリソースが分類されています。これには、リソース構成ファイルを作成するためのPL/SQLコードが含まれます。例では、JavaおよびPL/SQLでリスナーを実装します。

例30-1は、2つのイベント・リスナーを定義するリソース構成ファイルの内容を示しています。各リスナーは、Post-LinkIn、Post-UnlinkIn、およびPost-Update型のリポジトリ・イベントのハンドラを定義します。これは、前提条件、デフォルト言語(Java)およびデフォルトのデータベース・スキーマを定義します。

最初のリスナーのハンドラは、データベース・スキーマCMで定義されたJavaクラスoracle.cm.quotaに実装されています。これらのハンドラは、ContentType image/gifのリソース上のイベントに対してのみ起動されます。

2番目のリスナーのハンドラは、データベース・スキーマIFS(このリソース構成ファイルのデフォルトのスキーマ)で定義されたJavaクラスoracle.ifs.quotaに実装されています。これらのハンドラは、名前空間http://foo.xsdのifs-file型のリソース上のイベントに対してのみ起動されます。

関連項目:

要素defaultChildConfigおよびapplicationDataは、「構成要素defaultChildConfigおよびconfiguration」を参照してください

簡単なエンドツーエンドの説明として、リソースの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-3は、例30-2で構成されているイベント・ハンドラを実装するPL/SQLコードを示しています。Post-LinkInイベント・ハンドラは、eventObjectリソースへのリンクをリソースのMIMEタイプに応じて、フォルダ/public/app/XML-TXT、/public/app/IMG、/public/app/FOLDERのいずれかに作成します。Pre-UnlinkInイベント・ハンドラは、Post-LinkInイベント・ハンドラによって作成されたリンクを削除します。

関連項目:

- 新規PL/SQLパッケージDBMS_XDBRESOURCEの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- 新規PL/SQLパッケージDBMS_XEVENTの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

- PL/SQLパッケージDBMS_XDB_REPOSの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

Javaの例は次に示す2行を除き例30-2と同様に構成されます。この2行は要素を例30-2にある同じ名前と置換します。

<source>category</source>
<language>Java</language>

例30-4は、イベント・ハンドラを実装するJavaコードを示しています。ロジックは例30-3と同じです。

例30-5は、例30-3または例30-4で実装されているイベント・ハンドラの起動を示しています。

例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>

例30-2 前提条件のないPL/SQLイベント・リスナーのリソース構成ファイル

DECLARE
b BOOLEAN := FALSE;
BEGIN
b := DBMS_XDB_REPOS.createFolder('/public/resconfig');
b := DBMS_XDB_REPOS.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 イベント・リスナーを実装する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_REPOS.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_REPOS.link(ResPath, LinkFolder, ResDisplayName);
END;
END;
/

例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_REPOS.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_REPOS.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 イベント・ハンドラの起動

DECLARE
ret BOOLEAN;
BEGIN
ret := DBMS_XDB_REPOS.createResource('/public/res-app/res1.xml',
'<name>TestForEventType-1</name>');
END;
/
DECLARE
b BOOLEAN := FALSE;
dummy_data CLOB := 'AAA';
BEGIN
b := DBMS_XDB_REPOS.createResource('/public/res-app/res2.gif', dummy_data);
END;
/
DECLARE
b BOOLEAN := FALSE;
dummy_data CLOB := 'AAA';
BEGIN
b := DBMS_XDB_REPOS.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_REPOS.deleteResource('/public/res-app/res2.gif');
EXEC DBMS_XDB_REPOS.deleteResource('/public/res-app/res1.xml');
EXEC DBMS_XDB_REPOS.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は、JSR-170としてJavaコミュニティが開発した標準Java APIであるContent Repository API for Java (JCRとも呼ばれる)を実装します。Oracle XML DBリポジトリには、Oracle XML DB Content Connectorを使用してアクセスできます。

- Content Repository API for Java(JCR)について

- Oracle XML DB Content Connectorについて

- JCRで公開されるOracle XML DBリポジトリ

- Oracle XML DB Content ConnectorのCLASSPATH

- JCRリポジトリ・オブジェクトの取得

- Oracle XML DB Content Connectorを使用してリポジトリにファイルをアップロードするためのJavaコード

- 追加のJCRコード例

- Oracle XML DB Content Connectorでの標準JavaロギングAPIの使用

- サポートされているJCRコンプライアンス・レベル

- Oracle XML DB Content Connectorの制限

- XML SchemaとJCR

31.1 Content Repository API for Java(JCR)について

JCR 1.0は、アプリケーションがコンテンツ・リポジトリと対話するための標準Java APIを定義します。コンテンツ・リポジトリは、ノードのツリーであり、各ノードは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にマップされます。

関連項目:

Java Community Processの『Content Repository for Java technology API』、http://jcp.org/en/jsr/detail?id=170。第4章(JSR-170の仕様)でJCR 1.0の簡単な概要を説明しています。

31.2 Oracle XML DB Content Connectorについて

Oracle XML DB Content Connectorでは、JCR 1.0 Javaを使用してOracle XML DBリポジトリにアクセスできます。アプリケーションは、スタンドアロンJava仮想マシン(JVM)またはJ2EEコンテナのいずれかで動作できます。このリポジトリのファイルおよびフォルダは、JCRノード(およびそれらのノードのプロパティ)として表されます。

JCR APIを使用して、リポジトリ・ファイルおよびフォルダを作成、取得および更新できます。

注意:

Oracle XML DB Content ConnectorをデータベースOracle JVM(データベース・プロセス内で使用可能なJava仮想マシン)で使用できません。データベース層でContent Connectorを使用するには、スタンドアロンJava仮想マシンまたはJ2EEコンテナのいずれかを使用する必要があります。

31.3 JCRで公開されるOracle XML DBリポジトリ

Oracle XML DB Content Connectorは、Oracle XML DBリポジトリのデータをJCRノードおよびプロパティとして表します。ファイルおよびフォルダは、それぞれ型がnt:fileとnt:folderのノードとして表されます。そのコンテンツとメタデータは、ノード型がnt:resourceのノードとして公開されます。

31.3.1 JCRでのファイルおよびフォルダの公開

JCRからの表示方法を示しつつ、2つのファイルを含むリポジトリ・フォルダの例を示しています。

フォルダ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"

31.3.2 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によってすべてのファイルとフォルダにアクセスできます。

31.3.3 バイナリ・コンテンツおよびXMLコンテンツ

プロパティjcr:dataにはファイルのバイナリ・コンテンツが入っています。nt:fileではなく、子ノード(jcr:content)のプロパティです。XMLコンテンツを含むファイルの場合、jcr:contentは子ノード(ojcr:xmlContent)を持っており、その下にあるXMLコンテンツは一組のJCRノードおよびプロパティとしてアクセスできます。

例31-1で参照されるファイルAddress.xmlがこのようなファイルに該当します。リポジトリのXMLファイルのXMLコンテンツは、JCRで定義されたドキュメント・ビュー・シリアライズを使用してJCRノードとプロパティにマップされます。その場合、次のようになります。

- XML要素は、JCRノードとして公開されます。

- XML属性は、JCRプロパティとして公開されます。

- XMLテキストは、jcr:xmltextというノード内のjcr:xmlcharactersというJCRプロパティとして公開されます。

31.3.4 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

31.3.5 JCRにマップされたユーザー定義のメタデータ

ユーザー定義の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

31.3.6 JCRとリポジトリのハード・リンクと弱いリンク

JCRでは、各ノードまたはプロパティは1つの親を持っているので(何も持たないルート・ノードを除く)、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: その親の子ファイルまたはフォルダの名前

31.4 Oracle XML DB Content ConnectorのCLASSPATH

Oracle XML DB Content Connectorでは、環境変数CLASSPATHに特定のエントリが必要です。

- $ORACLE_HOME/lib/jcr-1.0.jar

- $ORACLE_HOME/lib/ojcr.jar

- $ORACLE_HOME/lib/xmlparserv2.jar

- $ORACLE_HOME/jlib/xquery.jar

31.5 JCRリポジトリ・オブジェクトの取得

Oracle XML DB Content Connectorでは、oracle.jcr.OracleRepositoryは、JCRリポジトリへのエントリ・ポイントとなるJCRインタフェースjavax.jcr.Repositoryを実装します。これを使用して、Oracle XML DBリポジトリのリポジトリ・オブジェクトを取得できます。

例31-2のコード・フラグメントは、これを示しています。

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-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);

31.6 Oracle XML DB Content Connectorを使用してリポジトリにファイルをアップロードするためのJavaコード

Oracle XML DB Content Connectorを使用して、ローカルのファイル・システムからOracle XML DBリポジトリにファイルをアップロードできます。

例31-3は、これを示すJavaプログラムです。コマンドラインからこれをコンパイルおよび実行できます。プログラムには、次のようなコマンドライン引数が必要です。

- JDBCデータベースURL

- ユーザーID

- ユーザー・パスワード

- ファイルをアップロードするOracle XML DBリポジトリのフォルダ

- アップロードするファイル

- MIMEタイプ

例31-4に、これを示します。

例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-4 コマンドラインを使用したファイルのアップロード

export CLASSPATH=.:$ORACLE_HOME/lib/jcr-1.0.jar:$ORACLE_HOME/lib/ojcr.jar:Foot 1
$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

31.7 追加のJCRコード例

追加のJCRコード例は、$ORACLE_HOME/xdk/demo/java/jcrで入手できます。コード・サンプルごとに、READMEファイルにその目的および使用方法が記述されています。

31.8 Oracle XML DB Content Connectorでの標準JavaロギングAPIの使用

Oracle XML DB Content Connectorは標準のjava.util.loggingフレームワークを使用します。そのフレームワークにより提供されたロギングAPIを使用して、ロギング動作を制御できます。

たとえば、次のJavaコード・フラグメントはすべてのロギングを無効にします。

import java.util.logging.LogManager;
...
LogManager.getLogManager().reset();

31.9 サポートされているJCRコンプライアンス・レベル

JCRバージョン1.0を定義するJSR-170標準では、2つのコンプライアンス・レベルと一連のオプション機能が定義されています。Oracle XML DB Content Connectorでは、レベル1(読取り機能)とレベル2(書込み機能)がサポートされています。

31.10 Oracle XML DB Content Connectorの制限

Oracle XML DB Content Connectorには特定の制限事項が適用されます。

31.10.1 デフォルトのワークスペース名

単一のワークスペースがサポートされています。javax.jcr.Repositoryのlogin(Credentials, String)メソッドまたはlogin(String)メソッドをコールする場合は、ワークスペース名を必ず空の文字列("")またはNULLにしてください。

31.10.2 特定のノード型に制限された操作

javax.jcr.Itemのメソッドsave()およびrefresh()は、型がnt:fileまたはnt:folderのノードでのみコールできます。または、javax.jcr.Sessionのメソッドmove()およびjavax.jcr.Workspaceのメソッドcopy()およびmove()は、ノードnt:fileおよびnt:folderでのみコールできます。

31.10.3 ファイルとフォルダの状態

ファイルまたはフォルダの状態を戻すjavax.jcr.Itemのメソッドには、特定の制約事項があります。

のメソッドisNew()およびisModified()は、項目自体ではなく、項目を含むファイルまたはフォルダの状態を戻します。メソッドisNew()は、ファイルまたはフォルダがJCR一時レイヤーで作成されているが保存されていない場合にtrueを戻します。メソッドisModified()は、ファイルまたはフォルダがJCR一時レイヤーで変更されているが保存されていない場合にtrueを戻します。

31.10.4 バイナリ・コンテンツとXMLコンテンツの間の相互作用

プロパティjcr:dataにはファイルのバイナリ形式のコンテンツが入っています。ファイル・コンテンツがXMLの場合、そのXMLコンテンツがJCRノードおよびプロパティとして公開されている場所にojcr:xmlContentノードも存在します。

ojcr:xmlContentサブツリーへの変更は、それらの変更が保存されるまでjcr:dataプロパティに反映されません。jcr:dataプロパティとojcr:xmlContentサブツリーの両方を変更した場合、それらの変更が保存されるとojcr:xmlContentサブツリーが優先されます。

31.10.5 変更の保存順

クラスjavax.jcr.Sessionまたはクラスjavax.jcr.Itemのsaveメソッドは、一時レイヤーで行われた変更を保存します。1つ以上のノードまたはプロパティが変更されている場合、JCRは変更の格納順を指定しません。Oracle XML DB Content Connectorは、変更を次の順序で保存します。

1. 既存のファイルとフォルダに、パスでソートされた順序で更新を適用します。

2. 新しいファイルとフォルダを、パスでソートされた順序で作成します。

3. 既存のファイルとフォルダを、パスでソートされた順序の逆順で移動します。

4. 既存のファイルとフォルダを、パスでソートされた順序の逆順で削除します。

31.10.6 未定義のプロパティ

型UNDEFINEDの定義を持つプロパティは、STRING値として格納されます。

31.10.7 ノード型nt:baseは抽象

ノード型nt:baseは抽象で、新しいノードの型としては指定できません。

31.10.8 自動作成されるノードjcr:content

型がnt:fileまたはnt:folderのノードを作成する場合、jcr:contentノードが子として自動的に作成されます。

31.10.9 jcr:xmltextノードは保存時に結合される

保存すると、連続したjcr:xmltextノードが単一jcr:xmltextノードの中に結合されます。このノードはXMLコンテンツまたはユーザー定義メタデータ内のテキストを表します。

31.10.10 ノード型mix:referenceable

ノード型nt:file、nt:folderおよびnt:resourceは、ミックスインノード型mix:referenceableのサブタイプです。現在、すべてのnt:file、nt:folderおよびnt:resourceノードは、UUIDで参照できます。mix:referenceableはどんな型のノードにも追加できません。

31.10.11 JCRと併用するための全文索引

PL/SQLパッケージDBMS_XDBT使用して、ファイル・コンテンツ上に全文索引を作成することができます。これにより、問合せで関数jcr:containsをjcr:contentノードのプロパティjcr:dataに適用することができます。他のプロパティ上での全文索引はサポートされません。

31.11 XML SchemaとJCR

Oracle XML DB Content ConnectorはXML SchemaからJCRノード型を作成できます。

31.11.1 JCRで使用する場合にXML Schemaを登録する理由

Oracle XML DB Content ConnectorによりXML SchemaをJCRで使用できるよう登録できます。これによりContent Connectorは、XML Schema単純型、複合型、グローバルな要素宣言の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でメタデータにアクセスしたり、型指定したりすることはできません。

ただし、JCRで使用するためにXMLスキーマを登録すると、コンテンツ・コネクタはXMLスキーマにXML Schema単純型、複合型、およびグローバル要素宣言のJCRノード・タイプを生成します。

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のコンテンツは、例31-6で示すXML Schemaに関して有効です。

最初は、このXML SchemaはJCRで使用できるように登録されていません。XMLコンテンツを表すJCRノードおよびプロパティは、例31-7に示されています。

XML SchemaはJCRで使用できるように登録されています。JCRノードおよびプロパティは例31-8に示されています。

ノードAddressのノード型はUSAddressです。同様に、ノードname、street、city、およびstateのノード型はxsd:stringです。ノードzipのノード型はxsd:longで、その子であるjcr:xmltextのjcr:xmlcharactersプロパティのプロパティ型はLONGです。

関連項目:

ユーザー定義のリポジトリ・メタデータ

例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-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>

例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)

例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)

31.11.2 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で使用できるよう登録します。

注意:

グローバルに登録されたXML Schema(local=>false)のみJCRで使用できます。

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を登録する方法は、「Oracle XML DBへのXML Schemaの登録」を参照してください。

- JavaメソッドregisterXMLSchema()の詳細は、『Oracle Database XML Java API Reference』、パッケージoracle.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;
/

例31-10 JCRで使用するためのXML Schemaの登録

import oracle.jcr.nodetype.OracleNodeTypeManager;...
OracleNodeTypeManager ntm = (OracleNodeTypeManager)
session.getWorkspace().getNodeTypeManager();

ntm.registerXMLSchema("http://www.example.com/Address", null);

31.11.3 XML SchemaからのJCRノード型の生成方法

Oracle XML DB Content Connectorは、JCRで使用できるよう登録されているXML SchemaからJCRノード型を生成します。

JCRおよびXML Schemaの型モデルは似ていますが、同じではありません。XML Schemaには、JCRで表現されない側面もあります。たとえば、XML Schema単純型の制約ファセットの中にはJCRから検出できないものもあります。そうした場合でも、それらはOracle XML DB Content Connectorにより適用されます。

一般的には、XML Schemaから生成されたJCRノード型は、JCRや他のインタフェース関係なく、そのXML Schemaに準拠するXMLデータが作成または更新されるときに実行されるXML Schema検証を補強したり、損ったり、変更することはありません。

31.11.3.1 JCRおよびXML Schemaの組込み単純型

JCRノード型はXML Schema組込み型ごとに提供されています。たとえば、JCRノード型xsd:decimalはXMLスキーマ組込み型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で表現されます。

31.11.3.2 JCRとXML Schemaで定義される単純型

JCRノード型はXML Schemaで定義された単純型ごとに作成されます。JCRノード型の継承階層は、XML Schema型の継承階層に従います。

リスト単位で派生した単純型は、複数値のJCRプロパティ定義により表現されます。

共用体単位で派生した単純型は、プロパティ型がUNDEFINEDのJCRプロパティ定義により表現されます。

無名単純型に対応するJCRノード型には、統合名anonymousNodeType#sequenceNumberがあります。アプリケーションは統合名に応じて決まるものではありません。統合名はセッション間で同じであることが保証されず、JCRで使用するためにXML Schemaが登録または未登録の、登録XML Schemaの定義が変更されたりするときに変更される可能性があります。

31.11.3.3 JCRと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の定義が変更されたりするときに変更される可能性があります。

31.11.3.4 JCRおよびグローバルXML要素宣言

JCRノード型はXML Schemaのグローバルな要素宣言ごとに作成されます。生成されたノード型のローカル名は、アンダースコア(_)をグローバルな要素宣言のローカル名の先頭に追加して作成されます。たとえば、名前空間修飾発注書XML Schemaでは、po:_purchaseOrderというノード型はpo:purchaseOrderというグローバル要素について作成されます。

脚注の凡例

脚注1:
この文は、説明のために2行に分割されています。

32 JavaでのOracle XML DBアプリケーションのガイドライン

JavaでOracle XML DBアプリケーションを作成する場合の設計のガイドラインを示します。これには、Oracle XML DBのJavaサーブレットを作成および構成するためのガイドラインが含まれます。

- Oracle XML DBのJavaアプリケーションの概要

- HTTP(S): JavaサーブレットへのアクセスまたはXMLTypeリソースへの直接アクセス

- JDBC XMLTypeサポートを使用した多数のXMLTypeオブジェクト要素へのアクセス

- サーブレットを使用したデータの操作およびXMLとしての迅速な書込み

- Oracle XML DBのJavaサーブレットのサポートの制限

- Oracle XML DBサーブレットの構成

- Oracle XML DBサーブレットに対するHTTPリクエストの処理

- セッション・プールおよびOracle XML DBサーブレット

- ネイティブなXMLストリームのサポート

- Oracle XML DBサーブレットのAPI

- Oracle XML DBサーブレットの例

32.1 Oracle XML DBのJavaアプリケーションの概要

Javaコードは、JDBC用のOCIドライバを使用してクライアント・サーバーかアプリケーション・サーバーで、またはJava仮想マシン(JVM)で使用できます。

データベース内のJavaは、データベース・サーバー・プロセスのコンテキストで実行されるため、Javaコードをデプロイする方法は、次のいずれかに制限されます。

- SQLまたはPL/SQLから起動するストアド・プロシージャとしてJavaコードを実行できます。

- Javaサーブレットを実行できます。

ストアド・プロシージャは、SQLコードおよびPL/SQLコードと簡単に統合できます。Oracle DatabaseにアクセスするプロトコルとしてOracle Net Servicesを使用する必要があります。

サーブレットは、Oracle Databaseへの最上位のエントリ・ポイントとしてより適切に機能し、Oracle DatabaseにアクセスするプロトコルとしてHTTP(S)を使用する必要があります。

すべてのOracle XML DB Application Program Interface (API) for Javaは、サーバー内とデータベース外の両方で実行するアプリケーションで使用できます。

これらのAPIには次のものが含まれます。

- XMLTypeに対するJDBCのサポート

- XMLTypeクラス

- Java DOMインプリメンテーション

32.2 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キャッシュが最も効率的です。

32.3 JDBC XMLTypeサポートを使用した多数のXMLTypeオブジェクト要素へのアクセス

ダウンストリーム・クライアントが、JavaプログラムによってXMLTypeインスタンスの多く、またはほとんどの要素にアクセスするアプリケーションである場合は、最適なパフォーマンスのためにJDBC XMLTypeサポートを使用します。また、Javaプログラムのデバッグは、通常、データベース・サーバーの外部で行う方が簡単です。

32.4 サーブレットを使用したデータの操作およびXMLとしての迅速な書込み

Oracle XML DBサーブレットは、エンドユーザーのためにHTMLページをフォーマットするのではなく、データベースにアクセスし、データを操作して、これをXMLとして迅速に書き込むアプリケーションに最適です。

サーブレットは、HTTP(S)を使用してアクセス可能なHTTPストアド・プロシージャをJavaで作成するためのものです。インターネット・アプリケーション全体を開発する必要がある場合は、アプリケーション・サーブレットをOracle Fusion Middlewareにデプロイし、JDBCを使用するか、またはjava.net.*などのAPIを使用してこのサーブレットでデータベースのデータにアクセスします。

32.5 Oracle XML DBのJavaサーブレットのサポートの制限

Oracle XML DBプロトコル・サーバーは、FTP、HTTP 1.1、WebDAVおよびJavaサーブレットをサポートします。これは、Javaサーブレットのバージョン2.2をサポートしますが、いくつかの例外があります。

Javaサーブレットのバージョン2.2のサポートには、次の制限があります。

- サーブレットのWARファイル(web.xml)はサポートされません。手動で操作する必要があるweb.xml構成パラメータが存在します。たとえば、ロールの作成は、SQL CREATE ROLEコマンドを使用して行う必要があります。

- RequestDispatcherおよび関連付けられたメソッドはサポートされません。

- HTTPServletRequest.getCookies()メソッドはサポートされません。

- 現在、1つのServletContext (および1つのweb-app)のみがサポートされています。

- ステートフル・サーブレット(およびHttpSessionクラスのメソッド)は、サポートされません。サーブレットは、データベース自体の状態を保持する必要があります。

32.6 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ファイルの構成の詳細は、 Oracle XML DBの管理を参照してください。

32.7 Oracle XML DBサーブレットに対するHTTPリクエストの処理

Oracle XML DBでのHTTPリクエストの処理について説明します。

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エラーが発生した場合、セッションはセッション・プールに戻されます。

関連項目:

プロトコルを使用したリポジトリへのアクセス

32.8 セッション・プールおよびOracle XML DBサーブレット

Oracle Databaseは、データベース・セッションごとに1つのJava仮想マシン(VM)を使用します。セッション・プールから再利用されるセッションは、セッションが最後に使用されてからは、JVM(Java静的変数)内でどのような状態も保持します。

これは、メタデータなど、ユーザー固有でないJava状態をキャッシュする場合に有効ですが、保護ユーザーのデータはJava静的メモリーに格納しないでください。保護ユーザーのデータをJava静的メモリーに格納した場合、アプリケーションによってセキュリティ・ホールが出現する可能性があります。

32.9 ネイティブなXMLストリームのサポート

Javaノード・クラスDOMには、Oracle固有のメソッドwrite()があり、これによってネイティブなXMLストリームのサポートが提供されます。

Javaメソッドwrite()は、次の引数を取り、voidを戻します。

- java.io.OutputStreamストリーム: XMLテキストの書き込み先Javaストリーム。

- String charEncoding: XMLテキストを書き込むキャラクタ・エンコーディング。NULLの場合、データベース・キャラクタ・セットが使用されます。

- Short indent: ネストしたXML要素のインデントの文字数。

ストリームがデータベース内部で提供されるServletOutputStreamである場合、メソッドwrite()には、ショートカットが実装されます。ノードのコンテンツは、出力ソケットにネイティブなコードのXMLデータで直接書き込まれます。これによって、JavaオブジェクトまたはUnicode(Java文字列に必要),との間の変換が回避され、パフォーマンスが向上します。

32.10 Oracle XML DBサーブレットのAPI

Oracle XML DBサーブレットでサポートされているAPIについて説明します。これらは、Javaサーブレット2.2仕様で定義されます。

これに対するJavadocは、http://download.oracle.com/javaee/1.2.1/api/index.htmlで入手できます。

表32-2に、未実装のJavaサーブレット2.2メソッドをリストします。実行時に例外が発生します。

表32-2 未実装のJavaサーブレット2.2メソッド

インタフェース

未実装のメソッド

HttpServletRequest

getSession()、isRequestedSessionIdValid()

HttpSession

all

HttpSessionBindingListener

all

32.11 Oracle XML DBサーブレットの例

例に、ファイル・リソースの内容を出力する単純なOracle XML DBサーブレットの定義、およびそのサーブレットを登録およびマップする方法を示します。

例32-1に示すサーブレットは、ファイル・リソース/public/test/foo1.textの内容を出力します。

サーブレットをインストールするには、サーブレットをコンパイルしてからOracle Databaseにロードします。

% loadjava –grant public –u quine/curry –r test.class

最後に、例32-2に示すようにサーブレットを登録してマップし、URLと関連付けます。

例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(); }}}

例32-2 Oracle XML DBサーブレットの登録およびマッピング

EXEC DBMS_XDB_CONFIG.addServlet('TestServletFoo', 'Java', 'TestServletFoo',
NULL, NULL, 'test', NULL, NULL, 'XDB');

EXEC DBMS_XDB_CONFIG.addServletMapping('/public/test/foo1.txt', 'TestServletFoo');

COMMIT;

33 URIを使用したデータ・アクセス

URIを生成してデータベースに格納し、これらを使用して、ターゲットとするデータベース・データを取得できます。この方法を使用できるURIには、DBUri、XDBUriおよびHTTPUriの3種類があります。

- Oracle XML DB URLの機能の概要

- URIとURL

- URITypeとそのサブタイプ

- URITypeインスタンスを使用したデータ・アクセス

- XDBUris: リポジトリ・リソースへのポインタ

- DBUris: データベース・データへのポインタ

- パッケージURIFACTORYを使用したURITypeの新しいサブタイプの作成

- SYS_DBURIGEN SQL関数

- DBUriServlet

33.1 Oracle XML DB URIの機能の概要

URIをインダイレクション・メカニズムとして使用してデータベース・データにアクセスしたり、データベース・データをターゲットとするURIを使用してXML文書を生成することができます。

- インダイレクション・メカニズムとしてのパスの使用: パスをデータベースに格納して、そのパスを参照することによって間接的にターゲットにアクセスすることができます。パスの種類としては、様々な種類のUniform Resource Identifier(URI)を使用できます。

- そのターゲット・データベース・データを使用したXML文書の生成: インダイレクションで特に使用できるURIの1つの種類であるDBUriは、データベース・データへのアドレッシングで使用できる便利なXPath表記法を提供します。DBUriを使用して、データベース・データを含み、データベースの構造を反映した構造を持つXML文書を構成できます。

33.2 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を参照してください。

33.3 URITypeとそのサブタイプ

様々な種類のパスをデータベース・オブジェクトとして表現できます。これらは、サーバーの内外に格納されたデータへの統一アクセスを提供するため、これらを使用することで、XML文書内のURIをデータベース列にマッピングし、文書が、リレーショナル列に格納されているデータを参照して外部に公開できるようになります。

使用可能なパス・オブジェクト型は、HTTPURIType、DBURITypeおよびXDBURITypeで、これらはすべて抽象オブジェクト型URITypeから導出されます。

- 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を表します。PL/SQLコンストラクタ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の新しいサブタイプの作成」を参照してください。

- XMLTypeデータの索引

33.3.1 DBUriおよびXDBUriの概要

DBUriおよびXDBUriの重要な用途は、WebページからXSLTスタイルシートを参照したり、データベース表またはリポジトリ・フォルダのデータをSQLを使用しないで参照したり、Webサーバーをバイパスすることによってパフォーマンスを向上させることです。

- データベースから生成されたWebページ内でXSLTスタイルシートを参照できます。PL/SQLパッケージDBMS_METADATAでは、DBUriを使用してXSLTスタイルシートを参照できます。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パッケージ」

33.3.2 URIType PL/SQLメソッド

抽象オブジェクト型URITypeに含まれているPL/SQLメソッドを、その各サブタイプで使用できます。これらの各メソッドは、任意のサブタイプによってオーバーライドできます。

表33-1にURITypeのPL/SQLメソッドのリストを示します。さらに、各サブタイプには、サブタイプと同名のコンストラクタが含まれます。

表33-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サブタイプのいずれかのインスタンスを構成します。

関連項目:

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

33.3.2.1 HTTPURIType PL/SQLメソッドGETCONTENTTYPE()

HTTPURIType PL/SQLメソッドgetContentType()は、ターゲット文書に関するMIME情報を戻します。この情報を使用して、文書をBLOBインスタンスとCLOBインスタンスのどちらで取得するかを判断できます。

たとえば、MIMEタイプx/jpegのWebページをBLOBインスタンスとして処理し、MIMEタイプtext/plainまたはtext/htmlのWebページをCLOBインスタンスとして処理できます。

例33-1では、データをCLOBインスタンスとBLOBインスタンスのいずれで取得するかを判断するためにHTTPコンテンツ・タイプがテストされています。コンテンツ・タイプ・データはHTTPURITypeの場合はHTTPヘッダー、DBURITypeの場合はデータベース列のメタデータです。

例33-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

33.3.2.2 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()

33.3.2.3 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>

33.3.2.4 DBURIType PL/SQLメソッドGETBLOB()

BLOB列をターゲットとするDBUriに適用されると、PL/SQLメソッド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値が、データベースのキャラクタ・セットで戻されます。

33.4 URITypeインスタンスを使用したデータ・アクセス

URITypeサブタイプのインスタンスをインダイレクションに使用するには、そのようなインスタンスをデータベースに格納し、getCLOB()などのPL/SQLメソッドを使用して問い合せてターゲットのデータを取得します。

データベース列を作成するには、URITypeまたはそのサブタイプのいずれかを使用するか、各URIのテキストのみを文字列として格納し、その後、URIへのアクセスがあったときに、必要なURITypeインスタンスをオン・デマンドで作成します。様々なURITypeサブタイプのオブジェクトを、同一のURIType データベース列に格納できます。

URITypeサブタイプから継承した独自のオブジェクト型を定義することもできます。新しい型を導出すると、カスタムのテクニックを使用してデータを取得、変換、またはフィルタリングできます。

関連項目:

- 新しいURITypeサブタイプの定義の詳細は、「パッケージURIFACTORYを使用したURITypeの新しいサブタイプの作成」を参照してください。

- XMLデータの変換の詳細は、「XSL変換とOracle XML DB」を参照してください。

例33-2は、HTTPUriおよびDBUri (URITypeサブタイプHTTPURITypeおよびDBURITypeのインスタンス)を、同じデータベース列(URIType型)に格納しています。問合せは、各URIが指しているデータを取得します。最初のURIはWebページのURLです。2番目のURIは標準データベース・スキーマHRの表employees内のデータを参照しています(説明を簡潔にするため、Webページの最初の部分のみを示しています)。

URIType PL/SQLメソッドcreateURI()を使用するには、使用する特定のURITypeサブタイプを把握している必要があります。パッケージURIFACTORYのPL/SQLメソッドgetURI()を使用すると、かわりに遅延バインディングを使用して、実行時に特定の型情報を決定できます。

PL/SQLファクトリ・メソッドURIFACTORY.getURI()は、引数としてURI文字列をとります。適切なサブタイプ(HTTPURIType、DBURITypeまたはXDBURIType)のURITypeインスタンスを、URI文字列の形式に基づいて戻します。

- URIの先頭がhttp://の場合、getURI()はHTTPUriを作成して戻します。

- URIの先頭が/oradb/または/dburi/の場合、getURI()はDBUriを作成して戻します。

- それ以外の場合はgetURI()はXDBUriを作成して戻します。

しかし、例33-3は例33-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ホームページを使用しています。

例33-3では、getURI()に渡されるURI文字列はハードコードされていますが、これをアプリケーションが実行時に取得する文字列値にすることも非常に簡単に可能です。

例33-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.

例33-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.

33.5 XDBUris: リポジトリ・リソースへのポインタ

XDBURITypeは、URIを使用してOracle XML DBリポジトリのリソースを公開するURITypeのサブタイプです。オブジェクト型XDBURITypeのインスタンスはXDBUrisと呼ばれます。

33.5.1 XDBUri URIの構文

XDBUri URIのURL部分は、ターゲットのリポジトリ・リソースの階層アドレスです。XPath式ではなく、リポジトリ・パスです。URIのオプションのフラグメント部分(シャープ記号(#)の後)は、XPath構文を使用してXML文書の部分をターゲットにします。

URIのオプションのフラグメント部分が適切なのは、ターゲットのリソースが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になります。

33.5.2 XDBUriの使用: 例

ここで示すXDBUriの例では、表のURIを使用してリポジトリ・リソースにアクセスし、PL/SQLメソッドgetXMLを使用してXML文書を問い合せおよび取得します。

例33-4では、XDBUriを作成して、値を発注書表に挿入し、すべての発注書を選択します。URIFACTORY.getURI()に渡されるURIに特別な接頭辞が付いていないため、作成されるURITypeインスタンスはXDBUriになります。

PL/SQLメソッドgetXML()はXMLTypeインスタンスを戻すため、これをXMLQueryなどのSQL/XML関数とともに使用できます。例33-5の問合せに、これを示します。この問合せは、番号が999のすべての発注書を取得します。

例33-4 XDBUriを使用した、URIによるリポジトリ・リソースへのアクセス

DECLARE
res BOOLEAN;
postring VARCHAR2(100):= '<?xml version="1.0"?>
<ROW>
<PO>999</PO>
</ROW>';
BEGIN
res:=DBMS_XDB_REPOS.createFolder('/public/orders/');
res:=DBMS_XDB_REPOS.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.

例33-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.

33.6 DBUris: データベース・データへのポインタ

DBUriは、データベース・データをターゲットとするURIです。URITypeサブタイプのすべてのインスタンスに関して、DBUriはデータへの間接アクセスを提供します。また、DBURITypeにより、XPathを使用してデータベース・データをアドレッシングして、DBUriのターゲットとなるデータベース・データが含まれ、データベースの構造が反映されたXML文書を構成することもできます。

- 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」を参照してください。

33.6.1 XMLデータ形式でのデータベース表示

DBURITypeを使用すると、ユーザーがアクセスできるデータベース部分のXMLビューを持つことができ、 XMLデータ形式で表示されます。この方法でビジュアル化されたデータベース・データはXML要素で効率的に囲まれており、1つまたはそれ以上のXML文書が結果として生成されます。

アクセスできるデータベース・スキーマは、アクセス権限を付与されているデータベース・スキーマのみです。データベースのこの部分が、データベースのユーザー独自のビューとなります。これは、XMLで格納されているデータだけでなく、すべての種類のデータベース・データに適用されます。

この種の「XMLビュー」は、技術的な意味ではデータベース・ビューではありません。ここで「ビュー」と呼ばれているものは、DBURITypeの理解に有効な抽象的な観点を示すものにすぎません。DBURITypeを、データベースをXMLデータ同様にビジュアル化し、アクセスを提供するものとみなすことができます。

ただし、DBURITypeは、ビジュアル化を実行し、データベース・データへの別個のアクセス手段を提供するだけのものではありません。各「XMLビュー」はXML文書として実現されます。つまり、DBURITypeを使用すると、データベース・データを基にしてXML文書を生成できます。

以上はすべて、DBURIType ではXPath表記法を使用して(1)アクセス権限のある任意のデータベース・データのアドレッシングとアクセス、および(2)データのXML表現の構成を行うことができるということです。

図33-1はリレーショナル表HR.employees、その表の一部に対応するXMLビュー、および対応するDBUri URI(簡素化されたXPath式)の間の関係を示しています。この場合、XMLとして公開されるデータの部分は、employee_idが200である行となります。URIを使用してデータにアクセスし、「XMLビュー」を反映するXML文書を構成することができます。

図33-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を生成する他の方法は、 リレーショナル・データからのXMLデータの生成を参照してください。

33.6.2 DBUri URIの構文

XPath式は、1つ以上のノードをアドレッシングする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を参照してください。

33.6.3 データベースおよびセッションを有効範囲とするDBUri

DBUriの有効範囲は指定されたデータベース・セッションなので、セッションのコンテキスト(接続しているユーザーおよびユーザーが持っている権限)に応じて、同じDBUriで同じ問合せでも結果が異なります。

データベースのXML「ビュー」のコンテンツ、つまり構成可能なXML文書のコンテンツは、指定された時点で特定のデータベース・データにアクセスするために持っている権限を反映しています。

少し複雑になりますが、データベース・スキーマ修飾がなくてもデータベース・データにアクセスできるXML要素PUBLICもあります。これは便利な機能ですが、混乱を招くこともあります。指定ユーザー用のデータベースのXMLビューが、そのユーザーが指定時点でデータベースに対して持っている特定のアクセス権限に依存していることを忘れないでください。

XML要素PUBLICはパブリック・シノニムの使用に対応しています。たとえば、ユーザーquineが問合せを実行する場合、次の問合せは、データベース・スキーマquineの下の表 fooを一致させようと試みますが、そのような表がない場合は、fooという名前のバブリック・シノニムを一致させようとします。

SELECT * FROM foo;

同様に、XML要素PUBLICは、指定のユーザーに表示されるすべてのデータベース・データと、パブリック・シノニムを介してそのユーザーに表示されるすべてのデータを含みます。このため、同一のDBUri URI /PUBLIC/FOOが、ユーザーquineが接続している場合はquine.fooと解決され、ユーザーcurryが接続している場合はcurry.fooと解決されます。

33.6.4 DBUriの使用 - 例

DBUriが識別できるのは、表、行、行内の列、オブジェクト列の属性のいずれかです。ここでの例は、別のオブジェクト型をターゲットにする方法を示しています。

33.6.4.1 DBUriを使用した表のターゲット化

例では、完全な表をターゲットにするDBUriを使用します。表のコンテンツに対応するXML文書が戻されます。最上位のXML要素の名前は表により決まります。各行の値はROW要素で囲まれます。

例33-6を参照してください。この構文を使用して、完全なデータベース表をターゲットにします。

/database_schema/table

例33-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.

33.6.4.2 DBUriを使用した表内の行のターゲット化

例では、表の中の1行をターゲットにするDBUriを使用します。XPath述語式は、従業員番号200に対応する、表の1行を識別します。結果は、ROWを最上位要素とするXML文書です。

例33-7を参照してください。この構文を使用して、表の特定の1行または複数の行をターゲットにします。

/database_schema/table/ROW[predicate_expression]

例33-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.

33.6.4.3 DBUriを使用した列のターゲット化

特定の列、オブジェクト列の特定の属性または属性が特定の値を持つオブジェクト列をターゲットにできます。例は、これらの可能性を示しています。

この構文を使用して、特定の列をターゲットにできます。

/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

例33-8では、例33-7と同じ従業員について、列last_nameをターゲットするDBUriを使用します。最上位のXML要素の名前はターゲット列により決まります。

例33-9では、cityおよびpostal code属性が特定の値になっているCUST_ADDRESSオブジェクト列をターゲットとするDBUriを使用します。最上位のXML要素には列の名前が付けられ、オブジェクト属性それぞれに対応する子要素が含まれます。

例33-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.

例33-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を値に持つオブジェクトを識別します。

33.6.4.4 DBUriを使用した列のテキスト値の取得

多くの場合、囲みタグを取り出さずに、列のテキスト値のみを取り出す方が有効です。たとえば、XSLTスタイルシートがCLOB列に格納されている場合は、文書を列名のタグで囲まなくても、その文書を取り出すことができます。このことの例を示します。

この場合は、text() XPathノード・テストを使用できます。ノードのテキスト値のみを取り出すように指定できます。次の構文を使用します。

/oradb/database_schema/table/ROW[predicate_expression]/column/text()

例33-10は、従業員番号200の従業員のlast_name列のテキスト値を、XMLタグなしで取得します。

例33-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.

33.6.4.5 DBUriを使用したコレクションのターゲット化

Ordered Collection Table (OCT)など、データベース・コレクションをターゲットにできます。ただし、コレクション全体をターゲットにする必要があります。個別のメンバーはターゲットにできません。

コレクションがターゲット化されると、DBUriにより生成されたXML文書には、各コレクションの全メンバーがそれぞれ、コレクションの型に対応する名前の要素で囲まれたXML要素として含まれます。

例33-11では、数値のコレクションをターゲット化するDBUriを使用します。最上位のXML要素はコレクションの名前が付けられ、その子はコレクションの型(NUMBER)の名前が付けられます。

例33-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.

33.7 パッケージURIFACTORYを使用したURITypeの新しいサブタイプの作成

特定のプロトコルに対応するURITypeの独自のサブタイプを定義できます。PL/SQLパッケージURIFACTORYを使用すると、URITypeインスタンスのURIを取得したり、URI文字列の文字のエスケープを追加または削除したり、特定のURLを処理するためのタイプ名を登録または登録解除することができます。

他のPL/SQLメソッドを表33-2にリストします。

表33-2 URIFACTORY PL/SQLメソッド

PL/SQLメソッド

説明

getURI()

URITypeインスタンスのURIを戻します。

escapeURI()

URIで許容されない文字を同等のエスケープ・シーケンスに置換することによって、URI文字列をエスケープします。

unescapeURI()

指定のURIからエスケープを削除します。

registerURLHandler()

特定のURLを処理するための特定の型名を登録します。その型のインスタンスを生成するためにgetURI()によってコールされます。

ブール引数を使用して、適切な型コンストラクタをコールする前に、接頭辞を削除する必要があることを示すことができます。

unregisterURLHandler()

URLハンドラを登録解除します。

特に注意を要するのは、パッケージURIFACTORYを使用して、型がURITypeの新しいサブタイプを定義できることです。そのサブタイプを使用して、URI用の特別な処理を提供することができます。特に、特定のプロトコルに対応するURITypeサブタイプを定義できます。URIFACTORYは、これらのサブタイプのインスタンスを、適切に認識して処理します。

新しい型を定義して、その型に固有のデータベース列を作成する利点は次のとおりです。

- その列に対して暗黙的な制約を提供して、その型のインスタンスのみを含むようにできます。これは、その列に特定のプロトコルのスペシャライズ・インデックスを実装する場合に有効です。たとえばDBUriの場合、SQL問合せを実行せず、ディスクから直接データをフェッチするスペシャライズ・インデックスを実装することができます。

- 型に基づいて、それぞれの列に異なる制約を規定できます。たとえばHTTPUriの場合、列に対してプロキシおよびファイアウォールの制約を定義して、HTTPを介したすべてのアクセスでプロキシ・サーバーを使用するようにできます。

33.7.1 パッケージ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サブタイプのインスタンスが生成されます。

例33-12では、新しいプロトコルecom://を処理する新しい型ECOMURITypeを作成しています。この例は1つの表に3種類の異なるURI(HTTPUri、DBUri、および新しい型ECOMURITypeのインスタンス)を格納します。この例を実行するには、各ECOMURITypeメンバー関数を定義する必要があります。

例33-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

33.8 SYS_DBURIGEN SQL関数

DBUriを作成するには、XPath式をコンストラクタDBURIType、または適切なURIFACTORY PL/SQLメソッドに対して指定します。Oracle SQL関数sys_DburiGenを使用すると、データベース列とその値から構成されたXPathを使用してDBUriを作成することもできます。

Oracle SQL関数sys_DburiGenは、引数として1つ以上の列または属性、およびオプションでrowidを取り、特定の列オブジェクトまたは行オブジェクトをターゲットにするDBUriを生成します。関数sys_DburiGenは、ノードのテキスト値が必要かどうかを示す追加のパラメータを取ります。図33-2を参照してください。

図33-2 SYS_DBURIGENの構文

参照するすべての列または属性は、同じ表内に存在する必要があります。それらはそれぞれ一意の値を参照する必要があります。複数の列を指定した場合、最初の列は行を識別し、最後の列はその行内の列を識別します。データベース・スキーマを指定しない場合、表名はパブリック・シノニムとして解釈されます。

関連項目:

『Oracle Database SQL言語リファレンス』

例33-13では、Oracle SQL関数sys_DburiGenを使用して、employee_idが206という条件下で表HR.employeesのemailをターゲットにするDBUriを生成しています。

例33-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.

33.8.1 列またはオブジェクト属性を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()

- 単一列の引数: 単一列の引数がある場合、列は、行を識別するキー列と参照列の両方として使用されます。

例33-14の問合せは、employee_idを、キー列と参照列の両方として使用します。employee_idが200の行をターゲットにするDBUriを生成します。

例33-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.

33.8.2 SQL関数SYS_DBURIGENの使用: 例

SQL関数sys_DburiGenを使用してデータベース参照を挿入する例、大きい列から部分的な結果を戻す例、および挿入されたオブジェクトのURLを戻す例を示します。

33.8.2.1 SYS__DBURIGENを使用したデータベース参照の挿入

SQL関数sys_DburiGenを使用して、特定のデータベース・データを参照するDBUriを挿入します。このことの例を示します。

例33-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.

33.8.2.2 SYS__DBURIGENを使用して部分的な結果を戻す方法

大きい列からデータを選択する場合は、結果の一部のみを取得し、完全な列にアクセスできるURLを作成する場合があります。

たとえば、旅行体験記についてのWebサイトを考えてみます。表に旅行体験記が格納されていて、ユーザーが関連する一連の体験記を検索する場合、検索結果のページに各体験記の全体をリストするのは不都合です。そのかわりに、各体験記の最初の20文字のみを要点として表示し、体験記全体のURLを戻す方がよいでしょう。これを行うには、次の手順を実行します。

例33-16では、旅行体験記の表を作成します。

例33-17では、旅行体験記の最初の20文字のみを戻す関数を作成します。

例33-18では、旅行体験記の最初の20文字のみを選択し、story列のDBUriを戻すビューを作成します。

例33-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.

例33-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.

例33-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.

33.8.2.3 SYS_DBURIGENを使用して挿入されたオブジェクトのURLを戻す方法

DML文のRETURNING句にあるOracle SQL関数sys_DburiGenを使用すると、オブジェクトの挿入時にそのオブジェクトのURLを取得できます。

例33-19では、文書が表clob_tabに挿入されると、そのURLが表uri_tabに常に挿入されます。これを実現するには、INSERT文のRETURNING句でOracle SQL関数sys_DburiGenを使用します。

例33-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.

33.9 DBUriServlet

リポジトリ・リソースは、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のサーブレットの詳細は、JavaでのOracle XML DBアプリケーションの作成方法を参照してください。

表33-3に、出力をカスタマイズするためにDBUriServletに渡すオプションのURLパラメータを示します。

表33-3 DBUriServlet: オプションの引数

引数

説明

rowsettag

XML文書のデフォルトのルート・タグ名を変更します。次に例を示します。

http://server:8080/oradb/HR/EMPLOYEES?rowsettag=OracleEmployees

contenttype

生成されるドキュメントのMIMEタイプを指定します。次に例を示します。

http://server:8080/oradb/HR/EMPLOYEES?contenttype=text/plain

transform

XSLTスタイルシートをその位置で取得するURIFACTORYにURLを渡します。このスタイルシートは、サーブレットによって戻されたXML文書に適用されます。次に例を示します。

http://server:8080/oradb/HR/EMPLOYEES?transform=
/oradb/QUINE/XSLS/DOC/text()&contenttype=text/htmlFoot 1

脚注 1

このURLは、説明のために2行に分割されています。

33.9.1 URLを使用したMIMEタイプのオーバーライド

MIMEコンテンツ・タイプをオーバーライドするには、別のMIMEタイプをcontenttypeパラメータとしてサーブレットに渡すURLを使用します。

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のコンテンツ・タイプを生成

33.9.2 DBUriServletのカスタマイズ

DBUriServletをカスタマイズするには、Oracle XML DBの構成ファイルxdbconfig.xmlを変更します。

関連項目:

- JavaでのOracle XML DBアプリケーションの作成方法

- Oracle XML DBの管理

- Oracle XML DB Configuration API

- データベース・スキーマXDBの詳細は、『Oracle Database 2日でセキュリティ・ガイド』を参照してください。

Oracle XML DBの構成ファイルxdbconfig.xmlを編集するには、データベース・スキーマ(ユーザー・アカウント) XDBとWebDAV、FTP、Oracle Enterprise ManagerまたはPL/SQLを使用します。FTPまたはWebDAVを使用してファイルを更新するには、文書をダウンロードし、編集し、データベースに再度保存します。PL/SQLパッケージDBMS_XDB_CONFIGは、ファイルにアクセスするための特に便利な方法と、特定の構成変更を実行するサブプログラムを提供します。たとえば、DBMS_XDB_CONFIG.deleteservletmappingを使用すると、サーブレット・マッピングを削除できます。

DBUriServletのインストール先は/oradb/*で、これはxdbconfig.xmlのservlet-patternタグで指定されているアドレスです。アスタリスク(*)は、oradb以降のすべてのパスが同じサーブレットにマップされることを示すために必要です。oradbは仮想パスとして公開されます。サーブレットにアクセスするために使用するパスを変更できます。

例33-20では、DBUriServletを/dburi/*にインストールするように構成ファイルが変更されています。(ここでは、XPath式が長いので、説明のために分割されています。実際には1行に記述してください)。

セキュリティ・パラメータ、サーブレットの表示名および説明も、xdbconfig.xml構成ファイル内でカスタマイズできます。サーブレットは、servlet-patternを削除することによって削除できます。また、XQuery Updateを使用してservlet-mapping要素をNULLに更新することによっても削除できます。

例33-20 DBUriServletのインストール先の変更

DECLARE
doc XMLType;
doc2 XMLType;
BEGIN
doc := DBMS_XDB_CONFIG.cfg_get();
SELECT XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/xdbconfig.xsd";
copy $i := $doc modify
for $j in
$i/xdbconfig/sysconfig/protocolconfig/httpconfig/webappconfig/servletconfig/servlet-mappingsFoot 2
/servlet-mapping[servlet-name="DBUriServlet"]/servlet-pattern
return replace value of node $j with $i/dburi/*
return $i'
PASSING DBMS_XDB_CONFIG.cfg_get() AS "doc"
RETURNING CONTENT) INTO doc2 FROM DUAL;
DBMS_XDB_CONFIG.cfg_update(doc2);
COMMIT;
END;
/

33.9.3 DBUriServletセキュリティのロールの使用

サーブレットのセキュリティは、Oracle Databaseでロールを使用することによって処理されます。サーブレットにログインするユーザーは、ユーザー自身のデータベース・ユーザー名およびパスワードを使用します。サーブレットは、ログインするユーザーが、構成ファイルに指定されているロールのいずれかを持っているかどうかを、パラメータsecurity-role-refを使用して確認します。

デフォルトでは、サーブレットはロールauthenticatedUser、および有効なデータベース・パスワードを使用してサーブレットにログインし、このロールを持っているあらゆるユーザーが利用できます。

ロール・パラメータを変更して、特定のデータベース・ロールにアクセスを制限できます。デフォルトのauthenticatedUserロールから、ユーザーが作成したロールに変更するには、Oracle XML DB構成ファイルを変更します。

例33-21では、デフォルト・ロールauthenticatedUserをロールservlet-users(ユーザーが作成したという想定のもの)に変更します。

例33-21 サーブレット・アクセスのデータベース・ロールへの制限

DECLARE
doc  XMLType;
doc2 XMLType;
doc3 XMLType;
BEGIN
doc := DBMS_XDB_CONFIG.cfg_get();
SELECT XMLQuery('copy $i := $p1 modify
(for $j in $i/xdbconfig/sysconfig/protocolconfig/httpconfig/webappconfig/servletconfig/Foot 3
servlet-list/servlet[servlet-name="DBUriServlet"]/security-role-ref/role-name
return replace value of node $j with $p2)
return $i'
PASSING DOC AS "p1", 'servlet-users' AS "p2" RETURNING CONTENT)
INTO doc2 FROM DUAL;
SELECT XMLQuery('copy $i := $p1 modify
(for $j in $i/xdbconfig/sysconfig/protocolconfig/httpconfig/webappconfig/servletconfig/
servlet-list/servlet[servlet-name="DBUriServlet"]/security-role-ref/role-link
return replace value of node $j with $p2)
return $i'
PASSING DOC2 AS "p1", 'servlet-users' AS "p2" RETURNING CONTENT)
INTO doc3 FROM DUAL;
DBMS_XDB_CONFIG.cfg_update(doc3);
COMMIT;
END;
/

33.9.4 DBUriを処理するためのパッケージURIFACTORYの構成

効率を向上させるには、URIFACTORYに対し、指定された形式のURIはデータベース・アクセスを表しているので、HTTPUriではなくDBUriとして実現する必要があることを指示します。そのためには、このURIのハンドラを接頭辞として登録し、生成するインスタンスの型としてDBURITypeを指定します。

http://server/servlets/oradbといったURLは、DBUriServlet (またはカスタム・サーブレット)により処理されます。この種のURLがURITypeインスタンスとして格納される場合、サブタイプDBURITypeを使用すると便利です。これは、このURIがデータベース・データをターゲットにしているためです。

ただし、URITypeインスタンスが、PL/SQLパッケージURIFACTORYのメソッドを使用して作成された場合は、デフォルトで使用されるサブタイプは、DBURITypeではなくHTTPURITypeです。これは、URIFACTORYがURI接頭辞のみに注目し、http://を検出して、URIターゲットがWebページであると想定するためです。これにより、不要な通信レイヤーが作成され、無駄な文字変換が行われます。

指定された形式のURIはデータベース・アクセスを表し、HTTPUriではなくDBUriとして実現する必要があることをURIFACTORYに対して指示するには、このURIのハンドラを接頭辞として登録し、生成するインスタンスの型としてDBURITypeを指定します。

例33-22では、URIFACTORYに対して、http://server/servlets/oradbで始まるあらゆるURI文字列がデータベース・アクセスに対応していることを効率的に通知しています。

このコードを実行すると、同一のセッションにおけるすべてのgetURI()コールにより、接頭辞http://server/servlets/oradbを持つあらゆるURI文字列用のDBUriが自動的に作成されます。

関連項目:

URIFACTORYファンクションの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

例33-22 DBUri接頭辞用のハンドラの登録

BEGIN
URIFACTORY.registerURLHandler('http://server/servlets/oradb',
'SYS', 'DBURIType', true, true);
END;
/

33.9.5 DBUriサーブレットを使用した、Webブラウザからの表またはビューへのアクセス

Oracle XML DBに含まれているDBUriサーブレットを使用すると、Webブラウザからすべての表またはビューのコンテンツに直接アクセスできます。これは、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」

XSLTスタイルシート処理を開始するには、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に設定します。

脚注の凡例

脚注2:
このXQuery式は、説明のみを目的として2行に分割されています。

脚注3:
このXQuery式は、説明のみを目的として2行に分割されています。

34 ネイティブなOracle XML DB Webサービス

Webサービスを使用すると、使用中のアプリケーションからネイティブなOracle XML DBにアクセスできます。

- ネイティブなOracle XML DB Webサービスの概要

- Oracle XML DBでのWebサービスの構成と有効化

- Webサービスを使用したOracle XML DBの問合せ

- Webサービスを使用したPL/SQLストアド・プロシージャへのアクセス

34.1 ネイティブな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の構成」

34.2 Oracle XML DBでのWebサービスの構成と有効化

Webサービスを使用できるようにするには、Oracle XML DB HTTPサーバーを起動し、Webサービス構成を明示的に追加する必要があります。その後、Webサービスの使用を特定のユーザーにのみ許可するため、それらのユーザーに適切なロールを付与する必要があります。

1. Webサービスを構成します。Oracle XML DBでのWebサービスの構成を参照してください。

2. 特定のユーザーに適切なロールを付与して、Webサービスを有効化します。「特定のユーザーに対するWebサービスの有効化」を参照してください。

セキュリティ上の理由により、Oracle XML DBに事前に組み込まれているネイティブなWebサービスはありません。

関連項目:

Oracle XML DB HTTPサーバーの詳細は、「HTTP(S)およびOracle XML DBプロトコル・サーバー」を参照してください。

34.2.1 Oracle XML DBでのWebサービスの構成

Oracle XML DBでWebサービスを使用できるようにするには、ユーザーSYSとしてログオンし、サーブレット構成をOracle XML DBの構成ファイルxdbconfig.xmlに追加して、サーブレットを構成します。次に、PL/SQLパッケージDBMS_XDB_CONFIGのプロシージャを使用して、サーブレット構成によって名前が付けられたサーブレットを追加します。

追加するサーブレット構成は、例34-2の問合せ出力として示されています。

例34-1に、PL/SQLパッケージDBMS_XDB_CONFIGのプロシージャを使用してサーブレットを追加する方法を示しています。例34-2は、サーブレットが正しく追加されたことを確認する方法を示しています。

関連項目:

xdbconfig.xmlによるOracle XML DBの構成の詳細は、「xdbconfig.xmlを使用したOracle XML DBの構成」を参照してください。

例34-1 Webサービス構成サーブレットの追加

DECLARE
SERVLET_NAME VARCHAR2(32) := 'orawsv';
BEGIN
DBMS_XDB_CONFIG.deleteServletMapping(SERVLET_NAME);
DBMS_XDB_CONFIG.deleteServlet(SERVLET_NAME);
DBMS_XDB_CONFIG.addServlet(
NAME     => SERVLET_NAME,
LANGUAGE => 'C',
DISPNAME => 'Oracle Query Web Service',
DESCRIPT => 'Servlet for issuing queries as a Web Service',
SCHEMA   => 'XDB');
DBMS_XDB_CONFIG.addServletSecRole(SERVNAME => SERVLET_NAME,
ROLENAME => 'XDB_WEBSERVICES',
ROLELINK => 'XDB_WEBSERVICES');
DBMS_XDB_CONFIG.addServletMapping(PATTERN => '/orawsv/*',
NAME    => SERVLET_NAME);
END;
/

例34-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.

34.2.2 特定のユーザーに対する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オブジェクトにアクセスできます。

34.3 Webサービスを使用したOracle XML DBの問合せ

データベース問合せに使用するOracle XML DB WebサービスのURLは、http://host:port/orawsvです。ここで、hostはデータベース・ホストでportはHTTP(S)ポートです。これは、XML Schemaを使用して入力ドキュメントおよび出力ドキュメントのフォーマットを指定するWSDLに関連付けられています。このWSDLのURLは、http://host:port/orawsv?wsdlです。

データベース問合せは、例34-3に示されているXML Schemaに準拠したXML文書としてアプリケーションからWebサービスへ送信されます。

この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のプロシージャ内でそれぞれに対応しているパラメータと同じ意味を持っています。

例34-4および例34-5は、単純なSQL問合せの入力および出力を示したものです。

例34-4では、問合せテキストは<![CDATA[...]]>で囲まれています。これは、この例の中では必ずしも必要なことではありませんが、問合せには通常<や>などの文字が含まれるため、一般的には適切な方法です。要素bindは、eというバインド変数に値(8300)をバインドするのに使用されます。要素pretty_printでは、出力内容のフォーマット出力が無効になっています。

例34-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>

例34-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>

例34-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>

34.4 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文書内のデータ型は、表34-1に従って、ストアド・ファンクションまたはストアド・プロシージャで使用されるSQLデータ型にマップされます。サポートされているデータ型は、これらのみです。

表34-1 XMLデータ型とOracle Databaseデータ型のWebサービスによるマッピング

Oracle Databaseデータ型

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

INT、INTEGER、SMALLINT、PLS_INTEGER、BINARY_INTEGER

xsd:integer

RAW、BLOB、REF

xsd:hexBinary

PL/SQL BOOLEAN

xsd:boolean

オブジェクト型

complexType

XMLType

空のcomplexType

オブジェクト型は、同じ名前の複合型要素としてXMLで表現されます。オブジェクト属性は、その要素の子として表現されます。

34.4.1 Webサービスを使用したPL/SQLファンクションの使用: 例

PL/SQLファンクションと、Webサービスを使用したアクセスの例を示します。このファンクションは、入力として部門IDおよび名前を取ります。部門の給与合計を戻します。またこのファンクションは、入出力パラメータおよび出力パラメータとしてそれぞれ、部門名およびその部門の従業員数を戻します。

部門IDのデフォルト値は20です。この単純な例では、入出力パラメータdept_nameの入力値は実際には使用されません。それは無視され、正しい名前が戻されます。

例34-6は、ファンクションの定義を示したものです。例34-7は、このファンクションの定義から自動的に作成されたWSDLドキュメントです。例34-8は、ストアド・ファンクションを起動する入力ドキュメントです。例34-9は、結果の出力ドキュメントです。

例34-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;
/

例34-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>

例34-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>

例34-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>

第VII部 Oracle XML DBをサポートするOracleツール

Oracle XML DBとともに様々なOracleツールを使用できます。これには、Oracle XML DBの管理、XMLデータのロード、およびXMLデータの交換のためのツールが含まれます。

- Oracle XML DBの管理

- XMLデータのロード方法

- Oracle XML DBデータのエクスポートとインポート

- Oracle Streams AQを使用したXMLデータの交換

35 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のリポジトリ・リソースの構成」を参照してください。

35.1 既存のOracle XML DBのインストールのアップグレードまたはダウングレード

Oracle Database 12c リリース1 (12.1.0.1)より前のリリースのOracle Databaseのすべてのアップグレードには、様々な考慮事項が適用されます。

- 通常どおり、スクリプトcatproc.sqlを実行します。

- ローリング・アップグレードを含むどのレプリケーション・メソッドでも、階層対応表のレプリケーションはサポートされていません。

- 追加ロギングが有効になっている場合、次の操作はサポートされません。

- INSERTでのAPPENDヒントの使用

- XMLTypeデータのSQL*Loaderダイレクト・パス挿入

- ローリング・アップグレード中にプライマリ・データベースで次のいずれかの操作を呼び出すと、スタンバイ・データベースでは「サポートされていない操作です。」エラーが発生します。

- DBMS_XDB_ADMIN: すべての操作

- DBMS_XMLSCHEMA.copyEvolve

- DBMS_XMLSCHEMA.compileSchema

- DBMS_XMLINDEX.dropparameter

- DBMS_XMLINDEX.modifyparameter

- DBMS_XMLINDEX.registerparameter

- ACLセキュリティ: Oracle Database 11gリリース1以前のリリースでは、同じプリンシパルおよび同じ権限のACE間の競合は、先行するACEに子grantがあるかどうかに関係なく、子denyのあるACEを優先させることで解決していました。つまり、ACEの順序は関係ありませんでした。Oracle Database 11g以降では、このdeny-trumps-grantの動作も使用できますが、デフォルトの動作ではありません。

- Oracle Database 12cリリース1 (12.1.0.1)より前は、Basicアクセス認証のみが使用可能なHTTP認証メカニズムでした。12cリリース1から、Digestアクセス認証が使用できるようになりました。データベースのアップグレードおよびダウングレードに適用される認証に関する考慮事項の詳細は、「データベースのインストール、アップグレードおよびダウングレードに関する認証の考慮事項」を参照してください。

関連項目:

- ローリング・アップグレードの実行の詳細は、『Oracle Data Guard概要および管理』を参照してください。

- ACE間の競合の詳細は、「ACLおよびACEの評価」を参照してください。

35.1.1 データベースのインストール、アップグレードおよびダウングレードに関する認証の考慮事項

データベースのインストール、アップグレードおよびダウングレードには、様々な認証に関する考慮事項が適用されます。

関連項目:

認証の構成方法は、「HTTPの認証メカニズムの構成および管理」を参照してください。

35.1.1.1 データベースのインストールに関する認証の考慮事項

データベースのインストールでは、デフォルトでDigest認証は有効、Basic認証は無効になっています。すべてのユーザーに、Digestベリファイアが自動的に生成されます。

35.1.1.2 データベースのアップグレードに関する認証の考慮事項

Oracle Database 12cリリース1 (12.1.0.1)より前のリリースからアップグレードすると、使用可能な認証メカニズムのリストにDigest認証が追加されます。ただし、アップグレード前にBasic認証が有効であった場合、現行の認証方法はそのままです。これは下位互換性のみのためです。

アップグレード後は、データベース管理者が速やかにBasic認証を無効にすることをお薦めします。アップグレード後にBasic認証を有効にしておく理由は、ユーザーがDigest認証をサポートしていないWebブラウザを使用して、各自のパスワードを変更できるようにするためです。

このようなアップグレードでは、新規ユーザーとアップグレード時にパスワードが変更された既存ユーザーすべてについて、Digestベリファイアが計算されます。それ以外のユーザーはDigestベリファイアを持っていません。

アップグレード後、DBAは次の手順に従ってデータベース・ビューDBA_DIGEST_VERIFIERSを使用し、ユーザーごとにDigestベリファイアの有無を確認して、適切に処理できます。

1. Oracle XML DBの構成ファイルxdbconfig.xmlで、Basic認証を使用可能な最初の認証メカニズムとして設定します。これにより、Basic認証をHTTPアクセスに使用できるようになります。

2. Digestベリファイアを持っていないユーザーのパスワードをすべて失効させます。この問合せは、該当するユーザーを戻します。

SELECT USERNAME FROM DBA_DIGEST_VERIFIERS
WHERE HAS_DIGEST_VERIFIERS = 'NO' AND DIGEST_TYPE is NULL;

3. 該当するすべてのユーザーのパスワードを変更したら、xdbconfig.xmlを再設定して、Digest認証を最初のまたは(できれば)唯一の使用可能な認証メカニズムとして有効にします。

35.1.1.3 データベースのダウングレードに関する認証の考慮事項

Digest認証がサポートされていないリリースにダウングレードすると、Digest認証は無効化され、認証の選択肢として使用できなくなります。

ダウングレード時に、すべてのDigest認証が消去されます。つまり具体的には、ダウングレード後にアップグレードした場合、ダウングレード前に認証されていたユーザーは、ダウングレードとそれに続くアップグレード後には、Digest認証が拒否されます。

35.1.2 Oracle XML DBの自動インストール

Oracle XML DBは、アップグレード中に自動的にインストールされます。Oracle XML DBを使用する場合は、互換性レベルが12.1.0.1以上であることを確認してください。

Oracle Database 12cリリース1 (12.1.0.1)以降にアップグレードする前に、Oracle XML DBがユーザーのデータベースにまだインストールされていなかった場合は、アップグレード時に表領域SYSAUXに自動的にインストールされます。

こうしてOracle XML DBが自動的にインストールされた場合、Oracle XML DBを使用するには、アップグレード操作後にデータベースの互換性を12.1.0.1以上に設定する必要があります。互換性が12.1.0.1より低位にある場合、Oracle XML DBの使用を試みるとエラーが発生します。

アップブレード時にOracle XML DBが自動的にインストールされ、現行の互換性レベルが12.1.0.1よりも低い場合、前のリリースにダウングレードすると、Oracle DBは自動的に削除されます。

35.1.3 ACL文書および構成ファイルの検証

アップグレード中に、既存のACL文書およびOracle XML DB構成ファイルが、XML Schemaに対して検証されます。検証に失敗した場合は、特定の対策を講じる必要があります。

アクセス制御リスト(ACL)の文書は、表XDB$ACLに格納されています。Oracle XML DBの構成ファイルxdbconfig.xmlは、表XDB$CONFIGに格納されています。Oracle Database 12cリリース1 (12.1.0.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の値を使用します。これらのファイルは削除されます。

35.2 Oracle Enterprise Managerを使用したOracle XML DBの管理

Oracle Enterprise Managerを使用すると、Oracle XML DB管理タスクを実行できます。これには、Oracle XML DBの構成、XML Schema、XMLType表およびビュー、Oracle XML DBリポジトリ・リソースとそのアクセス制御リスト(ACL)の作成、検索、編集および削除、XML Schemaの登録、ファンクション索引が含まれます。

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を使用しないリソースの作成および管理の詳細は、「Oracle XML DBリポジトリ」を参照してください。

- XMLType表およびビューの検索、作成、編集および削除。

- XMLスキーマの検索、作成、登録および削除。
Oracle Enterprise Managerを使用しないXML Schemaの操作の詳細は、「XML Schemaの格納と問合せ: 基本」を参照してください。

関連項目:

Oracle Enterprise Managerを使用した、これらのタスクの実行の詳細は、Oracle Enterprise Manager付属のオンライン・ヘルプを参照してください。

35.3 xdbconfig.xmlを使用したOracle XML DBの構成

Oracle XML DBは、Oracle XML DBリポジトリにリソースとして格納された構成ファイルの/xdbconfig.xmlを介して内部管理できます。Oracle Enterprise Managerを使用してOracle XML DBを構成するかわりに、Oracle XML DB構成ファイルを使用して直接構成できます。

構成ファイルは実行時に変更できます。構成ファイルを更新すると、このリポジトリ・リソースの新しいバージョンが作成されます。セッションが開始されると、現行のバージョンの構成ファイルがそのセッションにバインドされます。最新のバージョンにセッションをリフレッシュするように明示的にコールしないかぎり、このセッション中は、このバージョンの構成ファイルが使用されます。

35.3.1 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」を参照してください。

35.3.1.1 要素xdbconfig (最上位)

要素xdbconfigは、Oracle XML DB構成ファイルの最上位の要素です。

その構造は次のとおりです。

<xdbconfig>
<sysconfig> ... </sysconfig>
<userconfig> ... </userconfig>
</xdbconfig>

要素sysconfigは、システム固有の組込みパラメータを定義します。要素userconfigを使用すると、新しいカスタム・パラメータを格納できます。

35.3.1.2 要素sysconfig (xdbconfigの子)

要素sysconfigは、xdbconfigの子です。

その構造は次のとおりです。

<sysconfig>
general parameters
<protocolconfig> ... </protocolconfig>
</sysconfig>

要素sysconfigには、アクセス制御リスト(ACL)の最大存続期間など、すべてのOracle XML DBに適用されるいくつかの一般的なパラメータが含まれます。子要素protocolconfigには、プロトコル固有のパラメータが含まれます。

注意:

要素case-sensitive (要素sysconfigの子)は、XQueryまたは全文検索の大/小文字の区別には影響しません。そうではなく、すべてのOracle XML DBの動作に影響します。

35.3.1.3 要素userconfig (xdbconfigの子)

要素userconfigは、xdbconfigの子です。これには追加する必要のあるパラメータが含まれます。

35.3.1.4 要素protocolconfig (sysconfigの子)

要素protocolconfigは、sysconfigの子です。

その構造は次のとおりです。

<protocolconfig>
<common> ... </common>
<ftpconfig> ... </ftpconfig>
<httpconfig> ... </httpconfig> </protocolconfig>

要素commonには、MIMEタイプについての情報など、すべてのプロトコルに適用されるパラメータが格納されます。FTP、HTTPおよびHTTPSプロトコルに固有のパラメータは、要素ftpconfigとhttpconfigにそれぞれ含まれます。

関連項目:

プロトコル構成パラメータのリストは、 プロトコルを使用したリポジトリへのアクセスの表28-1、表28-2および表28-3を参照してください。

35.3.1.5 要素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-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パッケージおよびタイプ・リファレンス』を参照してください。

35.3.1.6 要素servlet (httpconfigの子孫)

要素servletは、要素httpconfigの子孫です。Javaサーブレットおよび埋込みPL/SQLゲートウェイ・サーブレットなど、サーブレットの構成に使用します。

「要素httpconfig (protocolconfigの子)」を参照してください。

注意:

次のサーブレットは、ファイルxdbconfig.xmlに事前構成済です。これらは削除しないでください。

- ORSServlet

- EMExpressServlet

servlet脚注1の子であるオプションの要素plsqlは、埋込みPL/SQLゲートウェイ・サーブレットを構成します。ただし、埋込みゲートウェイの構成方法としては、xdbconfig.xmlファイルを編集するのではなく、PL/SQLパッケージDBMS_EPGのプロシージャを使用する方法をお薦めします。

要素plsqlは、埋込みゲートウェイの構成に必要な、埋込みPL/SQL DAD属性脚注2ごとに子要素を持っています。これらの子はすべてオプションです。要素名はDAD属性名と同じです。要素のコンテンツは、DAD属性値と同じです。

関連項目:

- Javaサーブレットの構成の詳細は、「JavaでのOracle XML DBアプリケーションの作成方法」を参照してください。

- 埋込みPL/SQLゲートウェイの構成と使用方法の詳細は、『Oracle Database開発ガイド』を参照してください。

- Oracle Application Expressの詳細は、『Oracle Application Expressアプリケーション・ビルダー・ユーザーズ・ガイド』を参照してください。

- DBMS_EPGパッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

35.3.1.7 Oracle XML DBの構成ファイルの例

Oracle XML DBの構成ファイルの例を示します。

例35-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>

35.3.1.8 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_CONFIGを使用できます。これにより次の関数およびプロシージャが公開されます。

- cfg_get - 現在のセッションの構成情報を表示します。

- cfg_refresh - 現在の構成ファイルを使用して、セッション構成情報をリフレッシュします。典型的なcfg_refreshの使用例には、次のものがあります。

- 構成の変更後、セッションで最新バージョンの構成情報を取得する必要がある場合。

- セッションの実行が長時間におよび、同時セッションによって構成が変更され、現行のセッションで最新バージョンの構成情報を取得する必要がある場合。

- cfg_update - 構成ファイルを書き込み、構成情報を更新します。COMMITが実行されます。

例35-2では、構成ファイル内のftp-portおよびhttp-portパラメータを更新します。

多くのパラメータを更新する場合、FTP、HTTP、HTTPSまたはOracle Enterprise Managerを使用すると、より簡単に構成を更新できます。

関連項目:

- DBMS_XDB_CONFIG: 構成管理

- 『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

例35-2 CFG_UPDATEおよびCFG_GETを使用した構成ファイルの更新

DECLARE
v_cfg XMLType;
BEGIN
SELECT XMLQuery('declare default element namespace
"http://xmlns.oracle.com/xdb/xdbconfig.xsd";
copy $i := $cfg
modify for $j in $i/xdbconfig
return (replace value of node $j/descendant::ftp-port with
"2121",
replace value of node $j/descendant::http-port with
"19090")
return $i'
PASSING DBMS_XDB_CONFIG.cfg_get() AS "cfg"
RETURNING CONTENT)
INTO v_cfg FROM DUAL;
DBMS_XDB_CONFIG.cfg_update(v_cfg);
END;
/

35.3.1.9 デフォルトの名前空間からスキーマの場所へのマッピングの構成

Oracle XML DBは、デフォルトのXML Schemaの場所のマッピングを構成するメカニズムを提供します。

Oracle XML DBでは、入力XML文書を事前解析して、XML Schemaに基づく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:属性も必要になります。

35.3.1.10 XMLファイル拡張子の構成

Oracle XML DBリポジトリは、特定のファイルをそのファイル拡張子に基づいてXML文書として処理します。このようなファイルがリポジトリに挿入されると、Oracle XML DBはこれらを事前解析し、XML Schemaの場所を識別(またはデフォルトのマッピングがある場合はそれを使用)して、文書を適切なデフォルト表に挿入します。

デフォルトでは、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>

35.4 Oracle XML DBとデータベース統合

プラガブル・データベースごとに、独自のOracle XML DBリポジトリと独自のOracle XML DB構成ファイルxdbconfig.xmlがあります。

マルチテナント・コンテナ・データベース(CDB)は、0(ゼロ)個以上のプラガブル・データベース(PDB)、ルートおよびシードPDB(PDBを作成するためのテンプレート)で構成されます。1つのPDBは、一度に1つのCDBにのみ関連付けることができます。ユーザーおよびアプリケーションは、1つのPDBを個別のデータベースとみなします。アプリケーションは常に単一のPDBと通信します。問合せおよびディクショナリ・ビューは、PDBに対してローカルです。PDBごとに個別のOracle XML DBリポジトリと固有のOracle XML DB構成ファイルxdbconfig.xmlを保持しています。

CDB(CDB$ROOT)のルートには、ユーザー・データは格納されません。ただし、固有の構成ファイルxdbconfig.xmlは保持しています。

CDBのルート構成ファイルには特定のパラメータのみが含まれ、これらのパラメータはルート構成ファイルからのみ使用されます。これらのパラメータが、CDBに含まれているPDBの構成ファイルにも存在する場合は無視され、ルート構成ファイル内の対応するパラメータが優先されます。

ルートから使用する(PDBからは無視される)構成パラメータを次に示します。

- acl-cache-size

- acl-max-age

- resource-view-cache-size

- xdbcore-loadableunit-size

- xdbcore-xobmem-bound

パラメータxdbcore-loadableunit-sizeおよびxdbcore-xobmem-boundはプロセス固有です。それ以外はSGA構成パラメータです。

データベース・スキーマ(ユーザー・アカウント)XDBは共通ユーザーであり、ルートおよび任意のPDBのどちらに対しても接続および操作を実行できます。

注意:

どのような場合でも、データベース・スキーマXDBは絶対にロック解除しないことをお薦めします。

関連項目:

- データベース統合およびPDBの詳細は、『Oracle Database管理者ガイド』および『Oracle Database概要』を参照してください。

- 構成パラメータresource-view-cache-size、xdbcore-loadableunit-sizeおよびxdbcore-xobmem-boundの詳細は、「Oracle XML DBリポジトリ操作のパフォーマンス・ガイドライン」を参照してください。

- 構成パラメータxdbcore-loadableunit-sizeおよびxdbcore-xobmem-boundの詳細は、「コレクションでの大規模な文書のロードおよび取得の考慮事項」を参照してください。

- 構成パラメータacl-max-ageの詳細は、「ACLキャッシング」を参照してください。

35.5 パッケージDBMS_XDB_ADMIN

PL/SQLパッケージDBMS_XDB_ADMINには、Oracle XML DBおよびOracle XML DBリポジトリを管理および構成するためのサブプログラムが含まれています。

表35-1では、これらのサブプログラムについて説明します。

表35-1 DBMS_XDB_ADMIN管理プロシージャ

ファンクションおよびプロシージャ

説明

moveXDB_tablespace

データベース・スキーマ(ユーザー・アカウント)XDBを指定した表領域に移動します。

rebuildHierarchicalIndex

階層リポジトリ索引を再構築します。これには、特にmoveXDB_tablespaceの起動後では、時間がかかる可能性があります。

注意:

Oracle Database 11gリリース2 (11.2.0.3)以前は、これらのプロシージャはPL/SQLパッケージDBMS_XDBに付属していました。パッケージDBMS_XDB内のこれらの2つのプロシージャはりリース11.2.0.3の時点では非推奨です。

注意:

XM操作に悪影響が生じる可能性があるため、Oracle XML DBリポジトリを含む表領域を読取り専用にすることはできません。

デフォルトでは、Oracle XML DBリポジトリは表領域SYSAUXにあり、他のものにも使用されています。かわりに、リポジトリだけが使用する専用の表領域を作成することをお薦めします。

プロシージャDBMS_XDB_ADMIN.moveXDB_tablespaceを使用して、データベース・スキーマXDBをリポジトリ専用のその表領域に移動します。表領域が読取り専用でないことを確認してください。

関連項目:

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

脚注の凡例

脚注1:
埋込みPL/SQLゲートウェイの構成に使用されるplsql要素には、2つの異なるものがあります。1つはhttpconfigの子で、グローバル・パラメータを定義します。もう1つはservletの子で、DAD属性を定義します。

脚注2:
DADは、データベース・アクセス記述子の略語です。DAD属性は、このような記述子を定義するパラメータです。

36 XMLデータのロード方法

XMLデータをOracle XML DBにロードする主な方法は、SQL*Loaderを使用することです。

- Oracle DatabaseへのXMLTypeデータのロードの概要

- SQL*Loaderを使用したXMLTypeデータのロード

- SQL*Loaderを使用した大規模なXML文書のロード

関連項目:

Oracle XML DBの使用方法の概要

36.1 Oracle DatabaseへのXMLTypeデータのロードの概要

XMLTypeデータは、SQL*Loaderを使用して、格納方式(オブジェクト・リレーショナル記憶域またはバイナリXML記憶域)に関係なく、従来の方式またはダイレクト・パス方式でロードできます。

Oracle9iリリース1(9.0.1)以上のExport/Import UtilityおよびSQL*Loaderでは、列の型としてXMLTypeがサポートされています。Oracle Database 10g以降は、SQL*LoaderはXMLType表のロードもサポートしています。

注意:

XMLデータのオブジェクト・リレーショナル記憶域の場合、データにXML Schema型の継承(拡張または制限)が含まれている場合、SQL*Loaderはダイレクト・パス・ロードをサポートしません。

つまり、他のcomplexType要素(ベース型)を拡張または制限するXML SchemaにcomplexType要素が含まれている場合は、SQLタイプのいくつかは他のSQLタイプによって定義されます。この場合、オブジェクト・リレーショナル記憶域では、ダイレクト・パス・ロードはサポートされません。

関連項目:

「Oracle XML DBデータのエクスポートとインポート」および「Oracle Databaseユーティリティ」

ユーザー・データのエクスポート時に、Oracle XML DBリポジトリの情報はエクスポートされません。つまり、リソースまたはすべての情報のいずれもエクスポートされません。

36.2 SQL*Loaderを使用したXMLTypeデータのロード

SQL*Loaderは、XMLType列および表をオブジェクト・リレーショナル列および表と同様に処理します。プライマリ・データ・ファイルまたはLOBFILE値からLOBデータをロードするすべての方法は、XMLTypeデータがLOBとして格納されている場合は、XMLType列および表のロードにも適用されます。

関連項目:

『Oracle Databaseユーティリティ』

注意:

LOBフィールドにはSQL文字列を指定できません。これは、LOBFILE_specを指定する場合も同じです。

XMLTypeデータは、制御ファイルまたはLOBファイルに存在する場合があります。この場合は、LOBファイルの名前が制御ファイルに表示されます。

XMLTypeデータは非常に大きいデータであるため、SQL*Loaderでは、LOBデータをプライマリ・データ・ファイル(残りのデータを持つインライン)またはLOBファイルのいずれかから、そのデータの格納方法に関係なくロードできます(基礎となる記憶域はオブジェクト・リレーショナルのままです)。

36.2.1 SQL*Loaderを使用したXMLType LOBデータのロード

プライマリ・データ・ファイルから内部LOB (バイナリ・ラージ・オブジェクト(BLOB)、キャラクタ・ラージ・オブジェクト(CLOB)および各国語キャラクタ・ラージ・オブジェクト(NCLOB))、またはXMLType列および表をロードするには、次の標準SQL*Loader形式を使用します。

- 事前にサイズが決まっているフィールド

- デリミタ付きフィールド

- Length-Value Pairフィールド

これらの各形式の詳細は、次の項および『Oracle Databaseユーティリティ』を参照してください。

36.2.1.1 事前にサイズが決まっているフィールドを使用したLOBデータのロード

事前にサイズが決まっているフィールドは、LOBをロードする非常に高速で概念的に単純なSQL*Loader形式を構成します。

注意:

ロードするLOBデータはサイズが均等ではないため、サイズが小さいデータ・フィールドに空白を埋め込み、すべてのLOBを同じサイズにできます。

36.2.1.2 デリミタ付きフィールドを使用したLOBデータのロード

デリミタ付きフィールド形式は、同じ列(データ・ファイルのフィールド)で異なるサイズのLOBを処理します。ただし、このような柔軟性によって、SQL*Loaderでデリミタ文字列を探してデータをスキャンする必要があるため、パフォーマンスに影響します。

単一文字のデリミタで、文字列のデリミタを指定する場合は、データ・ファイルのキャラクタ・セットに注意してください。データ・ファイルのキャラクタ・セットが制御ファイルのキャラクタ・セットと異なる場合は、デリミタを16進文字列の表記法で指定できます('hexadecimal string')。デリミタを実際に16進数文字列で指定する場合は、入力データ・ファイルのキャラクタ・セット中の有効な文字で指定する必要があります。一方、16進数文字列で指定しない場合、デリミタは、クライアント(制御ファイル)のキャラクタ・セットで指定してください。この場合、デリミタは、SQL*Loaderによってデータ・ファイル内で検索される前に、データ・ファイルのキャラクタ・セットに変換されます。

36.2.1.3 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データ型を使用します。

36.2.1.4 LOBFILEの指定

LOBFILEを静的に指定(ファイルにファイル名を指定)するか、または動的に指定(FILLERフィールドをファイル名のソースとして使用)できます。

いずれの場合も、LOBFILEの終わりに到達するとファイルがクローズされ、そのファイルからさらにデータを読み取る場合は、空のフィールドからデータを読み取ることになります。

同じLOBFILEを、2つの異なるフィールドのソースとして指定しないでください。指定すると、通常、2つのフィールドで、データが別々に読み取られます。

36.2.2 SQL*Loaderによる制御ファイルからのXMLTypeデータの直接ロード

XMLTypeデータは、制御ファイルから直接ロードできます。SQL*Loaderは、XMLTypeデータを他のスカラー型と同様に処理します。

たとえば、NUMBER列に続いてXMLType列がオブジェクト・リレーショナル形式で格納されている表について考えてみます。この表に使用される制御ファイルには、NUMBER列の値とそれに続くXMLTypeインスタンスの値が含まれます。

SQL*Loaderは、サイズが非常に大きいXMLTypeインスタンスに対応できます。このようなデータをLOBファイルからロードするオプションもあります。

36.2.3 SQL*Loaderを使用した大規模なXML文書のロード

SQL*Loaderを使用すると、大量のXMLデータをOracle Databaseにロードできます。

1. データ・ファイル(filelist.datなど)、つまりロードするXML文書の場所を特定します。

2. データ・ファイルにリストされているファイルを処理するコマンドを使用して、制御ファイル(load_data.ctlなど)を作成します。

3. SQL*Loaderシェル・コマンドsqlldrを起動し、この制御ファイル名を渡します。

これは例36-1、例36-2、例36-3で説明しています。ファイルfilelist.datには、2002年の発注書を含むXMLファイルがリストされます。

アプリケーションで索引または制約が使用されている場合、これらの処理を行うとロードのパフォーマンスに影響する場合があります。パッケージDBMS_XMLSTORAGE_MANAGE内のPL/SQLサブプログラムdisableIndexesAndConstraintsおよびenableIndexesAndConstraintsを使用して、この処理を一時的に無効化できます。

関連項目:

- Oracle XML DBの使用方法の概要、「SQL*Loaderを使用した大規模なXMLファイルのロード」

- シェル・コマンドsqlldrの詳細は、『Oracle Databaseユーティリティ』を参照してください。

- DBMS_XMLSTORAGE_MANAGEサブプログラムdisableIndexesAndConstraintsおよびenableIndexesAndConstraintsの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

例36-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
...

例36-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
)

例36-3 シェル・コマンドsqlldrを使用したXMLデータのロード

sqlldr load_data.ctl

ダイレクト・パス・ロードを使用する場合は、かわりに次のコマンドを使用します。

sqlldr load_data.ctl direct=y

37 Oracle XML DBデータのエクスポートとインポート

Oracle Data Pumpを使用して、Oracle XML DBで使用するXMLType表をエクスポートおよびインポートできます。

注意:

元のエクスポート・ユーティリティ(exp)およびインポート・ユーティリティ(imp)を使用すると、Oracle Database 11gより前のデータベース・リリースにデータを移行できます。ただし、これらの元のユーティリティは、バイナリXMLとして格納されているXMLTypeデータの使用をサポートしていません。

- XMLType表のエクスポートおよびインポートの概要

- Oracle XML DBリポジトリのエクスポート/インポートの制限事項

- エクスポート/インポートの構文および例

37.1 XMLType表のエクスポートおよびインポートの概要

Oracle XML DBは、XML Schemaに基づくかどうかに関係なく、XMLデータを格納するXMLType表および列のエクスポートおよびインポートをサポートします。

Oracle Data Pumpにより、データベース間でデータとメタデータを高速で移動できます。Oracle Data Pumpを使用するには、2つのモード(トランスポータブル表領域モードとトランスポータブル表領域以外のモード)があります。

トランスポータブル表領域モードでは、XMLTypeデータに関して、XMLType記憶域モデルを変更できないという制約があります。

XMLデータは、他のデータベース・オブジェクトの場合と同様に、エクスポート側サーバーのキャラクタ・セットでエクスポートされます。インポート中、このデータはインポート側サーバーのキャラクタ・セットに変換されます。

Oracle Data Pumpには、expdpおよびimpdpという2つのコマンドライン・クライアントがあり、それぞれデータ・ポンプ・エクスポート・ユーティリティおよびデータ・ポンプ・インポート・ユーティリティを起動します。expdpおよびimpdpクライアントは、PL/SQLパッケージDBMS_DATAPUMP で提供されているプロシージャを使用して、コマンドラインに入力されたパラメータを渡してエクスポートおよびインポートのコマンドを実行します。これらのパラメータにより、完全なデータベースまたはデータベースのサブセットの、データおよびメタデータのエクスポートとインポートが可能になります。

データ・ポンプ・エクスポート・ユーティリティおよびインポート・ユーティリティ(それぞれコマンドexpdpおよびimpdpにより起動)は、元のエクスポート・ユーティリティ(exp)およびインポート・ユーティリティ(imp)と外観は似ていますが、完全に別のものです。

データ・ポンプ・エクスポート・ユーティリティ(expdpで起動)は、ダンプ・ファイル・セットと呼ばれるオペレーティング・システムのファイル・セットにデータおよびメタデータをアンロードします。ダンプ・ファイル・セットは、データ・ポンプ・インポート・ユーティリティ(impdpを使用して起動)でのみインポートできます。

Oracle XML DBは、XML Schemaに基づくかどうかに関係なく、XMLデータを格納するXMLType表および列のエクスポートおよびインポートをサポートします。表がXML Schemaに基づいている場合、表のデータを定義するために使用されたXML Schemaに依存します。オブジェクト・リレーショナル記憶域の場合、このXML Schemaに、データを格納するために使用されたSQLオブジェクト型への依存関係があることもあります。

そのため、XML Schemaに基づくXMLType表を持つユーザーをエクスポートすると、次もエクスポートされます。

- SQLオブジェクト型(オブジェクト・リレーショナル記憶域が使用されている場合)

- XML Schema

- XML表

XMLType記憶域形式(オブジェクト・リレーショナルまたはバイナリXML)に関係なく、このデータをエクスポートおよびインポートできます。ただし、Oracle Data Pumpはテキスト形式のXMLデータまたはバイナリXMLデータのみをエクスポートまたはインポートします。このため、XMLTypeのオブジェクト・リレーショナル記憶域に使用される、基礎となる表および列はエクスポートされません。それらの表および列は、バイナリ形式に変換され、自己記述的なバイナリXMLデータとしてエクスポートされます。

注意:

Oracle Data Pump for Oracle Database 11gリリース1(11.1)は、XML Schema、XML Schemaに基づくXMLType列またはバイナリXMLデータをリリース11.1より前のバージョンにエクスポートする機能をサポートしていません。

XMLType記憶域モデルに関係なく、ダンプ・ファイルの形式はテキストまたは自己記述的なバイナリXMLにトークン・マップ・プリアンブルを加えたもののいずれかになります。デフォルトでは、自己記述的なバイナリXMLが使用されます。

Oracle Data Pumpがこのデータをダンプ・ファイルに格納する方法は、エクスポート・パラメータdata_optionsの値に依存します(このパラメータに対して唯一有効な値は、xml_clobsです)。エクスポート・コマンドラインでこの値を指定すると、XMLTypeデータがすべてダンプ・ファイルにテキスト形式で格納されます。それ以外の場合、ダンプ・ファイルではバイナリXMLが使用されます。

注意:

エクスポート・パラメータdata_optionsの値xml_clobsは、Oracle Database 12cリリース1 (12.1.0.1)から非推奨になりました。

XMLTypeデータはXMLデータとしてエクスポートおよびインポートされるため、ソース・データベースおよびターゲット・データベースはそのデータに対して異なるXMLType記憶域モデルを使用できます。つまり、ある方式でXMLTypeデータが格納されたデータベースからデータをエクスポートし、それとは異なる方式でXMLTypeデータが格納されたデータベースへインポートできます。

注意:

XMLType記憶域モデルを使用しているかどうかにかかわらず、オプションtable_exists_action=appendを指定して、同じダンプ・ファイルからXMLType表に複数回インポートしないでください。XMLType表内の列は常に一意のオブジェクト識別子を使用してエクスポートおよびインポートされるため、これを行うと一意制約違反エラーが発生します。

table_exists_actionの詳細は、『Oracle Databaseユーティリティ』を参照してください。

37.2 Oracle XML DBリポジトリのエクスポート/インポートの制限事項

登録されたXML Schemaに基づいたOracle XML DBリポジトリ・リソースのデータを格納する表をエクスポートまたはインポートする場合は、そのXMLデータのみがエクスポートされます。リポジトリ構造はエクスポート中に失われるため、これらの表がインポートされたときは階層に対応していません。

登録されたXML Schemaに基づくOracle XML DBリポジトリ・リソースの場合、XMLデータを格納するXMLType表はエクスポートおよびインポートできます。

ただし、エクスポートされるのはXMLデータのみです。リポジトリ構造は、エクスポート中に失われます。フォルダ階層、行レベルのセキュリティ(RLS)ポリシーおよびパス索引トリガーの関係は、階層対応表にエクスポートされません。これらの表のインポート時には階層対応していません。

37.3 エクスポート/インポートの構文および例

コマンドexpdpおよびimpdpとXMLTypeデータを使用する場合のガイドラインおよび例を示します。

ここに示す例では、コマンドライン・コマンドexpdpおよびimpdpを使用します。このようなコマンドをユーザー名およびコマンド・パラメータとともに発行すると、パスワードの入力を要求されます。この例では、この入力要求は示されていません。

Oracle Data Pumpを使用したエクスポートおよびインポートはOracle Databaseユーティリティで説明されています。

37.3.1 表モード・エクスポート/インポートの実行

表モード・エクスポートおよび表モード・インポート、ダンプ・ファイルの送受信の実行の例をそれぞれ示します。

XMLType表は、それを定義するために使用されたXML Schemaに依存します。同様に、そのXML Schemaはそれ用に作成または指定されたSQLオブジェクト型に依存します。XMLType表をインポートするには、対応するXML SchemaおよびSQLオブジェクト型が存在する必要があります。

TABLEモード・エクスポートを使用すると、表関連のメタデータおよびデータのみがエクスポートされます。このデータを正常にインポートできるようにするには、関連するXML Schemaとオブジェクト型が作成済であることを確認する必要があります。

この項に示す例では、次のようなデータベースを使用していることを前提としています。

- スキーマuser23を使用したデータベース

- バイナリXMLとして格納されているXMLType列を持つ表user23.tab41

- READおよびWRITE権限が、expdpまたはimpdpを実行しているユーザーに対して与えられているディレクトリ・オブジェクトdpump_dir

例37-1に、TABLESパラメータを使用して表モード・エクスポートを指定する例を示します。これにより表tab41がダンプ・ファイルtab41.dmpにエクスポートされます。

注意:

表モードでは、expdpコマンドでスキーマ接頭辞を指定しないと、エクスポート側のスキーマがデフォルトで使用されます。

例37-2は表モード・インポートを示しています。これにより表tab41がダンプ・ファイルtab41.dmpからインポートされます。

このインポートの際にtab41という名前の表がすでに存在している場合は、table_exists_action = appendと指定すると、その表に行が追加されます。パラメータ値appendを使用すると、データは必ず新しい領域にロードされます。既存の領域が再利用されることはありません。このため、ロード操作後にはデータの圧縮が必要になることがあります。

関連項目:

Oracle Data Pumpおよびそのコマンドライン・クライアントexpdpおよびimpdpの詳細は、『Oracle Databaseユーティリティ』を参照してください。

例37-1 表モードでのXMLTypeデータのエクスポート

expdp system directory=dpump_dir dumpfile=tab41.dmp tables=user23.tab41

例37-2 表モードでのXMLTypeデータのインポート

impdp system tables=user23.tab41 directory=dpump_dir dumpfile=tab41.dmp table_exists_action=append

37.3.2 スキーマ・モード・エクスポート/インポートの実行

ここで示す例では、スキーマ・モード・エクスポートおよびインポートを実行します。スキーマ・モード・エクスポートを実行する際には、ロールEXP_FULL_DATABASEが割り当てられている場合、データベース・スキーマ、データベース・スキーマ定義、およびそのデータベース・スキーマのシステム権限をエクスポートできます。

この項に示す例では、次のようなデータベースを使用していることを前提としています。

- ユーザーx4aが表po2を作成済。

- ユーザーx4aが登録されたXML Schema ipoを持っており、そのXML SchemaがOrdered Collection Table item_oct2およびsitem_nt2を作成済。

ユーザーx4aは、例37-3に示すようにして表po2を作成します。

その後、例37-4に示すように表po2がデータが移入され、エクスポートされます。

例37-4では、次のものすべてがエクスポートされます。

- XML Schema、ipoの登録時に生成されたすべてのデータ型

- XML Schema、ipo

- XML Schema、ipoの登録時に生成された表po2およびOrdered Collection Table(OCT)、item_oct2およびsitem_nt2

- これらすべての表にあるすべてのデータ

例37-5は、x4a.dmp内のすべてのデータをユーザーx4aがすでに存在する他のデータベースにインポートします。

例37-6は例37-5と同じ動作をしますが、ユーザーx4aからユーザーquineへのデータベース・スキーマの再マップも行います。

例37-6は、x4a.dmp内のすべてのデータ(ユーザーx4aのデータベース・スキーマからエクスポートしたデータ)を、データベース・スキーマquineにインポートします。スキーマを再マップするには、ユーザーx4aがローカル・データベース上でIMP_FULL_DATABASEロールを、ソース・データベース上でEXP_FULL_DATABASEロールを付与されている必要があります。REMAP_SCHEMAは、すべてのオブジェクトをソース・スキーマからターゲット・スキーマにロードします。

注意:

XML Schemaをエクスポート元と同じデータベースにインポートするときに、このXML Schemaがインポート時にもOracle XML DBに登録されている場合、impdpパラメータtransform=oid:nも指定しないかぎり、remap_schemaを使用しないでください。パラメータtransformの詳細は、『Oracle Databaseユーティリティ』を参照してください。

例37-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;

例37-4 スキーマ・モードでのXMLTypeデータのエクスポート

expdp x4a directory=tkxm_xmldir dumpfile=x4a.dmp

例37-5 スキーマ・モードでのXMLTypeデータのインポート

impdp x4a directory=tkxm_xmldir dumpfile=x4a.dmp

例37-6 スキーマ・モードでのXMLTypeデータのインポート、スキーマの再マップ

impdp x4a directory=tkxm_xmldir dumpfile=x4a.dmp remap_schema=x4a:quine

38 Oracle Streams AQを使用したXMLデータの交換

XMLデータは、データベース統合化メッセージ・キューイングを提供するOracle Streamsアドバンスト・キューイング(AQ)を使用して交換できます。AQは、メッセージを使用して、アプリケーション間の非同期通信を可能にし、その管理を行います。 ポイント・ツー・ポイント通信モデルおよびパブリッシュ・サブスクライブ通信モデルをサポートします。

Oracle Databaseとメッセージ・キューイングの統合により、メッセージ・キューイングにOracle Databaseの整合性、信頼性、リカバリ能力、スケーラビリティ、パフォーマンスおよびセキュリティ機能が追加されます。また、メッセージ・フローからのインテリジェント機能の抽出が容易になります。

- XMLおよびOracle Streamsアドバンスト・キューイング

- Oracle Streamsおよびアドバンスト・キューイング

- オブジェクト型のXMLType属性

- Internet Data Access Presentation (iDAP): AQ用のSOAP

- iDAPアーキテクチャ

- XMLおよびOracle Streamsアドバンスト・キューイングを使用する場合のガイドライン

38.1 XMLおよびOracle Streamsアドバンスト・キューイング

Oracle Streamsアドバンスト・キューイング(AQ)は、ネイティブのXMLメッセージをサポートしています。AQ操作をXMLベースのInternet-Data-Access-Presentation (iDAP)形式で定義できます。iDAPは拡張可能なメッセージの起動プロトコルです。これはインターネット標準に基づいて構築され、転送メカニズムとしてHTTP(S)および電子メール・プロトコルを使用します。XMLがiDAP用のデータ表示用の言語です。

38.1.1 Oracle Streamsアドバンスト・キューイングおよびXMLメッセージ・ペイロード

XMLメッセージは、Oracle Streamsアドバンスト・キューイング(AQ)を使用してアプリケーション間で非同期に渡すことができます。

図38-1に、AQを使用して3つのアプリケーションと通信するOracle Databaseを示します。メッセージ・ペイロードはXMLデータです。この使用例においてAQが実行する一般的なタスクは、次のとおりです。

- サブスクリプション・ルールを使用したメッセージ・フロー

- メッセージ管理

- メッセージからのビジネス・インテリジェンスの抽出

- メッセージ変換

AQを使用してアプリケーション間で非同期にXMLメッセージを渡すユースケース:

- 企業内業務。典型的な使用例には、販売注文の遂行およびサプライチェーンの管理などがあります。

- 企業間業務処理。複数の統合ハブが、インターネットを介して通信できます。使用例には、旅行の予約、メーカーとサプライヤ間の調整、銀行間での資金の移動、保険請求の清算などがあります。
Oracleは、このアプローチを企業アプリケーション統合製品で使用します。XMLメッセージは、アプリケーションからAQハブへ送信されます。このハブは、メッセージを必要とするすべてのアプリケーションに対してメッセージ・サーバーとして機能します。このハブ・アンド・スポーク・アーキテクチャを介して、XMLメッセージを、疎結合された複数のアプリケーションへ非同期に送信できます。

図38-1に、AQを使用して、次のアプリケーションを介して配送したXMLペイロード・メッセージを示します。

- iDAPを使用し、HTTPおよびHTTPS接続を介したAQ操作を行うWebベースのアプリケーション

- Net*接続を介してXMLメッセージを伝播するために、AQを使用するアプリケーション

- AQを使用して、HTTP、HTTPSまたはSMTPを介してインターネットまたはXMLメッセージを直接データベースへ伝播するアプリケーション

図38-1は、AQクライアントが、OCI、JavaまたはPL/SQLを使用してデータにアクセスできることも示しています。

図38-1 Oracle Streamsアドバンスト・キューイングおよびXMLメッセージ・ペイロード

38.1.2 Oracle Streamsアドバンスト・キューイングを使用するメリット

Oracle Streamsアドバンスト・キューイング(AQ)によって、アプリケーション間の通信の構成の柔軟性が提供されます。統合されたソリューションの管理、構成およびビジネス・ニーズの変化に伴う変更が容易になります。複雑な業務トランザクションを実行するための、アプリケーションの協調、調整、同期化が可能になります。

AQが提供するメッセージ管理では、異なるアプリケーション間のメッセージ・フローを管理できます。AQは、監査や追跡目的、およびビジネス・インテリジェンスの抽出のためにもメッセージを保持できます。

AQは、メッセージにアクセスするためのSQLビューを提供します。これらのビューを使用して、動向を分析できます。

38.2 Oracle Streamsおよびアドバンスト・キューイング

Oracle Streamsを使用すると、ストリーム内のデータおよびイベントを共有できます。ストリームによって、データベース内またはデータベース間で情報を伝播し、指定した宛先に情報をルーティングできます。これによって、イベントを取得および管理し、他のデータベースおよびアプリケーションとイベントを共有するための機能性と柔軟性が提供されます。

Oracle Streamsを使用すると、あるソリューションを使用したために別のソリューションが使用できなくなるということがなくなります。分散した企業とアプリケーション、データ・ウェアハウスおよび高可用性ソリューションを構築および操作できます。

Oracle Streamsを使用して、次に示すすべてを実行できます。

- データベースでの変更の取得。バックグラウンドの取得プロセスが表、データベース・スキーマまたはデータベース全体に加えられた変更を取得するように構成できます。取得プロセスでは、REDOログから変更が取得され、取得された各変更が論理変更レコード(LCR)にフォーマットされます。REDOログに変更が生成されたデータベースをソース・データベースと呼びます。

- キューへのイベントのエンキュー。Streamsキューには、LCRおよびユーザー・メッセージという2つのタイプのイベントをステージングできます。取得プロセスでは、LCRイベントが、指定したキューにエンキューされます。そのキューは、LCRイベントを同じデータベース内で共有するか、または他のデータベースと共有できます。また、ユーザー・アプリケーションを使用してユーザー・イベントを明示的にエンキューすることもできます。明示的にエンキューされたこれらのイベントは、LCRまたはユーザー・メッセージになります。

- あるキューから別のキューへのイベントの伝播。これらのキューは、同じデータベース内または異なるデータベース内に存在できます。

- イベントのデキュー。バックグラウンドの適用プロセスによって、イベントをデキューできます。また、ユーザー・アプリケーションを使用してイベントを明示的にデキューすることもできます。

- データベースでのイベントの適用。適用プロセスがキュー内のすべてのイベントまたは指定したイベントのみを適用するように構成できます。また、適用プロセスが、ユーザー独自のPL/SQLサブプログラムをコールしてイベントを処理するように構成することもできます。
LCRイベントが適用され、他のタイプのイベントが処理されるデータベースを宛先データベースと呼びます。構成によっては、ソース・データベースと宛先データベースが同じ場合もあります。

38.2.1 Oracle Streamsのメッセージ・キューイング

Oracle Streamsにより、アプリケーションでメッセージをエンキュー、伝播およびデキューできます。

Oracle Streamsでは、SYS.AnyData型のメッセージがステージングされます。ほぼすべての型のメッセージをSYS.AnyDataラッパーでラップし、SYS.AnyDataキューにステージングできます。Oracle Streamsアドバンスト・キューイング(AQ)では、マルチ・コンシューマ・キュー、パブリッシュおよびサブスクライブ、コンテンツベースのルーティング、インターネット伝播、変換、他のメッセージ・サブシステムへのゲートウェイなど、メッセージ・キューイング・システムのすべての標準機能がサポートされます。

関連項目:

『Oracle Streams概要および管理』 およびその付録Aの「LCRのXML Schema」を参照してください。

38.3 オブジェクト型のXMLType属性

XMLType属性を持つOracleオブジェクト型を使用するキューを作成できます。これらのキューは、XML文書であるメッセージを転送および格納するために使用できます。

XMLTypeを使用すると、次の操作を実行できます。

- 任意の型のメッセージをキューに格納する。

- 文書をCLOBインスタンスとして内部的に格納します

- 複数の型のペイロードをキューに格納する。

- XMLExistsなどのSQL/XML関数を使用してXMLType列を問い合せる。

- サブスクライバ・ルールまたはデキュー条件にその演算子を指定する。

38.4 Internet Data Access Presentation (iDAP): AQ用のSOAP

インターネット上でSimple Object Access Protocol (SOAP)を使用してOracle Streams Advanced Queuing (AQ)にアクセスできます。Internet Data Access Presentation (iDAP)は、AQ操作に対するSOAP仕様です。iDAPは、SOAP Request Bodyの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 Databaseアドバンスト・キューイング・ユーザーズ・ガイド

38.5 iDAPアーキテクチャ

HTTP(S)を使用するOracle Streamsアドバンスト・キューイング操作には、iDAP HTTPクライアント、WebサーバーおよびOracleサーバーが必要です。

図38-2に、これらのコンポーネント間の関係を示します。

- クライアント・プログラムは、iDAP形式に準拠したXMLメッセージをAQサーブレットに送信します。これには、Webブラウザなど任意のHTTPクライアントが含まれます。

- Webサーバーまたはサーブレット・コンテナは、Apache JServ、Tomcatなど、受信したXMLメッセージを解析するためのAQサーブレットをホストします。

- Oracle Streams AQサーブレットは、Oracle Databaseに接続し、キュー操作を実行します。

図38-2 HTTPまたはHTTPSを使用してAQ操作を実行するためのiDAPアーキテクチャ

38.5.1 XMLTypeキュー・ペイロード

XMLType 属性を含むペイロードを持つキューを作成できます。これらのペイロードは、XML文書を含むメッセージの転送および格納に使用できます。

XMLType属性を持つOracleオブジェクトを定義すると、次の操作を実行できます。

- 複数の型のXML文書を同じキュー内に格納します。この文書は、CLOBインスタンスとして内部的に格納されます。

- XMLExistsやXMLQueryなどのSQL/XML関数を使用して、XMLType属性を持つメッセージを選択的にデキューします。

- 変換を定義して、OracleオブジェクトをXMLTypeに変換します。

- XMLExistsやXMLQueryなどのSQL/XML関数を使用して、メッセージ内容を問い合せるルールベースのサブスクライバを定義します。

この例で示すアプリケーションの海外向け出荷サイトでは、注文がSYS.XMLTypeを使用して表現されると想定します。注文入力サイトでは、注文がOracleオブジェクトのORDER_TYPとして表現されます。

例38-1では、海外向け出荷用のキュー表およびキューを作成します。

海外向け出荷サイトの注文の表現は、注文入力サイトでの注文の表現と異なるため、メッセージは注文入力サイトから海外向け出荷サイトに送信される前に変換される必要があります。例38-2では変換を作成し、例38-3でそれを適用します。

注文入力アプリケーションによって使用される型から、海外向け出荷によって使用される型への変換の定義の詳細は、Oracle Databaseアドバンスト・キューイング・ユーザーズ・ガイドを参照してください。

例38-4では、別の国(この場合はカナダ)の顧客の注文を処理するアプリケーションで、メッセージをどのようにデキューできるかを示しています。

例38-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;
/

例38-2 メッセージ・データをXMLに変換するための変換の作成

CREATE OR REPLACE FUNCTION convert_to_order_xml(input_order ORDER_TYP)
RETURN XMLType AS
new_order XMLType;
BEGIN
SELECT XMLElement("Row", 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;
/

例38-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;
/

例38-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;
/

38.6 XMLおよびOracle Streamsアドバンスト・キューイングを使用する場合のガイドライン

XMLデータおよびOracle Streamsアドバンスト・キューイングを使用する場合のガイドラインを示します。

38.6.1 多くのPDFファイルを持つOracle Streams AQ XMLメッセージを1つのレコードとして格納する方法

Oracle Streamsアドバンスト・キューイング(AQ)を使用して、企業間でXML文書を交換できます。各メッセージには、XMLヘッダー、XMLアタッチメント(XMLデータ・ストリーム)、DTDおよびPDFファイルが含まれます。データは、キュー表などのデータベース表に格納できます。

メッセージは、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);

次に、このオブジェクト型を単一のメッセージとして格納します。

38.6.2 メッセージをエンキューした後の新しい受信者の追加

キュー表を使用して、メッセージ割当てをサポートできます。

たとえば、他の企業は、メッセージを特定の企業に送信するときに、これらのメッセージを処理するために誰が割り当てられるかは認識していません。ただし、そのメッセージが人事部(HR)宛てであることは認識しています。そのため、すべてのメッセージは人事部管理者へ送信されます。この時点で、メッセージはキュー表にエンキューされます。このメッセージの受信者は人事部管理者のみであり、その他のすべての人事部社員はこのキューのサブスクライバとして事前定義されています。

メッセージがエンキューされた後に受信者のリストを変更することはできません。受信者のリストを指定しない場合、サブスクライバはそのキューをサブスクライブし、メッセージをデキューできます。この場合は、新しい受信者がそのキューのサブスクライバである必要があります。それ以外の場合は、メッセージをデキューし、そのメッセージを新しい受信者が再度エンキューする必要があります。

38.6.3 XMLメッセージのエンキューおよびデキュー

Oracle Streams AQは、オブジェクトのエンキューおよびデキューをサポートします。このオブジェクトは、メタデータ属性に加えて、XML文書を含むXMLType型の属性を持つことができます。

詳細および例は、『Oracle Databaseアドバンスト・キューイング・ユーザーズ・ガイド』を参照してください。

38.6.4 XMLコンテンツを持つメッセージのOracle Streams AQキューからの解析

XMLコンテンツを持つメッセージをOracle Streamsアドバンスト・キューイング(AQ)キューから解析し、Operational Data Store (ODS)にある表およびフィールドを更新できます。

Oracle Streams AQと同時に、Oracle XML Parser for JavaおよびJavaストアド・プロシージャを使用すると、特定のXMLデータをターゲットにする問合せに基づいて、AQエンキューまたはAQデキューの回数やJMSヘッダー情報などのメタデータを取得できます。この方法は、Oracle Text XML検索とともに使用できます。

関連項目:

XQueryを使用しないXMLデータの全文検索

38.6.5 XML文書が処理されるまでのリスナー停止の回避

メッセージを受信後、PL/SQLパッケージDBMS_JOBを使用してジョブを送信できます。ジョブは、異なるデータベース・セッションで非同期に起動されます。リスナーは受信したXMLメッセージが処理されるまで待機する必要があるため、これによってメッセージがキューに蓄積するのを防ぐことができます。

クライアントからのXMLメッセージの受信後、すぐにメッセージを処理する必要がある場合があります。しかし、各XML文書は処理数秒かかります。PL/SQLでは、XML文書を処理するために、1つのプロシージャがリスナーの開始、メッセージのデキュー、別のプロシージャのコールを行います。リスナーはXML文書が処理されるまで停止し、その間メッセージがキューに蓄積されます。

メッセージを受信後、かわりにPL/SQLパッケージDBMS_JOBを使用してジョブを送信できます。ジョブは、異なるデータベース・セッションで非同期に起動されます。

メッセージがキューに入れられると非同期に起動されるPL/SQLコールバックを登録できます。PL/SQLコールバックは、 Oracle Streams AQ通知フレームワークの一部です。

38.6.6 AQでのHTTPSの使用

HTTPSを使用してXMLメッセージをサプライヤに送信し、レスポンスを受信するために、Oracle Streamsアドバンスト・キューイング(AQ)のインターネット・アクセス機能を使用できます。確実なトランザクション処理でHTTP(S)を介してXMLメッセージをエンキューまたはデキューできます。

関連項目:

Oracle Databaseアドバンスト・キューイング・ユーザーズ・ガイド

38.6.7 Oracle Streams AQメッセージ・ペイロードへのXMLの格納

SYS.XMLTypeが含まれるADTをペイロードとして使用する以外にも、XMLをOracle Streamsアドバンスト・キューイング(AQ)メッセージ・ペイロードにネイティブに格納できます。ペイロードとXMLType属性を持つキューを作成できます。

38.6.8 iDAPとSOAP

iDAPはOracle Streamsアドバンスト・キューイング(AQ)操作のためのSOAP仕様です。SOAPは、サービスを起動するための共通のメカニズムを定義します。iDAPは、AQ操作を実行するためのメカニズムを定義します。

iDAPには、SOAPが定義していない、次の主要なプロパティが含まれます。

- トランザクション動作。AQ操作をトランザクションとして実行できます。トランザクションは、複数のiDAPリクエストにまたがることができます。

- すべてのiDAP操作は、許可済ユーザーおよび認証済ユーザーのみが実行できます。

第VIII部 JSON

Oracle DatabaseでJSONを使用できます。

- Oracle DatabaseのJSON

39 Oracle DatabaseのJSON

Oracle Databaseは、トランザクション、索引付け、宣言的問合せおよびビューを含むリレーショナル・データベースの機能を使用してJavaScript Object Notation (JSON)データをネイティブにサポートしています。

- JSONの概要

- Oracle DatabaseにおけるJSONの概要

- JSON: Oracle Databaseのキャラクタ・セットおよび文字エンコーディング

- Oracle JSONパス式

- JSONデータで使用するためのOracle SQL関数および条件

- JSONデータに対する単純なドット表記法アクセス

- JSONデータの索引

- JSONデータの全文検索

- 外部JSONデータのロード

- JSONデータのレプリケーション

- JSONに対するOracle Databaseのサポート

39.1 JSONの概要

JavaScript Object Notation (JSON)は、標準ECMA-404 (JSONデータ交換フォーマット)およびECMA-262 (ECMAScript言語仕様、第3版)で定義されています。ECMAScriptのJavaScript言語は、WebブラウザおよびWebサーバーで広く使用されている汎用プログラミング言語です。

JSONは、JavaScriptのオブジェクト・リテラル表記法のサブセットであるとも言えます。脚注1JSONは、JavaScriptのオブジェクト・リテラルを表すために使用できるため、一般的にデータ交換言語として機能します。この点において、XMLとよく似ています。

JSONは、JavaScript表記法(のサブセットとも言える表記法)であるため、多くの場合、解析やシリアライズを行う必要なくJavaScriptプログラムで使用できます。これは、JavaScriptのオブジェクト・リテラル、配列およびスカラー・データを表すテキスト・ベースの方法です。

JSONは、JavaScriptのコンテキストで定義されているため、実際には言語に依存しないデータ・フォーマットです。JSONデータは様々なプログラミング言語で解析および生成できます。

JSONは、人間にとっては読み書きが比較的簡単であり、ソフトウェアにとっては解析および生成が簡単です。多くの場合、構造化されたデータをシリアライズし、通常はサーバーとWebアプリケーション間でネットワークを介して交換するために使用されます。

関連項目:

- JSONデータ交換フォーマットの定義は、http://www.ecma-international.org/publications/standards/Ecma-404.htmおよびhttp://tools.ietf.org/html/rfc4627を参照してください。

- ECMAScript言語仕様の詳細は、http://www.ecma-international.org/publications/standards/Ecma-262.htmを参照してください。

- JSONの詳細は、http://www.json.orgを参照してください。

- ECMAScript (JavaScript)の詳細は、http://www.ecmascript.orgを参照してください。

39.1.1 JSON構文およびJSON構文が表すデータの概要

JSON (およびJavaScript)の値、スカラー、オブジェクトおよび配列について説明します。

JSON value は、object、array、number、string、、、またはnullのいずれかです。オブジェクトおよび配列を除くすべての値はスカラーです。

注意:

JSON値のnullは、SQLに関するかぎり、1つの値です。これは、SQLで値の欠如(存在しないデータ、不明なデータまたは適用できないデータ)を表すNULLとは異なります。特に、SQL条件のIS NULL条件は、JSONのnull値に対してfalseを戻し、SQL条件のIS NOT NULLはtrueを戻します。

JavaScriptオブジェクトは、0個以上のプロパティ名および関連するJSON値のペアの連想配列またはディクショナリです。脚注3 これは、中カッコ({、})で囲まれたプロパティ・リストとして作成されますが、この場合、名前と値のペアはカンマ(,)で区切られ、各ペアの名前と値はコロン(:)で区切られます。

JSONでは、各プロパティ名および各文字列値は、二重引用符(")で囲む必要があります。JavaScript表記法では、オブジェクト・リテラルで使用されるプロパティ名は、二重引用符で囲むことができますが、必須ではありません。これはまた、一重引用符(')で囲むこともできます。

こうした違いの結果、実際には、引用符で囲まれていないプロパティ名か一重引用符で囲まれたプロパティ名を使用して表されたデータが、JSONで表されているように緩やかに参照される場合があり、Oracle Database実装を含むJSON実装では、引用符で囲まれていないプロパティ名も、一重引用符で囲まれたプロパティ名も使用できる柔軟な構文がサポートされます。

JSONの文字列は、バックスラッシュ(\)によるエスケープを使用したUnicode文字で構成されています。JSONの数値(数字)は10進数表記法で表され、符号が付いている場合や10進数指数が含まれる場合があります。

オブジェクト・プロパティは、多くの場合フィールドと呼ばれます。オブジェクト・プロパティの名前と値のペアは、オブジェクト・メンバーと呼ばれる場合があります。オブジェクト・メンバー間の順序は重要ではありません。

注意:

- JSONフィールド名は空("" )にできます。脚注 4

- 特定のJSONオブジェクト内のフィールド名は、それぞれが一意である必要はありません。同じフィールド名を繰り返すことができます。Oracle Databaseで採用されているJSONパスの評価では常に、特定のフィールド名を持つオブジェクト・メンバーの1つのみが使用されます。同じ名前を持つ他のメンバーは無視されます。このような複数のメンバーのうちどれが使用されるかは指定されていません。
"JSONオブジェクトの一意フィールドと重複フィールドを参照してください。

JavaScript配列には、0個以上の要素があります。JSONでは、配列は配列の要素を囲む大カッコ([、])によって表され、これらの要素はカンマ(,)によって区切られ、それぞれがオブジェクト、配列またはスカラー値です。配列要素の順序は重要ではありません。

例39-1は、発注書を表すJSONオブジェクトを示しており、最上位のフィールド名はPONumber、Reference、Requestor、User、Costcenter、ShippingInstruction、Special Instructions、AllowPartialShipmentおよびLineItemsです。

- ほとんどのフィールドには文字列値があります。たとえば、フィールドUserには値"ABULL"があります。

- フィールドPONumberおよびzipCodeにはそれぞれ数値1600および99236があります。

- フィールドShipping Instructionsには値としてオブジェクトがあります。このオブジェクトには、フィールドname、AddressおよびPhoneを持つ3つのメンバーがあります。フィールドnameには文字列値("Alexis Bull")があります。フィールドAddressおよびPhoneにはそれぞれオブジェクト値があります。

- フィールドAddressの値は、フィールドstreet、city、state、zipCodeおよびcountryを持つオブジェクトです。フィールドzipCodeには数値があります。他のフィールドには文字列値があります。

- フィールドPhoneには値として配列があります。この配列には2つの要素があり、それぞれがオブジェクト・リテラルを表します。これらの各オブジェクトには、フィールドtypeおよびnumberの2つのメンバーとそれらの値があります。

- フィールドSpecial Instructionsにはnull値があります。

- フィールドAllowPartialShipmentにはブール値trueがあります。

- フィールドLineItemsには値として配列があります。この配列には2つの要素があり、それぞれがオブジェクトを表します。これらの各オブジェクトには、フィールドItemNumber、PartおよびQuantityを持つ3つのメンバーがあります。

- フィールドItemNumberおよびQuantityには数値があります。フィールドPartには値として、フィールドDescription、UnitPriceおよびUPCCodeを持つオブジェクトがあります。フィールドDescriptionには文字列値があります。フィールドUnitPriceおよびUPCCodeには数値があります。

関連項目:

- 「厳密なJSON構文と緩慢なJSON構文について」

- 例39-4

例39-1 A JSONオブジェクト(JavaScriptのオブジェクト・リテラルの表現)

{ "PONumber"             : 1600,
"Reference"            : "ABULL-20140421",
"Requestor"            : "Alexis Bull",
"User"                 : "ABULL",
"CostCenter"           : "A50",
"ShippingInstructions" : { "name"   : "Alexis Bull",
"Address": { "street"  : "200 Sporting Green",
"city"    : "South San Francisco",
"state"   : "CA",
"zipCode" : 99236,
"country" : "United States of America" },
"Phone" : [ { "type" : "Office", "number" : "909-555-7307" },
{ "type" : "Mobile", "number" : "415-555-1234" } ] },
"Special Instructions" : null,
"AllowPartialShipment" : false,
"LineItems"            : [ { "ItemNumber" : 1,
"Part"       : { "Description" : "One Magic Christmas",
"UnitPrice"   : 19.95,
"UPCCode"     : 13131092899 },
"Quantity"   : 9.0 },
{ "ItemNumber" : 2,
"Part"       : { "Description" : "Lethal Weapon",
"UnitPrice"   : 19.95,
"UPCCode"     : 85391628927 },
"Quantity"   : 5.0 } ] }

39.1.2 XMLと比較したJSONの概要

一般的に、JSONとXML (Extensible Markup Language)は両方ともデータ交換言語として使用されます。主な違いは次のとおりです。

- JSONのデータ型は数が少なく、事前に定義されています。XMLデータは、型がないか、XML SchemaまたはDocument Type Definition (DTD)に基づいています。

- JSONには、単純な構造定義および文書結合構造体がありますが、属性、名前空間、継承および代替はありません。

- JavaScriptのオブジェクト・リテラルのメンバーの順序は重要ではありません。通常、順序が問題になるのはXML文書内です。

- JSONには、XMLのテキスト・ノード(XPathノード・テストtext())に相当するものがありません。これは特に、混合コンテンツがないことを意味します。

JSONは、単純な構造データで使用する場合に最も役立ちます。XMLは、構造化されたデータと半構造化されたデータの両方で役立ちます。通常、JSONは文書中心ではなくデータ中心ですが、XMLはどちらにも対応しています。JSONはマークアップ言語ではなく、データ表現のみを目的として設計されています。XMLは、文書マークアップ言語とデータ表現言語の両方を兼ねています。

通常、JSONデータの方がXMLデータより、定義および機能が単純であるため、生成、解析および処理が簡単です。XMLにはモジュール性と継承の役に立つ名前空間および他の構造体が用意されているため、通常、様々なデータ・ソースの結合が関わるユースケースはXMLの使用に適しています。

JSONには、XML (またはJavaScript)とは異なり、日付データ型がありません。JSONでは、日付は文字列などの使用可能なデータ型を使用して表されます。実際の日付と文字列間における変換には、事実上の業界標準がいくつかあります。ただし、いずれにせよ、JSONを使用するプログラムでは日付表現の変換を処理する必要があります。

39.2 Oracle DatabaseにおけるJSONの概要

JSONデータとXMLデータは、Oracle Databaseでは同等の方法で使用できます。リレーショナル・データとは異なり、両方とも、データを定義するスキーマを必要とせずに格納、索引付けおよび問合せを行うことができます。Oracle Databaseは、トランザクション、索引付け、宣言的問合せおよびビューを含むリレーショナル・データベースの機能を使用してJSONをネイティブにサポートしています。

多くの場合、JSONデータは、Oracle NoSQL DatabaseおよびOracle Berkeley DBなどのNoSQLデータベースに格納されています。これらを使用すると、スキーマに基づいていないデータを格納および取得できますが、これらにはリレーショナル・データベースの厳密な整合性モデルは用意されていません。

このような短所を補うために、場合によっては、NoSQLデータベースと並行してリレーショナル・データベースが使用されます。したがって、NoSQLデータベースに格納されたJSONデータを使用するアプリケーションでは、データの整合性をそれ自体で確保する必要があります。

JSONがOracle Databaseでネイティブにサポートされることで、このような負荷を未然に防ぐことができます。トランザクション、索引付け、宣言的問合せおよびビューなどの、JSONで使用するためのリレーショナル・データベース機能のメリットすべてを利用できます。

Oracle Databaseの問合せは宣言的に行われます。JSONデータはリレーショナル・データに結合できます。また、JSONデータをリレーショナルに投影できるため、JSONデータはリレーショナルなプロセスおよびツールで使用できるようになります。さらに、データベースの外部で外部表に拡張されたJSONデータをデータベース内で問い合せることもできます。

データベースに格納されたJSONデータには、他のデータベース・データへのアクセスと同じ方法(OCI、.NETおよびJDBCの使用を含む)でアクセスできます。

SQLデータ型XMLTypeを使用して格納されるXMLデータとは異なり、JSONデータは、SQLデータ型VARCHAR2、CLOBおよびBLOBを使用してOracle Databaseに格納されます。列値が有効なJSONインスタンスであることを確認するために、常にis_jsonチェック制約を使用することをお薦めします(例39-3を参照)。

データベース内のJSONデータはテキストですが、このテキストはデータ型BLOBのみでなくVARCHAR2またはCLOBを使用して格納できます。可能な場合、BLOB記憶域の使用をお薦めします。特に、そうするとキャラクタ・セット変換の必要がなくなります(「JSON: Oracle Databaseのキャラクタ・セットおよび文字エンコーディング」を参照してください)。

注意:

Hadoop Distributed File System (HDFS)に基づく外部表に格納されたJSONデータは、LOB記憶域が使用されている場合は、Oracle Big Data SQLにオフロードされません。Oracle Big Data Applianceソフトウェア・ユーザーズ・ガイドを参照してください。

JSONデータをBLOB列に格納する場合、JSONに対してOracle SQL関数または条件(json_value、json_query、json_table、json_exists)を使用する問合せでキーワードFORMAT JSONを使用して、データがJSONであることを宣言する必要があります。これを行わない場合、エラーが発生し、JSON入力データがバイナリであり、その形式を指定していないことが通知されます。

注意:

JSONデータをBLOBまたはCLOB列に格納する場合は常に、この列に対してLOBキャッシュ・オプションをオンにすることをお薦めします。このオプションは、デフォルトで選択が解除されています。『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照してください。

定義上、テキストのJSONデータは、Unicodeエンコーディング(UTF-8またはUTF-16)を使用してエンコードされます。非Unicodeキャラクタ・セットで格納されたテキスト・データはJSONデータであるかのように使用できますが、この場合、このキャラクタ・セットはデータの処理時に自動的にUTF-8に変換されます。

SQLでは、Oracle Databaseに格納されたJSONデータには、次を使用してアクセスできます。

- 関数json_value、json_query、 and json_table。

- 条件json_exists、is json、is not jsonおよびjson_textcontains。

- json_valueとjson_queryの組合せと同じように機能し、SQLオブジェクトのアクセス式と似たドット表記法(つまり、抽象データ型(ADT)の属性ドット表記法)。

単純な実例として、例39-2では単純なドット表記法を使用して、すべての発注書の要求者についてJSON列po_documentを問い合せています(JSONフィールドRequestor)。

関連項目:

- 「Oracle JSONパス式」

- 「JSONデータで使用するためのOracle SQL関数および条件」

- 「JSONデータに対する単純なドット表記法アクセス」

- 「JSONに対するOracle Databaseのサポート」

- キャラクタ・セットの自動変換の詳細は、「JSON: Oracle Databaseのキャラクタ・セットおよび文字エンコーディング」を参照してください。

例39-2 JSONデータの単純なSQL問合せ

SELECT po.po_document.Requestor FROM j_purchaseorder po;

39.2.1 Oracle DatabaseでJSONを使用する前に

一般的に、Oracle DatabaseでJSONデータを扱う場合に実行するタスクには、(1)is jsonチェック制約を使用したJSON列の作成、(2)列へのJSONデータの挿入、(3)JSONデータの問合せがあります。

1. JSON列があるリレーショナル表を作成し、この列に整形式のJSONデータのみを確実に含めるためにis jsonチェック制約を追加します。

次の文では、JSON列po_documentを使用してリレーショナル表j_purchaseorderを作成しています(例39-3も参照)。

CREATE TABLE j_purchaseorder
(id          RAW (16) NOT NULL,
date_loaded TIMESTAMP WITH TIME ZONE,
po_document CLOB
CONSTRAINT ensure_json CHECK (po_document IS JSON));

2. Oracle Databaseで使用可能な任意のメソッドを使用してJSON列にJSONデータを挿入します。

次の文では、SQL INSERT文を使用して単純なJSONデータを挿入しています。ここでは、一部のデータが省略されています(...)。これらの詳細は、例39-4を参照してください。

INSERT INTO j_purchaseorder
VALUES (SYS_GUID(),
SYSTIMESTAMP,
'{"PONumber"             : 1600,
"Reference"            : "ABULL-20140421",
"Requestor"            : "Alexis Bull",
"User"                 : "ABULL",
"CostCenter"           : "A50",
"ShippingInstructions" : {...},
"Special Instructions" : null,
"AllowPartialShipment" : true,
"LineItems"            : [...]}');

3. JSONデータを問い合せます。戻り値は常に、JSON値を表すVARCHAR2インスタンスです。ここでは、単純な例をいくつか示します。

次の問合せでは、列po_document内の各JSON文書から、スカラー値(JSON列po_document内のオブジェクトのフィールドPONumberの値であるJSON数値)を抽出しています(例39-18も参照)。

SELECT po.po_document.PONumber FROM j_purchaseorder po;

次の問合せでは、JSON列po_document内の各文書から、JSON電話オブジェクトの配列(フィールドShippingInstructionsの値のフィールドPhoneの値)を抽出しています(例39-19も参照)。

SELECT po.po_document.ShippingInstructions.Phone FROM j_purchaseorder po;

次の問合せでは、各JSON文書から、複数の値(配列Phone内の各オブジェクトのフィールドtypeの値)を配列として抽出しています。戻される配列は、格納されているデータの一部ではありませんが、問合せによって自動的に構成されます。(配列要素の順序は指定されません。)

SELECT po.po_document.ShippingInstructions.Phone.type FROM j_purchaseorder po;

関連項目:

- 「列にJSONデータが含まれることを確認するためのチェック制約の使用」

- 「JSONデータに対する単純なドット表記法アクセス」

39.3 JSON: Oracle Databaseのキャラクタ・セットおよび文字エンコーディング

テキストのJSONデータでは常にUnicodeキャラクタ・セットが使用されます。この点で、JSONデータの方がXMLデータより簡単に使用できます。これは、JSONデータ交換フォーマットの重要な部分です(RFC 4627)。Oracle Databaseで処理されるJSONデータでは、必要なキャラクタ・セットの変換が自動的に行われます。

Oracle Databaseでは、JSONデータの処理時にUTF-8を内部で使用します(解析、問合せ)。このような処理に入力されるデータまたはこのような処理から出力されるデータをUTF-8とは異なるキャラクタ・セットにする必要がある場合は、適切なキャラクタ・セット変換が自動的に実行されます。

キャラクタ・セット変換はパフォーマンスに影響する可能性があります。また、情報が失われる可能性もあります。入力データをUTF-8に変換する操作では情報が失われる可能性は高くありませんが、出力キャラクタ・セットで表すことができない文字の場合、出力への変換の結果として情報の損失が発生する可能性があります。

テキストのJSONデータがUnicodeのようにデータベースに格納されている場合、キャラクタ・セットの変換は必要ありません。これは、データベースのキャラクタ・セットがAL32UTF8 (Unicode UTF-8)である場合です。可能である場合、このようにすることをお薦めします。

テキストとして(つまり、文字として)格納されていないJSONデータでキャラクタ・セット変換が行われることはありません。この場合、変換する文字がありません。このことは、データ型BLOBを使用して格納されているJSONデータではキャラクタ・セット変換が行われないことを意味します。

JSONデータが非Unicodeキャラクタ・データとして格納されている(つまり、Unicode以外のVARCHAR2またはCLOBでの格納が使用されている)場合は、キャラクタ・セット変換を回避するために次の実行を検討してください。

- json_valueなどのOracle SQL関数の戻り値に対してVARCHAR2ではなくNUMBERを使用します。

- 入力時に特定のUnicode文字をエスケープします。「JSONデータ内のUnicode文字のエスケープ」を参照してください"

関連項目:

- Unicodeの詳細は、http://www.unicode.orgを参照してください。

- JSONデータ交換フォーマットの詳細は、http://tools.ietf.org/html/rfc4627およびhttp://www.ecma-international.org/publications/standards/Ecma-404.htmを参照してください。

- データベースでの様々なキャラクタ・セットの使用の詳細は、『Oracle Database Migration Assistant for Unicodeガイド』を参照してください。

- データベースでのキャラクタ・セット変換の詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。

39.3.1 JSONデータ内のUnicode文字のエスケープ

ASCII文字は、Unicodeの最初の128文字に直接対応しています。アプリケーションでASCIIエスケープ・シーケンスを使用することにより、別の方法ではキャラクタ・セット変換が必要になる可能性がある入力Unicode文字を表すことができる場合、このような変換によって生じる可能性があるパフォーマンス・ペナルティまたは情報の紛失を回避できます。

Unicode文字に対するASCIIのエスケープ・シーケンスは、\uの後ろに、この文字のUnicodeコード・ポイントを表すASCIIの16進数字を4つ付けたものです。

たとえば、EURO SIGNという名前のUnicodeのユーロ文字€,はコード・ポイント20AC (16進数字を使用)を持つため、ASCIIのエスケープ・シーケンス\u20ACを使用して表すことができます。

入力データには明示的なASCIIのエスケープを使用できます。JSONデータにはUnicodeが内部で使用されるため、このデータが出力される場合、デフォルトではキャラクタ・セット変換が引き続き適用されます。ただし、Oracle SQL関数json_value、json_queryおよびjson_tableの場合、キーワードASCIIを使用することにより、非ASCII Unicode文字に対してASCIIのエスケープ・シーケンスを自動的に使用するよう指定できます。

関連項目:

「JSON用のOracle SQL関数のRETURNING句」

39.4 Oracle JSONパス式の概要

Oracle Databaseでは、Oracle SQLパス式を使用したJSONデータへのSQLアクセスが提供されます。

JSONは、JavaScript値の表記法です。JSONデータがデータベースに格納されている場合、XMLデータ用のXQueryまたはXPath式とある程度似たパス式を使用してこのデータを問い合せることができます。SQL/XMLでXQuery式を使用してXMLデータに対するSQLのアクセスが許可されるのと同じように、Oracle Databaseでは、Oracle JSONパス式を使用してJSONデータに対するSQLのアクセスが提供されます。

Oracle JSONパス式の構文は単純です。Oracle JSONパス式では、この式と一致するかこの式を満たす0個以上のJSON値が選択されます。

Oracle SQL条件json_existsの場合、少なくとも1つの値が一致する場合はtrueが戻され、一致する値がない場合はfalseが戻されます。単一の値が一致した場合、この値がスカラーである場合はSQL関数json_valueによってこの値が戻され、スカラーでない場合はエラーが発生します。パス式に一致する値がない場合は、json_valueによってSQL NULLが戻されます。

Oracle SQL関数json_queryは、一致する値をすべて戻します。つまり、この関数は複数の値を戻すことができます。この動作は、XQueryの場合のように値のシーケンスを戻す動作とみなすことも、複数の値を戻す動作とみなすこともできます。(ユーザーから見えるシーケンスが現れることはありません。)

どのような場合でも、パス式の照合では、パス式の各ステップを順番に照合しようとします。いずれかのステップの照合が失敗すると、後続のステップの照合は行われず、パス式の照合は失敗します。各ステップの照合が成功すると、パス式の照合は成功します。

関連項目:

パス式のステップの詳細は、「Oracle JSONパス式の構文」を参照してください。

39.4.1 Oracle JSONパス式の構文

Oracle SQLパス式は、パスの部分を選択するためにOracle SQLファンクションおよび条件によってJSONデータと照合されます。パス式にはワイルドカードおよび配列範囲を使用できます。

Oracle JSONパス式およびJSONデータをOracle SQL関数または条件に渡します。パス式はデータに対して照合され、一致するデータが特定のSQL関数または条件によって処理されます。この照合プロセスは、パス式が一致データを関数または条件に戻すという観点で検討することができます。

関連項目:

- 「Oracle JSONパス式の基本的な構文」

- 「Oracle JSONパス式の構文の緩和」

- 「JSONデータで使用するためのOracle SQL関数および条件」

- 「厳密なJSON構文と緩慢なJSON構文について」

39.4.1.1 Oracle JSONパス式の基本的な構文

Oracle JSONパス式の基本的な構文は、次のとおりです。コンテキスト項目の性質に応じて、コンテキスト項目、0(ゼロ)または複数のオブジェクト・ステップまたは配列ステップ構成されます。例を示します。

ただし、この基本的な構文は、非配列パターンに対する配列の照合および配列パターンに対する非配列の照合の緩和によって拡張されます。「Oracle JSONパス式の構文の緩和」を参照してください。

- Oracle JSONパス式は、パス式のコンテキスト項目(つまり、照合するJSONデータ)を表すドル記号($)から始まります。このデータは、Oracle SQL関数に引数として渡されたSQL式の評価結果です。
ドル記号の後ろには0個以上のステップが続き、これらの各ステップは、コンテキスト項目がJSONオブジェクトとJSON配列のどちらを表すかに応じてオブジェクト・ステップまたは配列ステップになります。

- オブジェクト・ステップは、場合によっては"ドット"と呼ばれるピリオド(.)の後ろに、オブジェクト・プロパティ(キー)名、またはすべてのフィールド(の値)を表すアスタリスク(*)ワイルドカードが付いた形式です。キー名は、大文字または小文字の文字A-Zで始まり、このような文字または10進数字(0-9)のみを含む必要があり、それ以外の場合は、二重引用符(")で囲む必要があります。オブジェクト・ステップは、指定されたキーの値を戻します。キーにワイルドカードが使用されている場合、すべてのキーの値が特に順序は指定されずに戻されます。

- 配列ステップは、左大カッコ([)の後ろに、すべての配列要素を表すアスタリスク(*)ワイルドカードまたはカンマで区切られた1つ以上の特定の配列索引または範囲指定のどちらかが続き、その後ろに右大カッコ(])が付いた形式です。パス式では、配列に対するJavaScript変換の場合のように、配列索引付けは0を基準として行われます(0、1、2、...)。範囲指定の形式はNからMであり、NおよびMは配列索引であり、Nは必ずMより小さい値である必要があります。(NがMより小さい値でない場合、問合せのコンパイル時にエラーが発生します。)アスタリスクと配列索引または範囲指定の両方を使用すると、エラーが発生します。
索引または範囲指定を使用する場合、一括して指定される配列要素は、反復せずに昇順で指定する必要があり、そうでない場合はコンパイル時にエラーが発生します。たとえば、[3, 1 to 4]、[4, 2]、[2, 3 to 3]および[2, 3, 3]のそれぞれについてエラーが発生しますが、最初の2つの場合は順序が昇順でないことが原因であり、最後の2つの場合は3が反復していることが原因です。

同様に、照合の結果として生じる配列値内の要素は昇順であり、反復は行われません。パス式にアスタリスクが使用される場合、すべての配列要素が配列順序で戻されます。

パス式の例を次に示しますが、その意味も詳述しています。

- $ - コンテキスト項目。

- $.friends - コンテキスト項目オブジェクトのキーfriendsの値。ドット付きの表記法は、コンテキスト項目がJSONオブジェクトであることを示します。

- $.friends[0] - コンテキスト項目オブジェクトのキーfriendsの値である配列の最初の要素であるオブジェクト。大カッコ表記法は、キーfriendsの値が配列であることを示します。

- $.friends[0].name - コンテキスト項目オブジェクトのキーfriendsの値である配列の最初の要素であるオブジェクトのキーnameの値。2番目のドットは、配列friendsの最初の要素が(キーnameを持つ)オブジェクトであることを示します。

- $.friends[*].name - コンテキスト項目オブジェクトのキーfriendsの値である配列の各オブジェクトのキーnameの値。

- $.*[*].name - コンテキスト項目オブジェクトのキーの配列値の各オブジェクトのキーnameの値。

- $.friends[3, 8 to 10, 12] - 配列friends (コンテキスト項目オブジェクトのキー)の12番目、3番目、8番目、9番目および10番目の要素。要素は昇順に指定する必要があり、戻される順序は、3番目、8番目、9番目、10番目、12番目の順です。

- $friends[3].cars - 配列friendsの3番目の要素であるオブジェクトのキーcars。ドットは、3番目の要素が(キーcarsを持つ)オブジェクトであることを示します。

- $friends[3].* - 配列friendsの3番目の要素であるオブジェクトのすべてのキーの値。

- $friends[3].cars[0].year - 変数friendsにバインドされている配列の3番目の要素であるオブジェクトのキーcarsの値である配列の最初の要素であるオブジェクトのキーyearの値。

関連項目:

「Oracle JSONパス式の構文の緩和」

39.4.1.2 Oracle JSONパス式の構文の緩和

暗黙的な配列のラップおよびアンラップを可能にするため、Oracle SQLパス式の基本的な構文は緩和されています。これは、データが発展して特定のJSON値のかわりにこのような値の配列が使用される(またはこの逆)場合、コード内のパス式を変更する必要がないことを意味します。例を示します。

「Oracle JSONパス式の基本的な構文」では、Oracle JSONパス式の基本的な構文を定義しています。サポートされている実際のパス式の構文では、この定義を次のように緩和します。

- パス式のステップが配列を対象としている(予測している)が、実際のデータは配列を示していない場合、データは暗黙的に配列にラップされます。

- パス式のステップが非配列を対象としている(予測している)が、実際のデータは配列を示している場合、配列タは暗黙的にアンラップされます。

この緩和により、次の省略が可能になります。すなわち、[*]は、オブジェクト・アクセッサ.の前にあり、オブジェクト・フィールド名が後ろに続く場合は常に省略でき、本質的に何の変更も行われません。この逆もまた真です。[*]は、オブジェクト・アクセッサ.の前に常に挿入でき、本質的に何の変更も行われません。

つまり、特定のオブジェクトの配列の各要素のフィールドpropの値を表すオブジェクト・ステップ[*].propは.propとして省略でき、単一オブジェクトのprop値を表すかのように見えるオブジェクト・ステップ.propは、オブジェクト・アクセッサが適用された配列の各要素のprop値も表します。

これは重要な機能です。なぜなら、データが発展して特定のJSON値のかわりにこのような値の配列が使用される(またはこの逆)場合、コード内のパス式を変更する必要がないからです。

たとえば、フィールドtypeおよびnumberを伴う単一オブジェクトが値であるフィールドPhoneを持つオブジェクトがデータにもともと含まれるときに、このデータが発展して電話の配列を表す場合、単一の電話番号と一致するパス式$.Phone.numberを引き続き使用できます。パス式$.Phone.numberは、番号を選択して単一の電話オブジェクトと一致することも、各番号を選択して電話オブジェクトの配列と一致することもできます。

同様に、データに両方の種類の表現が混在する(単一の電話オブジェクトを使用するデータ・エントリ、および電話オブジェクトの配列を使用するエントリ、または両方を使用するエントリさえも存在する)場合、同じパス式を使用して、これらの異なる種類のエントリの電話情報にアクセスできます。

次に、「Oracle JSONパス式の基本的な構文」の項のパス式の例を、相当する式の説明とともに示します。

- $.friends – 次のいずれかのフィールドfriendsの値。

- (単一の)コンテキスト項目オブジェクト。

- ($[*].friendsに相当)コンテキスト項目配列内の各オブジェクト。

- $.friends[0].name - 次のオブジェクトのいずれかのフィールドnameの値。

- コンテキスト項目オブジェクトのフィールドfriendsの値である配列の最初の要素。

- ($.friends.nameに相当)コンテキスト項目オブジェクトのフィールドfriendsの値。

- ($[*].friends.nameに相当)コンテキスト項目配列の各オブジェクトのフィールドfriendsの値。

- ($[*].friends[0].nameに相当)コンテキスト項目配列の各オブジェクトのフィールドfriendsの値である各配列の最初の要素。

コンテキスト項目はオブジェクトでもオブジェクトの配列でもかまいません。後者の場合、配列内の各オブジェクトはフィールドfriendsについて照合されます。

フィールドfriendsの値はオブジェクトでもオブジェクトの配列でもかまいません。後者の場合、配列内の最初のオブジェクトが使用されます。

- $.*[*].name – 次のオブジェクトのいずれかのフィールドnameの値。

- コンテキスト項目オブジェクトのフィールドの配列値の要素。

- ($.*.nameに相当)コンテキスト項目オブジェクトのフィールドの値。

- ($[*].*.nameに相当)コンテキスト項目配列のオブジェクトのフィールドの値。

- ($[*].*[*].nameに相当)コンテキスト項目配列のオブジェクトのフィールドの配列値の各オブジェクト。

関連項目:

「Oracle JSONパス式の基本的な構文」

39.5 JSONデータで使用するためのOracle SQL関数および条件

Oracle Databaseには、格納されているJSONデータを作成、問合せおよび操作するために使用可能なSQL関数および条件が用意されています。これらの一部では、リテラルのSQL文字列としてのOracle JSONパス式の後ろに場合によってはRETURNING句、ラッパー句またはエラー句が続いたものが引数として使用されます。

- Oracle SQL条件IS JSONおよびIS NOT JSON - データが整形式のJSONデータであるかどうかをテストします。特にチェック制約として使用されます。

- Oracle SQL条件JSON_EXISTS - JSONデータ内に特定の値が存在するかどうかをテストします。

- Oracle SQL関数JSON_VALUE - SQL値としてスカラー値をJSONデータから選択します。

- Oracle SQL関数JSON_QUERY - JSON値を表すSQL文字列として1つ以上の値をJSONデータから選択します。特に、JSON文書のフラグメント(通常はJSONオブジェクトまたは配列)を取得するために使用されます。

- Oracle SQL関数JSON_TABLE - JSONデータを仮想表としてリレーショナル形式に投影します(これは、インライン・リレーショナル・ビューとみなすこともできます)。

関連項目:

- 「Oracle JSONパス式」

- 「JSON用のOracle SQL関数および条件で使用される句」

- JSONデータを作成、問合せおよび操作するOracle SQL関数の構文とセマンティクスに関する完全な情報は、『Oracle Database SQL言語リファレンス』を参照してください。

- 「JSONデータに対する単純なドット表記法アクセス」

- Oracle SQL条件json_textcontainsを使用したJSONデータの全文検索の詳細は、「JSONデータの全文検索」 を参照してください。

- Oracle SQL条件json_textcontainsの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

39.5.1 JSON用のOracle SQL関数および条件で使用される句

RETURNING、ラッパー、およびエラー処理について説明します。これらは、Oracle SQLファンクションおよび条件のjson_value、json_query、json_table、is json、is not jsonおよびjson_existsの1つ以上で使用されます。

39.5.1.1 JSON用のOracle SQL関数のRETURNING句

Oracle SQLファンクションjson_valueおよびjson_queryは、オプションでRETURNING句を受け入れます。この句は、関数から返される値のデータ型を指定します。この句についてと、デフォルト動作(RETURNING句なし)について説明します。

json_valueの場合、VARCHAR2またはNUMBERをRETURNING句で使用できます。 json_queryの場合、使用できるのはVARCHAR2のみです。

必要に応じて、VARCHAR2の長さ(デフォルト: 4000)、およびNUMBERの精度とスケールを指定できます。

デフォルトの動作(RETURNING句なし)では、VARCHAR2(4000)を使用します。

また、RETURNING句は、PRETTYおよびASCIIの2つのオプションのキーワードも受け入れます。両方を使用する場合は、PRETTYがASCIIの前にくる必要があります。ASCIIは、Oracle SQL関数json_valueおよびjson_queryでのみ使用できます。PRETTYは、json_queryでのみ使用できます。

キーワードPRETTYを使用すると、改行文字の挿入およびインデントにより、戻されたデータがわかりやすいように出力されます。デフォルトの動作では、わかりやすいようには出力されません。

キーワードASCIIを使用すると、標準のASCII Unicodeエスケープ・シーケンスを使用することにより、戻されるデータ内の非ASCII Unicode文字がすべて自動的にエスケープされます。デフォルトの動作では、非ASCII Unicode文字はエスケープされません。

ヒント:

パス式として$のみを使用することにより、コンテキスト項目全体をわかりやすいように出力できます。

関連項目:

「JSONデータ内のUnicode文字のエスケープ」

39.5.1.2 Oracle SQL関数JSON_QUERYおよびJSON_TABLEのラッパー句

Oracle SQLファンクションのjson_queryおよびjson_tableは、オプションのラッパー句を受け入れます。これには、json_queryによって返される値、またはjson_tableリレーショナル列のデータに使用される値の形式を指定します。この句についてと、デフォルト動作(ラッパー句なし)について説明します。例を示します。

ラッパー句は、次のいずれかの形式をとります。

- WITH WRAPPER - パス式と一致するすべてのJSON値が含まれるJSON配列を表す文字列値を使用します。配列要素の順序は指定されません。

- WITHOUT WRAPPER - パス式と一致する単一のJSONオブジェクトまたは配列を表す文字列値を使用します。パス式がスカラー値(オブジェクトまたは配列ではありません)または複数の値と一致する場合、エラーが発生します。

- WITH CONDITIONAL WRAPPER - パス式と一致するすべてのJSON値を表す文字列値を使用します。0個の値、単一のスカラー値、または複数の値の場合、WITH CONDITIONAL WRAPPERはWITH WRAPPERと同じです。単一のJSONオブジェクトまたは配列値の場合は、WITHOUT WRAPPERと同じです。

デフォルトの動作はWITHOUT WRAPPERです。

オプションのキーワードUNCONDITIONALは、これを使用する方が明確になる場合はキーワードWITHの直後に追加できます。WITH WRAPPERとWITH UNCONDITIONAL WRAPPERは同じことを意味します。

オプションのキーワードARRAYは、これを使用する方が明確になる場合はキーワードWRAPPERの直前に追加できます。WRAPPERとARRAY WRAPPERは同じことを意味します。

表39-1は、ラッパー句の使用可能性を示しています。配列ラッパーは太字で示されています。

表39-1 JSON_QUERYラッパー句の例

パス式と一致するJSON値

WITH WRAPPER

WITHOUT WRAPPER

WITH CONDITIONAL WRAPPER

{"id": 38327} (単一のオブジェクト)

[{"id": 38327}]

{"id": 38327}

{"id": 38327}

[42, "a", true] (単一の配列)

[[42, "a", true]]

[42, "a", true]

[42, "a", true]

42

[42]

エラー(スカラー)

[42]

42, "a", true

[42, "a", true]

エラー(複数の値)

[42, "a", true]

なし

[]

エラー(値なし)

[]

たとえば、JSONオブジェクトを取得するためのjson_query問合せを検討してみます。パス式がオブジェクトではなくJSONスカラー値と一致した場合、または複数のJSON値(任意の種類)と一致した場合はどうなるでしょうか。エラーを発生させずに、一致した値を取得したい場合があります。たとえば、オブジェクトである値の1つを選択し、さらに処理したい場合があります。配列ラッパーを使用すると、このような処理を行うことができます。

ラッパーを使用する理由がエラーの発生を回避することのみであり、これらのエラー事例をエラーでない事例と区別する必要がない場合、条件付きラッパーが役立ちます。アプリケーションが探しているものが単一のオブジェクトまたは配列であり、パス式によって一致したデータがそのものである場合、予期した値を単一の配列にラップする必要はありません。

一方、無条件ラッパーの場合、結果として生成される配列は常にラッパーであることが判明しています。アプリケーションはこの事実に頼ることができます。条件付きラッパーを使用する場合、アプリケーションでは、戻された配列を解析するために追加の処理を行う必要がある場合があります。たとえば、表39-1では、同じ配列([42, "a", true])が、この配列と一致するパス式、およびその各要素と一致するパス式という、まったく異なる事例に対して戻されています。

39.5.1.3 JSON用のOracle SQL関数および条件のエラー句

JSONの一部のSQL関数および条件は、オプションでエラー句を受け入れます。これにより、Oracle SQL関数または条件によって発生したエラーの処理方法を指定します。この句についてと、デフォルト動作(エラー句なし)について説明します。

オプションのエラー句により、Oracle SQL関数または条件によって発生したエラーの処理方法を指定します。

この句は、次のいずれかの形式をとります。

- ERROR ON ERROR - エラーを発生させます(特別な処理なし)。

- NULL ON ERROR - エラーを発生させるかわりにNULLを戻します。

- TRUE ON ERROR - エラーを発生させるかわりにtrueを戻します。この形式の句が使用可能なのは、Oracle SQL条件json_existsの場合のみです。

- FALSE ON ERROR - エラーを発生させるかわりにfalseを戻します。この形式の句が使用可能なのは、Oracle SQL条件json_existsの場合のみです。

- EMPTY ON ERROR - エラーを発生させるかわりに空の配列([])を戻します。この形式の句が使用可能なのは、Oracle SQL関数json_queryの場合のみです。

- DEFAULT 'literal_return_value' ON ERROR - エラーを発生させるかわりに指定した値を戻します。値は、問合せのコンパイル時に定数である必要があります。
この形式の句は、json_queryでは使用できません。

デフォルトの動作はNULL ON ERRORです。

注意:

ON ERROR句は、構文的に正しいOracle JSONパス式がJSONデータに対して照合されたときに発生する実行時エラーに対してのみ有効です。構文的に正しくないパス式の場合、コンパイル時エラーが発生します。これは、ON ERROR句によっては処理されません。

39.5.2 Oracle SQL条件IS JSONおよびIS NOT JSON

Oracle SQL条件is jsonおよびis not jsonは補足的な条件です。これらは、引数がJSONデータとして構文的に正しい(つまり、整形式である)かどうかをテストします。これらは、SELECT文のCASE式またはWHERE句で使用できます。

引数が構文的に正しい場合、is jsonはtrueを戻し、is not jsonはfalseを戻します。引数がなんらかの理由(解析中にエラーが発生した場合など)によって評価できない場合、データは単に整形式でないとみなされます。この場合、is jsonによってfalseが戻され、is not jsonによってtrueが戻されます。整形式とは、データが構文的に正しいことを意味します。(JSONデータは、厳密な構文と緩慢な構文と呼ばれる2つの概念の整形式にすることができます。)

関連項目:

- is jsonおよびis not jsonの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- 「厳密なJSON構文と緩慢なJSON構文について」

39.5.2.1 列にJSONデータが含まれることを確認するためのチェック制約の使用

SQL条件is jsonの一般的な使用方法は、JSON列のデータが(整形式の) JSONデータであることを確認するためのチェック制約として使用する方法です。JSONデータを対象とした列を作成する場合は常にis_jsonチェック制約を使用することをお薦めします。

例39-3および例39-4に、これを示します。これらの例では、別の場所にある例で使用されるデータを保持する表を作成し、データを入力します。

例39-4では、簡潔にするために、1行のデータ(1つのJSON文書)のみが挿入されています。完全なデータ・セットを挿入する例は、「外部JSONデータのロード」を参照してください。

注意:

Oracle SQL条件IS JSONおよびIS NOT JSONは、NULL以外のSQL値に対してはtrueまたはfalseを戻します。ただし、これらは両方とも、SQLのNULLに対してはunknown (trueでもfalseでもありません)を戻します。チェック制約で使用される場合、NULL値の挿入が阻止されることはありません。ただし、SQLのWHERE句で使用される場合、NULLは選択されません(戻されません)。

チェック制約によってデータ挿入のパフォーマンスが低下することは事実です。特定の列に整形式のJSONデータのみが挿入されることが確実である場合、チェック制約を無効にすることを検討できますが、制約は削除しないでください。

関連項目:

- 「列にJSONデータが必然的に含まれるかどうかの確認」

- 完全表j_purchaseorderの作成の詳細は、「外部JSONデータのロード」 を参照してください

例39-3 JSONデータが整形式であることを確認するためのチェック制約でのIS JSONの使用

CREATE TABLE j_purchaseorder
(id          RAW (16) NOT NULL,
date_loaded TIMESTAMP (6) WITH TIME ZONE,
po_document CLOB
CONSTRAINT ensure_json CHECK (po_document IS JSON));

例39-4 JSON列のあるリレーショナル表へのデータの挿入

INSERT INTO j_purchaseorder
VALUES (
SYS_GUID(),
SYSTIMESTAMP,
'{"PONumber"             : 1600,
"Reference"            : "ABULL-20140421",
"Requestor"            : "Alexis Bull",
"User"                 : "ABULL",
"CostCenter"           : "A50",
"ShippingInstructions" : {"name"   : "Alexis Bull",
"Address": {"street"  : "200 Sporting Green",
"city"    : "South San Francisco",
"state"   : "CA",
"zipCode" : 99236,
"country" : "United States of America"},
"Phone" : [{"type" : "Office", "number" : "909-555-7307"},
{"type" : "Mobile", "number" : "415-555-1234"}]},
"Special Instructions" : null,
"AllowPartialShipment" : true,
"LineItems"            : [{"ItemNumber" : 1,
"Part"       : {"Description" : "One Magic Christmas",
"UnitPrice"   : 19.95,
"UPCCode"     : 13131092899},
"Quantity"   : 9.0},
{"ItemNumber" : 2,
"Part"       : {"Description" : "Lethal Weapon",
"UnitPrice"   : 19.95,
"UPCCode"     : 85391628927},
"Quantity"   : 5.0}]}');

39.5.2.2 列にJSONデータが必然的に含まれるかどうかの確認

データが整形式のJSONデータであることを確認するチェック制約が特定の列に設定されているかどうかは、どうすれば確認できるでしょうか。この場合、この列はDBA_JSON_COLUMNS、USER_JSON_COLUMNSおよびALL_JSON_COLUMNSの静的データ・ディクショナリ・ビューにリストされます。

各ビューには、所有者の名前、表、列、および列のデータ型がリストされます。このデータを問い合せることにより、JSON列を検索できます。Foot 5

データがJSONデータであることを確認するチェック制約が無効である場合でも、列はビュー内にリストされたままです。チェック制約が削除されている場合、列はビューから削除されます。

関連項目:

「列にJSONデータが含まれることを確認するためのチェック制約の使用」

39.5.2.3 JSONオブジェクトの一意フィールドと重複フィールド

デフォルトでは、指定のJSONオブジェクトに対してオブジェクト・フィールド(オブジェクト・プロパティ)が一意である必要はありませんが、特定のJSONデータに重複するフィールド名を持つオブジェクトがない場合のみ、このJSONデータが整形式であるとみなすように指定することもできます。

JSON標準では、特定のJSONオブジェクトに対してフィールド名が一意である必要があるかどうかは指定されません。つまり、このことは先験的に、整形式のJSONオブジェクトには同じフィールド名を持つ複数のメンバーを設定できることを意味します。これは、Oracle DatabaseでJSONデータを処理する場合のデフォルトの動作です。

特定のJSONデータに含まれるすべてのオブジェクトが一意のフィールド名を持つ(つまり、重複するフィールド名を持つオブジェクトがない)場合のみ、このJSONデータが整形式であるとみなすように指定できます。これは、Oracle SQL条件is jsonでキーワードWITH UNIQUE KEYSを使用することで行います。脚注 6UNIQUE KEYSを指定しないか、キーワードWITHOUT UNIQUE KEYSを使用する場合、オブジェクトが重複フィールド名を持ったままでも整形式であるとみなすことができます。

Oracle Databaseで採用されている評価では常に、特定のフィールド名を持つオブジェクト・メンバーの1つのみが使用されます。同じフィールド名を持つ他のメンバーは無視されます。このような複数のメンバーのうちどれが使用されるかは指定されていません。

整形式のJSONデータで重複フィールド名が許可されるかどうかは、整形式かどうかの確認に、厳密な構文と緩慢な構文のどちらが使用されるかとかかわっています。

39.5.2.4 厳密なJSON構文と緩慢なJSON構文について

JSON向けのOracleのデフォルト構文は緩慢です。特に、この構文は、オブジェクト・フィールドに対してJavaScript構文を反映し、ブール型の値およびnull値では大/小文字が区別されず、数字、ホワイトスペースおよびUnicode文字のエスケープについてはより寛容です。

標準ECMA-404のJSONデータ交換フォーマット、およびECMA-262のECMAScript言語指定により、JSON構文が定義されます。

これらの指定に応じて、各JSONのフィールドおよび各文字列値は、二重引用符(")で囲む必要があります。Oracleではこの厳密なJSON構文をサポートしていますが、これはデフォルトの構文ではありません。

JavaScript表記法では、オブジェクト・リテラルで使用されるフィールドは、二重引用符で囲むことができますが、必須ではありません。これはまた、一重引用符(')で囲むこともできます。Oracleではこの緩慢なJSON構文もサポートしており、これがデフォルトの構文です。

また、実際に、一部のJavaScript実装(ただし、JavaScript標準ではありません)では次の1つ以上が許可されています。

- キーワードtrue、falseおよびnullの大/小文字の相違(TRUE、True、TrUe、fALSe、NulLなど)。

- 配列の最後の要素またはオブジェクトの最後のメンバーの後ろに追加されるカンマ(,) ([a, b, c,]、{a:b, c:d,}など)。

- 先頭に1つ以上の0がある数字(0042.3など)。

- 小数点の前に0がない小数(0.14ではなく.14など)。

- 小数点の後に小数部分がない数字(342.や1.e27など)。

- 数値がマイナスではないことを意味する、数字の前のプラス記号(+) (+1.3など)。

この構文も、Oracleのデフォルトの(緩慢な) JSON構文の一部として許可されます。(厳密な数字構文は、JSON標準を参照してください。)

ASCIIのスペース文字(U+0020)以外にも、JSON標準では、引用符で囲まれたフィールドまたは文字列値の外側で使用される場合、次の文字は重要でない(無視される)ホワイトスペースとして定義されています。

- タブ、水平タブ(HT、 ^I、10進数の9、U+0009、\t)

- 行送り、改行(LF、 ^J、10進数の10、U+000A、\n)

- キャリッジ・リターン(CR、 ^M、10進数の13、U+000D、\r)

ただし、Oracle JSONの緩慢な構文では、ASCII制御文字(0-31)のすべて、およびASCIIスペース文字(10進数の32、U+0020)は(重要でない)ホワイトスペース文字として処理されます。制御文字には次のようなものがあります。

- Null (NUL、 ^@、10進数の0、U+0000、\0)

- ベル(NEL、 ^G、10進数の7、U+0007、 \a)

- 垂直タブ(VT、 ^K、10進数の11、U+000B)

- エスケープ(ESC、 ^[、10進数の27、U+001B、\e)

- 削除(DEL、 ^?、10進数の127、U+007F)

ASCIIのスペース文字(U+0020)は、引用符で囲まれたフィールドまたは文字列値内で許可されてエスケープされていない唯一のホワイトスペース文字です。これは、厳密なOracle JSON構文と緩慢なOracle JSON構文の両方に対して当てはまります。

厳密なOracle JSON構文と緩慢な構文の両方において、引用符で囲まれたオブジェクト・フィールドおよび文字列値に含めることができるのはUnicode文字のみですが、これらの一部は次のようにエスケープする必要があります。

- ASCII制御文字は許可されていませんが、\b (バックスペース)、\f (フォーム・フィード)、\n (改行、行送り)、\r (キャリッジ・リターン)および\t (タブ、水平タブ)の各エスケープ・シーケンスによって表される文字は除きます。

- 二重引用符(")、スラッシュ(/)およびバックスラッシュ(\)文字もエスケープする(バックスラッシュを前に置く)必要があります(それぞれ\"、\/および\\)。

緩慢なOracle構文では、引用符で囲まれていないオブジェクト・フィールドに、ホワイトスペースとJSON構造文字(左右の大カッコ([、])と中カッコ({、})、コロン(:)およびカンマ(,))を除く任意のUnicode文字を含めることができますが、エスケープ・シーケンスは許可されません。

名前または文字列にも任意のUnicode文字を含めることができますが、この場合、Unicodeコード・ポイントを表す4つのASCIIの16進数字を後ろに付けたASCIIのエスケープ構文\uを使用します。

厳密なOracle JSON構文と緩慢なOracle JSON構文のいずれにおいても、出力可能でないかホワイトスペースとして表示される可能性がある他のUnicode文字(ノーブレークスペース文字(U+00A0)など)はホワイトスペースとみなされません。

表39-2は、JSON構文のいくつかの例を示しています。

表39-2 JSONオブジェクト・フィールドの構文例

例

整形式かどうか

"part number": 1234

緩慢および厳密: はい。スペース文字は許可されます。

part number: 1234

緩慢(および厳密): いいえ。引用符で囲まれていない名前では、スペース文字を含むホワイトスペース文字は許可されません。

"part\tnumber": 1234

緩慢および厳密: はい。タブ文字のエスケープ・シーケンスは許可されます。

"part    number": 1234

緩慢および厳密: いいえ。エスケープされていないタブ文字は許可されません。エスケープされていないホワイトスペース文字で許可されるのはスペースのみです。

"\"part\"number": 1234

緩慢および厳密: はい。名前が引用符で囲まれている場合、エスケープされている二重引用符は許可されます。

\"part\"number: 1234

緩慢および厳密: いいえ。名前は引用符で囲む必要があります。

'\"part\"number': 1234

緩慢: はい、厳密: いいえ。一重引用符で囲まれた名前(オブジェクト・フィールドと文字列)は、緩慢な構文でのみ許可されます。引用符で囲まれた名前では、エスケープされている二重引用符が許可されます。

"pärt number":1234

緩慢および厳密: はい。引用符で囲まれた名前では、任意のUnicode文字が許可されます。

part:number:1234

緩慢(および厳密): いいえ。引用符で囲まれている名前では、構造文字は許可されません。

"pärt:number":1234

緩慢: はい、厳密: いいえ。引用符で囲まれている名前でホワイトスペース以外の構造文字およびUnicode文字が許可されるのは、緩慢な構文の場合のみです。

関連項目:

- JSONデータ交換フォーマットの構文の詳細は、http://tools.ietf.org/html/rfc4627およびhttp://www.ecma-international.org/publications/standards/Ecma-404.htmを参照してください。

- JSONおよびJavaScriptの詳細は、http://www.ecmascript.org、http://www.ecma-international.orgおよびhttp://www.json.orgを参照してください。

- 「JSON構文およびJSON構文が表すデータの概要」

- 「JSONデータ内のUnicode文字のエスケープ」

39.5.2.5 厳密なOracle JSON構文と緩慢なOracle JSON構文の指定

デフォルトのOracle JSON構文は緩慢です。構文が厳密か緩慢かが問題になるのは、SQL条件is jsonおよびis not jsonの場合のみです。他のすべてのOracle SQL関数および条件では、入力を解析するために緩慢な構文が使用され、出力を戻すために厳密な構文が使用されます。

特定のJSON入力データに厳密に正しい構文が使用されていることを確認する必要がある場合は、最初にis jsonまたはis not jsonを使用してチェックしてください。

JSON標準に応じてデータを厳密な整形式としてチェックするよう指定するには、(STRICT) (カッコを含む)をis jsonまたはis not json式に追加します。

例39-5に、これを示します。これは例39-3と同じですが、列に挿入されたすべてのデータがJSON標準に応じた整形式であることを確認するために(STRICT)が使用されています。

関連項目:

「厳密なJSON構文と緩慢なJSON構文について」

例39-5 JSONデータが厳密な整形式(標準)であることを確認するためのチェック制約でのIS JSONの使用

CREATE TABLE j_purchaseorder
(id          RAW (16) NOT NULL,
date_loaded TIMESTAMP WITH TIME ZONE,
po_document CLOB
CONSTRAINT ensure_json CHECK (po_document IS JSON (STRICT)));

39.5.3 Oracle SQL条件JSON_EXISTS

Oracle SQL条件json_existsでは、Oracle JSONパス式を行フィルタとして使用して、JSON文書の内容に基づいて行を選択できます。条件json_existsは、SELECT文のCASE式またはWHERE句で使用できます。

条件json_existsは、JSONデータ内に特定の値が存在するかどうかをチェックします。値が存在する場合はtrueが戻され、存在しない場合はfalseが戻されます。より正確に言うと、json_existsでは、対象とするデータが1つ以上のJSON値と一致する場合はtrueが戻されます。一致するJSON値がない場合は、falseが戻されます。

また、json_existsを使用して、JSONデータで使用するビットマップ索引を作成することもできます。例39-20を参照してください。

エラー・ハンドラERROR ON ERROR、FALSE ON ERRORおよびTRUE ON ERRORが適用されます。デフォルトはFALSE ON ERRORです。このハンドラが有効になるのはエラーが発生したときですが、通常、エラーが発生するのは、特定のJSONデータが(緩慢な構文を使用した)整形式でない場合です。条件is jsonおよびis not jsonの事例とは異なり、条件json_existsでは、検査するデータが整形式のJSONデータであることを予期しています。

json_existsの2番目の引数は、Oracle JSONパス式の後ろにオプションのRETURNING句とオプションのエラー句が付いた形式です。このパス式では単一のスカラー値を対象とする必要があり、そうでない場合、コンパイル時にエラーが発生します。

注意:

JSON値nullに適用されたOracle SQL条件json_existsは、SQL文字列'true'を戻します。

関連項目:

- 「JSON用のOracle SQL関数のRETURNING句」

- 「JSON用のOracle SQL関数のエラー句」

- json_valueの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

39.5.3.1 JSON_TABLEとしてのJSON_EXISTS

Oracle SQL条件json_existsは、Oracle SQL関数json_tableの特別な事例であるとみなすことができます。

例39-6に、この対応を示します。2つのSELECT文で得られる結果は同じになります。

この対応は、おそらくjson_existsについてより深く理解する手助けとなるのみでなく、どちらを使用しても同じ結果が得られることを意味しているため、実質的に重要な意味を持ちます。

特に、json_existsを複数回使用する場合、またはこれをjson_valueまたはjson_query (これらもjson_tableを使用して表すことができます)と組み合せて使用して同じデータにアクセスする場合、json_tableを1回呼び出す方が、データが解析されるのが1回のみであるという利点があります。

このため、オプティマイザがjson_exists、json_valueおよびjson_queryの複数の呼出し(任意の組合せ)を、より少ないjson_tableの呼出しに自動的にリライトすることがよく起こります。

関連項目:

「JSON_TABLEによる他のOracle SQL関数の汎化」

例39-6 JSON_TABLEを使用して表されたJSON_EXISTS

SELECT select_list
FROM table WHERE json_exists(column, json_path error_handler ON ERROR);

SELECT select_list
FROM table,
json_table(column, '$' error_handler ON ERROR
COLUMNS ("COLUMN_ALIAS" NUMBER EXISTS PATH json_path)) AS "JT"
WHERE jt.column_alias = 1;

39.5.4 Oracle SQL関数JSON_VALUE

Oracle SQL関数json_valueは、JSONデータからscalar値を選択し、これをSQL値として戻します。

また、json_valueを使用して、JSONデータで使用する関数ベースのBツリー索引を作成することもできます。「JSONデータの索引」を参照してください。

関数json_valueは、2つの必須引数を持ち、オプションのRETURNING句およびエラー句を受け入れます。

json_valueの最初の引数は、スカラーのSQLデータ型のインスタンスを戻すSQL式です(つまり、オブジェクト・データ型でもコレクション・データ型でもありません)。これは、データ型VARCHAR2、BLOBまたはCLOBのいずれかになります。これは、適切にキャストされた表またはビューの列の値、PL/SQL変数、バインド変数のいずれかになります。SQL式の評価の結果は、パス式を評価するためのコンテキスト項目として使用されます。

json_valueの2番目の引数は、Oracle JSONパス式の後ろにオプションのRETURNING句とオプションのエラー句が付いた形式です。このパス式では単一のスカラー値を対象とする必要があり、そうでない場合、エラーが発生します。

デフォルトのエラー処理動作はNULL ON ERRORであり、これは、エラーが発生しても値が戻されない、つまり、エラーが発生しないことを意味します。特に、パス式が配列などの非スカラー値を対象としている場合、デフォルトではエラーは発生しません。エラーが発生するようにするには、ERROR ON ERRORを使用します。

注意:

特定のJSONオブジェクト内のフィールド名は、それぞれが一意である必要はありません。同じフィールド名を繰り返すことができます。Oracle Databaseで行われるストリーム評価では、特定のフィールド名を持つ1つのオブジェクト・メンバーのみが常に使用され、同じフィールド名を持つ他のメンバーは無視されます。このような複数のメンバーのうちどれが使用されるかは指定されていません。

"JSONオブジェクトの一意フィールドと重複フィールドを参照してください。

関連項目:

- 「JSON用のOracle SQL関数のRETURNING句」

- 「JSON用のOracle SQL関数のエラー句」

- json_valueの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

39.5.4.1 Oracle SQL関数JSON_VALUEとブール型のJSON値の使用

JSONには、ブール型の値trueおよびfalseがあります。Oracle SQLには、ブール・データ型がありません。Oracle SQLファンクションjson_valueによってOracle JSONパス式が評価され、結果がtrueまたはfalseである場合、結果をSQLで処理する方法は文字列と数値の2通りあります。

デフォルトでは、戻されるデータ型はSQL文字列(VARCHAR2)であり、これは、結果が文字列'true'または'false'であることを意味します。または、結果をSQL数値として戻すこともでき、この場合、JSON値trueは数値1として戻され、falseは0として戻されます。

例39-7に、これを示します。最初の問合せでは文字列'true'を戻し、2番目の問合せでは数値1を戻します。

注意:

ブール値を数値として戻すことはできますが、このような値はJSONの検索索引の対象となりません。このような理由により、デフォルトの戻り値のデータ型VARCHAR2を使用することをお薦めします。

例39-7 JSON_VALUE: SQLでJSONのブール値を戻す2通りの方法

SELECT json_value(po_document, '$.AllowPartialShipment')
FROM j_purchaseorder;

SELECT json_value(po_document, '$.AllowPartialShipment' RETURNING NUMBER)
FROM j_purchaseorder;

39.5.4.2 JSONのnull値に適用されるOracle SQL関数JSON_VALUE

JSON値nullに適用されたOracle SQL関数json_valueは、SQL文字列'null'ではなく、SQLのNULLを戻します。つまり、特に、json_valueを使用してJSON値nullと値が存在しないことの区別はできません。この場合、SQLのNULLは両方の事例を表します。

39.5.4.3 JSON_TABLEとしてのJSON_VALUE

Oracle SQL関数json_valueは、関数json_tableの特別な事例であるとみなすことができます。

例39-8に、この対応を示します。2つのSELECT文で得られる結果は同じになります。

この対応は、おそらくjson_valueについてより深く理解する手助けとなるのみでなく、どちらの関数を使用しても同じ結果が得られることを意味しているため、実質的に重要な意味を持ちます。

特に、json_valueを複数回使用する場合、またはこれをjson_existsまたはjson_query (これらもjson_tableを使用して表すことができます)と組み合せて使用して同じデータにアクセスする場合、json_tableを1回呼び出す方が、データが解析されるのが1回のみであるという利点があります。

このため、オプティマイザがjson_exists、json_valueおよびjson_queryの複数の呼出し(任意の組合せ)を、より少ないjson_tableの呼出しに自動的にリライトすることがよく起こります。

関連項目:

「JSON_TABLEによる他のOracle SQL関数の汎化」

例39-8 JSON_TABLEを使用して表されたJSON_VALUE

SELECT json_value(column, json_path RETURNING data_type error_hander ON ERROR)
FROM table;

SELECT jt.column_alias
FROM table,
json_table(column, '$' error_handler ON ERROR
COLUMNS ("COLUMN_ALIAS" data_type PATH json_path)) AS "JT";

39.5.5 Oracle SQL関数JSON_QUERY

Oracle SQL関数json_queryは、1つ以上の値をJSONデータから選択し、JSON値を表す文字列(VARCHAR2)を戻します。(関数json_valueとは異なり、戻されるデータ型をNUMBERにすることはできません。)したがって、json_queryを使用してJSON文書のフラグメントを取得できます。

json_queryの最初の引数は、スカラーのSQLデータ型のインスタンスを戻すSQL式です(つまり、オブジェクト・データ型でもコレクション・データ型でもありません)。これは、データ型VARCHAR2、BLOBまたはCLOBのいずれかになります。これは、適切にキャストされた表またはビューの列の値、PL/SQL変数、バインド変数のいずれかになります。SQL式の評価の結果は、パス式を評価するためのコンテキスト項目として使用されます。

json_queryの2番目の引数は、Oracle JSONパス式の後ろにオプションのRETURNING句、オプションのラッパー句およびオプションのエラー句が付いた形式です。このパス式は、任意の数のJSON値を対象とすることができます。

RETURNING句で指定できるのはデータ型VARCHAR2のみであり、NUMBERを指定することはできません。

ラッパー句により、戻される文字列値の形式が決まります。

json_queryのエラー句ではEMPTY ON ERRORを指定でき、これは、エラーが発生した場合は空の配列([])が戻されることを意味します。

例39-9は、Oracle SQL関数json_queryとともに配列ラッパーを使用する例を示しています。文書ごとにVARCHAR2値が戻され、この内容は、電話のタイプの要素が不特定の順序で含まれるJSON配列を表します。例39-4の文書では、電話のタイプは"Office"および"Mobile"であり、戻される配列は["Mobile", "Office"]または["Office", "Mobile"]です。

例39-9でパス式$.ShippingInstructions.Phone.typeが使用されていたとしても、同じ結果が得られるはずです。Oracle JSONのパス式構文の緩和のため、[*].typeは.typeに相当します。

関連項目:

- json_queryの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- 「Oracle JSONパス式の構文の緩和」

- 「JSON用のOracle SQL関数のRETURNING句」

- 「Oracle SQL関数JSON_QUERYおよびJSON_TABLEのラッパー句」

- 「JSON用のOracle SQL関数のエラー句」

例39-9 JSON_QUERYを使用したJSON値の選択

SELECT json_query(po_document, '$.ShippingInstructions.Phone[*].type'
WITH WRAPPER)
FROM j_purchaseorder;

39.5.5.1 JSON_TABLEとしてのJSON_QUERY

Oracle SQL関数json_queryは、関数json_tableの特別な事例であるとみなすことができます。

例39-10に、この対応を示します。2つのSELECT文で得られる結果は同じになります。

この対応は、おそらくjson_queryについてより深く理解する手助けとなるのみでなく、どちらの関数を使用しても同じ結果が得られることを意味しているため、実質的に重要な意味を持ちます。

特に、json_queryを複数回使用する場合、またはこれをjson_existsまたはjson_value (これらもjson_tableを使用して表すことができます)と組み合せて使用して同じデータにアクセスする場合、json_tableを1回呼び出す方が、データが解析されるのが1回のみであるという利点があります。

このため、オプティマイザがjson_exists、json_valueおよびjson_queryの複数の呼出し(任意の組合せ)を、より少ないjson_tableの呼出しに自動的にリライトすることがよく起こります。

関連項目:

「JSON_TABLEによる他のOracle SQL関数の汎化」

例39-10 JSON_TABLEを使用して表されたJSON_QUERY

SELECT json_query(column, json_path
RETURNING data_type array_wrapper error_hander ON ERROR)
FROM table;

SELECT jt.column_alias
FROM table,
json_table(column, '$' error_handler ON ERROR
COLUMNS ("COLUMN_ALIAS" data_type FORMAT JSON array_wrapper
PATH json_path)) AS "JT";

39.5.6 Oracle SQL関数JSON_TABLE

Oracle SQL関数json_tableは、JSONデータをリレーショナル・フォーマットに投影します。json_tableを使用して、JSON式の評価結果を新規の仮想表のリレーショナル行および列に分解しますが、これは、インラインのリレーショナル・ビューであるとみなすこともできます。

この仮想表は、既存のデータベース表に挿入でき、またSQLを使用して(join式など)問合せできます。

特に、json_tableの一般的な使用目的は、JSONデータのリレーショナル・ビューを作成することです。このようなビューは、任意のリレーショナル表またはリレーショナル・ビューを使用する場合と同じように使用できます。このため、アプリケーション、ツールおよびプログラマは、JSONデータをリレーショナルであるかのように、つまり、JSONまたはJSONパス式の構文を考慮せずに操作できます。

JSONデータを介してリレーショナル・ビューを定義することにより、実質的にある種のスキーマがそのデータにマップされます。このマッピングは、事後に行われます。つまり、基礎となるJSONデータは、スキーマまたは特定の使用パターンを考慮せずに定義および作成できます。データが最初で、スキーマが後です。

このようなスキーマ(マッピング)により、基礎となる表に格納できるJSON文書の種類に(整形式のJSONデータであること以外の)制約が課されることはありません。リレーショナル・ビューでは、ビューを定義するマッピング(スキーマ)に準拠するデータのみが公開されます。ビューを再定義するだけでスキーマを変更でき、基礎となるJSONデータを再編成する必要はありません。例39-17は、json_tableを使用したリレーショナル・ビューの作成を示しています。

json_tableはSQLのFROM句で使用します。したがって、これは行ソースです。これにより、行パス式(行パターン)によって選択されたJSON値ごとにリレーショナル・データの行が生成されます。

json_tableの呼出しによって作成される行は、暗黙的にこれらの行の生成元の行に水平結合されます。つまり、json_tableによって生成される仮想表を、JSONデータが含まれる表に明示的に結合する必要はありません。

json_tableの最初の引数は、スカラーのSQLデータ型のインスタンスを戻すSQL式です(つまり、オブジェクト・データ型でもコレクション・データ型でもありません)。これは、データ型VARCHAR2、BLOBまたはCLOBのいずれかになります。これは、適切にキャストされた表またはビューの列の値、PL/SQL変数、バインド変数のいずれかになります。SQL式の評価の結果は、行パス式を評価するためのコンテキスト項目として使用されます。

json_tableの2番目の引数は、Oracle JSON行パス式の後ろに、行を処理するためのオプションのエラー句と(必須の) COLUMNS句が付いた形式です。(RETURNING句はありません。)このパス式は、任意の数のJSON値を対象とすることができます。

行パス式は、生成される仮想表の行のパターンとして機能します。これが、SQLのFROM句によって提供されるコンテキスト項目と照合されることにより、COLUMNS句に指定するリレーショナル列に編成されるSQLデータの行が生成されます。これらの各行が0個以上の列パス式と照合され、仮想表のリレーショナル列が生成されます。

json_tableのエラー処理には2つのレベルがありますが、これらは、パス式の2つのレベルである行と列に対応しています。存在する場合、列のエラー・ハンドラにより、行レベルのエラー処理がオーバーライドされます。両レベルのデフォルトのエラー・ハンドラはNULL ON ERRORです。

必須のCOLUMNS句は、json_tableによって作成される仮想表の列を定義します。これは、キーワードCOLUMNSの後ろに次のエントリをカッコで囲んだ形式で構成されます。

- COLUMNS句内の多くても1つのエントリは、生成される行数の列(SQLデータ型NUMBER)を指定するキーワードFOR ORDINALITYを列名の後ろに付けた形式にすることができます。これらの数は1から始まります。

- オプションのFOR ORDINALITYエントリ以外、COLUMNS句の各エントリは、標準列指定またはネストした列指定です。

- 標準列指定は、列名の後ろに、列のオプションのスカラー・データ型(JSON用の他のOracle SQL関数のRETURNING句の場合と同じようにSQLデータ型VARCHAR2またはNUMBERにすることができます)、その後ろにオプションの値句および必須のPATH句が付いた形式で構成されます。デフォルトのデータ型はVARCHAR2(4000)です。

- ネストした列 は、キーワードNESTEDの後ろにオプションのPATHキーワード、Oracle JSON行パス式、およびCOLUMNS句が付いた形式で構成されます。このCOLUMNS句は、ネストしたデータを表す列を指定します。ここで使用される行パス式により、指定したネストした列のコンテキストが洗練されます。ネストした各列のパス式は行パス式を基準にしたものになります。
COLUMNS句は(ネストしていてもネストしていなくても)どのレベルでも同じ特性を持ちます。つまり、COLUMNS句は再帰的に定義されます。ネストのレベルごとに(つまり、キーワードNESTEDが使用されるたびに)、ネストしたCOLUMNS句は、ネスト元のCOLUMNS句(その親)の子と呼ばれます。同じ親句を持つ複数のCOLUMNS句は兄弟です。

親子のCOLUMNS句によって定義される仮想表は、外部結合を使用して結合されますが、この場合、親が外部表になります。兄弟のCOLUMNS句によって定義される仮想列は、和結合を使用して結合されます。

例39-16は、ネストした列句の使用を示しています。

- オプションの値句は、列に投影されたデータを処理する方法、つまり、データをjson_value、json_existsまたはjson_queryと同じように処理するかどうかを指定します。この値処理には、戻りデータ型、戻り形式(prettyまたはASCII)、ラッパー、およびエラーの処理が含まれます。
デフォルトでは、投影されたデータはjson_valueによって処理されたかのように処理されます。キーワードEXISTSを使用すると、json_existsによって処理されたかのように処理されます。キーワードFORMAT JSONを使用すると、json_queryによって処理されたかのように処理されます。

FORMAT JSONの場合、明示的なラッパー句を追加することにより、デフォルトのラッパー動作をオーバーライドできます。

特定のハンドラ(json_value、json_existsまたはjson_query)のデフォルトのエラー処理を、それに適した明示的なERROR句を追加することでオーバーライドできます。

- 必須のPATH句は、列の内容として使用される行の部分を指定します。キーワードPATHに続く列パス式は、仮想行によって提供されるコンテキスト項目と照合されます。この列パス式は、行パス式によって指定されるパスに対して相対的であるため、相対パスの表記にする必要があります。

関連項目:

- 「JSON用のOracle SQL関数のRETURNING句」

- 「Oracle SQL関数JSON_QUERYおよびJSON_TABLEのラッパー句」

- 「JSON用のOracle SQL関数のエラー句」

- json_tableの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

39.5.6.1 JSON_TABLEによる他のOracle SQL関数の汎化

Oracle SQLファンクションjson_tableは、SQL条件json_existsとSQLファンクションjson_valueおよびjson_queryを一般化します。これらの関数を使用して実行できる処理はすべて、json_tableを使用して実行できます。これらによって実行されるジョブについては、これらの関数の構文の方がjson_tableの構文よりも簡単に使用できます。

json_exists、json_valueまたはjson_queryを複数回使用して、またはこれらを組み合せて使用して同じデータにアクセスする場合、json_tableを1回呼び出す方が、データが解析されるのが1回のみであるという利点があります。

このため、オプティマイザがjson_exists、json_valueおよびjson_queryの複数の呼出し(任意の組合せ)を、データの解析が1回だけになるように、より少ないjson_tableの呼出しに自動的にリライトすることがよく起こります。

例39-11および例39-12に、これを示します。これらではそれぞれ、列j_purchaseorder.po_document内の各オブジェクトによって使用される要求者および一連の電話を選択しています。ただし、例39-12では、この列を4回ではなく1回のみ解析しています。

例39-12と関連して次の点に注意してください。

- JSON値のnullは、SQLに関するかぎりは1つの値であり、SQLで値の欠如(存在しないデータ、不明なデータまたは適用できないデータ)を表すNULLとは異なります。例39-12で、オブジェクト属性zipCodeのJSON値がnullである場合、SQL文字列'true'が戻されます。

- json_existsによってブール値が戻されますが、これは、SQL値として、SQL文字列'true'または'false'によって表されます。json_existsがSQLのWHERE句またはCASE文の条件として直接使用される場合、この戻り値を明示的にテストする必要はありません。単にjson_exists(...)と入力してかまいません。ただし、json_existsが値を得るために他の場所で使用される場合、この値をテストする唯一の方法はこの値を明示的な文字列として使用する方法です。これが例39-12の事例です。値は列jt.has_zipに格納されてから、SQL文字列'true'と等価かどうかが明示的にテストされています。

- JSONオブジェクト属性AllowPartialShipmentには、JSONのブール値があります。この値にjson_valueが適用される場合、これは文字列または数値として戻される場合があります。例39-12では、json_valueの暗黙的な使用により、この値はデータ型NUMBERとして戻されてから、数値1と等価かどうかがテストされています。

例39-11 JSONデータに複数回アクセスすることによるデータの抽出

SELECT json_value(po_document, '$.Requestor' RETURNING VARCHAR2(32)),
json_query(po_document, '$.ShippingInstructions.Phone'
RETURNING VARCHAR2(100))
FROM j_purchaseorder
WHERE json_exists(po_document, '$.ShippingInstructions.Address.zipCode')
AND json_value(po_document,  '$.AllowPartialShipment' RETURNING NUMBER(1))
= 1;

例39-12 JSON_TABLEの使用によって複数回の解析が不要なデータの抽出

SELECT jt.requestor, jt.phones
FROM j_purchaseorder,
json_table(po_document, '$'
COLUMNS (requestor VARCHAR2(32 CHAR) PATH '$.Requestor',
phones    VARCHAR2(100 CHAR) FORMAT JSON
PATH '$.ShippingInstructions.Phone',
partial   NUMBER(1) PATH '$.AllowPartialShipment',
has_zip   VARCHAR2(5 CHAR) EXISTS
PATH '$.ShippingInstructions.Address.zipCode')) jt
WHERE jt.partial = 1 AND has_zip = 'true';

39.5.6.2 JSON_TABLEとJSON配列の使用

JSON値は、1つの配列にすることも、1つ以上の配列を含めることも可能であり、他のJSON配列またはオブジェクト内の任意の数のレベルにネストしてもかまいません。json_table NESTEDパス句を使用して、配列の特定の要素を投影できます。

例39-13では、JSONデータ内の要求者および関連する電話番号を列po_document内に投影しています。JSON配列Phone全体がJSONデータph_arrのリレーショナル列として投影されています。このJSONデータをVARCHAR2列としてフォーマットするには、キーワードFORMAT JSONが必要です。

JSON配列Phone全体ではなく、配列の個別要素のみを投影する場合はどうすればよいでしょうか。例39-14は、これを行う方法の1つを示しており、投影する必要があるデータが配列要素のみである場合、この方法を使用できます。

要求者と関連する電話データの両方を投影する場合、例39-14の行パス式($.Phone[*])は適切ではありません。この式は、配列Phoneの(電話オブジェクト)要素のみを対象としています。

例39-15は、両方を対象とする方法の1つを示しています。ここでは、名前と電話配列全体の両方を対象とする行パス式を使用するとともに、個別電話オブジェクトのフィールドtypeおよびnumberを対象とする列パス式を使用しています。

例39-15では例39-13の場合のようにキーワードFORMAT JSONが必要ですが、これは、生成される列VARCHAR2にJSONデータ(つまり、電話ごとに1つの配列要素という形式による電話のタイプまたは電話番号の配列)が含まれるためです。また、例39-13の事例とは異なり、列phone_typeおよびphone_numにラッパー句が必要ですが、これは、フィールドtypeおよびnumberを持つオブジェクトが配列Phoneに複数含まれるためです。

例39-15の結果は、状況によっては求めるものとは異なる場合があります。たとえば、電話番号のJSON配列が含まれるリレーショナル列(特定の発注書のすべての番号に対して1つの行)ではなく、単一の電話番号が含まれるリレーショナル列(番号当たり1つの行)が必要な場合があります。

この場合、配列に対してjson_tableのNESTEDパス句を使用することにより、配列要素を投影するようjson_tableに命令を出す必要があります。NESTEDパス句は実質的に、追加の行ソース(行パターン)として機能します。例39-16に、これを示します。

キーワードNESTEDは1回のjson_tableの呼出しで何回でも使用できます。

例39-16では、外部のCOLUMNS句は、ネストした(内部の) COLUMNS句の親です。定義されている仮想表は外部結合を使用して結合されますが、この場合、親句によって定義される表が結合における外部表になります。

(同じ親の下で直接ネストされた2番目の列の句がある場合、これら2つのネストした句は兄弟のCOLUMNS句になります。)

例39-17は、JSONデータを介してリレーショナル・ビューを定義しています。ここでは、NESTEDパス句を使用して配列LineItemsの要素を投影しています。

例39-13 JSON配列全体のJSONデータとしての投影

SELECT jt.*
FROM j_purchaseorder,
json_table(po_document, '$'
COLUMNS (requestor VARCHAR2(32 CHAR) PATH '$.Requestor',
ph_arr    VARCHAR2(100 CHAR) FORMAT JSON
PATH '$.ShippingInstructions.Phone')) AS "JT";

例39-14 JSON配列の要素の投影

SELECT jt.*
FROM j_purchaseorder,
json_table(po_document, '$.ShippingInstructions.Phone[*]'
COLUMNS (phone_type VARCHAR2(10) PATH '$.type',
phone_num  VARCHAR2(20) PATH '$.number')) AS "JT";

PHONE_TYPE     PHONE_NUM
----------     ---------
Office         909-555-7307
Mobile         415-555-1234

例39-15 JSON配列の要素と他のデータの投影

SELECT jt.*
FROM j_purchaseorder,
json_table(po_document, '$'
COLUMNS (
requestor  VARCHAR2(32 CHAR) PATH '$.Requestor',
phone_type VARCHAR2(50 CHAR) FORMAT JSON WITH WRAPPER
PATH '$.ShippingInstructions.Phone[*].type',
phone_num  VARCHAR2(50 CHAR) FORMAT JSON WITH WRAPPER
PATH '$.ShippingInstructions.Phone[*].number')) AS "JT";

REQUESTOR    PHONE_TYPE            PHONE_NUM
---------    ----------            ---------
Alexis Bull  ["Office", "Mobile"]  ["909-555-7307", "415-555-1234"]

例39-16 JSON_TABLE: NESTEDを使用した配列要素の投影

SELECT jt.*
FROM j_purchaseorder,
json_table(po_document, '$'
COLUMNS (
requestor VARCHAR2(32 CHAR) PATH '$.Requestor',
NESTED                      PATH '$.ShippingInstructions.Phone[*]'
COLUMNS (phone_type VARCHAR2(32 CHAR) PATH '$.type',
phone_num  VARCHAR2(20 CHAR) PATH '$.number'))) AS "JT";

例39-17 JSONデータを介したリレーショナル・ビューの定義

CREATE OR REPLACE VIEW j_purchaseorder_detail_view AS
SELECT d.*
FROM j_purchaseorder po,
json_table(po.po_document, '$'
COLUMNS (
po_number        NUMBER(10)         PATH '$.PONumber',
reference        VARCHAR2(30 CHAR)  PATH '$.Reference',
requestor        VARCHAR2(128 CHAR) PATH '$.Requestor',
userid           VARCHAR2(10 CHAR)  PATH '$.User',
costcenter       VARCHAR2(16)       PATH '$.CostCenter',
ship_to_name     VARCHAR2(20 CHAR)
PATH '$.ShippingInstructions.name',
ship_to_street   VARCHAR2(32 CHAR)
PATH '$.ShippingInstructions.Address.street',
ship_to_city     VARCHAR2(32 CHAR)
PATH '$.ShippingInstructions.Address.city',
ship_to_county   VARCHAR2(32 CHAR)
PATH '$.ShippingInstructions.Address.county',
ship_to_postcode VARCHAR2(10 CHAR)
PATH '$.ShippingInstructions.Address.postcode',
ship_to_state    VARCHAR2(2 CHAR)
PATH '$.ShippingInstructions.Address.state',
ship_to_zip      VARCHAR2(8 CHAR)
PATH '$.ShippingInstructions.Address.zipCode',
ship_to_country  VARCHAR2(32 CHAR)
PATH '$.ShippingInstructions.Address.country',
ship_to_phone    VARCHAR2(24 CHAR)
PATH '$.ShippingInstructions.Phone[0].number',
NESTED PATH '$.LineItems[*]'
COLUMNS (
itemno      NUMBER(38)         PATH '$.ItemNumber',
description VARCHAR2(256 CHAR) PATH '$.Part.Description',
upc_code    VARCHAR2(14 CHAR)  PATH '$.Part.UPCCode',
quantity    NUMBER(12,4)       PATH '$.Quantity',
unitprice   NUMBER(14,2)       PATH '$.Part.UnitPrice'))) d;

39.6 JSONデータに対する単純なドット表記法アクセス

問合せに対しては、より詳細だがより柔軟なOracle SQL関数json_queryおよびjson_valueの使用に代わるものとして、単純なドット表記法構文が用意されています。ドット表記法は、可能な場合は常にJSON値を戻すよう作られています。

Oracle SQL関数json_queryおよびjson_valueは、Oracle JSONパス式を引数として受け入れ、ターゲットのJSONデータと照合します。それらは、戻り値のデータ型、複数の値を配列としてラップするかどうか、およびエラーの処理方法を指定するために、オプションのRETURNING句、ラッパー句、およびエラー処理句をそれぞれ受け入れます。

単純なユースケースに代わる手段として、ドット表記法構文を使用することにより、json_queryまたはjson_valueを使用せずにJSONデータを問い合せることができます。

ドット表記法を使用した問合せの動作は、json_queryとjson_valueのどちらとも異なります。実質的に、これらの動作を組み合せて、可能であれば常に1つ以上のJSON値を戻します。

パス式がJSONデータと一致しないためにこれらのSQL関数のどちらかではNULLが戻されたりエラーが発生する可能性がありますが、ドット表記法の問合せでは多くの場合、有用なJSON値が戻されます。戻り値は常に、JSONデータを表す文字列(データ型VARCHAR2)です。文字列の内容は、次のように対象のJSONデータによって決まります。

- 単一のJSON値が対象である場合、この値はJSONスカラー、オブジェクトまたは配列のいずれであるかに関係なく文字列内容です。

- 複数のJSON値が対象である場合、文字列の内容は、これらの値が要素であるJSON配列です。

最初の事例における動作は、スカラー値の場合はjson_valueの動作と似ており、オブジェクトまたは配列値の場合はjson_queryの動作と似ています。

2番目の事例における動作は、配列ラッパーを使用したjson_queryの動作と似ています。

ドット表記法の構文は、表の別名(必須)に、ドット(.)、JSON列の名前および. json_keyまたは. json_keyにarray_stepを続けたものの形式をした1つ以上のペアです。ここでjson_keyはJSONキーで、array_stepは、「Oracle JSONパス式の基本的な構文」で説明されている配列ステップ式です。

各json_keyは有効なSQL識別子である必要があり、列にはis jsonチェック制約が設定されている必要があり、これにより、整形式のJSONデータが含まれるようにします。これらの規則のどちらも順守されない場合、問合せのコンパイル時にエラーが発生します。(エラーの発生を回避するには、チェック制約が存在する必要があります。ただし、これは、アクティブである必要はありません。制約を非アクティブ化すると、このエラーは発生しません。)

このJSONドット表記法の場合、SQLの一般的な事例とは異なり、引用符で囲まれていない識別子(列名の後ろ)は、大文字と小文字を区別して(つまり、引用符で囲まれているかのように)処理されます。これは大変都合がよく、JSONキーを引用符で囲まなくても識別子として使用できます。たとえば、jcolumn."friends"ではなく、jcolumn.friendsと入力してかまいません。また、JSONオブジェクトが大文字を使用して名前を付けられている場合(FRIENDSなど)、jcolumn.friendsではなくjcolumn.FRIENDSと書く必要があります。

次に、ドット表記法構文の例をいくつか示します。すべて、poという別名を持つ表のJSON列po_documentを参照しています。

- po.po_document.PONumber – キーPONumberの値。

- po.po_document.LineItems[1] – 配列LineItemsの2つ目の要素(配列の位置は0が基準)。

- po.po_document.LineItems[*] – 配列LineItemsのすべての要素(*はワイルドカード)。

- po.po_document.ShippingInstructions.name – オブジェクトShippingInstructionsの子であるキーnameの値。

注意:

- ドット表記法構文の各コンポーネントは最大30バイトに制限されています。
SQLドット表記法構文およびSQL識別子の詳細は、Oracle Database SQL言語リファレンスを参照してください。

- 単純なドット表記法のJSON問合せでは、4Kバイトよりも長い値は戻せません。値がこの制限を超えると、かわりにSQL NULLが戻されます。実際の値を取得するには、記法にドットを付けず、通常の問合せ構文を使用します。つまり、Oracle SQL関数json_queryまたはjson_valueを使用して、RETURNING句で適切な戻り型を指定します。
JSONドット表記法構文の詳細は、Oracle Database SQL言語リファレンスを参照してください。

JSONデータに対するJSONドット表記法の式の照合は、Oracle JSONパス式の場合と同じであり、これには、暗黙の配列反復を許可する緩和が含まれます(「Oracle JSONパス式の構文の緩和」を参照)。ドット表記法の式のJSON列はパス式のコンテキスト項目に相当し、ドット表記法で使用される各識別子は、パス式で使用される各識別子に相当します。

たとえば、JSON列jcolumnがパス式のコンテキスト項目に相当する場合、ドット表記法の式jcolumn.friendsは$.friendsに相当し、jcolumn.friends.nameは$.friends.nameに相当します。

後者の場合、コンテキスト項目はオブジェクトでもオブジェクトの配列でもかまいません。これがオブジェクトの配列である場合、各オブジェクトはキーfriendsに対して照合されます。キーfriendsの値自体はオブジェクトでもオブジェクトの配列でもかまいません。後者の場合、配列内の最初のオブジェクトが使用されます。

配列要素に対してワイルドカードを暗黙で使用する場合(「Oracle JSONパス式の構文の緩和」を参照)以外では、ワイルドカードを使用したパス式をドット表記法構文を使用して表すことはできません。ドット表記法構文は、単純なパス式の使用に対する便利な代替手段ですが、一般的なパス式の使用の代用手段ではありません。

例39-18は、ドット表記法の問合せとjson_valueの問合せの対応を示しています。例39-4のデータが与えられた場合、各問合せにより、文字列"1600" (JSON数値1600を表す値VARCHAR2)が戻されます。

例39-19は、ドット表記法の問合せとjson_queryの問合せの対応を示しています。最初のペアの各問合せにより、電話オブジェクトのJSON配列(を表す値VARCHAR2)が戻されます。2番目のペアの各問合せにより、例39-9の場合のように、電話のタイプの配列(を表す値VARCHAR2)が戻されます。

関連項目:

- SQLオブジェクトおよびオブジェクト属性へのアクセス(オブジェクト・アクセス式)に使用されるドット表記法の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

- 「Oracle JSONパス式」

- 「列にJSONデータが含まれることを確認するためのチェック制約の使用」

- 「JSONデータで使用するためのOracle SQL関数および条件」

例39-18 JSONドット表記法の問合せとJSON_VALUEの比較

SELECT po.po_document.PONumber FROM j_purchaseorder po;

SELECT json_value(po_document, '$.PONumber') FROM j_purchaseorder;

例39-19 JSONドット表記法の問合せとJSON_QUERYの比較

SELECT po.po_document.ShippingInstructions.Phone FROM j_purchaseorder po;

SELECT json_query(po_document, '$.ShippingInstructions.Phone')
FROM j_purchaseorder;

SELECT po.po_document.ShippingInstructions.Phone.type FROM j_purchaseorder po;

SELECT json_query(po_document, '$.ShippingInstructions.Phone.type' WITH WRAPPER)
FROM j_purchaseorder;

39.7 JSONデータの索引

JSONデータには、これを格納するために使用する任意のデータ型の場合と同じように索引を付けることができます。また、JSON検索索引を定義できます。これは、非定型の構造的問合せと全文問合せの両方に便利です。

関連項目:

- JSONデータに対して関数ベースの索引が選択されるかどうかを確認する方法

- Oracle SQL条件JSON_EXISTSのビットマップ索引の作成

- JSON_VALUE関数ベースの索引の作成

- JSON_VALUE関数ベースの索引とJSON_TABLE問合せの使用

- JSON_VALUEの索引付けおよび問合せに関するデータ型の考慮事項

- コンポジットBツリー索引を使用した複数のJSONフィールドの索引付け

39.7.1 JSONデータに対して関数ベースの索引が選択されるかどうかを確認する方法

特定の問合せで特定の関数ベースの索引が選択されるかどうかを確認するには、問合せの実行計画内で索引名を検索します。

たとえば、例39-22で定義されている索引が指定された場合、例39-18のjson_value問合せの実行計画では索引po_num_id1を使用して索引スキャンが参照されます。

39.7.2 Oracle SQL条件JSON_EXISTSのビットマップ索引の作成

json_existsで戻される値に対して、ビットマップ索引を作成できます。条件に対して想定される戻り値が2つ(trueおよびfalse)のみであるため、これはjson_existsでの使用に適した索引です。

これを、例39-20に示します。

例39-21では、json_valueによって戻される値のビットマップ索引を作成しています。データ内のフィールドCostCenterに対して想定される値が少ない場合、これは使用に適した索引です。

例39-20 JSON_EXISTSのビットマップ索引の作成

CREATE BITMAP INDEX has_zipcode_idx
ON j_purchaseorder (json_exists(po_document,
'$.ShippingInstructions.Address.zipCode'));

例39-21 JSON_VALUEのビットマップ索引の作成

CREATE BITMAP INDEX cost_ctr_idx
ON j_purchaseorder (json_value(po_document, '$.CostCenter'));

39.7.3 JSON_VALUE関数ベースの索引の作成

SQLファンクションjson_valueに対して関数ベースの索引を作成できます。これには標準の構文を使用(json_value)するか、単純なドット表記法構文を使用できます。これらいずれかの方法で作成された索引は、ドット表記法問合せとjson_value問合せのどちらとも一緒に使用できます。

例39-22では、表j_purchaseorderの列po_document内にあるオブジェクトのフィールドPONumberに対するjson_valueの関数ベースの索引を作成しています。オブジェクトはパス式のコンテキスト項目として渡されます。

ここでERROR ON ERRORを使用することは、フィールドPONumberがないレコード、または非数値の値を持つフィールドPONumberがあるレコードがデータに含まれる場合、索引の作成が失敗することを意味します。また、索引が存在する場合、このようなレコードを挿入しようとしても失敗します。

代替方法として、「JSONデータに対する単純なドット表記法アクセス」で説明されている簡単な構文を使用して索引を作成する方法があります。例39-23はこれを示しています。ここでは、ドット表記法の問合せで戻すことが可能な内容に応じてスカラー結果と非スカラー結果の両方に索引を付けています。

例39-22と例39-23の両方で作成された索引は、ドット表記法構文を使用する問合せとjson_valueを使用する問合せのいずれかに対して選択できます。

例39-23の索引が問合せjson_valueに対して選択される場合、正しいフィールド値をテストするために、索引の選択後にフィルタリングが適用されます。この索引には非スカラー値を格納でき、ドット表記法の問合せではこのような値を戻すことができますが、json_valueの問合せではできないため、このような値は索引選択後にフィルタで除外されます。

次のいずれかの形式を使用してjson_valueに対して関数ベースの索引を作成することをお薦めします。

- RETURNINGデータ型を指定し、ERROR ON ERRORを使用するjson_value式
索引が付けられる値は、指定したデータ型の(非nullの)スカラー値のみです。それでもなお、索引は、このようなスカラー結果が生成されるドット表記法問合せで使用できます。

- ドット表記法構文
索引が付けられる値は、可能な場合は常にJSON値を戻すドット表記法問合せの柔軟な動作に対応します。これには、非スカラーのJSON値(JSONオブジェクトおよび配列)が含まれる場合があります。これらは、json_valueの問合せに加えてドット表記法の問合せと照合できます。索引は、初期セットの一致結果を見つけ出すために使用され、これらの一致結果は問合せの詳細事項に応じてフィルタされます。たとえば、索引が付けられた値のうちJSONスカラーでないものはフィルタで除外されます。

このように、これらいずれかの方法で作成された索引は、ドット表記法問合せとjson_value問合せのどちらとも一緒に使用できます。

例39-22 JSONオブジェクト・フィールドに対する関数ベースの索引の作成: JSON_VALUE

CREATE UNIQUE INDEX po_num_idx1
ON j_purchaseorder (json_value(po_document, '$.PONumber'
RETURNING NUMBER ERROR ON ERROR));

例39-23 JSONオブジェクト・フィールドに対する関数ベースの索引の作成: ドット表記法

CREATE UNIQUE INDEX po_num_idx2 ON j_purchaseorder po (po.po_document.PONumber);

39.7.4 JSON_VALUE関数ベースの索引とJSON_TABLE問合せの使用

json_tableによって投影された列をWHERE句が参照し、この列を対象とする有効なJSONパスが索引付きパス式と一致する場合、json_tableが関連する問合せに対して、ERROR ON ERRORが設定されたjson_value,を使用して作成された索引を使用できます。

この索引が索引付きパスに対する制約として機能することにより、JSONコレクション内の各項目に対して1つの(非nullの)スカラーのJSON値のみが確実に投影されるようになります。

したがって、例39-24の問合せでは、例39-22で作成された索引を使用しています。

注意:

json_value式またはドット表記法を使用して作成された関数ベースの索引を、問合せのWHERE句内で対応する存在に対して選択できるのは、この存在がSQLの比較式(>=など)で使用されている場合のみです。特に、これは、条件IS NULLまたはIS NOT NULLで使用される存在としては選択されません。

SQL比較条件の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

例39-24 JSON_VALUE関数ベースの索引とJSON_TABLE問合せの使用

SELECT jt.*
FROM j_purchaseorder po,
json_table(po.po_document, '$'
COLUMNS po_number  NUMBER(5) PATH '$.PONumber',
reference  VARCHAR2(30 CHAR) PATH '$.Reference',
requestor  VARCHAR2(32 CHAR) PATH '$.Requestor',
userid     VARCHAR2(10 CHAR) PATH '$.User',
costcenter VARCHAR2(16 CHAR) PATH '$.CostCenter') jt
WHERE po_number = 1600;

39.7.5 JSON_VALUEの索引付けおよび問合せに関するデータ型の考慮事項

デフォルトでは、JSON用のOracle SQL関数ではVARCHAR2値が戻されます。json_valueを使用して関数ベースの索引を作成する場合、RETURNING句を使用して異なる戻りデータ型を指定しないかぎり、非VARCHAR2値を想定する問合せに対してこの索引は選択されません。

たとえば、例39-25の問合せの場合、json_valueでRETURNING NUMBERが使用されています。この問合せには例39-22で作成された索引を選択できますが、これは、索引が付けられたjson_value式で戻り型としてNUMBERが指定されているためです。

ただし、例39-23で作成された索引にはRETURNING NUMBER (デフォルトでは、戻り型はVARCHAR2(4000)です)が使用されていないため、このような問合せに対して選択することはできません。

ここで、戻される値の型がVARCHAR2になるようにRETURNING句なしでjson_valueを使用している例39-26と例39-27の問合せについて検討してみます。

例39-26では、SQL関数to_numberにより、json_valueによって戻されるVARCHAR2値を数値に明示的に変換しています。同様に、例39-27では、比較条件> (より大きい)により、値を数値に暗黙的に変換しています。

例39-22と例39-23の索引のいずれも、これらの問合せに対して選択されません。これらの問合せでは、いずれの事例でも型キャストのために正しい結果が戻される可能性がありますが、これらの索引を使用してこれらの問合せを評価することはできません。

また、一部のデータを特定のデータ型に変換できない場合に何が起きるかについても検討してください。たとえば、例39-25、例39-26および例39-27の問合せが実行された場合、"alpha"などのPONumber値はどうなるでしょうか。

例39-26および例39-27の場合、値を数値にキャストしようとするために問合せはエラーで停止します。ただし、例39-25の場合、デフォルトのエラー処理動作がNULL ON ERRORであるため、非数値"alpha"は単純にフィルタで除外されます。値には索引が付けられますが、問合せに対しては無視されます。

同様に、たとえばDEFAULT '1000' ON ERRORが問合せで使用されたとすると、つまり、数値のデフォルト値が指定されたとすると、値"alpha"に対してエラーは発生しません。この場合、デフォルト値の1000が使用されます。

例39-25 JSON_VALUE問合せと明示的なRETURNING NUMBER

SELECT count(*) FROM j_purchaseorder po  WHERE json_value(po_document, '$.PONumber' RETURNING NUMBER) > 1500;

例39-26 JSON_VALUE問合せと明示的な数値変換

SELECT count(*) FROM j_purchaseorder po  WHERE to_number(json_value(po_document, '$.PONumber')) > 1500;

例39-27 JSON_VALUE問合せと暗黙的な数値変換

SELECT count(*) FROM j_purchaseorder po  WHERE json_value(po_document, '$.PONumber') > 1500;

39.7.6 コンポジットBツリー索引を使用した複数のJSONフィールドの索引付け

JSONオブジェクトの複数のフィールドに索引を付けるには、最初にこれらの仮想列を作成します。次に、仮想列に対してコンポジットBツリー索引を作成します。

例39-28および例39-29に、これを示します。例39-28では、JSONオブジェクト・フィールドUserおよびCostCenterそれぞれに対して仮想列useridおよびcostcenterを作成しています。

例39-29では、例39-28の仮想列に対してコンポジットBツリー索引を作成しています。

仮想列または対応するJSONデータ(オブジェクト・フィールド)を参照するSQL問合せでは、コンポジット索引が選択されます。このことは、例39-30の両方の問合せに当てはまります。

これら2つの問合せの効果は同一であり、パフォーマンスも同一です。ただし、最初の問合せ形式はJSONデータ自体を対象としておらず、このデータに索引を付けるために使用される仮想列を対象としています。

問合せのパフォーマンスを向上させるために実装された索引にデータが論理的に依存することはありません。実装からのこのような独立性がコードに反映されるようにするには、2番目の問合せ形式を使用してください。このようにすることにより、問合せは索引の有無とは関係なく同じ機能を果たすようになります。この場合、索引はパフォーマンスの向上に特化して機能します。

例39-28 JSONオブジェクト・フィールドの仮想列の作成

ALTER TABLE j_purchaseorder ADD (userid VARCHAR2(20)
GENERATED ALWAYS AS (json_value(po_document, '$.User' RETURNING VARCHAR2(20))));

ALTER TABLE j_purchaseorder ADD (costcenter VARCHAR2(6)
GENERATED ALWAYS AS (json_value(po_document, '$.CostCenter'
RETURNING VARCHAR2(6))));

例39-29 JSONオブジェクト・フィールドのコンポジットBツリー索引の作成

CREATE INDEX user_cost_ctr_idx on j_purchaseorder(userid, costcenter);

例39-30 コンポジット索引を使用して索引が付けられたJSONデータを問い合せる2通りの方法

SELECT po_document FROM j_purchaseorder WHERE userid      = 'ABULL'
AND costcenter  = 'A50';

SELECT po_document
FROM j_purchaseorder WHERE json_value(po_document, '$.User')       = 'ABULL'
AND json_value(po_document, '$.CostCenter') = 'A50';

39.8 JSONデータの全文検索

SELECT文のCASE式またはWHERE句でOracle SQL条件json_textcontainsを使用して、VARCHAR2、BLOBまたはCLOB列に格納されているJSONデータの全文検索を実行できます。

条件json_textcontainsを使用するには、JSONデータでの使用に特化して設計されたOracle Text索引であるJSON検索索引を最初に作成する必要があります。そうしない場合、json_textcontainsを使用するとエラーが発生します。

JSON検索索引はJSONデータの一般的な非定型問合せに適しており、これらの問合せで全文検索が使用されるかどうかとは関係ありません。

注意:

JSON検索索引は、データベースのキャラクタ・セットがAL32UTF8である場合のみ、およびVARCHAR2、BLOBまたはCLOB記憶域を使用するJSONデータの場合のみサポートされます。そうでない場合、索引作成時にエラーが発生します。

JSON検索索引を作成するには、索引型のCTXSYS.CONTEXTおよびセクション・グループCTXSYS.JSON_SECTION_GROUPをPARAMETERS句を使用して指定します。例39-31に、これを示します。

例39-32は、明細項目の部品の説明にキーワードMagicが含まれる発注書を検索する全文問合せを示しています。

例39-33は、で作成したJSON検索索引も使用するJSONデータの非全文問合せを示しています

注意:

json_valueが使用される場合、JSON検索索引が処理後のフィルタとして使用されます。この索引は、戻り値がNUMBERではなくVARCHAR2である場合のみjson_valueに対して選択でき、等価性比較の場合のみ選択できます。たとえば、これは、json_value(column, '$.name_first') > 'Nimrod'などの比較に対しては選択されません。

問合せの実行計画内にJSON検索索引の名前が存在する場合、索引が実際に問合せに対して選択されたことがわかります。例39-34に示すものと似た行が表示されます。

JSON検索索引は、要求に応じて非同期にメンテナンスされます。したがって、索引メンテナンスのコストを遅延し、コミット時のみまたはデータベースの負荷が軽減されている特定の時期に実行できます。これにより、DMLのパフォーマンスを向上させることができます。また、索引の同期化を行う際に、非同期索引行のバルク・ロードを有効にすると、索引メンテナンスのパフォーマンスを向上させることができます。一方、索引の非同期メンテナンスとは、索引が同期化されるまでは、変更されたか新しく挿入されたデータに索引が使用されないことを意味します。

関連項目:

- JSONデータを索引付けする別の方法の詳細は、JSONデータの索引を参照してください。

- 条件json_textcontainsの詳細は、Oracle Database SQL言語リファレンスを参照してください。

- CTXSYS.CONTEXT索引の詳細は、『Oracle Textリファレンス』を参照してください。

- セクション・グループCTXSYS.JSON_SECTION_GROUPの詳細は、『Oracle Textリファレンス』を参照してください。

- JSON検索索引の同期化の詳細は、Oracle Textリファレンスを参照してください。

例39-31 JSON検索索引の作成

CREATE INDEX po_search_idx ON j_purchaseorder (po_document)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('section group CTXSYS.JSON_SECTION_GROUP SYNC (ON COMMIT)');

例39-32 JSONデータの全文問合せ

SELECT po_document FROM j_purchaseorder
WHERE json_textcontains(po_document, '$.LineItems.Part.Description', 'Magic');

例39-33 JSONデータの非定型問合せ

SELECT po_document FROM j_purchaseorder
WHERE json_exists(po_document, '$.ShippingInstructions.Address.country');

SELECT po_document FROM j_purchaseorder
WHERE json_value(po_document, '$.User') = 'ABULL';

例39-34 JSON検索索引が使用されていることを示す実行計画

|* 2|   DOMAIN INDEX     | PO_SEARCH_IDX |     |     |     4 (0)

39.9 外部JSONデータのロード

JSONデータのデータベース表を、JSONダンプ・ファイルの内容から作成できます。

例39-3および例39-4では、説明を目的として、表j_purchaseorderを作成し、この表にJSONデータの単一行を挿入しています。この項では、JSONダンプ・ファイル$ORACLE_HOME/demo/schema/order_entry/PurchaseOrders.dmp内のデータから全表を作成する方法について説明します。このファイルの形式には、Oracle NoSQL Databaseなどの一般的なNoSQLデータベースによって作成されるエクスポート形式との互換性があります。ファイルの各行には、JSONオブジェクトとして表される単一のJSON文書が含まれます。

例39-35では、ファイルシステム・ディレクトリ$ORACLE_HOME/demo/schema/order_entryに対応するデータベース・ディレクトリを作成しています。次に、例39-37では、このデータベース・ディレクトリを使用して外部表であるjson_dump_file_contentsを作成し、ダンプ・ファイルPurchaseOrders.dmpのデータを入力しています。

例39-38では、外部表json_dump_file_contentsからリレーショナル表j_purchaseorderの列json_documentにJSON文書をコピーしています。

関連項目:

- 外部表の概要は、『Oracle Database概要』を参照してください。

- 外部表の詳細は、『Oracle Databaseユーティリティ』を参照してください。

例39-35 データベース・ディレクトリ・オブジェクトの作成

CREATE OR REPLACE DIRECTORY order_entry_dir
AS '$ORACLE_HOME/demo/schema/order_entry';

例39-36 データベース・ディレクトリ・オブジェクトの作成

CREATE OR REPLACE DIRECTORY loader_output_dir AS '/tmp';Foot 7

例39-37 外部表の作成およびJSONダンプ・ファイルからの入力

CREATE TABLE json_dump_file_contents (json_document CLOB)
ORGANIZATION EXTERNAL (TYPE ORACLE_LOADER DEFAULT DIRECTORY order_entry_dir
ACCESS PARAMETERS
(RECORDS DELIMITED BY 0x'0A'
DISABLE_DIRECTORY_LINK_CHECK
BADFILE loader_output_dir: 'JSONDumpFile.bad'
LOGFILE order_entry_dir: 'JSONDumpFile.log'
FIELDS (json_document CHAR(5000)))
LOCATION (order_entry_dir:'PurchaseOrders.dmp'))
PARALLEL
REJECT LIMIT UNLIMITED;

例39-38 外部表からリレーショナル表へのJSONデータのコピー

INSERT INTO j_purchaseorder
SELECT SYS_GUID(), SYSTIMESTAMP, json_document FROM json_dump_file_contents
WHERE json_document IS JSON;

39.10 JSONデータのレプリケーション

Oracle GoldenGateを使用して、JSONデータが格納された列を持つ表をレプリケートできます。

Oracle GoldenGateでは、レプリケートする表に非仮想主キー列が必要であることに注意してください。主キー列を仮想にすることはできません。

JSONデータ上のすべての索引もレプリケートされます。ただし、レプリカ・データベース上で、JSON検索索引をメンテナンスするために使用する任意のOracle Text操作を実行する必要があります。このようなプロシージャの例は、次のとおりです。

- CTX_DDL.create_section_group

- CTX_DDL.drop_section_group

- CTX_DDL.set_sec_grp_attr

- CTX_DDL.sync_index

- CTX_DDL.optimize_index

関連項目:

Oracle GoldenGateの詳細は、Oracle GoldenGateのドキュメントを参照してください

39.11 JSONに対するOracle Databaseのサポート

JavaScript Object Notation (JSON)に対するOracle Databaseのサポートは、リレーショナル記憶域の使用範囲とJSONデータの問合せの使用範囲のベスト・フィットを実現することにより、リレーショナル問合せとJSON問合せを互いに連携して機能させることを目指しています。

注意:

Oracleは、SQL/JSON標準の一部としてJSONデータへのSQLアクセスに関する標準化に積極的に取り組んでいます。JSONに対するOracle Databaseのサポートは、引き続きこのような標準の開発を追跡し、これとともに進化していきます。

関連項目:

- http://www.json.orgおよびhttp://www.ecma-international.org

脚注の凡例

脚注1:
JSONはこの点においてJavaScriptとは表記法が異なります。JSONでは、文字列内でエスケープされていないUnicode文字U+2028 (LINE SEPARATOR)およびU+2029 (PARAGRAPH SEPARATOR)が許可されます。JavaScriptの表記法では、文字列内でこのような制御文字をエスケープする必要があります。JSONP (JSON with padding)データを生成するときにこの違いが重要になる場合があります。

脚注2:
したがって、JavaScriptオブジェクトは、CおよびC++のハッシュ表、JavaのHashMap、PHPの連想配列、Pythonのディクショナリ、PerlおよびRubyのハッシュと似ています。

脚注3:
コンストラクタObjectまたはオブジェクト・リテラル構文{...}を使用してJavaScriptでオブジェクトが作成されます。

脚注4: 一部のコンテキストでは、空のフィールド名はOracle Databaseと一緒には使用できません。使用する場合は必ず、名前を二重引用符で囲む必要があります。
脚注5:
チェック制約によって論理条件ORを使用して条件is jsonが別の条件と結合される場合、列はこれらのビューにリストされません。この場合、列内のデータがJSONデータであるかどうかは確実ではありません。たとえば、制約jcol is json OR length(jcol) < 1000の場合、列jcol内のデータがJSONデータであることは確認されません。

脚注6: オブジェクト・フィールドは、オブジェクトの「キー」と呼ばれることもあります。
脚注7:
この例では、一時ファイルシステム・ディレクトリを使用します。UNIXシステムおよびLinuxシステムでは、これは通常、/tmpです。MS Windowsでは、これは通常、フォルダtemp (c:\tempなど)です。

付録

次の付録では、Oracle XML DBの参考資料を提供します。

- Oracleが提供するXML Schemaおよび例

- Oracle XML DBの制限

- XMLデータを更新するための非推奨の関数

- 非推奨となったXML変換の構造体

- XQueryを使用しないXMLデータの全文検索

A Oracleが提供するXML Schemaおよび例

Oracle XML DBが提供するXML Schema、発注書XML Schema、および様々な例で使用されているXSLTスタイルシートの完全なリスト、および、XMLコンテンツをOracle XML DBにロードするためのC言語(OCI)の例と、XMLコンテキストを初期化および終了するためのC言語(OCI)の例を示します。

- 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

- XSLTスタイルシートの例、PurchaseOrder.xsl

- C (OCI)を使用したXMLデータのロード

- XMLコンテキスト(OCI)の初期化および終了

A.1 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="73" elementFormDefault="qualified" xdb:flags="23"
xdb:mapStringToNCHAR="false" xdb:mapUnboundedStringToLob="false"
xdb:storeVarrayAsTable="false" xdb:schemaOwner="XDB"
xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xdb="http://xmlns.oracle.com/xdb"
xmlns:xdbres="http://xmlns.oracle.com/xdb/XDBResource.xsd">
<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="0"
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="0"
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="0" 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="0"
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="0"
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="0"
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="0" 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="0" 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="true"
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"/>
<attribute xdb:propNumber="777" name="IsXMLIndexed" type="boolean"
xdb:memByteLength="1" xdb:memType="252" xdb:system="false"
xdb:mutable="true" xdb:JavaType="boolean" default="false" xdb:hidden="true"
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>

A.2 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"
targetNamespace="http://xmlns.oracle.com/xdb/XDBResConfig.xsd"
xmlns:xdb="http://xmlns.oracle.com/xdb"
xmlns:rescfg="http://xmlns.oracle.com/xdb/XDBResConfig.xsd"
elementFormDefault="qualified" xdb:schemaOwner="XDB" 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" minOccurs="1" maxOccurs="1"/>
<element name="namespace" type="string" minOccurs="0" maxOccurs="1"/>
</all>
</complexType>
<!-- listener pre-condition element  -->
<complexType name="condition">
<all>
<element name="existsNode" type="rescfg:existsNode" minOccurs="0" maxOccurs="1"/>
</all>
</complexType>
<complexType name="events">
<all>
<element name="Render" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-Create" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-Create" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-Delete" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-Delete" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-Update" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-Update" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-Lock" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-Lock" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-Unlock" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-Unlock" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-LinkIn" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-LinkIn" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-LinkTo" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-LinkTo" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-UnlinkIn" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-UnlinkIn" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-UnlinkFrom" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-UnlinkFrom" type="string" minOccurs="0"/ maxOccurs="1">
<element name="Pre-CheckIn" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-CheckIn" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-CheckOut" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-CheckOut" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-UncheckOut" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-UncheckOut" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-VersionControl" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-VersionControl" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-Open" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-Open" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Pre-InconsistentUpdate" type="string" minOccurs="0" maxOccurs="1"/>
<element name="Post-InconsistentUpdate" type="string" minOccurs="0" maxOccurs="1"/>
</all>
</complexType>
<!-- event listener element  -->
<complexType name="event-listener">
<all>
<element name="description" type="string" minOccurs="0" maxOccurs="1"/>
<element name="schema" type="string" minOccurs="0" maxOccurs="1"/>
<element name="source" type="string"  minOccurs="1" maxOccurs="1"/>
<element name="language" type="rescfg:language" minOccurs="0" maxOccurs="1"/>
<element name="pre-condition" type="rescfg:condition" minOccurs="0" maxOccurs="1"/>
<element name="events" type="rescfg:events" minOccurs="0" maxOccurs="1"/>
</all>
</complexType>
<complexType name="event-listeners">
<sequence>
<element name="listener" type="rescfg:event-listener" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
<attribute name="default-schema" type="string" xdb:baseProp="true" use="optional"/>
<attribute name="default-language" type="rescfg:language" xdb:baseProp="true" use="optional"/>
<attribute name="set-invoker" type="boolean" xdb:baseProp="true" default="false"/>
</complexType>
<complexType name="defaultPath">
<all>
<element name="pre-condition" type="rescfg:condition" minOccurs="0" maxOccurs="1"/>
<element name="path" type="string" minOccurs="0" maxOccurs="1" xdb:transient="generated"/>
<element name="resolvedpath" type="string" minOccurs="1" maxOccurs="1"
xdb:baseProp="true" xdb:hidden="true"/>
<element name="oid" type="hexBinary"minOccurs="1" maxOccurs="1"
xdb:baseProp="true" xdb:hidden="true"/>
</all>
</complexType>
<complexType name="defaultACL">
<sequence>
<element name="ACL" type="rescfg:defaultPath" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="defaultConfig">
<sequence>
<element name="configuration" type="rescfg:defaultPath"
minOccurs="1" 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" minOccurs="0" default="OID"/>
<element name="LinkMetadata" type="rescfg:link-metadata" minOccurs="0" default="None"/>
<element name="pre-condition" type="rescfg:condition" minOccurs="0 "maxOccurs="1"/>
</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" minOccurs="0" default="OID"/>
<element name="ConflictRule" type="rescfg:conflict-rule" minOccurs="0" default="Error"/>
</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" maxOccurs="1"/>
<element name="defaultChildACL" type="rescfg:defaultACL" minOccurs="0" maxOccurs="1"/>
<element name="event-listeners" type="rescfg:event-listeners" minOccurs="0" maxOccurs="1"/>
<element name="XLinkConfig" type="rescfg:xlink-config" minOccurs="0" maxOccurs="1"/>
<element name="XIncludeConfig" type="rescfg:xinclude-config" minOccurs="0" maxOccurs="1"/>
<element name="SectionConfig" type="rescfg:section-config" minOccurs="0" maxOccurs="1"/>
<element name="ContentFormat" type="rescfg:content-format" minOccurs="0" maxOccurs="1"/>
<!-- application data -->
<element name="applicationData" minOccurs="0" maxOccurs="1">
<complexType>
<sequence>
<any namespace="##other" maxOccurs="unbounded" processContents="lax"/>
</sequence>
</complexType>
</element>
</all>
<attribute name="enable" type="boolean" xdb:baseProp="true" default="true"/>
<attribute name="copy-on-inconsistent-update" type="boolean" use="optional"/>
</complexType>
<element name="ResConfig" type="rescfg:ResConfig" xdb:defaultTable="XDB$RESCONFIG"/>
</schema>

A.3 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>

A.4 xdbconfig.xsd: Oracle XML DBを構成するためのXML Schema

Oracle XML DBを構成するために使用されるXML Schemaが含まれるファイルxdbconfig.xsdの完全なリストを示します。

注意:

ここでは、要素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"/>
<element name="host-name" 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"/>
<element name="white-list" minOccurs="0">
<complexType>
<sequence>
<element name="white-list-pattern" minOccurs="0"
maxOccurs="unbounded">
<simpleType>
<restriction base="string">
<pattern value="(/[^\*/]+)*(/\*)?"/>
</restriction>
</simpleType>
</element>
</sequence>
</complexType>
</element>
</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>
<!-- session-state-cache-param captures all the parameters
of the session state cache. expiration-timeout is
specified in centi-seconds. -->
<element name="session-state-cache-param" minOccurs="0">
<complexType>
<sequence>
<element name="cache-size" type="unsignedInt"/>
<element name="expiration-timeout" type="unsignedInt"/>
</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"/>
<enumeration value="SecurityOn"/>
<enumeration value="SecurityOff"/>
</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>

A.5 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>

A.6 発注書XML Schema

様々な例で使用されている発注書XML Schemaの完全なリストを示します。

例A-1に、注釈の付いていない発注書XML Schemaを示します。

例A-1 注釈の付いていない発注書XML Schema

<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>

例A-3は、例A-2を変更したものです。この変更版は XML Schemaの拡張でXML Schemaの拡張について説明するために使用されています。例A-2は、XML Schemaの格納と問合せ: 基本の例で使用されている注釈付きXML Schemaの完全なリストです。

例A-2 注釈付き発注書XML Schema

<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-3は、例20-1に示されている、修正された注釈付き発注書XML Schemaの完全なリストです。太字は、例A-2のスキーマ内のものに追加されたものか、あるいは大幅に異なるものを示しています。

例A-3 修正された注釈付き発注書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>

A.7 XSLTスタイルシートの例、PurchaseOrder.xsl

様々な例で使用される、XSLTスタイルシートPurchaseOrder.xslの完全なリストを示します。

例A-4 XSLTスタイルシート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>

A.8 C (OCI)を使用したXMLデータのロード

XMLデータをXMLType表に挿入するCプログラムの完全なリストを示します。

Cを使用したXMLコンテンツのロードには、同じプログラムの一部が示されています。

例A-5 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();
}

A.9 XMLコンテキスト(OCI)の初期化および終了

OCI関数のOCIXmlDbInitXmlCtx()およびOCIXmlDbFreeXmlCtx()を使用して、XMLコンテキストを初期化および終了する方法の例を示します。C DOM APIを使用してXML文書を構成し、データベース内に保存します。

例A-6の一部は「C API for XML」の「XMLコンテキストの初期化および終了」に示されています。これはデータベース・スキーマCAPIUSERでmy_table表を作成するため、次のSQLコードを最初に実行したことを前提としています。

CONNECT CAPIUSER
Enter password: <password>

Connected.

CREATE TABLE my_table OF XMLType;

例A-6 OCIXmlDbInitXmlCtx()およびOCIXmlDbFreeXmlCtx()の使用

#ifndef S_ORACLE
#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 */
static sword exec_bind_xml(OCISvcCtx *svchp,
OCIError *errhp,
OCIStmt *stmthp,
void *xml,
OCIType *xmltdo,
OraText *sqlstmt);

/* Helper function 2: Initialize OCI handles and connect */
static sword init_oci_handles(test_ctx *ctx);

/* Helper function 3: Free OCI handles and disconnect */
static 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 */
static 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 */
static 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 */
static 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、NVARCHAR2およびNCLOBの未サポート: Oracle XML DBは、次の操作のためにSQLデータ型NCHAR、NVARCHAR2および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では、32767または4000バイト(初期化パラメータMAX_STRING_SIZEの値によって異なる)以下のXML識別子のみをサポートしています。『Oracle Database SQL言語リファレンス』を参照してください。

- リポジトリ・ファイルのサイズ制限: 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のコンポジット・パーティション化なし: コンポジット・パーティション化は、XMLType表および列に対してサポートされません(XMLType記憶域モデルとは関係ありません)。

- 階層対応表のパーティション化なし: 階層対応表をパーティション化することはできません。(階層対応表の詳細は、「リポジトリ・リソースおよびデータベース表のセキュリティ」を参照してください。)

- XMLTypeに対するOracle Real Application Testing (RAT)なし: Oracle Real Application Testing (RAT)はXMLTypeに対してサポートされません。

- XMLTypeへのデータベース・リンクを介したアクセスの非サポート: リモートのXMLType表または列へのアクセスはサポートされていません。

- 一部の機能の利用にOracle JVMが必要: 通常、Oracle XML DBの動作はOracle JVM(Java仮想マシン)がインストールされているかどうかに依存しません。ただし、JavaサーブレットまたはPL/SQLパッケージDBMS_XMLSAVEまたはDBMS_XMLQUERYを使用する場合は、Oracle JVMをインストールする必要があります。

- エディショニング・ビューとXMLTypeの非互換性: エディショニング・ビューは、オブジェクト・リレーショナル形式で格納されているXMLTypeデータと互換性がありません。永続オブジェクト・タイプを含むデータベース・スキーマでは有効化できません。

- トランスポータブル表領域およびデータベース統合: Oracle Database 11gリリース2 (11.2)のOracle XML DBリポジトリ内に既存のデータがある場合は、トランスポータブル表領域を使用してデータベースをコンテナ・データベース(CDB)に直接接続することはできません。かわりに11.2データベースを12.1にアップグレードし、それを切断してから接続します。

- XMLTypeのオブジェクト・リレーショナル記憶域に対するXMLType仮想列なし: オブジェクト・リレーショナルXMLType表またはオブジェクト・リレーショナルXMLType列を持つ表に仮想XMLType列を追加できません。

関連項目:

- "Oracle XML DBでのXQueryサポートの詳細は、Oracle XML DBでのXQueryサポート を参照してください。

- Oracle Exadata Storage Serverの詳細は、『Oracle Exadata Storage Server Softwareユーザーズ・ガイド』

C XMLデータを更新するための非推奨の関数

Oracle Database 12c リリース1 (12.1.0.1)から非推奨になった、XMLデータを更新するためのOracle SQL関数について説明します。XMLデータを更新するには、かわりにXQuery Updateを使用してください(XQueryとOracle XML DBを参照)。

- XMLデータを更新するためのOracle関数のXQuery Updateへの移行

- XMLデータを更新するための非推奨のOracle SQL関数

- UPDATEXML (非推奨のOracle SQL関数)

- XMLデータを変更する非推奨のOracle SQL関数の最適化

- XMLデータを変更する非推奨のOracle SQL関数を使用した、XMLビューの作成

- INSERTCHILDXML (非推奨のOracle SQL関数)

- INSERTCHILDXMLBEFORE (非推奨のOracle SQL関数)

- INSERTCHILDXMLAFTER (非推奨のOracle SQL関数)

- INSERTXMLBEFORE (非推奨のOracle SQL関数)

- INSERTXMLAFTER (非推奨のOracle SQL関数)

- APPENDCHILDXML (非推奨のOracle SQL関数)

- DELETEXML (非推奨のOracle SQL関数)

C.1 XMLデータを更新するためのOracle関数のXQuery Updateへの移行

XQuery Update Facility 1.0勧告は、Oracle Database 12cリリース1 (12.1.0.1)からOracle XML DBでサポートされるようになりました。これよりも前のリリースでXMLデータを更新するには、Oracle固有のSQL関数appendChildXML、deleteXML、insertChildXML、insertchildXMLafter、insertChildXMLbefore、insertXMLafter、insertXMLbeforeおよびupdateXMLを問合せで必ず使用する必要がありました。

これらの関数については、この付録の別の項で詳しく説明します。

これらの関数を使用しているレガシー・コードがある場合は、そのコードを移行してXQuery Updateを使用することをお薦めします。この項では、問合せで使用されているOracle固有のXML更新関数を置き換える場合に使用できるXQuery Updateの構造体について説明します。

表C-1は、Oracle固有の更新のSQL関数を使用した一般的な問合せから、XQuery Updateを使用した問合せへのマッピングを示しています。

XQuery Updateの構造体renameおよびinsert as first intoには、同等のOracle固有の関数はありません。

また、ターゲットのXPath式が複数のノードと一致する場合、Oracle更新関数は該当するすべてのノードに作用しますが、XQuery Update関数ではこの場合、エラーが発生します。XQuery Updateを使用して複数のノードに作用するには、明示的な繰返し(for式)を使用する必要があります。

表C-1 Oracle固有のXML更新問合せのXQuery Updateへの移行

元の式

置換後の式

-- Insert a node as the last child of a node.
UPDATE warehouses SET warehouse_spec =
appendChildXML(
warehouse_spec,
'/Warehouse/Parking',
XMLType('<Spaces>250</Spaces>'));

-- Insert a node as the last child of a node.
UPDATE warehouses SET warehouse_spec =
XMLQuery('copy $tmp := . modify insert node
<Spaces>250</Spaces>
as last into $tmp/Warehouse/Parking
return $tmp'
PASSING warehouse_spec RETURNING CONTENT)
WHERE warehouse_spec IS NOT NULL;

-- Delete a node.
UPDATE warehouses SET warehouse_spec =
deleteXML(value(po), '/Warehouse/VClearance');

-- Delete a node.
UPDATE warehouses SET warehouse_spec =
XMLQuery('copy $tmp := . modify delete node
$tmp/Warehouse/VClearance return $tmp'
PASSING warehouse_spec RETURNING CONTENT)
WHERE warehouse_spec IS NOT NULL;

-- Insert a node as a child of a node.
UPDATE warehouses SET warehouse_spec =
insertChildXML(
warehouse_spec,
'/Warehouse/Parking',
'Spaces',
XMLType('<Spaces>300</Spaces>');

-- Insert a node as a child of a node.
UPDATE warehouses SET warehouse_spec =
XMLQuery('copy $tmp := . modify insert node
<Spaces>300</Spaces>
into $tmp/Warehouse/Parking
return $tmp'
PASSING warehouse_spec RETURNING CONTENT)
WHERE warehouse_spec IS NOT NULL;

-- Insert a node before a node.
UPDATE warehouses SET warehouse_spec =
insertXMLbefore(
warehouse_spec,
'/Warehouse/RailAccess',
XMLType('<SkyAccess>N</SkyAccess>');

-- Insert a node before a node.
UPDATE warehouses SET warehouse_spec =
XMLQuery('copy $tmp := . modify insert node
<SkyAccess>N</SkyAccess>
before $tmp/Warehouse/RailAccess
return $tmp'
PASSING warehouse_spec RETURNING CONTENT)
WHERE warehouse_spec IS NOT NULL;

-- Insert a node after a node.
UPDATE warehouses SET warehouse_spec =
insertXMLafter(
warehouse_spec,
'/Warehouse/RailAccess',
XMLType('<SkyAccess>N</SkyAccess>');

-- Insert a node after a node.
UPDATE warehouses SET warehouse_spec =
XMLQuery('copy $tmp := . modify insert node
<SkyAccess>N</SkyAccess>
after $tmp/Warehouse/RailAccess
return $tmp'
PASSING warehouse_spec RETURNING CONTENT)
WHERE warehouse_spec IS NOT NULL;

-- Replace the text value of a set of nodes.
-- (Assumes a collection of <Building> nodes.)
UPDATE warehouses SET warehouse_spec =
updateXML(warehouse_spec,
'/Warehouse/Building/text()',
'Owned');

-- Replace the text value of a set of nodes.
-- (Assumes a collection of <Building> nodes.)
UPDATE warehouses SET warehouse_spec =
XMLQuery('copy $tmp := . modify
(for $i in $tmp/Warehouse/Building/text()
return replace value of node $i
with ''Owned'')
return $tmp'
PASSING warehouse_spec RETURNING CONTENT)
WHERE warehouse_spec IS NOT NULL;

-- Insert a child under each node in a collection.
-- (Assumes a collection of <Building> nodes.)
UPDATE warehouses SET warehouse_spec =
insertChildXML(
warehouse_spec,
'/Warehouse/Building',
'Owner',
XMLType('<Owner>LesserCo</Owner>'));

-- Insert a child under each node in a collection.
-- (Assumes a collection of <Building> nodes.)
UPDATE warehouses SET warehouse_spec =
XMLQuery('copy $tmp := . modify
(for $i in $tmp/Warehouse/Building
return insert node
<Owner>LesserCo</Owner>
into $i)
return $tmp'
PASSING warehouse_spec RETURNING CONTENT)
WHERE warehouse_spec IS NOT NULL;

-- Insert as child before the other children.
-- (Assumes a collection of <Owner> nodes.)
UPDATE warehouses SET warehouse_spec =
insertChildXMLbefore(
warehouse_spec,
'/Warehouse/Building[1]',
'Owner',
XMLType('<Owner>LesserCo</Owner>'));

-- Insert as child before the other children.
-- (Assumes a collection of <Owner> nodes.)
UPDATE warehouses SET warehouse_spec =
XMLQuery(
'copy $tmp := . modify
(for $i in $tmp/Warehouse/Building[1]/Owner
return insert node <Owner>LesserCo</Owner>
before $i)
return $tmp'
PASSING warehouse_spec RETURNING CONTENT)
WHERE warehouse_spec IS NOT NULL;

-- Insert as child after the other children.
-- (Assumes a collection of <Owner> nodes.)
UPDATE warehouses SET warehouse_spec =
insertChildXMLafter(
warehouse_spec,
'/Warehouse/Building[1]',
'Owner',
XMLType('<Owner>LesserCo</Owner>'));

-- Insert as child after the other children.
-- (Assumes a collection of <Owner> nodes.)
UPDATE warehouses SET warehouse_spec =
XMLQuery(
'copy $tmp := . modify
(for $i in $tmp/Warehouse/Building[1]/Owner
return insert node <Owner>LesserCo</Owner>
after $i)
return $tmp'
PASSING warehouse_spec RETURNING CONTENT)
WHERE warehouse_spec IS NOT NULL;

-- Delete a node.
UPDATE warehouses SET warehouse_spec =
updateXML(warehouse_spec,
'/Warehouse/Docks',
NULL);

-- Delete a node.
UPDATE warehouses SET warehouse_spec =
XMLQuery('copy $tmp := . modify delete node
$tmp/Warehouse/Docks return $tmp'
PASSING warehouse_spec RETURNING CONTENT)
WHERE warehouse_spec IS NOT NULL;

-- Replace with an empty node.
UPDATE warehouses SET warehouse_spec =
updateXML(warehouse_spec, '/Warehouse/Docks', '' );

-- Replace with an empty node.
UPDATE warehouses SET warehouse_spec =
XMLQuery('copy $tmp := $p1 modify
(for $j in $tmp/Warehouse/Docks
return replace node $j with $p2)
return $tmp'
PASSING warehouse_spec "p1", '' AS "p2"
RETURNING CONTENT)
WHERE warehouse_spec IS NOT NULL;

-- Update multiple paths.
UPDATE warehouses SET warehouse_spec =
updateXML(warehouse_spec,
'/Warehouse/Docks/text()', '4',
'/Warehouse/Area/text()', '3500');

-- Update multiple paths.
UPDATE warehouses SET warehouse_spec =
XMLQuery(
'copy $tmp := . modify
((for $i in $tmp/Warehouse/Docks/text()
return replace value of node $i with 4),
(for $i in $tmp/Warehouse/Area/text()
return replace value of node $i with 3500))
return $tmp'
PASSING warehouse_spec RETURNING CONTENT)
WHERE warehouse_spec IS NOT NULL;

C.2 XMLデータを更新するための非推奨のOracle SQL関数

非推奨になる前は、次のOracle SQL関数を使用して、XMLデータを付加的に更新(周囲のXML文書全体を置き換えずにXMLデータを置換、挿入または削除)していました。これは、部分更新とも呼ばれます。

- updateXML: 任意の種類のXMLノードを置換します。「UPDATEXML (非推奨のOracle SQL関数)」を参照してください。

- insertChildXML: XMLの要素ノードまたは属性ノードを、指定された要素ノードの子として挿入します。「INSERTCHILDXML (非推奨のOracle SQL関数)」を参照してください。

- insertChildXMLbefore: 新しいコレクション要素を、同じ型の指定されたコレクション要素の直前に挿入します。「INSERTCHILDXMLBEFORE (非推奨のOracle SQL関数)」を参照してください。

- insertChildXMLafter: 新しいコレクション要素を、同じ型の指定されたコレクション要素の直後に挿入します。「INSERTCHILDXMLAFTER (非推奨のOracle SQL関数)」を参照してください。

- insertXMLbefore: 任意の種類のXMLノードを、指定されたノード(属性ノード以外)の直前に挿入します。「INSERTXMLBEFORE (非推奨のOracle SQL関数)」を参照してください。

- insertXMLafter: 任意の種類のXMLノードを、指定されたノード(属性ノード以外)の直後に挿入します。「INSERTXMLAFTER (非推奨のOracle SQL関数)」を参照してください。

- appendChildXML: 任意の種類のXMLノードを、指定された要素ノードの最後の子ノードとして挿入します。「APPENDCHILDXML (非推奨のOracle SQL関数)」を参照してください。

- deleteXML: 任意の種類のXMLノードを削除します。「DELETEXML (非推奨のOracle SQL関数)」を参照してください。

関数insertChildXML、insertChildXMLbefore、insertChildXMLafter、insertXMLbefore、insertXMLafterおよびappendChildXMLは、XMLデータの挿入に使用します。関数deleteXMLは、XMLデータを削除します。関数updateXMLは、XMLデータを置換します。

特に、親ノード全体を置き換えることによって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式の引数が、属性ノードやテキスト・ノードなどの適切ではないノードをターゲットにしている場合は、更新のOracle SQL関数(非推奨)でエラーが発生する可能性があります。

関連項目:

XML Schemaに対する部分検証の詳細は、「XML Schemaの部分検証と全体検証」を参照してください

C.2.1 非推奨のOracle 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関数の最適化」

C.3 UPDATEXML (非推奨のOracle SQL関数)

非推奨のOracle SQL関数updateXMLは、任意の種類のXMLノードを置換します。更新のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数updateXMLには、次のパラメータがあります(この順序どおり)。

- target-data (XMLType) - 置換するターゲット・ノードを含むXMLデータ。

- xpathパラメータとreplacementパラメータの1つ以上の組。

- 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文を使用します。

図C-1に構文を示します。

図C-1 UPDATEXMLの構文

例C-1では、新しいXML文書を作成するのではなく、UPDATE文の右側にupdateXMLを使用して表内のXML文書を更新します。選択された部分のみではなく、文書全体が更新されます。

例C-2では、Oracle SQL関数updateXMLを使用して複数のノードを更新します。

例C-3では、SQL関数updateXMLを使用して、コレクション内で選択されたノードを更新します。

例C-1 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>

例C-2 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>

例C-3 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>

C.3.1 非推奨のOracle SQL関数UPDATEXMLおよびNULL値

非推奨のOracle SQL関数updateXMLにNULL値を指定して使用する場合は、いくつかの考慮事項が適用されます。

- XML要素をNULLに更新すると、要素の属性および子が削除され、要素は空になります。要素のタイプおよび名前空間プロパティは保持されます。例C-4を参照してください。

- 属性値をNULLに更新した場合、値は空の文字列として表示されます。例C-4を参照してください。

- 要素のテキスト・ノードをNULLに更新すると、その要素のコンテンツ(テキスト)は削除されます。要素自体は残りますが、空になります。例C-5を参照してください。

例C-4では、次のものすべてをNULLに更新します。

- Description要素と、Part要素の属性Id値が715515009058のLineItem要素のQuantity属性

- Description要素のコンテンツ(テキスト)が「The Unbearable Lightness Of Being」であるLineItem要素

例C-5では、Description属性の値が"A Night to Remember"であるPart要素のテキスト・ノードをNULLに更新します。この例のXMLデータは、修正された別の発注書XML Schemaに対応しています(「コピーに基づく拡張の使用例」を参照)。そのXML Schemaでは、DescriptionはPart要素の属性であり、兄弟要素ではありません。

関連項目:

例3-26

例C-4 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>

例C-5 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"/>

C.3.2 UPDATEXMLを使用した同じXMLノードの複数回の更新(非推奨)

同じXMLノードをupdateXML式で複数回更新できます。更新の順番は、左から右へ、XPath式の順番によって決定されます。連続する更新はそれぞれ、前の更新結果に基づいて機能します。

たとえば、/EMP[EMPNO=217]および/EMP[EMPNAME="Jane"]/EMPNOの両方を更新できます。ここで最初のXPathはそれを含むEMPNOノードも識別します。

C.3.3 UPDATEXML使用時のDOM再現性のガイドライン(非推奨)

Oracle SQL関数updateXMLを使用するときのDOM再現性に関するガイドラインを示します。

- DOM再現性が維持される場合 -
要素をNULLに更新すると、その要素がその親で空に表示されるようになります。要素内のテキスト・ノードをNULLに更新すると、そのテキスト・ノードが削除されます。属性ノードをNULLに更新すると、属性値が空の文字列になります。

空の要素の例は、<myElem/>です。文字列値が空の属性の例は、myAttr=""です。

- DOM再現性が維持されない場合 -
complexType要素をNULLに更新すると、これがその親で空に表示されるようになります。SQLインラインsimpleType要素をNULLに更新すると、これがその親で表示されなくなります。テキスト・ノードをNULLに更新することは、親simpleType要素をNULLに設定することと同じです。

また、複合コンテンツを格納する位置指定ディスクリプタがないため、DOM再現性が維持されない場合、テキスト・ノードはsimpleType要素内にのみ出現できます。属性ノードをNULLに更新すると、要素からその属性が削除されます。

- DOM再現性が維持されるかどうかの判別方法 -
特定のXML Schema内の特定のXMLTypeインスタンスの特定部分についてDOM再現性が維持されるかどうかを判別するには、属性maintainDOMのXML Schemaメタデータを問い合せます。

関連項目:

- スキーマを問い合せてDOM再現性の値を取得する例は、「登録されたXML Schemaの問合せによる注釈の取得」を参照してください

- 「DOM再現性」

C.4 XMLデータを変更する非推奨のOracle SQL関数の最適化

ほとんどの場合、XMLデータを変更する非推奨のOracle SQL関数は、入力されたXML文書全体のコピーをメモリー内に生成してから、そのコピーを更新します。ただし、関数updateXML、insertChildXML、insertChildXMLbefore、insertChildXMLafterおよびdeleteXML、つまり、insertXMLbefore、insertXMLafterおよびappendChildXMLを除くすべてがXMLType UPDATE操作のために最適化されます。

オブジェクト・リレーショナル記憶域の場合、特定の条件が満たされると、関数コールは、オブジェクト・リレーショナル列を新しい値で直接更新するようにリライトできます。バイナリXML記憶域の場合、ターゲットの更新の前のデータは変更されず、SecureFiles LOBが使用されている場合(デフォルトの動作)は、スライド挿入を使用して、変更が必要なデータ部分のみが更新されます。

関連項目:

- XPathリライトの条件の詳細は、 Oracle XML DBの使用方法の概要および オブジェクト・リレーショナル記憶域のXPathリライトを参照してください。

- 「XQuery用のパフォーマンス・チューニング」

オブジェクト・リレーショナル記憶域の例では、例C-6に記載されているupdateXMLへのXPath引数は、Oracle XML DBで処理され、例C-7に記載されている同等のオブジェクト・リレーショナルSQLコードにリライトされます。

注意:

ここで説明するDML用のXMLDATAの使用方法は、Oracle XML DBの内部動作の説明に限定されます。DML操作には、XMLDATA自身を使用しないでください。XMLDATAを直接使用できるのは、DDL操作に対してのみで、DML操作には使用できません。

一般的に、コード内ではXML Schemaオブジェクト・モデルとSQLオブジェクト・モデル間の現在のマッピングに依存しないでください。Oracle XML DB実装のマッピングは将来変更される可能性があります。

例C-6 UPDATEXML式内のXPath式

SET LONG 2000

--

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

例C-7 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

C.5 XMLデータを変更する非推奨のOracle SQL関数を使用した、XMLビューの作成

XMLデータを変更する非推奨のOracle SQL関数(updateXML、insertChildXML、insertChildXMLbefore、insertChildXMLafter、insertXMLbefore、insertXMLafter、appendChildXMLおよびdeleteXML)を使用して、XMLデータの新しいビューを作成できます。

例C-8では、非推奨のOracle SQL関数updateXMLを使用してpurchaseorder表のビューを作成します。

例C-8 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>

C.6 INSERTCHILDXML (非推奨のOracle 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 = ""になります。

図C-2に構文を示します。

図C-2 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を使用してください。

例C-9に、SQL UPDATE文とOracle SQL関数insertChildXMLを使用して、新しいLineItem要素をLineItems要素の子として挿入する方法を示します。

更新するXMLデータがXMLスキーマに基づいていて、ネームスペースを参照する場合、挿入するデータも同じネームスペースを参照する必要があります。参照しない場合は、挿入されるデータがXMLスキーマに準拠しないため、エラーが発生します。

例C-10は例C-9と似ていますが、挿入されるLineItem要素が名前空間を参照しています。これは、関連するXML Schemaでこの要素に対する名前空間が必要であることを前提としています。

このような名前空間の使用方法は、関数insertChildXMLに対する名前空間引数の使用方法とは異なるため、注意してください。そのオプションの引数に指定される名前空間は、挿入されるコンテンツではなく、XPath引数のみに適用されます。

例C-9 INSERTCHILDXMLを使用したコレクションへの挿入(非推奨)

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.

例C-10 名前空間を使用する要素の挿入

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");

C.7 INSERTCHILDXMLBEFORE (非推奨のOracle 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-xpathがNULLの場合、エラーが発生します。

- target-dataまたはparent-xpathがNULLの場合、NULLが戻されます。

- child-dataがNULLの場合、挿入は行われず、target-dataがそのままの状態で戻されます。

図C-3に構文を示します。

図C-3 INSERTCHILDXMLBEFOREの構文

C.8 INSERTCHILDXMLAFTER (非推奨のOracle 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-xpathがNULLの場合、エラーが発生します。

- target-dataまたはparent-xpathがNULLの場合、NULLが戻されます。

- child-dataがNULLの場合、挿入は行われず、target-dataがそのままの状態で戻されます。

図C-4に構文を示します。

図C-4 INSERTCHILDXMLAFTERの構文

C.9 INSERTXMLBEFORE (非推奨のOracle 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がそのままの状態で戻されます。

図C-5に構文を示します。

図C-5 INSERTXMLBEFOREの構文

例C-11では、非推奨のOracle SQL関数insertXMLbeforeを使用して、LineItem要素を最初のLineItem要素の前に挿入します。

注意:

Oracle SQL関数insertXMLbeforeを使用する問合せは、最適化されません。このため、関数insertChildXML、insertChildXMLbeforeまたはinsertChildXMLafterをかわりに使用することをお薦めします。XQuery用のパフォーマンス・チューニングを参照してください。

例C-11 INSERTXMLBEFOREを使用した要素の前への挿入(非推奨)

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>

C.10 INSERTXMLAFTER (非推奨のOracle SQL関数)

非推奨のOracle SQL関数insertXMLafterは、任意の種類の1つ以上のノードを、属性ノード以外のターゲット・ノードの直後に挿入します。挿入のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

そのため、関数insertXMLafterは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がそのままの状態で戻されます。

図C-6に構文を示します。

図C-6 INSERTXMLAFTERの構文

注意:

Oracle SQL関数insertXMLafterを使用する問合せは、最適化されません。このため、関数insertChildXML、insertChildXMLbeforeまたはinsertChildXMLafterをかわりに使用することをお薦めします。XQuery用のパフォーマンス・チューニングを参照してください。

C.11 APPENDCHILDXML (非推奨のOracle 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がそのままの状態で戻されます。

図C-7に構文を示します。

図C-7 APPENDCHILDXMLの構文

例C-12では、非推奨のOracle SQL関数appendChildXMLを使用して、Date要素をAction要素の最後の子として挿入します。

注意:

Oracle SQL関数appendChildXMLを使用する問合せは、最適化されません。このため、関数insertChildXML、insertChildXMLbeforeまたはinsertChildXMLafterをかわりに使用することをお薦めします。XQuery用のパフォーマンス・チューニングを参照してください。

例C-12 APPENDCHILDXMLを使用した最後の子としての挿入(非推奨)

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>

C.12 DELETEXML (非推奨のOracle 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を戻します。

図C-8に構文を示します。

図C-8 DELETEXMLの構文

例C-13では、非推奨のOracle SQL関数deleteXMLを使用して、ItemNumber属性の値が222のLineItem要素を削除します。

例C-13 DELETEXMLを使用した要素の削除(非推奨)

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.

D 非推奨となったXML変換の構造体

XML変換をサポートするOracle構造体について説明します。これらは、Oracle Database 12c リリース1 (12.1.0.1)から非推奨となりました。

- XML変換(非推奨)

- PL/SQLパッケージDBMS_XMLTRANSLATIONS (非推奨)

D.1 XML変換(非推奨)

非推奨のXML変換のOracleサポートを使用して、Oracle XML DBリポジトリ内のXMLType文書に含まれる文字列を様々な(自然)言語に変換できます。

Oracle XML DBリポジトリ内のXML文書をXMLTypeインスタンスとして格納できます。これらの文書には、様々な(自然)言語に翻訳しなければならない文字列が含まれている場合があります。非推奨となったOracle XML変換のサポートを利用するには、元の文字列と変換結果の両方をリポジトリに格納します。ユーザーの言語設定に応じて、これらの文字列を取得および操作できます。

注意:

オブジェクト・リレーショナル形式で格納されたXML Schemaは変換できません。

D.1.1 変換のためのXML SchemaとXMLインスタンス・ドキュメントの変更(非推奨)

XML Schemaおよび関連するXMLインスタンス・ドキュメントに特定の変更を加えて、このドキュメントを変換できるようにする必要があります。

D.1.1.1 XML Schema内での変換可能な要素の指示(非推奨)

XML Schema内で、変換する要素ごとに属性xdb:translateを指定する必要があります。属性xdb:translateには、いくつかの制限が適用されます。XML Schemaの登録時に、PL/SQLプロシージャDBMS_XMLSCHEMA.registerSchemaは、XML Schemaがこれらの制限を満たしているかを確認します。

- 属性xdb:translateは、simpleContentを持つcomplexType要素にのみ指定できます。ここで、simpleContentは、string型の拡張または制限である必要があります。ただし、complexType要素にxdb:translateフラグが設定されている場合、その子孫にはこのフラグを設定できません。

- 属性xdb:translateは、単一値要素(1つだけの変換を持つ要素)にのみ設定できます。このような要素では、xdb:maxOccursの値を0または1に設定する必要があります。この属性を複数値要素に設定する場合、要素を一意に識別するID属性を要素が持つ必要があります。

D.1.1.2 XMLインスタンス・ドキュメント内での変換言語属性の指示(非推奨)

変換言語属性xml:langおよびxml:srclangのサポートについて説明します。

- xml:lang: 変換をサポートするXML Schemaに関連付けられたインスタンス・ドキュメントには、変換言語を指定する必要があります。これは、変換のたびに属性xml:langを使用して注釈を付けることで指定できます。属性xml:langで使用できる値は、IETF RFC 3066で識別される言語識別子です。

- xdb:srclang: 複数値要素、つまり、複数の変換を持つことができる要素には、1つの変換のみをソース言語変換として使用できます。この変換は、属性xdb:srclangによって指定されます。これは、セッション言語が指定されていない場合に戻されるデフォルトの変換です。

D.1.2 XML文書を変換可能にする方法(非推奨)

非推奨の変換を指定するXML Schema属性を使用して、サンプル・ドキュメント内の要素を変換できるようにすることができます。

例D-1は、変換可能でなければならないタイトル文字列を含むドキュメントを定義するXML Schemaを示します。

例D-2は、例D-1のXML Schemaに関連付けられるドキュメントを示します。

最上位のタイトルを変換可能にするには、xdb:translateをtrueに設定します。これは、単一値要素(xdb:maxOccursが1)です。例D-3は、属性xdb:translateがtrueに設定されている新規のXML Schemaを示します。

例D-4は、タイトル・テキストを変換した後のインスタンス・ドキュメントを示します。

複数値要素の場合にタイトルを変換可能にするには、xdb:maxOccursをunboundedに設定します。ただし、xdb:translateは、各要素を一意に識別する識別子属性がないかぎり、複数値要素用にtrueに設定できません。例D-5は、title要素に識別子属性idを使用するXML Schemaを示します。

例D-6は、例D-5のXML Schemaに関連付けられたドキュメントを示します。

例D-1 変換の必要があるタイトルを含むドキュメントを定義する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>

例D-2 変換されていないインスタンス・ドキュメント

<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>

例D-3 単一値要素の属性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>

例D-4 変換後のドキュメント

<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>

例D-5 複数値要素の属性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>

例D-6 複数値要素を持つ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>

D.1.3 変換済のドキュメントに対する操作(非推奨)

変換済のドキュメントに対して、挿入、問合せおよび更新の操作を実行できます。言語情報があるドキュメントおよび言語情報がないドキュメントの挿入の例を示します。

- 挿入: 変換をサポートするXML Schemaにドキュメントが準拠する場合は、それをOracle XML DBに挿入できます。変換を含むドキュメントに対しては、言語情報を提供するか、セッション言語変換を使用できます。

- ドキュメントに言語情報が含まれず、属性xml:langが設定されていない場合、変換にはセッション言語が使用されます。例D-7は、セッション言語が日本語のドキュメントを表します。属性xml:langはsession languageに設定され、属性xdb:srclangはtrueに設定されています。
例D-8は、Oracle XML DBリポジトリに挿入された後のドキュメントを示します。

- 言語情報を提供すると、明示的に言語をxdb:srclang=trueとマークするか、属性xdb:srclangの中のセッション言語を使用して、属性xml:langが設定されます。いずれも行わないと、任意の変換が選択され、xdb:srclangがtrueに設定されます。
例D-9は、セッション言語が日本語のドキュメントを表します。

例D-10は、Oracle XML DBリポジトリに挿入された後のドキュメントを示します。

- 問合せ: 変換された要素を伴うノードを問い合せる場合、問合せは変換のデフォルト動作を表示します。問合せの結果に変換のデフォルト動作が適用されるように指定するには、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述語を持つ索引を作成する必要があります。

SQL関数XMLSerializeおよびPL/SQLコンストラクタXDBURITypeを使用して完全なドキュメントを取得する場合は、セッション言語変換に一致する変換のみが戻されます。プロトコルに対しては、言語のプリファレンスを設定でき、ドキュメントはその言語でのみ戻されます。

次のPL/SQLプロシージャおよび関数は、XML変換をサポートします。

- DBMS_XMLTRANSLATIONS.translateXML: ドキュメントを指定した言語に変換します。指定した言語変換が存在する場合はそれが戻され、存在しない場合はソース言語変換が戻されます。
たとえば、translateXML(doc, 'fr')と記述して例D-10の変換言語にフランス語を指定する場合、次のコードが戻され、他の変換はすべて無視されます。

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関数XMLQueryをXQuery Updateとともに使用して変換済のノードを更新します。ただし、変換言語を指定せずに変換済ノードを更新しようとした場合、エラーが発生します。次のPL/SQLプロシージャは、変換済のドキュメントへの更新操作をサポートします。

- DBMS_XMLTRANSLATIONS.updateTranslation: この関数は、指定したxpathにある変換を特定の言語で更新します。特定の言語での変換が存在しない場合は、それが挿入されます。

- DBMS_XMLTRANSLATIONS.setSourceLang: このプロシージャは、指定したxpathにあるソース言語を指定した言語に設定します。

例D-7 言語情報のないドキュメントの挿入

<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>

例D-8 リポジトリに挿入された後のドキュメント

<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>

例D-9 言語情報を持つドキュメントの挿入

<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>

例D-10 挿入後のドキュメント

<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>

D.2 PL/SQLパッケージDBMS_XMLTRANSLATIONS (非推奨)

Oracle XML DBでは、DBMS_XMLTRANSLATIONSパッケージを使用して変換サポートが提供されています。このパッケージは変換を実行するインタフェースを提供し、様々な言語での検索や表示を可能にしています。この機能は非推奨になっています。

関連項目:

XML変換の概要は、XML Schemaの格納と問合せ: 基本を参照してください。

D.2.1 DBMS_XMLTRANSLATIONSメソッド(非推奨)

非推奨のPL/SQLパッケージDBMS_XMLTRANSLATIONSには、メソッドupdateTranslation、setSourceLang、translateXML、getBaseDocument、extractXLiff、mergeXLiff、disableTranslationおよびenableTranslationが用意されています。

- 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パッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

E XQueryを使用しないXMLデータの全文検索

XMLデータのOracle固有の全文検索について、Oracle SQL関数containsおよびOracle XPath関数ora:containsの使用方法などを説明します。

このようなOracle固有の関数を使用すれば、XMLデータの全文検索を実行できますが、XMLTypeデータがバイナリXMLとして格納されている場合は、かわりにXQueryの全文検索機能を使用されることをお薦めします。XQuery and XPath Full Textの標準は、Oracle Database 12cリリース1 (12.1.0.1)からOracle XML DBでサポートされるようになりました。

関連項目:

- XQueryとOracle XML DB

- 「全文問合せ用のXMLデータの索引付け」

- Oracle Textの詳細は、『Oracle Textリファレンス』および『Oracle Textアプリケーション開発者ガイド』を参照してください。

- XMLデータのOracle固有の全文検索の概要

- 全文検索の例について

- SQL関数CONTAINSおよびXPath関数ora:containsの概要

- SQL関数CONTAINS

- ora:contains XQuery関数

- Text Path BNFの仕様

- 全文XMLのサポートの例

E.1 XMLデータのOracle固有の全文検索の概要

XMLドキュメントの構造を使用して全文検索を限定できます。たとえば、コメント内にワード"electric"が含まれるすべてのXML発注書を検索するか、または明細項目の下にあるコメント内にワード"electric"が含まれるものをすべて検索するかして、検索内容を限定できます。

XML文書がXMLType型の場合は、その文書のXML構造を使用して問合せの結果を投影できます。たとえば、コメント内にワード"electric"が含まれるすべての発注書を検索した後で、コメント全体を戻すか、またはワード"electric"が含まれるコメントのみを戻すことができます。

E.1.1 全文検索と他の検索タイプの比較

全文検索は、構造化検索や部分文字列検索と多くの点で異なります。

- 全文検索では、部分文字列ではなく単語全体が検索されます。文字列"law"が含まれるコメントの部分文字列検索を行うと、"my lawn is going wild"が含まれるコメントが戻されます。ワード"law"の全文検索では、このコメントは戻されません。

- 全文検索では、部分文字列検索ではサポートできない言語ベースとワードベースの検索がいくつかサポートされています。たとえば、言語ベースの検索を使用すると、"mouse"と言語語幹が同じワードを含むすべてのコメントを検索でき、Oracle Textでは"mouse"と"mice"が検索されます。ワードベースの検索の例では、"wild"を含む5ワード以内にワード"lawn"があるすべてのコメントを検索できます。

- 全文検索には通常、関連性の概念が含まれています。たとえば、ワード"lawn"が含まれるすべてのコメントを全文検索する場合、ある結果は他の結果より関連性が高い場合があります。関連性は通常、検索ワード(または類似ワード)の文書内での出現回数に関連しています。

E.1.2 XMLデータの検索

非構造化文書の検索では通常、一連の文書を検索して、指定したテキスト述語を満たすものを戻します。XML検索では多くの場合、XML文書の構造を使用して検索を限定します。また、検索を満たす文書の一部のみを戻す場合があります。

E.1.3 全文検索および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のコールで使用できます。

E.2 全文検索の例について

全文検索の例について詳しく説明します。

E.2.1 全文に必要なロールと権限の例

全文検索の例を実行するには、データベース・ロールCTXAPP、CONNECT、RESOURCEが必要です。また、CTXSYSパッケージCTX_DDLに対するEXECUTE権限も必要です。

E.2.2 全文検索の例に使用するスキーマおよびデータ

全文検索の例は、『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を使用することもできます。

E.3 SQL関数CONTAINSおよびXPath関数ora:containsの概要

SQL関数CONTAINSとXPath関数ora:containsは、どちらも全文検索に使用できます。

- SQL関数CONTAINSの概要

- XPath関数ora:containsの概要

- SQL関数CONTAINSとXPath関数ora:containsの比較

E.3.1 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

例E-1に、Oracle SQL関数containsを使用した一般的な問合せを示します。表purchase_ordersで、doc列に単語"lawn"が含まれ、idが25よりも小さい値の各行のidが戻されます。

docは、一連のXML文書が含まれる列であるとします。この場合、docに対して、そのXML構造を使用して問合せを限定する全文検索を実行できます。例E-2の問合せでは、表purchaseordersで、XML要素commentのtext()ノードにワード"lawn"が含まれるdoc列のid値が戻されます。

INPATH演算子およびXPath式を使用すると、XML構造によるさらに複雑な限定を適用できます。例E-3の問合せでは、XPath式/purchaseOrder/items/item/commentのターゲットとなるcomment要素のtext()ノードに、ワード"electric"が含まれる発注書が検索されます。

例E-1 Oracle SQL関数CONTAINSを使用した単純な問合せ

SELECT id FROM purchase_orders WHERE contains(doc, 'lawn') > 0 AND id < 25;

例E-2 CONTAINSおよびWITHINを使用した問合せの制限

SELECT id FROM purchase_orders WHERE contains(doc, 'lawn WITHIN comment') > 0;

例E-3 CONTAINSおよびINPATHを使用した問合せの制限

SELECT id FROM purchase_orders
WHERE contains(doc, 'electric INPATH (/purchaseOrder/items/item/comment)') > 0;

E.3.2 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を使用した場合、重みは無視されます。

例E-4は、XMLExistsのXPathパラメータにおけるora:containsのコールを示しています。Oracle XML DBネームスペースを表すものとして、接頭辞oraを宣言するネームスペース宣言に注意してください。

関連項目:

「ora:contains XPath関数」の詳細は、「ora:contains XQuery関数」を参照してください。

例E-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");

E.3.3 SQL関数CONTAINSとXPath関数ora:containsの比較

Oracle SQL関数containsおよびOracle XPath関数ora:containsでは、いずれもXML構造の検索と全文検索を組み合せることができます。2つの手法が比較されます。

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を使用します。

E.4 SQL関数CONTAINS

Oracle SQL関数containsを使用した全文検索について説明します。

- SQL関数CONTAINSを使用した全文検索

- SQL関数SCORE

- CONTAINS検索の有効範囲

- CONTAINS結果の投影

- CONTEXT索引

E.4.1 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)が検索されます。

E.4.1.1 全文ブール演算子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リファレンス』を参照してください。

例E-5 単純なブール演算子を使用したCONTAINS問合せ

SELECT id FROM purchase_orders WHERE contains(doc, 'lawn AND wild') > 0;

例E-6 複雑なブールを使用したCONTAINS問合せ

SELECT id FROM purchase_orders
WHERE contains(doc, '((lawn OR garden) AND (wild OR flooded)) NOT(flamingo)')
> 0;

E.4.1.2 text_query: $を使用した全文ステミング

ステミングはtext_query言語とともに使用できます。

例E-7では、"lawns"と同じ言語語幹のワードが含まれるすべての文書が戻されるため、"lawn"または"lawns"が検索されます。ステミング演算子は、ドル記号($)で記述されます。

例E-7 ステミングを使用したCONTAINS問合せ

SELECT id FROM purchase_orders WHERE contains(doc, '$(lawns)') > 0;

E.4.1.3 ブールとステミング演算子の組合せ

text_query言語では演算子を組み合わせることができます。

例E-8に、これを示します。

関連項目:

text_query演算子の完全なリストは、『Oracle Textリファレンス』を参照してください。

例E-8 複雑な問合せ式を使用したCONTAINS問合せ

SELECT id FROM purchase_orders
WHERE contains(doc, '($lawns AND wild) OR flamingo') > 0;

E.4.2 SQL関数SCORE

Oracle SQL関数scoreはOracle SQL関数containsに関連します。関数scoreは問合せ内のどの場所でも使用できます。これは関連性を測定するもので、大規模なドキュメント・セット全体を全文検索するときに特に有効です。

関数scoreは通常、問合せ結果の一部として戻されるか、ORDER BY句で使用されるか、あるいはその両方です。

SCORE構文

score(label NUMBER) RETURN NUMBER

例E-9のscore(10)では、結果セット内の各行に対するスコアが戻されます。Oracle SQL関数scoreは、関数containsの特定のコールに関する結果セット内の行の関連性を戻します。scoreのコールは、LABEL(この場合は番号10)によってcontainsのコールにリンクされます。

関数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リファレンス』を参照してください。

例E-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;

E.4.3 CONTAINS検索の有効範囲

デフォルトでは、Oracle SQL関数containsでは、文書全体が全文検索されます。XML構造を使用してcontains問合せを限定するためには、WITHIN、INPATHおよびHASPATHの3つの演算子が使用できます。

前述の例で、構造による限定のない"lawn"の検索では、発注書内のどこかにワード"lawn"があるすべての発注書が検索されます。

注意:

この説明では、セクションはXMLノードと同じであると考えてください。

E.4.3.1 構造体演算子WITHINの使用

WITHIN演算子は、問合せをXML文書内のあるセクションに限定します。コメント・セクションのどこかにワード"lawn"が含まれている発注書を検索するには、WITHINを使用します。セクション名の大/小文字は区別されます。

例E-10 WITHIN

SELECT id FROM purchase_orders WHERE contains(DOC, 'lawn WITHIN comment') > 0;

E.4.3.1.1 ネストされたWITHINの使用

演算子WITHINをネストすることで問合せを限定できます。

例E-11では、セクション"comment"内にワード"lawn"が含まれ、"lawn"の出現箇所がセクション"item"内にもあるすべての文書が検索されます。

例E-11では行が戻されません。使用する発注書サンプルには、コメント内にワード"lawn"が含まれています。しかし、項目内の唯一のコメントは"Confirm this is electric"です。そのため、ネストしたWITHIN問合せでは行が戻されません。

例E-11 ネストしたWITHIN

SELECT id FROM purchase_orders
WHERE contains(doc, '(lawn WITHIN comment) WITHIN item') > 0;

E.4.3.1.2 WITHIN属性の使用

演算子WITHINを使用すると、属性の範囲内で検索できます。ですが、属性は、ネストしたWITHINでは検索できません。

例E-12では、purchaseOrder要素のorderDate属性にワード"10"が含まれているすべての発注書が検索されます。

デフォルトでは、マイナス記号(-)は単語セパレータとして処理されます。つまり、"1999-10-20"は3つの単語、"1999"、"10"および"20"として処理されます。したがって、この問合せでは1行戻されます。

属性内のテキストは、主検索可能文書の一部ではありません。text_queryをWITHIN purchaseOrder@orderDateで修飾せずに10を検索すると、行は戻されません。

例E-12 WITHIN (属性の場合)

SELECT id FROM purchase_orders
WHERE contains(doc, '10 WITHIN purchaseOrder@orderDate') > 0;

E.4.3.1.3 WITHINおよびANDの使用

演算子WITHINおよびANDを一緒に使用して、同じセクションに出現する一群の語や、あるセクションに個別に出現する一群の語を検索できます。

コメント・セクション内にlawnとelectricの2つのワードが含まれる発注書を検索するとします。purchaseOrderにはコメント・セクションが複数ある場合があります。このため、この問合せの作成方法は2通りあり、異なる結果となります。

両方のワードが含まれ、各ワードがあるコメント・セクション内に出現する発注書を検索する場合は、例E-13のような問合せを作成します。

purchaseOrderデータに対してこの問合せを実行すると、1行戻されます。この例ではカッコは必要ありませんが、使用すると問合せがわかりやすくなります。

両方のワードが含まれ、両方のワードが同じコメント内に出現する発注書を検索する場合は、例E-14のような問合せを作成します。

例E-14の問合せでは、行が戻されません。例E-15の問合せのように、lawn AND electricを囲むカッコを外すと、1行戻されます。

演算子WITHINの優先順位はANDより高いため、例E-15は例E-16と同じように解析されます。

例E-13 WITHINおよびAND: あるコメント・セクション内の2つのワード

SELECT id FROM purchase_orders
WHERE contains(doc, '(lawn WITHIN comment) AND (electric WITHIN comment)') > 0;

例E-14 WITHINおよびAND: 同じコメント内の2つのワード

SELECT id FROM purchase_orders
WHERE contains(doc, '(lawn AND electric) WITHIN comment') > 0;

例E-15 WITHINおよびAND: カッコなし

SELECT id FROM purchase_orders
WHERE contains(doc, 'lawn AND electric WITHIN comment') > 0;

例E-16 WITHINおよびAND: 演算子優先順位を示すカッコ

SELECT id FROM purchase_orders
WHERE contains(doc, 'lawn AND (electric WITHIN comment)') > 0;

E.4.3.1.4 セクションの定義

様々なセクションについて説明しています。

セクションは次のいずれかです。

- パス・セクションまたはゾーン・セクション
これは、ノードの子孫であるテキスト・ノードのすべてを、間を空白で区切って文書順に連結したものです。ノードからゾーン・セクションに変換するには、ノードをシリアライズしてすべてのタグを空白で置換する必要があります。パス・セクションの有効範囲と動作はゾーン・セクションと同じですが、パス・セクションでは INPATHおよびHASPATH構造演算子を使用した問合せがサポートされます。

- フィールド・セクション
ゾーン・セクションと同じですが、文書内の繰返しノードが空白で区切られて単一のセクションに連結されます。

- 属性セクション

- 特殊セクション(文または段落)

関連項目:

特殊セクションの詳細は、『Oracle Textリファレンス』を参照してください。

E.4.3.2 構造体演算子INPATHの使用

演算子WITHINを使用すると、text_queryで、単純な構造による限定を表現できます。大量のXML構造を使用する問合せでは、ネストしたWITHIN演算子のかわりに、演算子INPATHとText Pathを使用できます。

演算子INPATHでは、左側にtext_queryを記述し、右側にカッコで囲んだText Pathを記述します。例E-17では、パス/purchaseOrder/items/item/comment内でワード"electric"が含まれるpurchaseOrdersが検索されます。

例E-17の検索範囲は、Text Pathで示されたセクションです。例E-18の問合せでは例E-17の問合せよりも範囲の広いパスを使用しますが、同じように1行しか戻されません。

例E-17 全文述語内の構造: INPATH

SELECT id FROM purchase_orders
WHERE contains(doc, 'electric INPATH (/purchaseOrder/items/item/comment)') > 0;

例E-18 全文述語内の構造: INPATH

SELECT id FROM purchase_orders
WHERE contains(doc, 'electric INPATH (/purchaseOrder/items)') > 0;

E.4.3.2.1 テキスト・パスの使用

Text Pathの構文とセマンティクスは、W3CのXPath 1.0勧告に基づいています。単純なパス式はサポートされますが(省略構文のみ)、関数はサポートされません。

関連項目:

- W3CのXPath 1.0勧告の詳細は、http://www.w3.org/TR/xpathを参照してください。

- Text Pathの文法については、「Text Path BNFの仕様」を参照してください。

例E-19では、属性partNumが"872-AA"と等しいitem要素の子であるcomment要素内にワード"electric"が含まれるすべての発注書が検索されます(つまり、ルート・ノードからいくつか下のレベルのitems要素の子です)。

例E-20では、3番目のレベルであるitem要素(またはその子孫)内にワード"lawnmower"が含まれ、すべてのレベルにcomment要素があるすべての発注書が検索されます。この問合せでは1行戻されます。問合せの有効範囲はcomment要素ではなく、子孫としてcomment要素を持つ一連のitems要素であることに注意してください。

例E-19 複雑なパス式を使用したINPATH (1)

SELECT id FROM purchase_orders
WHERE contains(doc, 'electric INPATH (//items/item[@partNum="872-AA"]/comment)')
> 0;

例E-20 複雑なパス式を使用したINPATH (2)

SELECT id FROM purchase_orders
WHERE contains(doc, 'lawnmower INPATH (/*/*/item[.//comment])') > 0;

E.4.3.2.2 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の仕様」を参照してください。

E.4.3.2.3 ネストされたINPATHの使用

INPATH式はネストできます。Text Pathのコンテキストは常にルート・ノードです。ネストしたINPATHの場合も変わりません。

例E-21では、任意のレベルのcomment要素にワード"electric"が含まれる発注書が検索されます(このワードの出現箇所は、最上位レベルpurchaseOrder要素の子であるitem要素内でもあります)。

このネストしたINPATH問合せは、例E-22に示すように、簡潔に記述できます。

例E-21 ネストしたINPATH

SELECT id FROM purchase_orders
WHERE contains(doc,
'(electric INPATH (//comment)) INPATH (/purchaseOrder/items)')
> 0;

例E-22 リライト済のネストしたINPATH

SELECT id FROM purchase_orders
WHERE contains(doc, 'electric INPATH (/purchaseOrder/items//comment)') > 0;

E.4.3.3 構造体演算子HASPATHの使用

演算子HASPATHを使用すると、=述語などを使用して、特定のパス内に特定のセクションが含まれる文書を検索できます。これは全文検索ではなく、パス検索の実行です。セクションが存在するかどうかの確認、またはセクションの内容の照合はできますが、ワード検索はできません。

データ型がXMLTypeの場合は、構造演算子HASPATHではなくSQL/XML関数XMLExistsの使用を考慮してください。

演算子HASPATHで使用するオペランドはText Pathのみで、カッコで囲み、右側に記述します。=述語などを使用して、特定のパス内に特定のセクションが含まれる文書を検索するときは、HASPATHを使用します。これは全文検索ではなく、パス検索です。セクションが存在するかどうかの確認、またはセクションの内容の照合はできますが、ワード検索はできません。データ型がXMLTypeの場合は、構造演算子HASPATHではなくSQL/XML関数XMLExistsの使用を考慮してください。

例E-23では、USPriceを持つ項目があるpurchaseOrdersが検索されます。

例E-24では、"148.95"とテキスト等値であるUSPriceを持つ項目があるpurchaseOrdersが検索されます。

関連項目:

テキスト等値の説明は、「Text PathとXPathの比較」を参照してください。

HASPATHは、INPATHなど他のcontains演算子と組み合せることができます。例E-25では、文書の任意の場所にワードelectricを含み、148.95とテキスト等値であるUSPriceを持つitemがあり、かつpurchaseOrder属性orderDate内に10が含まれるpurchaseOrdersが検索されます。

例E-23 単純なHASPATH

SELECT id FROM purchase_orders
WHERE contains(DOC, 'HASPATH (/purchaseOrder//item/USPrice)') > 0;

例E-24 HASPATH (等価性)

SELECT id FROM purchase_orders
WHERE contains(doc, 'HASPATH (/purchaseOrder//item/USPrice="148.95")') > 0;

例E-25 HASPATHと他の演算子の組合せ

SELECT id FROM purchase_orders
WHERE contains(doc,
'electric
AND HASPATH (/purchaseOrder//item/USPrice="148.95")
AND 10 INPATH (/purchaseOrder/@orderDate)')
> 0;

E.4.4 CONTAINS結果の投影

WHERE句内にcontainsを使用したSQL問合せの結果は常に、行のセット(および多くの場合score情報)、または一致する行全体の投影です。contains式を満たす各XML文書の一部のみを戻すには、SQL/XML関数XMLQueryを使用します。

この例では、XMLType表purchase_orders_xmltypeが使用されます。

例E-26では、最上位レベルのpurchaseOrder要素の子孫であるcomment要素内にワード"electric"が含まれるpurchaseOrderが検索されます。各結果の行IDを戻すかわりに、XMLQueryを使用してcomment要素のみを戻します。

例E-26の結果は、要素commentの2つのインスタンスです。関数containsは、comment要素内に単語"electric"が含まれている行(ID = 1の行)を示します。関数XMLQueryは文書内のその行にある要素commentのインスタンスをすべて抽出します。purchaseOrder要素には要素 commentのインスタンスが2つあり、問合せではその両方が戻されます。

これは希望の結果と異なる場合があります。contains式を満たすcomment要素の実例のみを問合せで戻す場合は、XMLQueryに渡されるXQuery式でその述語を繰り返す必要があります。これには、XPath関数ora:containsを使用します。例E-27に、これを示します。

例E-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;

例E-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;

E.4.5 CONTEXT索引

CONTEXT索引を使用して全文検索を有効化できます。

- CONTEXT索引の使用

- CONTAINSにおけるCONTEXT索引の効果

- CONTEXT索引プリファレンス

- セクション・グループの概要

E.4.5.1 CONTEXT索引の使用

汎用の全文索引タイプは、データベース・ユーザーCTXSYSが所有するCONTEXT索引タイプです。デフォルトの全文索引を作成するには、CREATE INDEXを実行し、INDEXTYPE IS CTXSYS.CONTEXT句を追加します。PARAMETERS句を使用して索引付け設定を選択できます。

例E-28は、CONTEXT索引を作成します。

全文索引を作成するときには、多数の選択肢があります。これらの選択肢は、索引付けプリファレンスとして表されます。索引付けプリファレンスを使用するには、例E-29に示すように、CREATE INDEXにPARAMETERS句を追加します。

関連項目:

「CONTEXT索引プリファレンス」

Oracle Textには、CTXCATやCTXRULEなどの他の索引タイプが用意されていますが、この章では説明しません。

関連項目:

CONTEXT索引の詳細は、『Oracle Textリファレンス』を参照してください。

例E-28 表PURCHASE_ORDERSの単純なCONTEXT索引

CREATE INDEX po_index ON purchase_orders(doc)
INDEXTYPE IS CTXSYS.CONTEXT;

例E-29 パス・セクション・グループを使用したXMLType表の単純なCONTEXT索引

CREATE INDEX po_index ON purchase_orders(doc)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('section group CTXSYS.PATH_SECTION_GROUP');

E.4.5.1.1 XMLType表でのCONTEXT索引の使用

CONTEXT索引は、テキストが含まれた任意のデータに対して作成できます。型がCHAR、VARCHAR、VARCHAR2、BLOB、CLOB、BFILE、XMLTypeまたはURITypeの列にCONTEXT索引を作成する構文は同じです。

例E-28では、VARCHAR2列に対するCONTEXT索引が作成されます。例E-30では、XMLType型の列に対するCONTEXT索引が作成されます。セクション・グループはデフォルトでPATH_SECTION_GROUPに設定されます。

XMLType表がある場合は、例E-31に示すように、オブジェクト構文を使用してCONTEXT索引を作成する必要があります。

例E-32に示すように、表を問合せできます。

例E-30 XMLType列の単純なCONTEXT索引

CREATE INDEX po_index_xmltype ON purchase_orders_xmltype(doc)
INDEXTYPE IS CTXSYS.CONTEXT;

例E-31 XMLType表の単純なCONTEXT索引

CREATE INDEX po_index_xmltype_table
ON purchase_orders_xmltype_table (OBJECT_VALUE)
INDEXTYPE IS CTXSYS.CONTEXT;

例E-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;

E.4.5.1.2 CONTEXT索引のメンテナンス

CONTEXT索引は非同期です。索引付けられたデータが変更されても、同期させるまで索引が変更されないことがあります。CONTEXT索引は、時間経過とともに断片化する可能性があります。断片化した索引では通常より多くの領域が使用されるため、問合せが遅くなります。CONTEXT索引を最適化(断片化解消)する方法はたくさんあります。

関連項目:

CONTEXT索引のメンテナンスの詳細は、『Oracle Textリファレンス』を参照してください。

E.4.5.1.3 CONTEXT索引付けのためのロールおよび権限

CONTEXT索引の作成に特別な権限は必要ありません。プリファレンスの作成と削除、およびOracle TextのPL/SQLパッケージの使用には、CTXAPPロールが必要です。また、CTXSYSパッケージCTX_DDLに対するEXECUTE権限も必要です。

E.4.5.2 CONTAINSにおけるCONTEXT索引の効果

Oracle SQL関数containsを使用するには、CONTEXT型の索引を作成する必要があります。containsをコールしたとき、最初の引数で指定された列にCONTEXT型の索引がない場合は、エラーが発生します。

text_queryの構文およびセマンティクスは、CONTEXT索引の作成時に選択した内容によって異なります。次に例を示します。

- ワードとしてカウントする対象

- 最も一般的なワードを処理対象とするかどうか

- 最も一般的なワード

- テキスト検索で大/小文字を区別するかどうか

- テキスト検索にキーワードの他にテーマ(概念)を含めることができるかどうか

E.4.5.3 CONTEXT索引プリファレンス

プリファレンスは、索引付けに関する選択肢の集合と考えることができます。プリファレンスには、セクション・グループ、データストア、フィルタ、ワードリスト、ストップリストおよび記憶域が含まれます。検索で大/小文字を区別するためのレクサー・プリファレンスを設定できます。

プリファレンスを作成するには、プロシージャCTX_DDL.create_preference(またはCTX_DDL.create_stoplist)を使用します。プロシージャCTX_DDL.set_attributeを使用して新規プリファレンスの属性を設定することによって、そのプリファレンス・グループのデフォルトの選択肢をオーバーライドします。その後、CREATE INDEXのPARAMETERS文字列内にpreference type preference_nameを含めることによって、CONTEXT索引でプリファレンスを使用します。

プリファレンスを作成すると、それを使用して索引をいくつでも作成できます。

E.4.5.3.1 検索で大/小文字を区別する方法

containsを使用した全文検索では、デフォルトで大/小文字が区別されません,。文書内のワードに対してtext_query内のワードを照合する際に、大/小文字は考慮されません。ただし、セクション名および属性名は常に、大/小文字が区別されます。CONTEXT索引を作成する場合、全文検索で大文字と小文字を区別するように選択できます。

例E-33では、text_query内の"HURRY"が、デフォルトの大/小文字が区別されない索引が設定されたpurchaseOrder内の"Hurry"と一致するため、1行戻されます。

例E-34では、属性mixed_caseがTRUEに設定された新しいレクサー・プリファレンスmy_lexerが作成されます。この例では、printjoin文字も"-"、"!"、","に設定されます。CONTEXT索引の作成およびポリシーの作成に同じプリファレンスを使用できます。

関連項目:

レクサー属性の完全なリストは、『Oracle Textリファレンス』を参照してください。

例E-35では、新しいmy_lexerレクサー・プレファレンスを使用してCONTEXT索引が作成されます。ここではプレファレンスpreference-case-mixedが使用されます。

例E-33では、text_query内の"HURRY"がpurchaseOrder内の"Hurry"と一致しないため、行は戻されません。例E-36では、text_queryの"Hurry"がpurchaseOrder内のワード"Hurry"と正確に一致するため、1行戻されます。

例E-33 CONTAINS: デフォルトの大/小文字を区別しない一致

SELECT id FROM purchase_orders
WHERE contains(doc, 'HURRY INPATH (/purchaseOrder/comment)') > 0;

例E-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;
/

例E-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');

例E-36 CONTAINS: 大/小文字混合の(正確な)一致

SELECT id FROM purchase_orders
WHERE contains(doc, 'Hurry INPATH (/purchaseOrder/comment)') > 0;

E.4.5.4 セクション・グループの概要

セクション・グループ・インスタンスは、文書の構造の種類、およびその構造の索引付け方法(したがって検索方法)を指定するセクション・グループ・タイプに基づいています。セクション・グループ・インスタンスによって、索引付けされる要素が指定される場合もあります。ほとんどのユーザーは、デフォルトのセクション・グループまたは事前定義のセクション・グループのいずれかを使用します。

CONTEXT索引の作成時に行う選択の1つにセクション・グループがあります。セクション・グループ・インスタンスは、セクション・グループ・タイプに基づいています。セクション・グループ・タイプでは、文書の構造の種類、およびその構造の索引付け方法(したがって検索方法)が指定されます。セクション・グループ・インスタンスによって、索引付けされる構造要素が指定される場合もあります。ほとんどのユーザーは、デフォルトのセクション・グループまたは事前定義のセクション・グループのいずれかを使用します。

E.4.5.4.1 セクション・グループ・タイプの選択

XQuery Full Textを使用しないXML検索で役立つセクション・グループ・タイプについて説明します。

XMLの全文検索要件がある大部分のユーザーは、PATH_SECTION_GROUPを使用することをお薦めします。一部のユーザーには、FIELDセクションを使用するXML_SECTION_GROUPの使用が適している場合もあります。この選択によって、通常、問合せパフォーマンスが向上し、索引が小さくなりますが、フィールド化構造の文書に限定されます(検索可能なノードは、繰返しのないすべてのリーフ・ノードです)。

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_SECTION_GROUPセクション・グループ・タイプの詳細は、『Oracle Textリファレンス』を参照してください。

E.4.5.4.2 セクション・グループの選択

索引で使用するセクション・グループを選択するときは、提供されているセクション・グループを選択するか、デフォルトを使用するか、または選択したセクション・グループ・タイプに基づく新しいセクション・グループを作成するかを選択できます。

セクション・グループ・タイプ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リファレンス』を参照してください。

セクション・グループを索引と関連付けるには、例E-37のように、PARAMETERS文字列にsection group <section group name>を追加します。

例E-37 パス・セクション・グループを使用したpurchase_orders表の単純なCONTEXT索引

CREATE INDEX po_index ON purchase_orders(doc)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('section group CTXSYS.PATH_SECTION_GROUP');

E.5 ora:contains XQuery関数

関数ora:containsは、SQL/XML関数XMLQuery、XMLTableおよびXMLExistsのXQuery式の引数で使用するために、Oracleによって定義されたXQuery(XPath)関数です。関数ora:containsは常に数値を戻します。スコアは戻しません。text_queryがinput_textと一致した場合、正数を戻します。そうでない場合は0(ゼロ)を戻します。

ora:containsを使用する場合は、Oracle XML DB名前空間xmlns:ora="http://xmlns.oracle.com/xdb"に接頭辞oraをマップする名前空間宣言も指定する必要があります。

E.5.1 XQuery関数ora:containsを使用した全文検索

ora:containsの引数text_queryは、全文検索を指定する文字列です。それはSQL関数contains text_queryの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索引」

例E-4に、ブール演算子と$(ステミング)を任意に組み合せた全文検索を示します。

関連項目:

- 全文演算子の詳細は、「SQL関数CONTAINSを使用した全文検索」を参照してください。

- containsおよびora:containsで使用できる演算子の完全なリストは、『Oracle Textリファレンス』を参照してください。

一致規則は、ポリシーpolicy_owner.policy_nameで定義されます。policy_ownerの指定がない場合、ポリシー所有者はデフォルトで現行ユーザーに設定されます。policy_nameとpolicy_ownerの両方が指定されない場合、ポリシーはデフォルトでCTXSYS.DEFAULT_POLICY_ORACONTAINSに設定されます。

E.5.2 ora:contains問合せの有効範囲

ora:containsのスコープは引数input_textによって定義され、それは現在のXPathコンテキストで評価されます。結果が単一のテキスト・ノードまたは属性である場合、それは検索ターゲットです。input_textが単一のテキスト・ノードまたは属性に対して評価されない場合は、エラーが発生します。

ポリシーによって、ora:containsの一致規則が決定されます。ora:containsのデフォルト・ポリシーに関連付けられたセクション・グループの型はNULL_SECTION_GROUPです。

ora:containsはXPath式のどこでも使用でき、そのinput_text引数は単一のテキスト・ノードまたは属性に対して評価されるXPath式です。

E.5.3 ora:contains結果の投影

各XML文書の一部のみを戻す場合は、関数XMLQueryを使用してノード順序を投影し、その結果にXMLCastを適用してノードのスカラー値を投影します。

例E-38では、ワード"lawn"を含むcommentがある各発注書のorderDateが戻されます。

関数XMLExistsは、ワード"lawn"の入ったcommentがpurchaseOrder要素に含まれる行(文書)に結果を限定します。その後、関数XMLQueryが、それらのpurchaseOrder要素から属性orderDateの値を戻します。関数XMLCastは、この結果をSQL DATE値としてキャストします。

//commentが抽出されていれば、WHERE句と一致したコメントのみではなく、両方のコメントがサンプル・ドキュメントから戻されます。

関連項目:

例E-26

例E-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");

E.5.4 ora:contains問合せでのポリシーの使用

ポリシーは、ora:contains問合せに関連付けることができるプリファレンスの集合であり、索引付けに関する選択で、SQL containsの索引付け選択と同じようなセマンティクス制御を提供します。

列のCONTEXT索引によって、その列に対するSQL contains問合せのセマンティクスが決まります。ポリシーはora:containsに対して用意されています。サポートしている索引に依存しないためです。

E.5.4.1 ポリシーの例: 提供されているストップリスト

ストップワード・リストが空のポリシーと、続いてポリシーを伴う、あるいは伴わずにora:containsを使用して問合せを作成する例を示し、相違点を説明します。

例E-39では、空のストップワード・リストを持つポリシーが作成されます。

わかりやすいように、このポリシーは空のストップリストで構成されており、所有者はユーザーCTXSYSです。このポリシーに組み込む新しいストップリストを作成するか、またはCONTEXT索引用に作成したストップリスト(またはレクサー)定義を再利用できます。

最も一般的なワード(ストップワード)も含めてすべてのワードを検索するには、ora:contains式でこのポリシーを参照してください。例E-40では、"is"はデフォルトでストップワードであり問合せできないため、コメントは戻されません。

例E-41では、空のストップワード・リストを指定するために、例E-39で作成されたポリシーが使用されます。この問合せでは"is"が検索され、コメントが1つ戻されます。

例E-41では、ポリシーmy_nostopwords_policyを使用します。例E-39では、このポリシーの名前は暗黙的にすべて大文字になります。XPathでは大/小文字が区別されるため、XPath述語内でこのポリシーは、my_nostopwords_policyではなくMY_NOSTOPWORDS_POLICYのように、すべて大文字を使用して記述する必要があります。

関連項目:

「CONTEXT索引プリファレンス」

例E-39 ora:containsで使用するポリシーの作成

BEGIN
CTX_DDL.create_policy(POLICY_NAME  =>  'my_nostopwords_policy',
STOPLIST     =>  'CTXSYS.EMPTY_STOPLIST');
END;
/

例E-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");

例E-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");

E.5.4.2 ora:containsでのポリシーの効果

ora:containsポリシーは、text_queryの一致セマンティクスに影響を与えます。ポリシーには、レクサー、ストップリスト、ワードリスト・プリファレンスまたはこれらの組合せが含まれる場合があります。CONTEXT索引の作成に使用できる他のプリファレンスは、ora:containsには適用できません。

プリファレンスの効果は次のとおりです。

- ワードリスト・プリファレンスによって、ステミング演算子のセマンティクスが改良されます。

- ストップリスト・プリファレンスによって、一般的であるために索引付け(検索可能に)しないワードが定義されます。

- レクサー・プリファレンスによって、ワードのトークン化および一致方法が定義されます。たとえば、ワードの一部としてカウントする文字および一致で大/小文字を区別するかどうかが定義されます。

関連項目:

- 事前定義のストップリストを使用したポリシーの作成例は、「ポリシーの例: 提供されているストップリスト」を参照してください。

- 大/小文字区別のポリシーの例は、「ポリシーの例: ユーザー定義レクサー」を参照してください。

E.5.4.2.1 ポリシーの例: ユーザー定義レクサー

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問合せで、任意のポリシーを使用できます。

例E-42では、text_query内の"HURRY"が、デフォルトの大/小文字が区別されない索引が設定されたpurchaseOrder内の"Hurry"と一致するため、1行戻されます。

例E-43では、属性mixed_caseがTRUEに設定された新しいレクサー・プリファレンスmy_lexerが作成されます。この例では、printjoin文字も"-"、"!"、","に設定されます。CONTEXT索引の作成およびポリシーの作成に同じプリファレンスを使用できます。

関連項目:

レクサー属性の完全なリストは、『Oracle Textリファレンス』を参照してください。

例E-44では、新規ポリシーmy_policyが作成され、レクサーのみが指定されます。他のプリファレンスはすべてデフォルトに設定されます。例E-44では、preference-case-mixedが使用されます。

例E-45では、問合せで新規ポリシーが使用されます。text_query内の"HURRY"はpurchaseOrder内の"Hurry"と一致しないため、行は戻されません。

例E-46では、text_queryの"Hurry"がcomment要素内のテキスト"Hurry"と正確に一致するため、1行戻されます。

例E-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");

例E-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;
/

例E-44 大/小文字混合の(大/小文字が区別されない)ポリシーの作成

BEGIN
CTX_DDL.create_policy(POLICY_NAME  => 'my_policy',
LEXER        => 'my_lexer');
END;
/

例E-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");

例E-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");

E.5.4.3 ポリシーのデフォルト

ora:containsのポリシーの引数はオプションです。省略した場合、問合せではデフォルトのポリシーCTXSYS.DEFAULT_POLICY_ORACONTAINSが使用されます。

ora:containsで使用するポリシーを作成するときは、すべてのプリファレンスを指定する必要はありません。たとえば、例E-44では、レクサー・プリファレンスのみが指定されていました。指定されないプリファレンスについては、CREATE_POLICYによって次のデフォルトのプリファレンスが使用されます。

- CTXSYS.DEFAULT_LEXER

- CTXSYS.DEFAULT_STOPLIST

- CTXSYS.DEFAULT_ WORDLIST

ポリシーの作成では、CONTEXT索引の作成が索引メタデータのコピー・セマンティクスに従うのと同様に、プリファレンスとその属性のコピー・セマンティクスに従います。

E.5.5 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索引

E.5.5.1 問合せでの1次フィルタの使用

XPath関数ora:containsは、処理のコストが比較的かかるため、可能な場合は1次フィルタを組み込んだ問合せの作成をお薦めします。この結果、ora:containsで処理される行数が最小化されます。

例E-47では、実行計画からわかるように、表内の各行が検査(全表スキャン)されます。この例で、ora:containsは各行に対して評価されます。

例E-48のように、列idに対して索引を作成し、例E-49のように、選択性の高い述語idを問合せに追加すると、実行計画に示すように、索引idによって実行処理が起動されます。関数ora:containsは、idが5未満の行でのみ実行されます。

例E-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

例E-48 IDのBツリー索引

CREATE INDEX id_index ON purchase_orders_xmltype_big(id);

例E-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

E.5.5.2 XPathリライトおよびCONTEXT索引

Oracle XQuery関数ora:containsはサポートしている索引に依存しませんが、XPathリライトが行われる際には多くの場合、高いパフォーマンスを得るためにora:containsは既存のCONTEXT索引を使用します。

Oracle Databaseでは、XPath式を使用する問合せを最適化することがあります。このXPathリライトは、問合せの最適化の一部として自動的に行われます。

関連項目:

オブジェクト・リレーショナル記憶域のXPathリライト

例E-50のXPath式の単純評価では、列docの各セルがその式と一致しているかどうかをテストします。

しかし、docがXML Schemaに基づいており、purchaseOrder文書がオブジェクト・リレーショナル表XMLTypeに物理的に格納されている場合は、列comment(存在する場合)に直接アクセスし、そこで各セルが"electric"と一致しているかどうかをテストするほうが効率的です。

ora:containsの最初の引数が単一のリレーショナル列にマップされている場合、完全なXPath式をXML文書全体に適用するかわりに、ora:containsをその列に適用することができます。この結果、索引が含まれていない場合でも、問合せのパフォーマンスが大幅に向上します。

ora:containsをCONTEXT索引を持つ列にマップするテキスト・ノードまたは属性とともに使用している場合、その索引を基礎となる列のデータに適用することがあります。CONTEXT索引をオブジェクト・リレーショナルXMLTypeデータとともに使用するには、次の両方の条件を満たす必要があります。

- ora:containsのターゲット(input_text)は、親ノードが列にマップされている(a)単一のテキスト・ノード、または(b)列にマップされている属性の必要があります。列は(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とリライトされたSQL 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索引の使用を強制する必要もあります。例E-51に、これを示します。

例E-51では、例6-10で作成したXMLIndex索引を使用しています。非構造化XMLIndexコンポーネントのVALUE列にCONTEXT索引を作成します。実行計画では、XMLIndex索引とCONTEXT索引の両方が選択されていることが示されています。前者はmy_path_tableおよびpikey索引SYS89559_PO_XMLINDE_PIKEY_IXへの参照によって示されます。後者はpo_otext_ixおよび述語アクセスのCONTAINSへの参照によって示されます。

例E-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");

例E-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.

E.6 Text Path BNFの仕様

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           ::=    "_"

E.7 全文XMLのサポートの例

XQueryを使用しないXMLデータの全文検索の例としてコードのサポートを示します。

- 発注書のXML文書、po001.xml

- CREATE TABLE文

- 全文検索する発注書XML Schemaの例

E.7.1 発注書のXML文書、po001.xml

発注書XML文書が示されています。XQueryを使用しないXMLでの全文検索の例で使用されます。

例E-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>

E.7.2 XQueryを使用しない全部検索例の表

XQueryを使用しない全文検索の例で使用される発注書表を作成するCREATE TABLE文が示されています。

例E-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;

例E-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;

例E-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;

E.7.3 全文検索する発注書XML Schemaの例

発注書XML Schemaが示されています。XML発注書に対する全文検索の例で使用されます。

例E-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>

索引

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)

- 定義 1

- アクセス制御リスト(ACL)

- 定義 1

- 概要 1

- システム 1

- アカウントXDB 1

- ACE

- 「アクセス制御エントリ」を参照

- ACL

- 「アクセス制御リスト」を参照

- Oracle XML DBの管理 1

- Advanced Queuing(AQ)

- IDAP 1

- メッセージングのシナリオ 1

- ポイント・ツー・ポイント・サポート 1

- パブリッシュ・サブスクライブ・サポート 1

- XMLTypeキュー・ペイロード 1

- 集約権限

- 定義 1

- ALL_JSON_COLUMNSビュー 1

- 注釈

- XML Schema

- 取得のための問合せ 1

- appendChildXML SQL関数(非推奨) 1

- 配列

- JavaScript 1

- 配列要素 1

- 配列ステップ, Oracle JSONパス式 1

- ASCIIエスケープ・シーケンス, JSON 1

- ASCIIキーワード, JSON SQL関数 1

- 基本権限

- 定義 1

- 属性

- xdb:columnProps 1

- xdb:defaultTable 1

- xdb:defaultTableSchema (非推奨) 1

- xdb:maintainDOM 1

- xdb:maintainOrder (非推奨) 1 , 2

- xdb:mapUnboundedStringToLob (非推奨) 1 , 2

- xdb:maxOccurs (非推奨) 1

- xdb:SQLCollSchema (非推奨) 1 , 2

- xdb:SQLCollType 1

- xdb:SQLInline 1

- xdb:SQLName 1

- xdb:SQLSchema (非推奨) 1

- xdb:SQLType 1

- xdb:srclang (非推奨) 1

- xdb:storeVarrayAsTable (非推奨) 1 , 2

- xdb:tableProps 1

- xdb:translate (非推奨) 1

- XML Schema属性データ型

- SQLへのマッピング 1

- 認証

- 定義 1

- 認可

- 定義 1

B

- 下位互換のXML Schema拡張

- 定義 1

- バイナリXML

- 定義 1

- ブートストラップACL

- 定義 1

C

- XML用のC API 1

- カスケーディング・スタイルシート(CSS) 1

- XMLTableコールのチェーン 1

- 確実に整形式のJSONにするためのチェック制約 1

- 子COLUMNS句, json_table SQL関数 1

- 循環依存

- XML Schema 1

- CLASSPATH環境変数

- JCR 1

- コレクション

- 表外の表 1

- 大規模な文書のロードおよび取得 1

- XML

- 定義 1

- collection属性(SQL) 1

- 列パターン, XMLTable SQL関数

- 定義 1

- columnProps属性 1

- COLUMNS句

- json_table SQL関数 1

- complexType

- 循環の処理 1

- 継承の処理 1

- マッピング

- フラグメントからLOB 1

- XML Schemaデータ型からSQL 1

- Oracle XML DBの制限および拡張 1

- 複合的なXLinkリンク

- 定義 1

- リソース・パス名の構成要素

- 定義 1

- 複合XML文書

- 定義 1

- 圧縮

- オンライン・トランザクション処理(OLTP)

- CREATE TABLEの使用 1

- XMLTypeのサポート 1

- Oracle XML DBの構成

- プロトコル・サーバー 1

- リポジトリ 1

- サーブレット 1

- DBMS_XDB APIの使用 1

- Oracle Enterprise Managerの使用 1

- xdbconfig.xml構成ファイル 1

- XMLTypeデータに対する制約

- 繰返しXML要素 1

- contains XPath関数(Oracle) 1

- コンテンツ管理アプリケーション

- 定義 1

- リソースのコンテンツ

- 定義 1

- Content Repository API for Java 1

- 「JCR」を参照

- Content Repository API for Java (JCR) 1

- コンテキスト項目, Oracle JSONパス式 1

- コピーに基づくXML Schemaの拡張 1

- copyEvolve PL/SQLプロシージャ 1

- copy-namespaceモード, XQuery 1

- COST_XML_QUERY_REWRITEオプティマイザ・ヒント 1

- コストベースのXML問合せのリライト

- 定義 1

- CREATE TABLE文

- バイナリXMLのためのエンコード・オプション 1

- 記憶域オプション 1

- XMLType表の作成

- ネストしたコレクション 1

- 記憶域オプション 1

- XML Schemaに基づく 1 , 2

- CTXAPPロール 1

- CTXCAT索引 1

- CTXSYS.JSON_SECTION_GROUP Oracle Textセクション・グループ 1

- 循環依存

- XML Schema 1

D

- データベース・ロール

- 定義 1

- データベース・ユーザー

- 定義 1

- XML Schema日時データ型

- SQLへのマッピング 1

- DBA_JSON_COLUMNSビュー 1

- DBMS_XDB_CONFIG PL/SQLパッケージ 1

- DBMS_XDB_REPOS PL/SQLパッケージ 1

- DBMS_XMLDOM PL/SQLパッケージ

- 例 1

- DBMS_XMLGEN PL/SQLパッケージ 1

- DBMS_XMLINDEX PL/SQLパッケージ

- modifyParameterプロシージャ 1

- registerParameterプロシージャ 1

- syncIndexプロシージャ 1

- DBMS_XMLPARSER PL/SQLパッケージ 1

- DBMS_XMLSCHEMA_ANNOTATE PL/SQLパッケージ 1

- DBMS_XMLSCHEMA PL/SQLパッケージ

- copyEvolveプロシージャ 1

- inPlaceEvolveプロシージャ 1

- registerSchemaプロシージャ 1

- DBMS_XMLSTORAGE_MANAGE PL/SQLパッケージ

- disableIndexesAndConstraintsプロシージャ 1

- enableIndexesAndConstraintsプロシージャ 1

- exchangePostProcプロシージャ 1

- exchangePreProcプロシージャ 1

- renameCollectionTableプロシージャ 1

- XPath2TabColMappingプロシージャ 1 , 3

- DBMS_XMLSTORE PL/SQLパッケージ 1

- DBMS_XSLPROCESSOR PL/SQLパッケージ 1

- DBUri

- 定義 1

- sys_DburiGen SQL関数を使用した生成 1

- 行の識別 1

- ターゲット列の指定 1

- 列のテキスト値の取出し 1

- 表全体の取出し 1

- セキュリティ 1

- サーブレット, インストール 1

- DBUri参照

- HTTPアクセス 1

- DBUriServlet

- 定義 1

- デバッグ

- XML Schema登録 1

- defaultTable属性 1

- デフォルトの表

- XML Schema登録時の作成 1

- defaultTableSchema属性(非推奨) 1

- deleteXML SQL関数(非推奨) 1

- 削除

- リソース 1

- DBMS_XMLSCHEMAを使用したXML Schema 1

- depth SQL関数 1

- XML Schema派生データ型

- SQLへのマッピング 1

- Digestアクセス認証 1

- Digestアクセス認証, 構成 1

- ダイジェスト認証 1

- Digest認証, 構成 1

- ディレクトリ

- 「フォルダ」を参照

- ドキュメント(DOM)

- 定義 1

- 文書が相互に関連する再帰的な問合せ

- 定義 1

- ドキュメント・リンク

- 定義 1 , 2

- ドキュメントの場所を示すヒント

- 定義 1

- ドキュメント・オブジェクト・モデル

- 「DOM」を参照

- ドキュメント・タイプ定義

- 「DTD」を参照

- ドキュメント・ビュー・シリアライズ, JCR

- 定義 1

- DOM

- 定義 1

- SAXとの違い 1

- ドキュメント

- 定義 1

- 再現性

- XML Schemaマッピング 1

- updateXML SQL関数の使用 1

- Java API for XMLType 1

- NamedNodeMapオブジェクト 1

- NodeListオブジェクト 1

- 概要 1

- PL/SQL API for XMLType 1

- DOM再現性

- 定義 1

- DTD

- 定義 1

- Oracle XML DBでのサポート 1

- Oracle XML DBの使用 1

- JSONオブジェクトの重複フィールド名 1

- 動的型チェック

- XQuery言語 1

E

- ノードの有効テキスト値

- 定義 1

- 要素

- 配列 1

- XML Schema要素データ型

- SQLへのマッピング 1

- Enterprise Manager

- Oracle XML DBの管理 1

- エンティティ, XML

- バイナリXML記憶域を使用したDTDの使用 1

- XMLType表の同一レベル・パーティション化

- 定義 1

- エラー

- ORA-08181 1

- ORA-18177 1

- エラー句, JSON SQL関数 1

- イベント

- リポジトリ

- 構成 1

- 事前定義済 1

- イベント・ハンドラ, リポジトリ

- 定義 1

- イベント・リスナー, リポジトリ

- 定義 1

- 拡張, XML Schema 1

- EXISTSキーワード, json_table SQL関数 1

- 拡張XLinkリンク

- 定義 1

- XMLからのデータの抽出 1

F

- 再現性

- DOM

- XML Schemaマッピング 1

- updateXML SQL関数の使用 1

- フィールド 1

- FLWOR XQuery式 1

- fn:available XQuery関数

- サポート 1

- fn:collection XQuery関数

- サポート 1

- fn:doc XQuery関数

- サポート 1

- fn:idref XQuery関数

- サポート 1

- fn:id XQuery関数

- サポート 1

- fn:replace XQuery関数 1

- フォルダ

- 定義 1

- フォルダリング 1

- フォルダ・リンク

- 定義 1

- フォルダ限定の問合せ

- 定義 1

- FORMAT JSONキーワード, json_table SQL関数 1

- FOR ORDINALITYキーワード, json_table SQL関数 1

- フラグメント, XML

- 定義 1

- SQL操作 1

- フラグメント, XML

- LOBへのマッピング 1

- FROMリストの順序

- XMLTable PASSING句 1

- FTP

- 構成パラメータ 1

- デフォルト表の作成 1

- プロトコル・サーバー, 機能 1

- 全文索引付け 1

- 全文検索

- JSONデータ 1

- XMLデータ 1 , 2

- 完全修飾されたXML SchemaのURL 1

- 機能上の評価

- 定義 1

- 関数

- SQL

- appendChildXML (非推奨) 1

- deleteXML (非推奨) 1

- depth 1

- insertChildXML (非推奨) 1

- insertChildXMLafter (非推奨) 1

- insertChildXMLbefore (非推奨) 1

- insertXMLafter (非推奨) 1

- insertXMLbefore (非推奨) 1

- json_query 1

- json_table 1

- json_value 1

- sys_DburiGen 1

- sys_XMLAgg 1

- under_path 1 , 2

- updateXML (非推奨) 1

- XMLデータの更新 1

- XMLAgg 1

- XMLAttributes 1

- XMLCast 1

- XMLCDATA 1

- XMLColAttVal 1

- XMLComment 1

- XMLConcat 1

- XMLElement 1

- XMLExists 1

- XMLForest 1

- XMLIsValid 1

- XMLParse 1

- XMLPI 1

- XMLQuery 1 , 2

- XMLRoot 1

- XMLSerialize 1

- XMLTable 1 , 2

- XMLtransform 1

G

- XMLの生成

- DBMS_XMLGEN PL/SQLパッケージ 1

- SQL関数 1

- sys_XMLAgg SQL関数 1

- XMLAgg SQL関数 1

- XMLAttributes SQL関数 1

- XMLCDATA SQL関数 1

- XMLColAttVal SQL関数 1

- XMLComment SQL関数 1

- XMLConcat SQL関数 1

- XMLElement SQL関数 1

- XMLForest SQL関数 1

- XMLParse SQL関数 1

- XMLPI SQL関数 1

- XMLRoot SQL関数 1

- XMLSerialize SQL関数 1

- getCLOB() XMLTypeメソッド 1

- getSchemaURL() XMLTypeメソッド 1

- JCRリポジトリ・オブジェクトの取得 1

- グローバルXML Schema

- 完全修飾されたURLを使用して上書き 1

- XMLIndex構造化コンポーネント内のグループ

- 定義 1

H

- ハード・リンク

- 定義 1

- JCR 1

- リポジトリの階層索引 1

- 階層対応表

- 定義 1

- HTTP

- DBUri参照へのアクセス 1

- JavaサーブレットまたはXMLTypeへのアクセス 1

- リポジトリ・リソースへのアクセス 1

- 構成パラメータ, WebDAV 1

- デフォルト表の作成 1

- パフォーマンスの向上 1

- Oracle XML DBサーブレット 1

- プロトコル・サーバー, 機能 1

- リクエスト 1

- サーブレット 1

- URIFACTORY 1

- URI参照を使用したポインタの格納 1

- httpconfig要素, xdbconfig.xml 1

- HTTPUri

- 定義 1

- Hybrid Columnar圧縮 1

I

- IDAP

- アーキテクチャ 1

- インターネットを介した転送 1

- 索引

- 階層リポジトリ 1

- 索引付け

- CTXCAT 1

- 全文 1

- Oracle Text

- XML対応 1

- XMLType

- 選択 1

- JSONデータの索引付け

- 複数フィールド用のコンポジットBツリー索引 1

- json_table問合せ 1

- 検索 1

- json_exists SQL条件 1

- json_value SQL条件

- データ型に関する考慮事項 1

- json_table問合せ 1

- 索引構成表 1

- 継承

- XML Schema, complexTypesでの制限 1

- inPlaceEvolve PL/SQLプロシージャ 1

- インプレースXML Schemaの拡張 1

- insertChildXMLafter SQL関数(非推奨) 1

- insertChildXMLbefore SQL関数(非推奨) 1

- insertChildXML SQL関数(非推奨) 1

- insertXMLafter SQL関数(非推奨) 1

- insertXMLbefore SQL関数(非推奨) 1

- インスタンス・ドキュメント

- 定義 1 , 2

- ルート要素(名前空間)の指定 1

- Internet Data Access Presentation(IDAP)

- AQに対するSOAP仕様 1

- インターネット・プロトコル・バージョン6

- FTP 1

- HTTP(S) 1

- IPv6

- FTP 1

- HTTP(S) 1

- is json SQL条件

- STRICTキーワード 1

- is not json SQL条件

- STRICTキーワード 1

- isSchemaBased() XMLTypeメソッド 1

- isSchemaValidated() XMLTypeメソッド 1

J

- Java

- 接続, シックおよびシン 1

- DOM API for XMLType 1

- Oracle XML DBアプリケーション 1

- Java Content Repository API

- 「JCR」を参照

- JavaScript

- 配列 1

- オブジェクト 1

- オブジェクト・リテラル 1

- JavaScript表記法とJSONの比較 1

- JavaScript Object Notation (JSON) 1

- Java Specification Request

- 170 1 , 2

- 173 1

- 225 1

- JCR

- コンプライアンス・レベル, サポート 1

- ドキュメント・ビュー・シリアライズ

- 定義 1

- ファイルとフォルダ, 公開 1

- getPath() Javaメソッド 1

- ハード・リンク 1

- ロギング 1

- Oracle XML DBリポジトリへのアクセス 1

- 概要 1

- 制限事項, Oracle XML DB Content Connector 1

- 弱いリンク 1

- XML Schema 1

- jcr:content 1

- jcr:dataプロパティ 1

- JCRノード型

- XML Schemaデータ型からのマッピング 1

- XML Schemaのグローバルな要素宣言からのマッピング 1

- nt:file 1

- nt:folder 1

- Oracle拡張機能 1

- JDBC

- XML文書へのアクセス 1

- ドライバ, OCIおよびThin 1

- 大規模なXML文書のロード 1

- XML文書の操作 1

- JSON

- ASCIIエスケープ・シーケンス 1

- 文字エンコーディング 1

- キャラクタ・セット変換 1

- JavaScript表記法との比較 1

- XMLとの比較 1

- パス式

- 構文 1

- 構文

- lax 1

- strict 1

- json_exists SQL条件,

- json_tableとして 1

- 索引付け 1

- json_query SQL関数

- json_tableとして 1

- PRETTYキーワード 1

- json_table

- 問合せ用の索引付け 1

- json_table SQL関数

- EXISTSキーワード 1

- FORMAT JSONキーワード 1

- FOR ORDINALITYキーワード 1

- PATH句 1

- json_textcontains SQL条件 1

- json_value SQL条件

- json_tableとして 1

- json_table問合せ用の索引付け 1

- JSON, 概要 1

- JSON, 構文 1

- JSON検索索引 1

- JSON SQL関数

- WITH WRAPPERキーワード 1

- JSON SQL関数

- json_query

- json_tableとして 1

- json_table 1

- json_value

- json_tableとして 1

- JSR-170 1 , 2

- 「JCR」も参照

- JSR-173 1

- JSR-225 1

L

- 大規模ノードの処理 1

- 緩慢なJSON構文 1

- XMLの遅延ロード(実体化の遅延) 1

- LDAPプリンシパル

- 定義 1

- リンク

- ドキュメント

- 定義 1

- フォルダ

- 定義 1

- ハード

- 定義 1

- リポジトリ

- 定義 1

- 弱い

- 定義 1

- リンク, リポジトリ

- 定義 1

- リンク名

- 定義 1

- リンク・プロパティ文書

- 定義 1

- ロード

- コレクションでの大規模な文書 1

- JDBCを使用した大規模なXML文書のロード 1

- XMLデータのロード, 遅延 1

- LOBロケータ 1

- LOB

- XMLフラグメントのマッピング 1

- ローカルXML Schema

- 定義 1

- 完全修飾されたURLを使用して指定 1

M

- maintainDOM属性 1

- maintainOrder属性(非推奨) 1 , 2

- 実体化, 遅延 1

- マッピング

- SQLへのcomplexType

- 表外に格納 1 , 2

- SQLType属性を使用したオーバーライド 1

- simpleContentからオブジェクト型 1

- XML Schema complexTypeデータ型のSQLへのマッピング 1

- XML Schemaデータ型のSQLデータ型へのマッピング 1

- mapUnboundedStringToLob attribute (非推奨) 1 , 2

- xdb名前空間のmaxOccurs属性(非推奨) 1

- メタデータ

- 定義 1

- システム定義

- 定義 1

- ユーザー定義

- 定義 1

- メソッド

- XMLType

- getCLOB() 1

- getSchemaURL() 1

- isSchemaBased() 1

- isSchemaValid() 1

- isSchemaValidated() 1

- schemaValidate() 1

- setSchemaValidated() 1

- XML Schema 1

- MIME

- DBUriサーブレットによるオーバーライド 1

- mix:referenceable 1

- モデル, XML Schema

- 定義 1

- modifyParameter PL/SQLプロシージャ 1

N

- NamedNodeMapオブジェクト(DOM) 1

- 名前空間

- 接頭辞

- ocjr 1

- XQuery 1 , 2

- SQLオブジェクトのネーミング 1

- リポジトリ・リソースへのナビゲーショナル・アクセス 1

- NESTED_TABLE_ID疑似列 1

- NESTED PATH句, json_table, json_table SQL関数

- NESTED PATH句 1

- ネストしたXML

- DBMS_XMLGENを使用した生成 1

- XMLElementを使用した生成 1

- NodeListオブジェクト(DOM) 1

- ノード, 大規模(DBMS_XMLDOM) 1

- Nonce

- 定義 1

- nonceキー

- 定義 1

- XML Schemaに基づかないビュー

- 定義 1

- nt:file JCRノード型 1

- nt:folder 1

- nt:folder JCRノード型 1

- XML Schema数値データ型

- SQLへのマッピング 1

O

- オブジェクト

- JavaScript 1

- オブジェクト属性

- コレクション(SQL) 1

- sys_DburiGen SQL関数

- への受渡し 1

- XMLType, AQ 1

- オブジェクトベースのXMLデータの永続性

- 定義 1

- オブジェクト識別子

- 定義 1

- オブジェクト・リテラル

- JavaScript 1

- オブジェクト・メンバー 1

- XMLデータのオブジェクト・リレーショナル記憶域

- 定義 1

- オブジェクト・ステップ, Oracle JSONパス式 1

- 出現インジケータ

- 定義 1

- OCI API for XML 1

- ocjr名前空間接頭辞 1

- OCT

- 定義 1

- ODP.NET 1

- OID

- 「オブジェクト識別子」を参照

- ojcr:folder 1

- オプティマイザ・ヒント

- COST_XML_QUERY_REWRITE 1

- ora:contains Oracle XPath関数

- ポリシー

- 定義 1

- ora:defaultTable Oracle XQueryプラグマ 1

- ora:matches Oracle XQuery関数(非推奨) 1 , 2

- ora:no_schema Oracle XQueryプラグマ 1

- ora:no_xmlquery_rewrite Oracle XQueryプラグマ 1

- ora:replace Oracle XQuery関数(非推奨) 1

- ora:sqrt Oracle XQuery関数 1

- ora:tokenize Oracle XQuery関数 1

- ora:use_xmltext_idx Oracle XQueryプラグマ 1

- ORA-08181エラー 1

- ORA-18177エラー 1

- Oracle ASMファイル

- アクセス

- FTPの使用 1

- Oracle ASM仮想フォルダ 1

- Oracle Data Provider for .NET。 1

- Oracle Enterprise Manager

- Oracle XML DBの管理 1

- JCRノード型に対するOracle拡張関数 1

- Oracle Internet Directory 1

- Oracle JSONパス式

- 緩和 1

- Oracle Net Services 1

- OracleRepository 1

- Oracle Text

- 索引 1

- リソースの検索 1

- XML対応索引 1

- Oracle XML DB

- アクセス・モデル 1

- アーキテクチャ 1

- 機能 1

- Javaアプリケーション 1

- 概要 1

- リポジトリ

- 「リポジトリ」を参照 1

- アップグレード 1

- バージョニング 1

- 使用のタイミング 1

- Oracle XML DB Content Connector

- ロギングAPI 1

- 概要 1

- 制限事項 1

- ファイルをアップロードするサンプル・コード 1

- Ordered Collection

- 定義 1

- Ordered Collections in Tables(OCT)

- VARRAYのデフォルトの格納 1

- Ordered Collection Table(OCT)

- 定義 1

- XMLIndexの順序索引

- 定義 1

- 表外に格納

- コレクション 1

- XPathリライト 1

P

- 親COLUMNS句, json_table SQL関数 1

- XMLデータの部分更新

- 定義 1

- XMLデータの部分検証

- 定義 1

- XMLType表のパーティション化 1

- XMLTableのPASSING句

- FROMリストの順序 1

- PATH_VIEW 1

- パスベースのリポジトリ・リソースへのアクセス 1

- PATH句, json_table 1

- リソース・パス名のパス要素

- 定義 1

- パス式, JSON 1 , 2

- XMLIndexのパス索引

- 定義 1

- パス索引トリガー

- 定義 1

- パス名

- 定義 1

- 解決 1

- XMLIndexのパス表 1

- PD (位置指定ディスクリプタ) 1

- XMLデータの永続性モデル 1

- PL/SQLファンクション

- 「関数, PL/SQL」を参照

- PL/SQLパッケージ

- DBMS_XDB_CONFIG 1

- DBMS_XDB_REPOS 1

- DBMS_XMLDOM 1

- DBMS_XMLGEN 1

- DBMS_XMLPARSER 1

- DBMS_XMLSCHEMA_ANNOTATE 1

- DBMS_XMLSTORE 1

- DBMS_XSLPROCESSOR 1

- XMLType 1

- PL/SQLプロシージャ

- 「プロシージャ, PL/SQL」を参照

- ポイント・ツー・ポイント

- AQでのサポート 1

- ora:contains XPath関数のポリシー(Oracle)

- 定義 1

- ポート, FTP 1

- ポート, HTTP 1

- ポート

- 構成

- FTP 1

- HTTP 1

- HTTPS 1

- 位置指定ディスクリプタ(PD) 1

- XMLデータの事後解析の永続性

- 定義 1

- プラグマ, XQuery

- 「XQueryプラグマ, Oracle」を参照

- 事前定義のACL 1

- プリファレンス

- Oracle Textの索引付け

- 定義 1

- PRETTYキーワード, json_query 1

- PRETTYキーワード, JSON SQL関数 1

- フォーマット出力

- マニュアルの例 1

- SQL/XML関数により実行されない 1

- Webサービス出力 1

- XML Schema基本データ型

- SQLへのマッピング 1

- プリンシパル

- 定義 1

- LDAP

- 定義 1

- プライベート(ローカル) XML Schema, 定義 1

- 権限

- 定義 1

- プロシージャ

- PL/SQL

- copyEvolve 1

- disableIndexesAndConstraints 1

- enableIndexesAndConstraints 1

- exchangePostProc 1

- exchangePreProc 1

- inPlaceEvolve 1

- modifyParameter 1

- registerParameter 1

- registerSchema 1

- renameCollectionTable 1

- syncIndex 1

- XPath2TabColMapping 1 , 3

- protocolconfig要素, xdbconfig.xml 1

- プロトコル, リポジトリ・リソースへのアクセス 1

- プロトコル・サーバー

- アーキテクチャ 1

- 構成パラメータ 1

- イベントベース・ロギング 1

- FTP

- 構成パラメータ 1

- HTTP

- 構成パラメータ 1

- WebDAV

- 構成パラメータ 1

- パブリック(グローバル) XML Schema, 定義 1

- パブリッシュ・サブスクライブ

- AQでのサポート 1

- 発注書のXML文書

- 全文の例で使用 1

- 発注書XML Schema

- 注釈付き 1

- 修正された 1 , 2

Q

- 修飾されたXML SchemaのURL 1

- 問合せベースのアクセス

- RESOURCE_VIEWおよびPATH_VIEWの使用 1

- SQLの使用 1

- XMLTypeデータの問合せ

- 選択 1

- 一時データ 1

R

- ra:use_text_index Oracle XQueryプラグマ 1

- 再帰的スキーマのサポート 1

- 登録されたXML Schema, リスト 1

- XML Schemaの登録

- デバッグ 1

- デフォルト表, 作成 1

- SQLオブジェクト型, 作成 1

- JCR用XML Schemaの登録 1

- registerParameter PL/SQLプロシージャ 1

- registerSchema PL/SQLプロシージャ 1

- XMLIndex索引の名前変更 1

- replace XQuery関数 1

- リポジトリ

- JCRを使用したアクセス 1

- データ記憶域 1

- イベント

- 構成 1

- 事前定義済 1

- イベント・ハンドラ

- 定義 1

- イベント・リスナー

- 定義 1

- 階層索引 1

- XQueryの使用 1

- リポジトリ・リンク

- 定義 1

- リポジトリ・オブジェクト 1

- RESID

- 定義 1

- リソース

- アクセス

- プロトコルの使用 1

- 定義 1 , 2

- 削除

- 空でないコンテナ 1

- DELETEの使用 1

- DBMS_XDB_REPOSを使用した管理 1

- DBMS_XDBを使用した管理 1

- 操作に必要な権限 1

- 検索, Oracle Textの使用 1

- ACLでのプロパティの設定 1

- 同時操作 1

- 更新 1

- RESOURCE_VIEW

- 説明 1

- リソース構成ファイル

- 定義 1

- リソース構成リスト

- 定義 1

- リソース・コンテンツ

- 定義 1

- リソース・ドキュメント

- 定義 1

- リソースID

- 定義 1

- リソース名

- 定義 1

- リソース・バージョン

- 定義 1

- resource-view-cache-size構成パラメータ 1

- コレクションでの大規模な文書の取得 1

- RETURNING句, JSON SQL関数 1

- XMLTableのRETURNING SEQUENCE BY REF句 1

- 再検証モード, XQuery Update 1

- リライト

- XPath (XPath) 1

- XQuery 1

- ロール

- CTXAPP 1

- データベース

- 定義 1

- ルート構成 1

- ルート・フォルダ, リポジトリ 1

- ルートXML Schema

- 定義 1

- 行パターン, XMLTable SQL関数

- 定義 1

- 行ソース

- JSON

- 定義 1

- ルールベースのXML問合せのリライト

- 定義 1

S

- スカラー値 1

- スキーマの拡張

- 「XML Schemaの拡張」を参照

- スキーマのスキーマ(XML Schema)

- 定義 1

- スキーマの場所を示すヒント

- 定義 1

- schemaValidate() XMLTypeメソッド 1

- セキュリティ

- DBUri 1

- servlet要素, xdbconfig.xml 1

- サーブレット

- リポジトリ・データへのアクセス 1

- API 1

- 構成 1

- セッション・プーリング 1

- 作成

- Java 1

- XML操作 1

- セッション・プーリング

- プロトコル・サーバー 1

- 兄弟COLUMNS句, json_table SQL関数 1

- simpleContent

- オブジェクト型へのマッピング 1

- 単純XLinkリンク

- 定義 1

- SOAP

- IDAP 1

- SQL/XML生成関数

- 定義 1 , 2

- SQL/XMLパブリッシング関数

- 定義 1 , 2

- SQL/XML問合せおよび更新関数

- 定義 1

- SQL/XML標準

- XMLデータの生成 1

- XMLデータの問合せ

- XMLQueryおよびXMLTable 1

- SQL*Loader 1

- SQL*Plus

- XQUERYコマンド 1

- SQLCollSchema属性(非推奨) 1 , 2

- SQLCollType属性 1

- SQL条件

- IS (NOT) NULLおよびJSON null 1

- is json 1

- is not json 1

- json_exists

- json_tableとして 1

- 索引付け 1

- json_textcontains 1

- SQL関数

- 「関数, SQL」を参照

- SQLInline属性 1

- SQLJ 1

- SQLName属性 1

- SQLオブジェクト型

- XML Schema登録時の作成 1

- SQLSchema属性(非推奨) 1

- SQLType属性 1

- sqrt XQuery関数(Oracle) 1

- srclang属性(非推奨) 1

- 標準のメタデータ 1

- 静的型チェック

- XQuery言語 1

- ステップ, Oracle JSONパス式 1

- 記憶域

- 表外

- コレクション 1

- XMLTypeの記憶域モデル

- 選択 1

- storeVarrayAsTable属性(非推奨) 1 , 2

- 厳密なJSON構文 1

- is (not) json構文のSTRICTキーワード 1

- XML Schema文字列データ型

- SQLへのマッピング 1

- VARCHAR2またはCLOBへのマッピング 1

- XMLTypeデータの構造化記憶域

- 定義 1 , 2

- 構造化XMLIndexコンポーネント

- 定義 1

- スタイルシート, CSS 1

- XMLインスタンス・ドキュメントの更新用スタイルシート 1

- syncIndex PL/SQLプロシージャ 1

- sys_DburiGen SQL関数

- データベース参照の挿入 1

- SYS_NC_ARRAY_INDEX$列 1

- sys_XMLAgg SQL関数 1

- sysconfig要素, xdbconfig.xml 1

- システムACL

- 定義 1

- システムACL 1

- システム定義メタデータ

- 定義 1

T

- tableProps属性 1

- 表

- 索引構成 1

- ノードのテキスト値, 有効

- 定義 1

- サード・パーティのXLinkリンク

- 定義 1

- タイムゾーン・サポート, 暗黙的 1

- translate属性(非推奨) 1

- トリガー, パス索引

- 定義 1

- 型チェック, 静的および動的

- XQuery言語 1

U

- ユーザー定義型

- 要素の生成 1

- UNCONDITIONALキーワード, JSON SQL関数 1

- under_path SQL関数

- フォルダごとに異なるcorrelation 1

- 均一なアクセス制御メカニズム

- 定義 1

- 属性の親要素の一意制約 1

- JSONオブジェクトの一意のフィールド名 1

- 未解決のXLinkリンクおよびXIncludeリンク 1

- 非構造化XMLIndexコンポーネント

- 定義 1

- updateXML SQL関数(非推奨) 1

- リポジトリ・リソースの更新 1

- XMLデータの更新

- 部分更新

- 定義 1

- 同じノードの複数回の更新 1

- SQL関数の使用

- 最適化 1

- Oracle XML DBのアップグレード 1

- URIFACTORY PL/SQLパッケージ

- DBURI参照を処理するための構成 1

- URITypeのサブタイプの作成 1

- URI参照

- データベースおよびセッション 1

- DBUri参照 1

- DBUri参照へのHTTPアクセス 1

- URIFACTORY PL/SQLパッケージ 1

- URITypeの例 1

- URIType

- 例 1

- ユーザー

- 定義 1

- USER_JSON_COLUMNSビュー 1

- userconfig要素, xdbconfig.xml 1

- ユーザー定義メタデータ

- 定義 1

- ユーザーXDB 1

V

- 検証

- 例 1

- XMLIsValid SQL関数

- CHECK制約として使用 1

- XMLデータの検証, 部分

- 定義 1

- 値 1

- XMLIndexの値索引

- 定義 1

- VARRAY, LOB内

- 定義 1

- VARRAY, 表内

- 定義 1

- VCR

- 「バージョン管理されたリソース」を参照

- バージョン対応リソース

- 定義 1

- バージョン管理されたリソース

- 定義 1

- バージョニング 1 , 2

- バージョン・リソース

- 定義 1

- リソースのバージョン・シリーズ

- 定義 1

- 表示

- ALL_JSON_COLUMNS 1

- DBA_JSON_COLUMNS 1

- USER_JSON_COLUMNS 1

- ビュー

- RESOURCEおよびPATH 1

W

- 弱いリンク

- 定義 1

- 削除 1

- JCR 1

- WebDAV

- 定義 1

- Webフォルダ

- Windows 2000での作成 1

- Webサービス

- フォーマット出力 1

- 整形式のJSONデータ 1

- 整形式のXML文書

- 定義 1

- WITHOUT UNIQUE KEYSキーワード, JSON条件is json 1

- WITH UNIQUE KEYSキーワード, JSON条件is json 1

- WITH WRAPPERキーワード, JSON SQL関数 1

- ラッパー句, JSON SQL関数 1

- WRAPPERキーワード, JSON SQL関数 1

- WSDL

- ストアドPL/SQLへのアクセスに使用するWebサービス 1

- データベース問合せに使用するWebサービス 1

X

- xdb:columnProps属性 1

- xdb:defaultTable属性 1

- xdb:defaultTableSchema属性(非推奨) 1

- xdb:maintainDOM属性 1

- xdb:maintainOrder属性(非推奨) 1 , 2

- xdb:mapUnboundedStringToLob属性(非推奨) 1 , 2

- xdb:maxOccurs属性(非推奨) 1

- xdb:SQLCollSchema属性(非推奨) 1 , 2

- xdb:SQLCollType属性 1

- xdb:SQLInline属性 1

- xdb:SQLName属性 1

- xdb:SQLSchema属性(非推奨) 1

- xdb:SQLType属性 1

- xdb:srclang属性(非推奨) 1

- xdb:storeVarrayAsTable属性(非推奨) 1 , 2

- xdb:tableProps属性 1

- xdb:translate属性(非推奨) 1

- XDBBinary要素

- 定義 1

- xdbconfig.xml構成ファイル 1

- xdbconfig要素, xdbconfig.xml 1

- xdbcore-loadableunit-size構成パラメータ 1 , 2

- xdbcore-xobmem-bound構成パラメータ 1

- XDBデータベース・スキーマ(ユーザー・アカウント) 1 , 2

- xdb名前空間 1

- XDBSchema.xsd

- 定義 1

- XDBUri

- 定義 1 , 2

- XInclude

- 定義 1

- 未解決リンク 1

- XLink

- 複合的なリンク

- 定義 1

- 定義 1

- 拡張リンク

- 定義 1

- リンク・タイプ 1

- 単純リンク

- 定義 1

- サード・パーティのリンク

- 定義 1

- 未解決リンク 1

- XML

- JSONとの比較 1

- XML_ENABLEパス・セクション・グループ属性 1

- XMLAgg SQL関数 1

- XML属性

- 「属性」を参照

- XMLAttributes SQL関数 1

- XMLCast SQL関数 1

- XMLCDATA SQL関数 1

- XMLColAttVal SQL関数 1

- XMLComment SQL関数 1

- XMLConcat SQL関数 1

- XML診断能力モード 1

- XMLElement SQL関数 1

- XMLエンティティ

- バイナリXML記憶域を使用したDTDの使用 1

- XMLExists SQL関数 1

- XMLForest SQL関数 1

- XMLフラグメント

- 定義 1

- LOBへのマッピング 1

- SQL操作 1

- XMLIndex

- 索引の作成 1

- 索引の削除 1

- 順序索引

- 定義 1

- パス索引

- 定義 1

- パス表 1

- 索引の名前変更 1

- 構造化コンポーネント

- 定義 1

- ORA-08181発生時の同期化 1

- 非構造化コンポーネント

- 定義 1

- 値索引

- 定義 1

- XMLインスタンス・ドキュメント

- 定義 1 , 2

- XMLIsValid SQL関数 1

- XMLNAMESPACES句 1

- XMLParse SQL関数 1

- XMLPI SQL関数 1

- XML問合せのリライト

- 定義

- コストベース 1

- ルールベース 1

- XMLQuery SQL関数 1 , 2

- XMLRoot SQL関数 1

- XML Schema

- 注釈

- 取得のための問合せ 1

- 循環依存 1

- complexType宣言 1 , 2

- 循環依存 1

- 定義 1 , 2

- 削除 1

- 拡張

- 下位互換性, 定義 1

- 登録可能なXML Schema 1

- 継承, complexTypeの制限 1

- ローカルおよびグローバル 1

- SQLオブジェクト型へのマッピング 1

- Oracle XML DBを使用した登録

- JCRで使用 1

- 登録後に更新 1

- URL 1

- JCRでの使用 1

- W3C勧告 1 , 2

- XMLTypeメソッド 1

- XMLスキーマ

- 定義 1

- XML Schemaに基づく表および列, 作成 1

- XML Schemaに基づくビュー

- 定義 1

- XML Schemaデータ型

- JCRノード型へのマッピング 1

- SQLデータ型へのマッピング 1

- XML Schema定義

- 定義 1

- XML Schemaの拡張

- コピーに基づく 1

- インプレース 1

- XML検索索引

- 定義 1

- XMLSerialize SQL関数 1

- XMLTable SQL関数

- XMLフラグメントの分割 1

- 列パターン

- 定義 1

- PASSING句およびFROMリストの順序 1

- RETURNING SEQUENCE BY REF句 1

- COLUMNS句のリバース・ノード参照 1

- 行パターン

- 定義 1

- XMLtransform SQL関数 1

- XMLType

- 抽象データ型として 1

- コンストラクタ 1

- DBMS_XMLDOM PL/SQL API 1

- DBMS_XMLPARSER PL/SQL API 1

- DBMS_XSLPROCESSOR PL/SQL API 1

- データの抽出 1

- 列の索引付け 1

- インスタンス, PL/SQL API 1

- データのロード 1

- SQL*Loaderでのロード 1

- メソッド

- getCLOB() 1

- getSchemaURL() 1

- isSchemaBased() 1

- isSchemaValid() 1

- setSchemaValidated() 1

- XML Schema 1

- PL/SQLパッケージ 1

- 問合せ 1

- 一時データの問合せ 1

- XMLType列の問合せ 1

- キュー・ペイロード 1

- 記憶域モデル 1

- 表, ビュー, 列 1

- ビュー, PL/SQL DOM APIを使用したアクセス 1

- XPath言語

- 関数

- ora:contains (Oracle) 1 , 2

- 構文 1

- XPathリライト

- 定義 1

- 単一の要素および属性の索引 1

- 表外に格納 1

- XQJ 1

- XQuery

- copy-namespaceモード 1

- 拡張式

- 「XQueryプラグマ, Oracle」を参照 1 , 2

- 更新の保留中リスト 1

- プラグマ, Oracle

- ora:defaultTable 1

- ora:no_schema 1

- ora:no_xmlquery_rewrite 1

- ora:use_text_index 1

- ora:use_xmltext_idx 1

- 再検証モード 1

- 単純式 1

- 静的型指定機能 1

- タイムゾーン・サポート, 暗黙的 1

- XDMインスタンス 1

- XQuery API for Java (XQJ) 1

- XQUERYコマンド, SQL*Plus 1

- XQuery Data Model (XDM) 1

- XQuery関数および演算子

- サポート 1

- XQuery言語

- 式

- FLWOR 1

- リライト 1

- 関数

- fn:replace 1

- ora:,matches (非推奨, Oracle) 1

- ora:contains (Oracle) 1 , 2

- ora:matches (非推奨, Oracle) 1

- ora:replace (非推奨, Oracle) 1

- ora:sqrt (Oracle) 1

- ora:tokenize (Oracle) 1

- 項目

- 定義 1

- 名前空間 1 , 2

- 最適化 1

- リレーショナル・データに関する最適化 1

- Oracle拡張関数 1

- Oracle XML DBのサポート 1

- パフォーマンス 1

- 事前定義の名前空間および接頭辞 1

- 参照透過性

- 定義 1

- 順序

- 定義 1

- SQL*Plus XQUERYコマンド 1

- チューニング 1

- 型チェック, 静的および動的 1

- 順序付けられていないモード

- 定義 1

- 更新のスナップショット 1

- Oracle XML DBリポジトリの使用 1

- XMLTypeリレーショナル・データの使用

- 最適化 1

- XMLQueryおよびXMLTable SQL関数

- 例 1

- XQuery Update Facility 1

- XSD

- 定義 1

- XSLスタイルシート

- 定義 1

- XSLT

- スタイルシート

- XMLインスタンス・ドキュメントの更新用 1

- DBUriサーブレットの使用 1 , 2

- Oracle XML DBの使用 1

- DBMS_XSLPROCESSORパッケージの使用 1

Oracleの法律上の注意点

コピーライト

Copyright © 1994-2017, Oracle and/or its affiliates. All rights reserved.

ライセンス制約の保証と結果的に生じる損害の免責

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

保証免責

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクルまでご連絡ください。

制限付権利について

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

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 Corporationおよびその関連会社は一切の責任を負いかねます。

商標と登録商標について

OracleおよびJavaはオラクルおよびその関連会社の登録商標です。その他の社名、商品名等は各社の商標または登録商標である場合があります。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

第三者のコンテンツ、製品、サービスに対する免責事項

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。適用されるお客様とOracle Corporationとの間の契約に別段の定めがある場合を除いて、Oracle Corporationおよびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。適用されるお客様とOracle Corporationとの間の契約に定めがある場合を除いて、Oracle Corporationおよびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても一切の責任を負いかねます。

Pre-General Availability (一般提供前)版のドキュメントについて

このドキュメントがPre-General Availability (一般提供前)版の場合:

このドキュメントはPre-General Availability (一般提供前)版であり、デモおよび暫定使用のみを目的としたものです。このソフトウェアを使用するハードウェアに限定するものではありません。Oracle Corporationおよびその関連会社は、このドキュメントに関して一切の責任を負わず、いかなる保証もいたしません。また、このドキュメントを使用したことによって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。

非公開のPre-General Availability (一般提供前)版のドキュメントについて

このドキュメントが非公開のPre-General Availability (一般提供前)版の場合:

このドキュメントに含まれる情報は、情報の共有のみを目的としたものであって、顧客諮問委員会(Customer Advisory Board)のメンバーとしてのお客様の立場でのみ、またはお客様のPre-General Availability Trial Agreement (Pre-GAトライアル契約)のみに従って検討されるべきものとします。マテリアル、コード、または機能の提供をお約束するものではなく、購入決定を行う際の判断材料とすべきではありません。このドキュメントに記載されている特徴または機能の開発、リリースおよび時期については、オラクルの裁量により決定されます。

このドキュメントには、ソフトウェアまたは印刷物などの形式を問わず、オラクルが独占的な権利を有する財産的情報が含まれています。この機密資料へのアクセスと使用は、お客様とオラクルとの間で締結され、お客様が遵守に同意した、Oracle Master Agreement、Oracle License and Oracle Services Agreement (オラクル・ライセンスおよびサービスに関する契約書)、Oracle Partner Network Agreement、Oracle Distribution Agreementまたはその他のライセンス契約の条件に従うものとします。このドキュメントとその内容の開示、コピー、複製および配布には、オラクルによる事前の承諾を必要とします。このドキュメントはライセンス契約の一部となるものではなく、オラクルおよびその子会社や関連会社との契約を構成するものではありません。

ドキュメントのアクセシビリティ

オラクルのアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWebサイト(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc)を参照してください。

Oracle Supportへのアクセス

サポートをご契約のお客様には、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)を参照してください。