• 検索結果がありません。

XML DBファーストステップ

N/A
N/A
Protected

Academic year: 2021

シェア "XML DBファーストステップ"

Copied!
83
0
0

読み込み中.... (全文を見る)

全文

(1)

Oracle XML DB

ファースト・ステップ

Creation Date: Dec 25, 2006 Last Update: Dec 25, 2006

(2)

目次

1 はじめに... 4 2 XML文書の格納 ... 5 2.1 XMLTYPE記憶域...7 2.2 構築手順... 12 2.2.1 非構造化記憶域 ... 13 2.2.2 構造化記憶域 ... 16 3 XML文書の操作 ...23 3.1 SQL/XML関数 ... 23 3.1.1 extract関数... 23 3.1.2 extractValue関数... 23 3.1.3 existsNode関数 ... 23 3.2 検索... 24 3.2.1 SQLを使った検索... 24 3.2.1.1 Table関数とXMLSequence関数を組み合わせた検索 ... 25 3.2.2 XQueryを使った検索 ... 26 3.2.2.1 SQL*PlusのXQuery検索 ... 26 3.2.2.2 SQL関数のXQuery検索 ... 27 3.2.2.2.1 XMLQuery関数... 27 3.2.2.2.2 XMLTable関数... 29 3.3 更新... 30 3.3.1 全体更新 ... 30 3.3.2 部分更新 ... 31 3.3.2.1 updateXML ... 31 3.3.2.2 insertChildXML ... 32 3.3.2.3 insertXMLbefore... 33 3.3.2.4 appendChildXML... 34 3.4 削除... 35 3.4.1 全体削除 ... 35 3.4.2 部分削除 ... 35 3.4.2.1 updateXML ... 35 3.4.2.2 deleteXML... 36 3.5 索引の設定... 38

(3)

3.5.1 実行計画の表示設定 ... 38 4 XMLTYPE記憶域別テクニック ...40 4.1 リレーショナル列の活用... 40 4.2 XML文書全体の取得 ... 42 4.3 スキーマ注釈の利用... 43 4.4 XPATHリライト... 50 4.4.1 XPathリライトの診断... 51 4.5 半構造化記憶域(ハイブリッド記憶域)... 53 5 ビューの作成...57 5.1 XMLTYPEビュー... 57 5.1.1 XMLTypeビューのDML操作 ... 58 5.2 リレーショナル・ビュー... 61 6 XMLスキーマのメンテナンス ...63 7 外部XML文書の取り込み ...69 8 FAQ ...74 9 付録...77 9.1 表作成DDL... 77 9.2 索引作成DDL ... 78 9.2.1 CTXXPATH索引の設定 ... 78 9.2.2 CONTEXT索引の設定 ... 80

(4)

1 はじめに

本書では、Oracle Database 10g を使用して、XML データを扱う方法を説明します。 Oracle Database 10g の Database Configuration Assistant (DBCA) を利用したデフ ォルトの設定によるデータベース作成では、Oracle XML DB コンポーネントも含まれて います。他社の XML データベース製品のように、XML データベース専用のサーバや、 データベースを新規に作成する必要はありません。 本書は、XMLの基本を理解しており、Oracle XML DBを使ったXMLアプリケーション を初めて構築するエンジニアを対象にしており、実際にSQL*Plusを使ってXMLデータに アクセス1をすることでOracle XML DBの理解を深めることを目的とします。Oracle

XML DB の 基 本 的 な 概 念 に つ い て は 、 OTN Japan ( Oracle Technology Network Japan) からダウンロード可能なマニュアルや技術資料等を参照してください。 Oracle XML DB のマニュアル 『Oracle XML DB 開発者ガイド 10g リリース 2(10.2)』 http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/index.htm XML Technology Center 初心者、中級もしくは上級のXML ユーザーに関わらず、あらゆる XML に関連する アプリケーションを構築するための最新情報を提供しています。 http://otn.oracle.co.jp/tech/xml/index.html 1 本ドキュメントのスクリプトは全てOracle Database 10gリリース 2 (10.2)で実行 したものを掲載しております。

(5)

2 XML 文書の格納

Oracle XML DB では、XML 専用のデータ型として XMLType 型が用意されています。 XMLType 型は、通常のリレーショナル表の列データ型として利用することが可能です。 また、XMLType 型はオブジェクト型の 1 つであるため、XMLType 型を利用してオブジ ェ ク ト 表 を 作 成 す る こ と も で き ま す 。XMLType 型を利用したオブジェクト表は、 XMLType 表と呼ばれます。 1.XMLType 表 オブジェクト表の1つで XMLType 列を1つしか持たない表です。ただし、下記 の XMLType 列を含んだ表とは異なり、問合せ時などに列名を明示する必要がな いという特徴を持っています。 図 2-1 XMLType 表 2.XMLType 列を含んだ表 通常のリレーショナル表で、その表に 1 つまたは複数の XMLType 列を持ってい ます。 XML 文書 XMLType 表 XML 文書 リレーショナル表 XML 文書 図 2-2 XMLType 列

(6)

XMLType データ型は、既存の CLOB 型や VARCHAR2 型と比較すると以下のメリッ トがあります。 XML文書の整形式2チェックが自動的に行われる XPath に準じた文法を利用して XML 文書の特定の部分にアクセスできる XML 文書に対しての検索、取り出し、更新、スタイルシートの適用などを行う SQL 関数を使用できる 2 整形式のXML文書とは、XML宣言で宣言されたXMLバージョンの構文に準拠してい るXML文書です。整形式チェックには、ルート要素が単一か、タグが適切にネストされて いるかなどが含まれます。

(7)

2.1 XMLType 記憶域

Oracle XML DB では、XML 文書を表や列に格納する際、業務要件に合わせて XMLType 記憶域を選択する必要があります。 XMLType記憶域の選択 非構造化記憶域: LOB ベースの記憶域では、スペース文字の保持を含むテキスト(XML 文書) の完全な再現性が保証されます。これは、XML 文書を CLOB 値として格納し て取り出したときにデータが損失しないことを意味します。データの整合 性は高く、XML ツリーへ戻すときの処理負荷は低くなります。 表 表AA 列 列11 1 列 列22 ((XXMMLLTTyyppee デデーータタ型型)) <?xml version="1.0" encoding="EUC-JP"?> <DayEntry> <Date>2006-02-26</Date> <Entries> <Entry> <EntryId>abc123</EntryId> <Created>2006-03-01T08:02:03</Created> <Title>Oracle OpenWorld</Title> <Content>実施中</Content> <EntryId> ・・・ ・・・ </Entry> </Entries> </DayEntry> 図2-3 非構造化記憶域 非構造化記憶域の XMLType 型では、XML 文書を単純なキャラクタ・ストリン グとして(内部的には CLOB 型で)保持します。

(8)

構造化記憶域: 構造化記憶域では、スペース文字の情報は失われますが、XML DOM再現性3 が保持され、SQL問合せの実行性およびパフォーマンスが向上し、XML要素 の部分更新が高速になります。 図2-4 構造化記憶域 XML 文書を構成している各 XML 要素(内容や属性)を SQL オブジェクトに マッピングして格納します。マッピング処理は、予め登録された XML スキーマ に基づいて自動的に行われます。 スキーマ注釈メカニズム(後述)を使用することにより、コレクション4を外 部のXMLType表に格納することが可能です。この作業によりコレクションに索引 を作成することが可能になります。 3 タグ外のインデント文字、空白文字などを除いたタグ構造やコンテンツが同一である ことを保証する特性を指します。 4 XML文書の同一階層内で複数回出現する要素を指します。 Entry Entriesnnn_T Date (DATE) DayEntrynnn_T 列 列22 ((XXMMLLTTyyppee デーデータ型タ型)) 表 表AA 列 列11 abc123 2006-03-01 2006-02-26 1 外 外部部XXMMLLTTyyppee 表表 def456 2006-03-02 EntryId (VARCHAR2) Created (TIMESTAMP) Entrynnn_T 2006-03-03 2

(9)

半構造化記憶域: 半構造化記憶域は特殊な構造化記憶域で、XML データの一部が構造化され た形式に分割され、残りのデータが CLOB 値として格納されます。構造化記 憶域のコレクション部分が XMLType 型の CLOB 値として格納されます。 XMLType 記憶域は以下のいずれかのタイプに分類されます。 図 2-5 XMLType 記憶域

(10)

非構造化記憶域 構造化記憶域 XML 文書一括 登録時間 短い 非構造化記憶域に比べると長い 柔軟性 XMLType 列または表に格納可能な XML 文書の構造で、最大限の柔軟 性を実現できる 柔軟性は制限される。XML スキー マに準拠する文書のみが XMLType 表または列に格納される。XML ス キーマを変更すると、データのア ンロードおよび再ロードが必要に なる XML 再現性 DOM 再現性が提供される。元の XML 文書がバイト単位で保持される DOM 再現性が提供される。ただ し、後続の新しい行、タグ間のス ペース文字、および一部のデー タ・フォーマットは失われる 更新操作 XML 文書の一部を更新する場合で も、文書全体をディスクに書き出 す 多くの更新処理は、XPath リライ ト(後述)を使用して実行される ため、要素の部分更新が可能。応 答時間が大幅に短縮され、スルー プットが増大する XPath ベース の問合せ XPath 操作は、XML データをメモリ ー上にツリー構造に展開して処理 するため、構造の複雑な XML 文書 を大量に処理する用途には不向き XPath 操作は XPath リライトを使 用して評価するので、パフォーマ ンスが大幅に向上する(特に大規 模なコレクションの場合) SQL 制約 使用不可 使用可能 索引 テキスト索引、ファンクション索 引 B ツリー索引、テキスト索引、フ ァンクション索引 メモリー管 理の最適化 最適化処理されない 最適化処理される 表 2-6 構造化記憶域と非構造化記憶域の特徴

(11)

索引名 メリット デメリット 非構造化 記憶域 構造化 記憶域 B ツリー 特定の要素に対する 検索が非常に高速 コレクションには設 定できない 利用不可 利用可 能 ファンクション 特定の要素に対する 検索が非常に高速 コレクションには設 定できない 利用可能 利用可 能 CTXXPATH コレクションにも設 定可能 索引作成時に要素を 特定する必要が無い - 利用可能 利用可 能 CONTEXT コレクションにも設 定可能 XML ツリー構造を意 識した全文検索が可 能 索引作成時に要素を 特定する必要が無い - 利用可能 利用可 能 ビットマップ 特定の要素で、種類 の少ないデータに対 する検索が非常に高 速 - 利用可能 利用可 能 表 2-7 利用可能な索引

(12)

2.2 構築手順

構造化記憶域と非構造化記憶域では、XML 文書を格納する XMLType 型の表や 列の作成方法が異なります。構造化記憶域を使用するには XML スキーマの作成 および登録が必要です。 手順 非構造化記憶域 構造化記憶域 #1 ※ XML スキーマの作成・登録 #2 表の作成 表の作成 #3 XML 文書の登録 XML 文書の登録 #4 XML 文書の確認 XML 文書の確認 表 2-8 構築手順 ※ 非構造化記憶域で作成した表にも XML スキーマを使用できますが、 ここでは省略します。 以下の XML 文書を例に説明します。 <?xml version="1.0" encoding="EUC-JP"?> <申込 NO="000123"> <契約者>オラクル太郎</契約者> <契約日>2005-12-25</契約日> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス> </申込> リスト 2-9 XML 文書例

(13)

2.2.1 非構造化記憶域

非構造化記憶域では、渡される XML 文書が整形式でありさえすれば、どんな 構造の文書でも登録できます。

#2. 表の作成

XMLType 表の場合

SQL> CREATE TABLE step1 OF XMLTYPE

2 XMLType STORE AS CLOB;

リスト 2-10 XMLType 表の作成

リスト 2-10 より、XML文書は一つの擬似列OBJECT_VALUE5に格納されます。

XMLType 列を含んだ表の場合 SQL> CREATE TABLE step1b

2 (id NUMBER primary key, 3 xml XMLType) 4 XMLType COLUMN xml 5 STORE AS CLOB; リスト 2-11 XMLType 列を含んだ表の作成 リスト 2-11 より、XML 文書は XML という名前の列(名前は任意に設定可 能)に格納されます。 #3. XML文書の登録 XMLType 表の場合 SQL> INSERT INTO step1

2 VALUES(XMLType('<?xmlversion="1.0"encoding="EUC-JP"?> 3 <申込 NO="000123"> 4 <契約者>オラクル太郎</契約者> 5 <契約日>2005-12-25</契約日> 6 <サービス CODE="G2456"> 7 <サービス名>Grid 提案サポート</サービス名> 5 XMLType表は列を持たないので、擬似列であるOBJECT_VALUEを指定します (OBJECT_VALUEは、Oracle Database 10gリリース 1 より前のリリースで使用されて いたvalue()およびSYS_NC_ROWINFO$ を利用した別名に換わるもので同様の意味を 持ちます)。

(14)

8 <開始日>2006-01-23</開始日> 9 <終了日>2007-05-23</終了日> 10 </サービス> 11 <サービス CODE="X4332"> 12 <サービス名>XMLDB サポート</サービス名> 13 <開始日>2005-11-03</開始日> 14 <終了日>2007-10-30</終了日> 15 </サービス> 16 </申込>')); リスト 2-12 XMLType 表への XML 文書の登録 XMLType 列を含んだ表の場合

SQL> INSERT INTO step1b(id,xml)

2 VALUES(1, XMLType('<?xml version="1.0" encoding="EUC-JP"?>

3 <申込 NO="000123"> 4 <契約者>オラクル太郎</契約者> 5 <契約日>2005-12-25</契約日> 6 <サービス CODE="G2456"> 7 <サービス名>Grid 提案サポート</サービス名> 8 <開始日>2006-01-23</開始日> 9 <終了日>2007-05-23</終了日> 10 </サービス> 11 <サービス CODE="X4332"> 12 <サービス名>XMLDB サポート</サービス名> 13 <開始日>2005-11-03</開始日> 14 <終了日>2007-10-30</終了日> 15 </サービス> 16 </申込>')); リスト 2-13 XMLType 列を含んだ表への XML 文書の登録 #4. XML文書の確認 XMLType 表の場合 SQL> SELECT * FROM step1; SYS_NC_ROWINFO$ --- <?xml version="1.0" encoding="EUC-JP"?> <申込 NO="000123"> <契約者>オラクル太郎</契約者> <契約日>2005-12-25</契約日> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス>

(15)

<サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス> </申込> リスト 2-14 XML 文書の確認 XMLType 列を含んだ表の場合 SQL> select * from step1b; ID --- XML --- 1 <?xml version="1.0" encoding="EUC-JP"?> <申込 NO="000123"> <契約者>オラクル太郎</契約者> <契約日>2005-12-25</契約日> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス> </申込> リスト 2-15 XML 文書の確認

(16)

2.2.2 構造化記憶域 構造化記憶域を使用するには、XML ツリーの構造を決定付ける XML スキーマ ファイルの作成と、Oracle XML DB への登録作業が必須です。 #1. XMLスキーマの作成・登録 1. 対象名前空間の名称設定 XML 名前空間とは、URI 参照(RFC-2396)によって識別され、XML 文書内 で要素型および属性名として使用される名前の集合です。名前空間を使って管理 することにより、他の名前空間に属する内容や属性も参照可能になるので、それ ぞれの名前空間を識別しやすい名称に設定することをお勧めします。ここでは以 下のように定義します。 so.xsd の名前空間: http://www.oracle.com/so.xsd 2. XML スキーマ・ファイルの作成 W3C(http://www.w3.org/)の規約に基づいて XML スキーマを作成します。こ れは XML 文書の論理設計に相当するもので、XML ツリー構造における様々な定 義を行います。ここでは、GUI 統合開発ツールの Oracle JDeveloper 10g(10.1.3) を使います。

(17)

スキーマ・コンポーネント・パレットから該当するアイコンをドラッグ&ドロ ップして、XML スキーマのツリー構造をグラフィカルに設計していきます。 Oracle JDeveloper 10g を使うと、ほんの数分で文法的に正しい XML スキーマ・ ファイルを完成させることができます。 ソース・タグをクリックすることで、XML スキーマのコードが作成されてい ることが確認できます。

Oracle JDeveloper 10g から直接 XML スキーマを Oracle Database に登録すること

も で き ま す が 、 こ こ で は 練 習 を 兼 ね て 、

DBMS_XMLSCHMEA.REGISTERSCHEMAプロシージャを使って登録します。

DECLARE

doc clob := '<xsd:schema ・・・・・・・・・ ・・・・・・・・・・・・ </xsd:schema>'; BEGIN dbms_xmlschema.registerSchema( schemaURL => 'http://www.oracle.com/so.xsd', ここに XML スキー マコードを記述しま す。 図 2-17 JDeveloper 10g による XML スキーマ設計画面2

(18)

schemaDoc => doc); END;

/

リスト 2-18 REGISTERSCHEMA の使い方 SQL> DECLARE

2 doc clob := '<xsd:schema

3 xmlns:xsd="http://www.w3.org/2001/XMLSchema"

4 xmlns:kd="http://www.oracle.com/so.xsd"

5 xmlns:xdb="http://xmlns.oracle.com/xdb"

6 targetNamespace="http://www.oracle.com/so.xsd"

7 elementFormDefault="qualified">

8 <xsd:element name="申込" type="kd:契約タイプ"/>

9 <xsd:complexType name="契約タイプ">

10 <xsd:sequence>

11 <xsd:element name="契約者" type="xsd:string"/>

12 <xsd:element name="契約日" type="xsd:date"/>

13 <xsd:element maxOccurs="unbounded" name="サービス" type="kd:サービスタイプ"/>

14 </xsd:sequence>

15 <xsd:attribute name="NO" type="xsd:string"/>

16 </xsd:complexType>

17 <xsd:complexType name="サービスタイプ">

18 <xsd:sequence>

19 <xsd:element name="サービス名" type="xsd:string"/>

20 <xsd:element name="開始日" type="xsd:date"/>

21 <xsd:element name="終了日" type="xsd:date"/>

22 </xsd:sequence>

23 <xsd:attribute name="CODE" type="xsd:string"/>

24 </xsd:complexType> 25 </xsd:schema>'; 26 BEGIN 27 dbms_xmlschema.registerSchema( 28 schemaURL => 'http://www.oracle.com/so.xsd', 29 schemaDoc => doc, 30 gentypes => true, 31 gentables => false); 32 END; 33 / リスト 2-19 XML スキーマの登録スクリプト XML ス キ ー マ を 削 除 す る と き は 、 DBMS_XMLSCHEMA.DELETESCHEMA プロシージャを実行します。 XML スキーマの登録をUSER_XML_SCHEMASビューで確認します。

(19)

SCHEMA_URL --- http://www.oracle.com/so.xsd リスト 2-20 XML スキーマの確認 #2. 表の作成 XMLType 表の場合

SQL> CREATE TABLE step2 OF XMLTYPE

2 XMLSchema "http://www.oracle.com/so.xsd" 3 ELEMENT "申込"; リスト 2-21 XMLType 表の作成 リスト 2-21 より、XML 文書は一つの擬似列 OBJECT_VALUE に格納されます。 表の作成時に対象となる名前空間(XMLSchema 句)とルート要素(ELEMENT 句)を指定することにより XML スキーマを一意に識別します。 XMLType 表を作成するときに限り、後述するスキーマ注釈の’defaultTable’で表 名 を 指 定 し て DBMS_XMLSCHEMA.REGISTERSCHEMA プ ロ シ ー ジ ャ の’gentables’パラメータを’true’にして実行することにより、CREATE TABLE 文に よる作成をスキップすることができます。 XMLType 列を含んだ表の場合 SQL> CREATE TABLE step2b 2 (id NUMBER primary key, 3 xml XMLType) 4 XMLType COLUMN xml 5 XMLSchema "http://www.oracle.com/so.xsd" 6 ELEMENT "申込"; リスト 2-22 XMLType 表の作成 リスト 2-22 より、XML 文書は XML という名前の列(名前は任意に設定可 能)に格納されます。 #3. XML文書の登録 XML スキーマに基づいた表に XML 文書を登録するには、名前空間情報(太 字)をルート属性に記述します。

(20)

XMLType 表の場合 SQL> INSERT INTO step2

2 VALUES(XMLTYPE('<?xml version="1.0" encoding="EUC-JP"?>

3 <申込 xmlns="http://www.oracle.com/so.xsd" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://www.oracle.com/so.xsd 6 http://www.oracle.com/so.xsd" NO="000123"> 7 <契約者>オラクル太郎</契約者> 8 <契約日>2005-12-25</契約日> 9 <サービス CODE="G2456"> 10 <サービス名>Grid 提案サポート</サービス名> 11 <開始日>2006-01-23</開始日> 12 <終了日>2007-05-23</終了日> 13 </サービス> 14 <サービス CODE="X4332"> 15 <サービス名>XMLDB サポート</サービス名> 16 <開始日>2005-11-03</開始日> 17 <終了日>2007-10-30</終了日> 18 </サービス> 19 </申込>')); リスト 2-23 XML 文書の登録例 XMLType 列を含んだ表の場合

SQL> INSERT INTO step2b(id, xml)

2 VALUES(1, XMLTYPE('<?xml version="1.0" encoding="EUC-JP"?> 3 <申込 xmlns="http://www.oracle.com/so.xsd" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://www.oracle.com/so.xsd 6 http://www.oracle.com/so.xsd" NO="000123"> 7 <契約者>オラクル太郎</契約者> 8 <契約日>2005-12-25</契約日> 9 <サービス CODE="G2456"> 10 <サービス名>Grid 提案サポート</サービス名> 11 <開始日>2006-01-23</開始日> 12 <終了日>2007-05-23</終了日> 13 </サービス> 14 <サービス CODE="X4332"> 15 <サービス名>XMLDB サポート</サービス名> 16 <開始日>2005-11-03</開始日> 17 <終了日>2007-10-30</終了日> 18 </サービス> 19 </申込>')); リスト 2-24 XML 文書の登録例

(21)

#4. XML文書の確認

XMLType 表の場合

SQL> select * from step2; SYS_NC_ROWINFO$ --- <?xml version="1.0" encoding="EUC-JP"?> <申込 xmlns="http://www.oracle.com/so.xsd" xmlns:xsi="http://www.w3.org/2001/XML Schema-instance" xsi:schemaLocation="http://www.oracle.com/so.xsd http://www.oracle.com/so.xsd" NO="000123"> <契約者>オラクル太郎</契約者> <契約日>2005-12-25</契約日> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス> </申込> リスト 2-25 XML 文書の確認 XMLType 列を含んだ表の場合

SQL> select * from step2b; ID --- XML --- 1 <?xml version="1.0" encoding="EUC-JP"?> <申込 xmlns="http://www.oracle.com/so.xsd" xmlns:xsi="http://www.w3.org/2001/XML Schema-instance" xsi:schemaLocation="http://www.oracle.com/so.xsd http://www.oracle.com/so.xsd" NO="000123"> <契約者>オラクル太郎</契約者> <契約日>2005-12-25</契約日> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名>

(22)

<開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス>

</申込>

(23)

3 XML 文書の操作

Oracle XML DB を利用することで、格納されている XML 文書の全体や特定の要素に

対してINSERT、UPDATE、DELETE 処理を実行できます。検索においては、SQL に加

えてXQuery による問合せも Oracle Database 10g リリース 2 から利用できます。

3.1 SQL/XML 関数

XMLType 型の要素(内容や属性)にアクセスするには、以下の SQL 関数を使 います。 3.1.1 extract 関数 XML フラグメントを含む XMLType 文書を戻します。 3.1.2 extractValue 関数 XMLType 文書と、要素セットをターゲットとする XPath 式をパラメータとし て取ります。この関数は、XMLType 文書の XPath 評価の結果に対応するスカ ラー値を戻します。 3.1.3 existsNode 関数 指定された XPath 解析が少なくとも 1 つの XML 要素またはテキスト要素を 参照しているかどうかを調べます。参照している場合、この関数は 1 を戻し ます。参照していない場合は 0(ゼロ)を戻します。 構造化記憶域と非構造化記憶域の記述の違い 構造化記憶域で対象名前空間を使用している場合、namespace パラメータが必 要です。 非構造化記憶域の場合 SQL> SELECT extract(object_value, '/申込/契約者') 2 FROM step1; リスト 3-1 namespace を必要としない検索 構造化記憶域の場合 SQL> SELECT extract(object_value, '/申込 契約者', / 2 'xmlns="http://www.oracle.com/so.xsd"') 3 FROM step2; リスト 3-2 namespace を必要とする検索

(24)

3.2 検索

Oracle XML DB に格納された複数の XML 文書に対し、SQL と XQuery を使っ て簡単に検索できます。 SQL*Plus のデフォルト表示では、大きなサイズの XML 文書全体を表示できな いため、以下の設定をセッションごとに行います。 SQL> SET PAGES 10000 SQL> SET LONG 10000 リスト 3-3 SQL*Plus の表示設定 3.2.1 SQL を使った検索 extract 関数と extractValue 関数を使用して、XML 文書を検索します。

SQL> SELECT extract(object_value, '/申込/契約者') 2 FROM step1;

EXTRACT(OBJECT_VALUE,'/申込/契約者')

--- <契約者>オラクル太郎</契約者>

リスト 3-4 要素の検索例

SQL> SELECT extractValue(object_value, '/申込/契約者') 2 FROM step1; EXTRACTVALUE(OBJECT_VALUE,'/申込/契約者') --- オラクル太郎 リスト 3-5 要素内容の検索例 コレクションの検索 '/申込/サービス/@CODE'が複数回出現する場合、extractValue 関数を利用する と次のようなエラーが表示されます。

SQL> SELECT extractValue(object_value, '/申込/サービス/@CODE') 2 FROM step1;

ORA-19025: EXTRACTVALUE は 1 要素のみの値を戻します

(25)

1 要素のみの結果を返すように位置を指定するとエラーがなくなります。

SQL> SELECT extractValue(object_value, '/申込/サービス[1]/@CODE') 2 FROM step1; EXTRACTVALUE(OBJECT_VALUE,'/申込/サービス[1]/@CODE') --- G2456 リスト 3-7 XPath の位置を使った検索 複数の結果を一覧として表示したい場合には、どうすればよいでしょうか? 3.2.1.1 Table 関数と XMLSequence 関数を組み合わせた検索 XMLSequence 関数は XML フラグメントを含む XMLType 値に対して SQL 操作 を実行可能にする SQL 関数です。これを Table 関数と組み合わせて、XMLType オブジェクトのコレクションを仮想表に変換して表示させます。 考え方 Step1: ループを実行したい深さまで XPath 式で記述

Step2: Step1 ループを起点として、取り出したい内容や属性を XPath 式で指定

SQL> SELECT extractValue(value(s), '/サービス/@CODE')

2 FROM step1, 3 Table(XMLSequence(extract(object_value, '/申込/サービス'))) s; EXTRACTVALUE(VALUE(S),'/サービス/@CODE') --- G2456 Step1 Step2 X4332 リスト 3-8 複数属性をレコードとして返す検索 コレクションの問合せに対して、要素の属性を一覧表示できました。

(26)

3.2.2 XQueryを使った検索

Oracle Database 10g リリース 2 より XQuery が使えるようになりました。 XQuery は、XML 専用の問合せ言語として開発されたため、複雑な構造を持った XML 文書の反復処理や条件分岐処理を得意とします。さらに XSLT に相当する文 書整形機能も実装しているため、結果セットを HTML 形式等に出力することも可 能です。実際に XQuery を使って検索します。

3.2.2.1 SQL*Plus の XQuery 検索

XQuery 式の前に SQL*Plus コマンドの XQUERY を付け、式の後にスラッシュ (/)を単独で付けることにより、クライアント側の SQL*Plus コマンドラインか ら XQuery 式を直接入力することで、サーバ上のデータに問い合わせることがで きます。 SQL> xquery 2 for $i in ora:view("STEP1")/申込 3 let $cd := $i/@NO 4 where $i/サービス[@CODE="G2456"] 5 return <Result> 6 {if ($cd eq "000123") then 7 <登録者>{$i/契約者/text()}</登録者> 8 else 9 <登録者>該当者無し</登録者>} 10 </Result> 11 / ここに XQuery のスクリプト を記述します。 リスト 3-9 XQuery コマンドを使った検索 Result Sequence --- <Result> <登録者>オラクル太郎</登録者> </Result> リスト 3-10 検索結果 XQuery 表現内で ora:view 関数を使うことにより、リレーショナル表やビュー に対して、XML 文書と同じように問い合わせることができます。 例として、SCOTT ユーザーの EMP 表(リレーショナル表)に対して、問合せ を実行します。 SQL> xquery 2 for $i in ora:view("SCOTT","EMP")/ROW

(27)

3 where $i/SAL > 2000

4 and $i/HIREDATE > xs:date("1986-12-01")

5 return $i 6 / Result Sequence --- <ROW> <EMPNO>7788</EMPNO> <ENAME>SCOTT</ENAME> <JOB>ANALYST</JOB> <MGR>7566</MGR> <HIREDATE>1987-04-19</HIREDATE> <SAL>3000</SAL> <DEPTNO>20</DEPTNO> </ROW> リスト 3-11 リレーショナル表に対する XQuery 検索 3.2.2.2 SQL 関数の XQuery 検索

XMLQuery 関数および XMLTable 関数は、SQL から XQuery を利用するための インタフェースとして定義されています。これらの関数を使用することにより、 リレーショナル・データを使用した XML データの構成、XML 同様のリレーショ ナル・データに対する問合せ、および XML データからのリレーショナル・デー タの構成が可能になります。 3.2.2.2.1 XMLQuery 関数 SQL関数XMLQueryを使用して、XMLデータの構成や問合せができます。この 関数は引数としてXQuery式、リテラル、そしてオプションで、XQueryコンテキス ト項目6をSQL式として取ります。関数はXQuery式の評価結果をXMLType文書と して戻します。

SQL> SELECT XMLQuery('for $i in ./申込

2 where $i/サービス[1]/@CODE eq "G2456" 3 return <登録者>{$i/契約者/text()}</登録者>' 4 PASSING value(s) RETURNING CONTENT) "XMLQueryResult" 5 FROM STEP1 s; XMLQueryResult --- <登録者>オラクル太郎</登録者> リスト 3-12 XMLQuery を使った検索1 6 暗黙的に参照できるXML要素を指します。

(28)

構造化記憶域の XMLType 表や XMLType 列を含んだ表で名前空間を指定する場 合、以下のように記述します。

SQL> SELECT XMLQuery('declare namespace

2 x="http://www.oracle.com/so.xsd"

3 ;for $i in ./x:申込

4 where $i/x:サービス[1]/@CODE eq "G2456"

5 return <登録者>{$i/x:契約者/text()}</登録者>'

6 PASSING value(s) RETURNING CONTENT) "XMLQueryResult" 7 FROM STEP2 s;

リスト 3-13 XMLQuery を使った検索2

Oracle Databaseでは、SQLの条件指定などでバインド変数7を使用することがで

きますが、XQueryでも以下のように使用できます。 SQL> variable EMPNO number;

SQL> begin 2 :EMPNO := 7934; 3 end; 4 / SQL> print :empno EMPNO --- 7934 SQL> SELECT 2 XMLQuery('for $i in ora:view("SCOTT","EMP")/ROW 3 where $i/EMPNO = $EMPNO

4 return $i'

5 PASSING :EMPNO AS "EMPNO" RETURNING CONTENT) 6 FROM dual; リスト 3-14 バインド変数を使った検索 7 バインド変数は、SQL*Plusで作成し、PL/SQL またはSQLで参照する変数です。 SQL*Plusでバインド変数を作成した場合、その変数はPL/SQLサブ・プログラムの中で宣 言した変数と同様に使用でき、SQL*Plusからもアクセスできます。バインド変数は、リ ターン・コードの格納、PL/SQLサブ・プログラムのデバッグなどに使用できます。

(29)

3.2.2.2.2 XMLTable 関数 XMLTable 関数は、XQuery 式の評価結果を、新しい仮想表のリレーショナル列 にマッピングします。その仮想表は、SQL を使用した(join 式など)問い合せな どを行うことが可能です。SQL 文の FROM 句で XMLTable 関数を指定します。 SQL> SELECT xtab.NAME 2 FROM STEP1 s, 3 XMLTable('for $i in ./申込 4 where $i/サービス[1]/@CODE eq "G2456" 5 return <登録者>{$i/契約者/text()}</登録者>' 6 PASSING value(s)

7 COLUMNS NAME varchar2(30) PATH '/登録者/text()') xtab; NAME --- オラクル太郎 リスト 3-15 XMLTable 関数を使った検索1 構造化記憶域の XMLType 表や XMLType 列を含んだ表で名前空間を指定する場 合、以下のように記述します。 SQL> SELECT xtab.NAME 2 FROM STEP2 s,

3 XMLTable('declare namespace x="http://www.oracle.com/so.xsd" 4 ;for $i in ./x:申込

5 where $i/x:サービス[1]/@CODE eq "G2456"

6 return <登録者>{$i/x:契約者/text()}</登録者>'

7 PASSING value(s)

8 COLUMNS NAME varchar2(30) PATH '/登録者/text()') xtab; リスト 3-16 XMLTable 関数を使った検索2

XMLTable 式で同一の名前空間が使用されている場合、以下の記述も可能です。

SQL> SELECT xtab.NAME 2 FROM STEP2 s,

3 XMLTable(XMLNAMESPACES(DEFAULT 'http://www.oracle.com/so.xsd'),

4 'for $i in ./申込

5 where $i/サービス[1]/@CODE eq "G2456" 6 return <登録者>{$i/契約者/text()}</登録者>' 7 PASSING value(s)

8 COLUMNS NAME varchar2(30) PATH '/登録者/text()') xtab; リスト 3-17 XMLTable 関数を使った検索3

(30)

3.3 更新

Oracle XML DB では、XML データを付加的に更新する(周囲の XML 文書全部 を置き換えずに XML データを置換、挿入または削除する)ために使用できる SQL 関数が実装されています。 SQL 関数名 機能 updateXML 任意の種類の XML 要素を置換 insertChildXML XML の要素または属性を、指定された要素の子として挿入 insertXMLbefore 任意の種類の XML 要素を、指定された要素(属性以外)の直前に 挿入 appendChildXML 任意の種類の XML 要素を、指定された要素の最後の子要素として 挿入 deleteXML8 任意の種類の XML 要素を削除 表 3-18 更新用 SQL 関数 表 3-18 の SQL 関数は、XML スキーマに基づく XML 文書に対しても、XML スキーマに基づかない XML 文書に対しても使用できます。 Oracle XML DB では、XPath 式を利用してシンプルに XML 文書を更新できま す。 3.3.1 全体更新 全体更新は UPDATE だけで実行します。 SQL> UPDATE STEP1

2 SET OBJECT_VALUE = XMLTYPE('<申込 NO="000345">全体更新</申込>') 3 WHERE extractValue(object_value, '/申込/@NO') = '000123';

リスト 3-19 UPDATE による全体更新の例

<申込 NO="000345">全体更新</申込>

リスト 3-20 更新データ確認

8 3.4 削除の項で説明します。

(31)

3.3.2 部分更新 部分更新は、UPDATE と表 3-18 にある SQL 関数との組み合わせで実行します。 3.3.2.1 updateXML SQL 関数 updateXML は、任意の種類の XML 要素を置換します。updateXML を使って"サービス"要素の内容を2つ同時に置換します。 SQL> UPDATE STEP1 2 SET OBJECT_VALUE = 3 updateXML(OBJECT_VALUE, 4 '//サービス[@CODE = "G2456"]/サービス名/text()','AS 提案サポート', 5 '//サービス[@CODE = "X4332"]/サービス名/text()','RAC 提案サポート') 6 WHERE extractValue(object_value, '/申込/@NO') = '000123';

リスト 3-21 updateXML 関数の例 <?xml version="1.0" encoding="EUC-JP"?> <申込 NO="000123"> <契約者>オラクル太郎</契約者> <契約日>2005-12-25</契約日> <サービス CODE="G2456"> <サービス名>AS 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <サービス CODE="X4332"> <サービス名>RAC 提案サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス> </申込> リスト 3-22 更新データ確認

(32)

3.3.2.2 insertChildXML SQL 関数 insertChildXML は、親の XML 要素の下に新しい子(同じ型の 1 つ以 上の要素、または単一の属性)を挿入します。insertChildXML を使って"サービス "要素の下に新しい子要素として追加の"サービス"要素を挿入します。 SQL> UPDATE step1 2 SET OBJECT_VALUE = 3 insertChildXML(OBJECT_VALUE, 4 '/申込', 5 'サービス', 6 XMLType('<サービス CODE="G7777"> 7 <サービス名>Enterprise Manager ラーニング</サービス名> 8 <開始日>2006-02-25</開始日> 9 <終了日>2007-03-24</終了日> 10 </サービス>')) 11 WHERE existsNode(OBJECT_VALUE,'/申込[@NO="000123"]') = 1; リスト 3-23 insertChildXML 関数の例 <?xmlversion ="1.0"encoding="EUC-JP"?> <申込 NO="000123"> <契約者>オラクル太郎</契約者> <契約日>2005-12-25</契約日> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス> <サービス CODE="G7777"> <サービス名>Enterprise Manager ラーニング</サービス名> <開始日>2006-02-25</開始日> <終了日>2007-03-24</終了日> </サービス> </申込> リスト 3-24 更新データ確認

(33)

3.3.2.3 insertXMLbefore SQL 関数 insertXMLbefore は、任意の種類の 1 つ以上の要素を、属性以外のタ ーゲット・要素の直前に挿入します。insertXMLbefore を使って"契約日"要素の直 前に"期間割引"要素を挿入します。 SQL> UPDATE step1 2 SET OBJECT_VALUE = 3 insertXMLbefore(OBJECT_VALUE, 4 '/申込/契約日', 5 XMLType('<期間割引>適用</期間割引>')) 6 WHERE existsNode(OBJECT_VALUE,'/申込[@NO="000123"]') = 1; リスト 3-25 insertXMLbefore 関数の例 <?xmlversion ="1.0"encoding="EUC-JP"?> <申込 NO="000123"> <契約者>オラクル太郎</契約者> <期間割引>適用</期間割引> <契約日>2005-12-25</契約日> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス> </申込> リスト 3-26 更新データ確認

(34)

3.3.2.4 appendChildXML SQL 関数 appendChildXML は、任意の種類の 1 つ以上のノードを、指定された 要素ノードの最後の子として挿入します。appendChildXML を使って"サービス"要 素の最後の子要素として"開催地"要素を挿入します。 SQL> UPDATE step1 2 SET OBJECT_VALUE = 3 appendChildXML(OBJECT_VALUE, 4 '/申込/サービス[2]', 5 XMLType('<開催地>渋谷</開催地>')) 6 WHERE existsNode(OBJECT_VALUE,'/申込[@NO="000123"]') = 1; リスト 3-27 appendChildXML 関数の例 <?xmlversion ="1.0"encoding="EUC-JP"?> <申込 NO="000123"> <契約者>オラクル太郎</契約者> <契約日>2005-12-25</契約日> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> <開催地>渋谷</開催地> </サービス> </申込> リスト 3-28 更新データ確認

(35)

3.4 削除

Oracle XML DB では、更新処理と同様に、XPath 式を利用してシンプルに XML 文書を削除することが可能です。全体削除と部分削除が可能で、全体削除は DELETE 文、部分削除は UPDATE 文で実行します。

3.4.1 全体削除

SQL> DELETE FROM STEP1

2 WHERE existsNode(object_value, '/申込[@NO="000123"]') = 1; リスト 3-29 全体削除 3.4.2 部分削除 部分削除は updateXML もしくは deleteXML で実行します。 3.4.2.1 updateXML SQL 関数 updateXML は、任意の種類の XML 要素を置換します。特定の要素を NULL 値に置換することによって要素内容を削除します。updateXML を使って" 契約日"要素を削除します。 SQL> UPDATE STEP1 2 SET OBJECT_VALUE =

3 updateXML(OBJECT_VALUE, '//契約日/text()', null)

4 WHERE extractValue(object_value, '/申込/@NO') = '000123'; リスト 3-30 部分削除 <?xmlversion ="1.0"encoding="EUC-JP"?> <申込 NO="000123"> <契約者>オラクル太郎</契約者> <契約日/> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> <開催地>渋谷</開催地> </サービス> </申込> リスト 3-31 削除データ確認

(36)

3.4.2.2 deleteXML SQL 関数 deleteXML は、任意の種類の XML 要素を削除します。deleteXML を 使って"契約日"要素を削除します。 SQL> UPDATE STEP1 2 SET OBJECT_VALUE = 3 deleteXML(OBJECT_VALUE, '//契約日')

4 WHERE extractValue(object_value, '/申込/@NO') = '000123'; リスト 3-32 deleteXML 関数の例 <?xmlversion ="1.0"encoding="EUC-JP"?> <申込 NO="000123"> <契約者>オラクル太郎</契約者> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス> </申込> リスト 3-33 削除データ確認 さらにサービスの 1 番目(CODE="G2456")をまとめて削除したい場合は以下 の SQL を実行します。 SQL> UPDATE STEP1 2 SET OBJECT_VALUE = 3 deleteXML(OBJECT_VALUE, '//サービス[1]')

4 WHERE extractValue(object_value, '/申込/@NO') = '000123'; リスト 3-34 deleteXML 関数の例 <?xmlversion ="1.0"encoding="EUC-JP"?> <申込 NO="000123"> <契約者>オラクル太郎</契約者> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス> "契約日"要素が削除 されました。

(37)

</申込>

(38)

3.5 索引の設定

Oracle XML DB では、通常のリレーショナル・データと同様に、自動的に索引 は設定されないので、必要に応じて CREATE INDEX 文で索引を作成します。 ここでは構造化記憶域の XMLType 表に B ツリー索引を作成する例を取り上げ ます。 索引は特定の要素(内容や属性)に設定するので、extractValue 関数を使います。 CONTEXT 索引と CTXXPATH 索引は XML 文書全体に対して作成する ので extractValue 関数による要素の指定は不要です。 ‘/申込/NO’属性に索引を作成する場合、以下のように記述します。

SQL> CREATE INDEX ix_step2 ON step2 s 2 (extractValue(value(s), 3 '/申込/@NO','xmlns="http://www.oracle.com/so.xsd"')); リスト 3-36 索引作成 次に検索実行時に索引が利用されていることを確認するために、実行計画を表 示します。 3.5.1 実行計画の表示設定 SQL の実行計画を確認する方法はいくつかありますが、ここでは一番シンプル な SQL*Plus の AUTOTRACE 機能を使用します。以下の手順で有効にします。 SQL> CONNECT SYS/パスワード as sysdba

SQL> @?/rdbms/admin/utlxplan SQL> @?/sqlplus/admin/plustrce SQL> GRANT plustrace TO ユーザー名; 初回のみ実行 SQL> CONNECT ユーザー名/パスワード SQL> SET AUTOTRACE ON リスト 3-37 AUTOTRACE 機能を有効にする

(39)

データの検索 要素を特定するために extractValue 関数を使用します。 SQL> SELECT extractValue(value(s), 2 '/申込/契約者','xmlns="http://www.oracle.com/so.xsd"') 3 FROM step2 s 4 WHERE extractValue(value(s), 5 '/申込/@NO','xmlns="http://www.oracle.com/so.xsd"')='000123'; EXTRACTVALUE(VALUE(S),'/申込/契約者 ','XMLNS="HTTP://WWW.ORACLE.COM/SO.XSD"') --- オラクル太郎 リスト 3-38 XML 文書の検索 問合せの結果に続いて実行計画(Execution Plan)を確認します。 --- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --- | 0 | SELECT STATEMENT | | 1 | 46 | 2 (0)| 00:00:01 | |* 1 | TABLE ACCESS BY INDEX ROWID| STEP2 | 1 | 46 | 2 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | IX_STEP2 | 1 | | 1 (0)| 00:00:01 | ---

リスト 3-39 実行計画

Operation カラムにINDEX RANGE SCANと表示され、Name カラムに作成済み

の索引名 IX_STEP2 が表示されていることから、検索実行時に索引を使用してい

(40)

4 XMLType 記憶域別テクニック

XMLType 記憶域の特徴を活用して、XML 文書を効率よく取り出す方法を学習します。

4.1 リレーショナル列の活用

非構造化記憶域を使った表で、複数要素の検索パフォーマンスを上げたい場合 は、XMLType 列を含んだ表で作成し、あらかじめ検索要素をリレーショナル列の データとして格納しておき、その列データを検索する方法があります。 ケース1:良くない例

SELECT 句で extract 関数,extractValue 関数を用いて、XMLType 表から複数の 要素を取り出す。 図 4-1 ケース2:良い例 XMLType 列を含んだリレーショナル表を用いて、あらかじめ取り出すデータをリ レーショナル列に格納しておき、SELECT 句で列として取り出す。 図 4-2 リレーショナル表 XMLType 表 SELECT extract(value(t), ‘/…’), extract(value(t), ‘/…’), …… extract(value(t), ‘/…’) FROM PO t WHERE existsNode(value(t),’/…’)=1; SELECT EMP_ID, S_NAME, …… XML 解析処理が不要 WHERE existsNode(value(t),’/…’)=1; FROM PO t CU_NO

(41)

extract 関数や extractValue 関数では、関数を記載した回数分、XML 構造を解析 する処理が実行されます。これがケース1の良くない例になります。解析処理の 回数を減らすことで検索応答時間を短縮することができるので、あらかじめ対象 要素をリレーショナル列に格納しておき、その列に対して検索を行う方法がケー ス2になります。

(42)

4.2 XML 文書全体の取得

Oracle XML DB のメリットは、複雑な構造を持ったデータ群から、特定要素の 内容や属性を効率良く取り出せるところにあります。構造化記憶域を選択するこ とで、必要な情報を高速に取り出すことができます。しかし、XML 文書の一部 ではなく、XML 文書の全体を取得する場合(Web サービス連携など)では非構 造化記憶域を使用した XMLType 表や XMLType 列を含んだ表を選択します。 SELECT extract(value(t), ‘/…’), extract(value(t), ‘/…’), …….. extract(value(t), ‘/…’) FROM PO t WHERE existsNode(value(t),’/…’)=1; SELECT value(t).getClobVal() リスト 4-4 全体の取得 リスト 4-3 一部の取得 FROM PO t WHERE existsNode(value(t),’/…’)=1; 構造化記憶域の表では、抽出した SQL オブジェクトを XML ツリーに再構築す る際に共有メモリー内にキャッシュされている XML スキーマ情報と照らし合わ せて処理をするため、抽出する要素が非常に多い場合、処理時間が長くなります。 これに対し、非構造化記憶域の表では CLOB 値として抽出した後の XML ツリー の再構築処理が省かれる分、高速に処理できます。このように構造化記憶域にも 苦手なケースがあるので、状況に応じて非構造化記憶域の利用を検討します。 ^^^^^^^^^^ ^^^^^^^ ^^^^^^^ XML Schema Oracle XML DB XML 文書 XMLType 表 キャッシュ 図 4-5 要素全体取得時の XML ツリー再構築

(43)

4.3 スキーマ注釈の利用

Oracle XML DBでは、XMLスキーマの登録処理によって生成されるオブジェク トおよび表に影響を与える機能を提供しています。ここではスキーマ注釈メカニ ズム9を使用してコレクションを高速に検索できるように設計します。 スキーマ注釈を使用すると、次のものをオーバーライドできます。 表、SQL オブジェクトおよび SQL 属性のネーミング コレクションの管理方法 XML スキーマのデータ型と SQL のデータ型間のマッピング ここで使用するスキーマ注釈は以下です。 注釈名 機能 defaultTable XML 文書を格納する表の名前を設定します。 SQLInline true:埋込み属性(maxOccurs > 1 の場合はコレクション)として 表内に格納されます。

false:REF 値(maxOccurs>1 の場合は REF 値のコレクション)と して表内に格納されます。

表 4-6 スキーマ注釈抜粋

スキーマ注釈を記述した XML スキーマを登録します。 SQL> DECLARE

2 doc clob := '<xsd:schema

3 xmlns:xsd="http://www.w3.org/2001/XMLSchema" 4 xmlns:kd="http://www.oracle.com/so3.xsd" 5 xmlns:xdb="http://xmlns.oracle.com/xdb"

6 targetNamespace="http://www.oracle.com/so3.xsd" 7 elementFormDefault="qualified">

8 <xsd:element name="申込" type="kd:契約タイプ" /> 9 <xsd:complexType name="契約タイプ">

10 <xsd:sequence>

11 <xsd:element name="契約者" type="xsd:string"/> 12 <xsd:element name="契約日" type="xsd:date"/>

13 <xsd:element name="サービス" type="kd:サービスタイプ"

9 Oracle XML DB独自に定義される名前空間http://xmlns.oracle.com/xdbを利用して、 XML Schemaで宣言されるcomplexType、elementおよびattributeの定義に特別な属性を 追加できます。

(44)

14 maxOccurs="unbounded" xdb:SQLInline="false"

15 xdb:defaultTable="SERVICE_LINES"/> 16 </xsd:sequence>

17 <xsd:attribute name="NO" type="xsd:string"/> 18 </xsd:complexType>

19 <xsd:complexType name="サービスタイプ"> 20 <xsd:sequence>

21 <xsd:element name="サービス名" type="xsd:string"/> 22 <xsd:element name="開始日" type="xsd:date"/> 23 <xsd:element name="終了日" type="xsd:date"/> 24 </xsd:sequence>

25 <xsd:attribute name="CODE" type="xsd:string"/> 26 </xsd:complexType> 27 </xsd:schema>'; 28 BEGIN 29 dbms_xmlschema.registerSchema( 30 schemaURL => 'http://www.oracle.com/so3.xsd', 31 schemaDoc => doc, 32 gentypes => true, 33 gentables => true); 34 END; 35 / リスト 4-7 XML スキーマの登録スクリプト XML ス キ ー マ 定 義 で ス キ ー マ 注 釈 の xdb:SQLInline="false" と xdb:defaultTable="SERVICE_LINES"を記述します。 次 に 、 DBMS_XMLSCHEMA.REGISTERSCHEMA プ ロ シ ー ジ ャ の 引 数 で 、 gentables => trueを指定して XML スキーマを Oracle XML DB に登録することによ り、コレクションを外部 XMLType 表 SERVICE_LINES に作成できます。

表の作成

XMLType 表も XMLType 列を含んだ表も、XML スキーマ登録時に作成された 外部の XMLType 表 SERVICE_LINES を使用できます。

XMLType 表の場合

SQL> CREATE TABLE STEP3 OF XMLType

2 XMLSCHEMA "http://www.oracle.com/so3.xsd" 3 ELEMENT "申込";

リスト 4-8 XMLType 列を含んだ表の場合

SQL> CREATE TABLE STEP3b 2 (id NUMBER,

3 xml XMLType) 4 XMLTYPE COLUMN xml

(45)

6 ELEMENT "申込";

リスト 4-9

XML文書の登録

XMLType 表の場合 SQL> INSERT INTO step3

2 VALUES(XMLTYPE('<?xml version="1.0" encoding="EUC-JP"?> 3 <申込 xmlns="http://www.oracle.com/so3.xsd" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://www.oracle.com/so3.xsd 6 http://www.oracle.com/so3.xsd" NO="000123"> 7 <契約者>オラクル太郎</契約者> 8 <契約日>2005-12-25</契約日> 9 <サービス CODE="G2456"> 10 <サービス名>Grid 提案サポート</サービス名> 11 <開始日>2006-01-23</開始日> 12 <終了日>2007-05-23</終了日> 13 </サービス> 14 <サービス CODE="X4332"> 15 <サービス名>XMLDB サポート</サービス名> 16 <開始日>2005-11-03</開始日> 17 <終了日>2007-10-30</終了日> 18 </サービス> 19 </申込>')); リスト 4-10 XMLType 列を含んだ表の場合 SQL> INSERT INTO step3b

2 VALUES(1,XMLTYPE('<?xml version="1.0" encoding="EUC-JP"?> 3 <申込 xmlns="http://www.oracle.com/so3.xsd" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://www.oracle.com/so3.xsd 6 http://www.oracle.com/so3.xsd" 7 NO="000123"> 8 <契約者>オラクル太郎</契約者> 9 <契約日>2005-12-25</契約日> 10 <サービス CODE="G2456"> 11 <サービス名>Grid 提案サポート</サービス名> 12 <開始日>2006-01-23</開始日> 13 <終了日>2007-05-23</終了日> 14 </サービス> 15 <サービス CODE="X4332"> 16 <サービス名>XMLDB サポート</サービス名> 17 <開始日>2005-11-03</開始日>

(46)

18 <終了日>2007-10-30</終了日> 19 </サービス> 20 </申込>')); リスト 4-11 XML文書の確認 XMLType 表の場合

SQL> SELECT object_value FROM step3; SYS_NC_ROWINFO$ --- <?xml version="1.0" encoding="EUC-JP"?> <申込 xmlns="http://www.oracle.com/so3.xsd" xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation="http://www.oracle.com/so3.xsd http://www.oracle.com/so3.xsd" NO="000123"> <契約者>オラクル太郎</契約者> <契約日>2005-12-25</契約日> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス> </申込> SERVICE_LINES 表 の内容 リスト 4-12 コレクションの確認

SQL> SELECT object_value FROM SERVICE_LINES; SYS_NC_ROWINFO$ --- <?xml version="1.0" encoding="EUC-JP"?> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <?xml version="1.0" encoding="EUC-JP"?> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名>

(47)

<開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス>

リスト 4-13

XMLType 列を含んだ表の場合 SQL> SELECT xml FROM step3b; XML --- <?xml version="1.0" encoding="EUC-JP"?> <申込 xmlns="http://www.oracle.com/so3.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.oracle.com/so3.xsd http://www.oracle.com/so3.xsd" NO="000123"> <契約者>オラクル太郎</契約者> <契約日>2005-12-25</契約日> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日> </サービス> SERVICE_LINES 表 の内容 </申込> リスト 4-14 コレクションの確認

SQL> SELECT object_value FROM SERVICE_LINES; SYS_NC_ROWINFO$ --- <?xml version="1.0" encoding="EUC-JP"?> <サービス CODE="G2456"> <サービス名>Grid 提案サポート</サービス名> <開始日>2006-01-23</開始日> <終了日>2007-05-23</終了日> </サービス> <?xml version="1.0" encoding="EUC-JP"?> <サービス CODE="X4332"> <サービス名>XMLDB サポート</サービス名> <開始日>2005-11-03</開始日> <終了日>2007-10-30</終了日>

(48)

</サービス> リスト 4-15 例 え ば ’/申 込 /サ ー ビ ス /サ ー ビ ス 名 ’に 索 引 を 設 定 す る 場 合 、 XMLType 表 SERVICE_LINES に対して以下の索引を作成します。 Bツリー索引作成 XMLType 表、XMLType 列を含んだ表の場合 SQL> CREATE INDEX ix_sname ON SERVICE_LINES s 2 (extractValue(value(s),'/サービス/サービス名', 3 'xmlns="http://www.oracle.com/so3.xsd"')); リスト 4-16 B ツリー索引作成 検索結果と実行計画の確認 以下のコレクションに対する問合せを実行し、実行計画より索引 ix_sname が使 われていることを確認してください。 XMLType 表の場合 SQL> SELECT extractValue(value(t),'/サービス/サービス名', 2 'xmlns="http://www.oracle.com/so3.xsd"')

3 FROM step3 s, table(xmlsequence(extract(value(s),

4 '/申込/サービス','xmlns="http://www.oracle.com/so3.xsd"'))) t 5 WHERE extractValue(value(t), '/サービス/サービス名',

6 'xmlns="http://www.oracle.com/so3.xsd"')='XMLDB サポート'; リスト 4-17 索引を利用した問合せ

--- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --- | 0 | SELECT STATEMENT | | 4 | 15688 | 28 (0)| 00:00:01 | | 1 | NESTED LOOPS | | 4 | 15688 | 28 (0)| 00:00:01 | | 2 | MERGE JOIN CARTESIAN | | 1 | 3920 | 4 (0)| 00:00:01 | | 3 | TABLE ACCESS FULL | STEP3 | 1 | 1878 | 3 (0)| 00:00:01 | | 4 | BUFFER SORT | | 1 | 2042 | 1 (0)| 00:00:01 | |* 5 | TABLE ACCESS BY INDEX ROWID | SERVICE_LINES | 1 | 2042 | 1 (0)| 00:00:01 | |* 6 | INDEX RANGE SCAN | IX_SNAME | 1 | | 0 (0)| 00:00:01 | |* 7 | COLLECTION ITERATOR PICKLER FETCH| | | | | | ---

(49)

XMLType 列を含んだ表の場合

SQL> select extractValue(value(t),'/サービス/サービス名', 2 'xmlns="http://www.oracle.com/so3.xsd"')

3 from step3b, table(xmlsequence(extract(xml,

4 '/申込/サービス','xmlns="http://www.oracle.com/so3.xsd"'))) t 5 where extractValue(value(t), '/サービス/サービス名',

6 'xmlns="http://www.oracle.com/so3.xsd"')='XMLDB サポート'; リスト 4-19 索引を利用した問合せ

--- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --- | 0 | SELECT STATEMENT | | 4 | 15688 | 28 (0)| 00:00:01 | | 1 | NESTED LOOPS | | 4 | 15688 | 28 (0)| 00:00:01 | | 2 | MERGE JOIN CARTESIAN | | 1 | 3920 | 4 (0)| 00:00:01 | | 3 | TABLE ACCESS FULL | STEP3 | 1 | 1878 | 3 (0)| 00:00:01 | | 4 | BUFFER SORT | | 1 | 2042 | 1 (0)| 00:00:01 | |* 5 | TABLE ACCESS BY INDEX ROWID | SERVICE_LINES | 1 | 2042 | 1 (0)| 00:00:01 | |* 6 | INDEX RANGE SCAN | IX_SNAME | 1 | | 0 (0)| 00:00:01 | |* 7 | COLLECTION ITERATOR PICKLER FETCH| | | | | | ---

(50)

4.4 XPath リライト

XMLType データが構造化記憶域に格納されていて XPath を使用する問合せが 実行されたとき、これらの問合せが基礎となるオブジェクト・リレーショナル列 に直接リライトされることがあります。この内部処理を XPath リライトといいま す。この XPath リライトが有効になる XPath 式の詳細はマニュアル『Oracle XML DB 開発者ガイド』を参照してください。

例えば、次のような問合せでは、Company 要素の内容の取得と文字列’Oracle’ との比較が試行されます。

SQL> SELECT OBJECT_VALUE FROM po p 2 WHERE extractValue(OBJECT_VALUE,

3 '/PurchaseOrder/Company') = 'Oracle';

XPath 式をリレーショナル列に XPath リライト

SELECT VALUE(p) FROM po p

WHERE p.xmldata.Company = 'Oracle';

リスト 4-12 XPath リライトの例

XMLType 表 po は XML スキーマに基づく構造化記憶域で作成されているため、 extractValue 関数はリレーショナル列にリライトされます。XPath リライト後の xmldata は XMLType 擬似属性と言われるもので、基礎となるオブジェクト列への 直接アクセスを可能にします。

表 4-6  スキーマ注釈抜粋

参照

関連したドキュメント

1 か月無料のサブスクリプションを取得するには、最初に Silhouette Design Store

この数字は 2021 年末と比較すると約 40%の減少となっています。しかしひと月当たりの攻撃 件数を見てみると、 2022 年 1 月は 149 件であったのが 2022 年 3

この資料には、当社または当社グループ(以下、TDKグループといいます。)に関する業績見通し、計

Oracle WebLogic Server の脆弱性 CVE-2019-2725 に関する注 意喚起 ISC BIND 9 に対する複数の脆弱性に関する注意喚起 Confluence Server および Confluence

分配関数に関する古典統計力学の近似 注: ややまどろっこしいが、基本的な考え方は、q-p 空間において、 ①エネルギー En を取る量子状態

機器表に以下の追加必要事項を記載している。 ・性能値(機器効率) ・試験方法等に関する規格 ・型番 ・製造者名

近年、気候変動の影響に関する情報開示(TCFD ※1 )や、脱炭素を目指す目標の設 定(SBT ※2 、RE100

いてもらう権利﹂に関するものである︒また︑多数意見は本件の争点を歪曲した︒というのは︑第一に︑多数意見は