ヘッダーをスキップ
Oracle® XML DB開発者ガイド
11gリリース2 (11.2)
B70200-03
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

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

この章では、データベース内にURLを生成および格納して、そのURLが指すデータを取り出す方法を説明します。説明するURIは3種類あります。

この章の内容は次のとおりです。

Oracle XML DB URLの機能の概要

この章では、次の2つの主要な機能について説明します。

  • インダイレクション・メカニズムとしてのパスの使用: パスをデータベースに格納して、そのパスを参照することによって間接的にターゲットにアクセスすることができます。パスの種類としては、様々な種類のUniform Resource Identifier(URI)を使用できます。

  • そのターゲット・データベース・データを使用したXML文書の生成: インダイレクションで特に使用できるURIの1つの種類であるDBUriは、データベース・データへのアドレッシングで使用できる便利なXPath表記法を提供します。DBUriを使用して、データベース・データを含み、データベースの構造を反映した構造を持つXML文書を構成できます。

URIとURL

WebベースのXMLアプリケーションの開発では、Uniform Resource Identifier(URI)を使用して、ネットワーク上にあるデータを参照することがよくあります。URL(Uniform Resource Locator)は、インターネット・プロトコルを使用してオブジェクトにアクセスするURIです。

URIには次の2つの部分があり、シャープ記号(#)で区切られています。

  • 文書を識別するURL部分。

  • ドキュメント内のフラグメントを識別するフラグメント部分。フラグメントの表記法は、ドキュメント・タイプによって異なります。HTML文書ではアンカー名となります。XML文書ではXPath式です。

一般的なURIは次のとおりです。

  • HTML: http://www.example.com/document1#some_anchor。ここでsome_anchorは、HTML文書内の名前付きアンカーです。

  • XML: http://www.example.com/xml_doc#/po/cust/custname。ここで、各項目は次のとおりです。

    • http://www.example.com/xml_docはXML文書の位置を識別します。

    • /po/cust/custnameは文書内のフラグメントを識別します。この部分はW3CのXPointer勧告で定義されています。


関連項目:


URITypeとそのサブタイプ

Oracle XML DBでは、様々な種類のパスをデータベース・オブジェクトとして表現できます。次に、使用できるパス・オブジェクト型を示します。

  • HTTPURIType: この型のオブジェクトはHTTPUriと呼ばれ、http://で始まるURLを表します。HTTPURITypeを使用すると、リモートのWebページ(またはファイル)へのリンクを表すオブジェクトを作成して、オブジェクト・メソッドをコールすることでそのWebページを取得することができます。HTTPUriTypeを使用するアプリケーションは、適切なアクセス権限を持っている必要があります。HTTPUriTypeは、リモート・ページにアクセスするためのHyper Text Transfer Protocol(HTTP(S))を実装します。HTTPURITypeはパッケージUTL_HTTPを使用してデータをフェッチするため、このパッケージのセッション設定およびアクセス制御を使用してHTTPフェッチを変更することもできます。


    関連項目:


  • DBURIType: この型のオブジェクトはDBUriと呼ばれ、データベース・データ(表、1つまたは複数の行、1つの列)をターゲットとするURIを表します。DBURITypeを使用すると、データベース・データへのリンクを表すオブジェクトを作成して、オブジェクト・メソッドをコールすることでそのデータをXML形式で取得することができます。DBUriは簡単な形式のXPath式をURI構文として使用します。たとえば、次のXPath式は、表HR.employeesの、列first_nameの値がJackである行へのDBUri参照です。

    /HR/EMPLOYEES/ROW[FIRST_NAME="Jack"] 
    
  • XDBURIType: この型のオブジェクトはXDBUriと呼ばれ、Oracle XML DBリポジトリのリソースをターゲットにしているURIを表します。XDBURITypeを使用すると、リポジトリ・リソースへのリンクを表すオブジェクトを作成し、オブジェクト・メソッドをコールすることによって、リソースの全体または一部を取得できます。XDBUriのURI構文はリポジトリ・リソース・アドレスで、オプションでその後にXPath式が続きます。たとえば、/public/hr/doc1.xml#/purchaseOrder/lineItemは、フォルダ/public/hrのリポジトリ・ファイルdoc1.xmlにおけるルート要素purchaseOrderlineItem子要素へのXDBUri参照です。

これらの各オブジェクト型は、抽象オブジェクト型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を使用してネイティブに索引付けできます。特別のデータストアは不要です。


関連項目:


DBUriとXDBUri: 目的

DBUriおよびXDBUriの典型的な用途は次のとおりです。

  • データベースから生成されたWebページ内でXSLTスタイルシートを参照できます。PL/SQLパッケージDBMS_METADATAでは、DBUriを使用してXSLスタイルシートを参照できます。XDBUriを使用すると、Oracle XML DBリポジトリに格納されたXSLTスタイルシートも参照できます。

  • データベースに格納されたHTML、イメージおよびその他のデータを参照できます。URLを使用して、データベース表またはリポジトリ・フォルダに格納されたデータを指すことができます。

  • Webサーバーをバイパスすることによって、パフォーマンスを向上できます。XML文書内にあるグローバルURLをデータベースへの参照に置換し、サーブレット、DBUri、XDBUriのいずれかを使用して、ターゲットのコンテンツを取得します。DBUriまたはXDBUriを使用すると、Webサーバーを介さずにデータベースと直接対話できるため、サーブレットを使用する場合よりパフォーマンスが向上します。

  • DBUriを使用すると、SQLを使用しないでデータベース内のXML文書にアクセスできます。

  • アクセス権限のあるデータベース表にリポジトリ・リソースが格納されている場合は、XDBUriやDBUriを使用してそのコンテンツにアクセスできます。


関連項目:

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_METADATAパッケージ」

URITypeメソッド

抽象オブジェクト型URITypeに含まれているPL/SQLメソッドを、その各サブタイプで使用できます。これらの各メソッドは、任意のサブタイプによってオーバーライドできます。表20-1URITypeのPL/SQLメソッドのリストを示します。さらに、各サブタイプには、サブタイプと同名のコンストラクタが含まれます。

表20-1 URIType PL/SQLメソッド

URITypeメソッド 説明
getURL()

URITypeインスタンスのURLを戻します。

URLを直接参照せず、このメソッドを使用します。URITypeサブタイプは、このメソッドをオーバーライドして、正確なURLを提供します。たとえば、HTTPURIType は、URLを、接頭辞http://なしで格納します。getURL()は接頭辞を付加してURLの全体を戻します。

getExternalURL()

getURL()と同様ですが、getExternalURL()ではURL内の文字をエスケープし、URL仕様に準拠させます。たとえば、空白はエスケープ値%20に変換されます。

getContentType()

URIのMIMEコンテンツ・タイプを戻します。

HTTPUri: コンテンツ・タイプを戻すため、URLが後に続き、MIMEヘッダーが検査されます。

DBUri: 戻されるコンテンツ・タイプはtext/plain(スカラー値の場合)またはtext/xml(それ以外)です。

XDBUri: リポジトリ・リソースのContentTypeメタデータ・プロパティの値が戻されます。

getCLOB()

URIのターゲットがCLOB値として戻されます。データベースのキャラクタ・セットを使用してデータがエンコーディングされます。

DBUri: XMLデータが戻されます(ターゲットのデータがそのまま戻される、ノード・テストtext()が使用された場合を除く)。BLOB列がターゲットの場合、列内のバイナリ・データは16進の文字データとして変換されます。

getBLOB()

URIのターゲットがBLOB値として戻されます。文字変換は行われず、文字エンコーディングはURIターゲットのエンコーディングです。このメソッドは、バイナリ・データのフェッチにも使用できます。

DBUri: getBLOB()は、BLOB列をターゲットとするDBUriに適用されると、16進の文字データとして変換されたバイナリ・データを戻します。バイナリ・データをターゲットとするDBUriに適用されると、データはデータベース・キャラクタ・セットで戻されます。

getXML()

URIのターゲットがXMLTypeインスタンスとして戻されます。これを使用することにより、getCLOB()およびgetBLOB()以外の操作を実行するアプリケーションは、XMLTypeメソッドを使用してそれらの操作を実行できます。URIのターゲットが整形式のXML文書でない場合は例外が発生します。

createURI()

URITypeサブタイプのいずれかのインスタンスを構成します。


HTTPURIType PL/SQLメソッドGETCONTENTTYPE()

HTTPURIType PL/SQLメソッドgetContentType()は、ターゲット文書に関するMIME情報を戻します。この情報を使用して、文書をBLOB値とCLOB値のどちらで取得するかを判断できます。たとえば、MIMEタイプx/jpegのWebページをBLOBとして処理し、MIMEタイプtext/plainまたはtext/htmlのWebページをCLOBとして処理できます。

例20-1では、データをCLOB値とBLOB値のいずれで取得するかを判断するためにHTTPコンテンツ・タイプがテストされています。コンテンツ・タイプ・データはHTTPURITypeの場合はHTTPヘッダー、DBURITypeの場合はデータベース列のメタデータです。

例20-1 HTTPURIType PL/SQLメソッドGETCONTENTTYPE()の使用

DECLARE
  httpuri HTTPURIType;
  y CLOB;
  x BLOB;
BEGIN
  httpuri := HTTPURIType('http://www.oracle.com/index.html');
  DBMS_OUTPUT.put_line(httpuri.getContentType());
  IF httpuri.getContentType() = 'text/html'
  THEN
     y := httpuri.getCLOB();
  END IF;
  IF httpuri.getContentType() = 'application-x/bin'
  THEN
     x := httpuri.getBLOB();
  END IF;
END;
/
text/html

DBURIType PL/SQLメソッドGETCONTENTTYPE()

PL/SQLメソッドgetContentType()はURLのMIME情報を戻します。DBUriのターゲットがスカラー値の場合、戻されるMIMEコンテンツ・タイプはtext/plainです。それ以外の場合はtext/xmlです。

CREATE TABLE dbtab (a VARCHAR2(20), b BLOB);

次のXPath式に対応するDBUriのコンテンツ・タイプは、それぞれがXMLデータの完全な列をターゲットにしているため、text/xmlです。

  • /HR/DBTAB/ROW/A

  • /HR/DBTAB/ROW/B

次のXPath式に対応するDBUriのコンテンツ・タイプは、それぞれがスカラー値をターゲットにしているため、text/plainです。

  • /HR/DBTAB/ROW/A/text()

  • /HR/DBTAB/ROW/B/text()

DBURIType PL/SQLメソッドGETCLOB()

PL/SQLメソッドgetCLOB()がDBUriに適用される場合、ターゲットとなるデータは、ターゲットの列または表の名前をXML要素名にしたXMLデータとして戻されます。ターゲットのXPathがノード・テストtext()を使用する場合、データは、XMLタグで囲まれていないテキストとして戻されます。どちらの場合も、データはデータベース・キャラクタ・セットで戻されます。

たとえば、XPathが/HR/DBTAB/ROW/A/text()であるDBUriに適用されると、Aが非バイナリ列の場合、列Aのデータがそのまま戻されます。XPathノード・テストtext()を使用しない場合、結果はXML形式にラップされたデータです。

<HR><DBTAB><ROW><A>...data_in_column_A...</A></ROW></DBTAB></HR>

バイナリ(BLOB)列をターゲットとするDBUriに適用された場合、列内のバイナリ・データは16進の文字データに変換されます。

たとえば、XPathが/HR/DBTAB/ROW/B/text()であるDBUriに適用されると、BBLOB列の場合、ターゲットのバイナリ・データは16進の文字データに変換されて戻されます。XPathノード・テストtext()を使用しない場合、結果はXML形式にラップされた変換データです。

<HR><DBTAB><ROW><B>...data_translated_to_hex...</B></ROW></DBTAB></HR>

DBURIType PL/SQLメソッドGETBLOB()

BLOB列をターゲットとするDBUriに適用されると、getBLOB()16進の文字データとして変換されたバイナリ・データを戻します。バイナリ・データをターゲットとするDBUriに適用されると、getBLOB()はデータを(BLOB値として)データベース・キャラクタ・セットで戻します。

例として表dbtabを参照してください。

CREATE TABLE dbtab (a VARCHAR2(20), b BLOB);

XPath式/HR/DBTAB/ROW/Bに対応するDBUriにgetBLOB()を適用した場合、列Bの16進文字変換をコンテンツとするルート要素Bを持つXML文書を含むBLOB値が戻されます。

XPath式/HR/DBTAB/ROW/B/text()に対応するDBUriにgetBLOB()を適用した場合、列Bのバイナリ・データの16進文字変換のみを含むBLOB値が戻されます。

バイナリ・データをターゲットとするXPath式/HR/DBTAB/ROW/A/text()に対応するDBUriにgetBLOB()を適用した場合、列Aのデータを含むBLOB値が、データベースのキャラクタ・セットで戻されます。

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

URITypeサブタイプのインスタンスをインダイレクションに使用するには、通常、その種のインスタンスをデータベースに格納し、それを問合せでgetCLOB()などのPL/SQLメソッドとともに使用してターゲットのデータを取得します。この項ではその方法を説明します。

データベース列を作成するには、URITypeまたはそのサブタイプのいずれかを使用するか、各URIのテキストのみを文字列として格納し、その後、URIへのアクセスがあったときに、必要なURITypeインスタンスをオン・デマンドで作成します。様々なURITypeサブタイプのオブジェクトを、同一のURIType データベース列に格納できます。

URITypeサブタイプから継承した独自のオブジェクト型を定義することもできます。新しい型を導出すると、カスタムのテクニックを使用してデータを取得、変換、またはフィルタリングできます。


関連項目:


例20-2は、HTTPUriおよびDBUri (URITypeサブタイプHTTPURITypeおよびDBURITypeのインスタンス)を、同じデータベース列(URIType型)に格納しています。問合せは、各URIが指しているデータを取得します。最初のURIはWebページのURLです。2番目のURIは標準データベース・スキーマHRの表employees内のデータを参照しています(説明を簡潔にするため、Webページの最初の部分のみを示しています)。

例20-2 URI列の作成と問合せ

CREATE TABLE uri_tab (url URIType);
Table created.
 
INSERT INTO uri_tab VALUES (HTTPURIType.createURI('http://www.oracle.com'));
1 row created.
 
INSERT INTO uri_tab VALUES (DBURIType.createURI(
                              '/HR/EMPLOYEES/ROW[FIRST_NAME="Jack"]'));
1 row created.
 
SELECT e.url.getCLOB() FROM uri_tab e;
 
E.URL.GETCLOB()
-------------------------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
. . .
 
<?xml version="1.0"?>
 <ROW>
  <EMPLOYEE_ID>177</EMPLOYEE_ID>
  <FIRST_NAME>Jack</FIRST_NAME>
  <LAST_NAME>Livingston</LAST_NAME>
  <EMAIL>JLIVINGS</EMAIL>
  <PHONE_NUMBER>011.44.1644.429264</PHONE_NUMBER>
  <HIRE_DATE>23-APR-06</HIRE_DATE>
  <JOB_ID>SA_REP</JOB_ID>
  <SALARY>8400</SALARY>
  <COMMISSION_PCT>.2</COMMISSION_PCT>
  <MANAGER_ID>149</MANAGER_ID>
  <DEPARTMENT_ID>80</DEPARTMENT_ID>
 </ROW>
 
2 rows selected.

URIType PL/SQLメソッドcreateURI()を使用するには、使用する特定のURITypeサブタイプを把握している必要があります。パッケージURIFACTORYのPL/SQLメソッドgetURI()を使用すると、かわりに遅延バインディングを使用して、実行時に特定の型情報を決定できます。

URIFACTORY.getURI()はURI文字列を引数に取ります。適切なサブタイプ(HTTPURIType、DBURITypeまたはXDBURIType)のURITypeインスタンスを、URI文字列の形式に基づいて戻します。

  • URIの先頭がhttp://の場合、getURI()はHTTPUriを作成して戻します。

  • URIの先頭が/oradb/または/dburi/の場合、getURI()はDBUriを作成して戻します。

  • それ以外の場合はgetURI()はXDBUriを作成して戻します。

しかし、例20-3例20-2と似ていますが、この例では、2つの異なる方法を使用してURIのターゲットとなっている文書を取得します。

  • PL/SQLメソッドSYS.URIFACTORY.getURI()絶対URI

    • HTTPアドレスhttp://www.oracle.comをターゲットとするHTTPUri

    • データベース・アドレス/oradb/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]をターゲットとするDBUri

  • コンストラクタSYS.HTTPURIType()相対URL (http://なし)。絶対URIの場合と同じHTTPUri、Oracleホームページを使用しています。

例20-3では、getURI()に渡されるURI文字列はハードコードされていますが、これをアプリケーションが実行時に取得する文字列値にすることも非常に簡単に可能です。

例20-3 各種の方法で作成された様々な種類のURIの使用

CREATE TABLE uri_tab (docUrl SYS.URIType, docName VARCHAR2(200));
Table created.
 
-- Insert an HTTPUri with absolute URL into SYS.URIType using URIFACTORY.
-- The target is Oracle home page.
INSERT INTO uri_tab VALUES
  (SYS.URIFACTORY.getURI('http://www.oracle.com'), 'AbsURL');
1 row created.
 
-- Insert an HTTPUri with relative URL using constructor SYS.HTTPURIType.
-- Note the absence of prefix http://. The target is the same.
INSERT INTO uri_tab VALUES (SYS.HTTPURIType('www.oracle.com'), 'RelURL');
1 row created.

-- Insert a DBUri that targets employee data from table HR.employees.
INSERT INTO uri_tab VALUES
  (SYS.URIFACTORY.getURI('/oradb/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]'), 'Emp200');
1 row created.

-- Extract all of the documents.
SELECT e.docUrl.getCLOB(), docName FROM uri_tab e;
 
E.DOCURL.GETCLOB()
-----------------
DOCNAME
------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
. . .
AbsURL
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
. . .
RelURL

<?xml version="1.0"?>
 <ROW>
  <EMPLOYEE_ID>200</EMPLOYEE_ID>
  <FIRST_NAME>Jennifer</FIRST_NAME>
  <LAST_NAME>Whalen</LAST_NAME>
  <EMAIL>JWHALEN</EMAIL>
  <PHONE_NUMBER>515.123.4444</PHONE_NUMBER>
  <HIRE_DATE>17-SEP-03</HIRE_DATE>
  <JOB_ID>AD_ASST</JOB_ID>
  <SALARY>4400</SALARY>
  <MANAGER_ID>101</MANAGER_ID>
  <DEPARTMENT_ID>10</DEPARTMENT_ID>
 </ROW>
Emp200

3 rows selected.
 
-- In PL/SQL
CREATE OR REPLACE FUNCTION returnclob
  RETURN CLOB
  IS a SYS.URIType;
BEGIN
  SELECT docUrl INTO a FROM uri_Tab WHERE docName LIKE 'Emp200%';
  RETURN a.getCLOB;
END;
/
Function created.
 
SELECT returnclob() FROM DUAL;
 
RETURNCLOB()
---------------------------------------------------------------
<?xml version="1.0"?>
 <ROW>
  <EMPLOYEE_ID>200</EMPLOYEE_ID>
  <FIRST_NAME>Jennifer</FIRST_NAME>
  <LAST_NAME>Whalen</LAST_NAME>
  <EMAIL>JWHALEN</EMAIL>
  <PHONE_NUMBER>515.123.4444</PHONE_NUMBER>
  <HIRE_DATE>17-SEP-03</HIRE_DATE>
  <JOB_ID>AD_ASST</JOB_ID>
  <SALARY>4400</SALARY>
  <MANAGER_ID>101</MANAGER_ID>
  <DEPARTMENT_ID>10</DEPARTMENT_ID>
 </ROW>
 
1 row selected.

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

XDBURITypeは、URIを使用してOracle XML DBリポジトリのリソースを公開する方法を提供するURITypeのサブタイプです。型XDBURITypeのインスタンスはXDBUriと呼ばれます。

XDBUri URIの構文

XDBUri URIのURL部分は、ターゲットのリポジトリ・リソースの階層アドレスです。XPath式ではなくリポジトリ・パスです。

URIのオプションのフラグメント部分はXPath構文を使用しており、シャープ記号(#)によってURL部分と区切られています。これが適切なのは、ターゲットのリソースがXML文書であり、フラグメント部分がXML文書の1つ以上の部分をターゲットとする場合のみです。ターゲットのリソースがXML文書でない場合は、フラグメントとシャープ記号を省略します。

次に、XDBUri URIの例を示します。

  • /public/hr/image27.jpg

  • /public/hr/doc1.xml#/PurchaseOrder/LineItem

これらのURIの形式に基づいて、次のように判断できます。

  • /public/hrはOracle XML DBリポジトリのフォルダ・リソースです。

  • image27.jpgおよびdoc1.xmlはフォルダ/public/hrにあるリソースです。

  • リソースdoc1.xmlはファイル・リソースで、1つのXML文書を含みます。

  • XPath式 /PurchaseOrder/LineItemは、XML文書doc1.xmlの要素PurchaseOrder内のLineItem子要素を参照しています。

XDBUriを作成するには、パッケージURIFACTORYのPL/SQLメソッドgetURI()を使用します。

XDBURITypeは、URIFACTORY PL/SQLメソッドgetURI()を使用してインスタンスを生成する場合にデフォルトで使用されるURITypeです。ただしURIに、認識された接頭辞http:///dburi、および/oradbのいずれかがある場合を除きます。

たとえば、リソースdoc1.xmlがリポジトリ・フォルダ/public/hrに存在する場合、次の問合せにより、そのリソースをターゲットにしているXDBUriが戻されます。

SELECT SYS.URIFACTORY.getURI('/public/hr/doc1.xml') FROM DUAL;

型がXDBURITypeであると判断するのは特別な接頭辞がないためであり、特定のリソース・ファイル拡張子がないためや、#に続いてXPath式があるためではありません。リソース名がdoc1.xmlでなくfoo.barであったとしても、戻されるURITypeインスタンスはやはりXDBUriになります。

XDBUriの例

例20-4では、XDBUriを作成して、値を発注書表に挿入し、すべての発注書を選択します。URIFACTORY.getURI()に渡されるURIに特別な接頭辞が付いていないため、作成されるURITypeインスタンスはXDBUriになります。

例20-4 XDBUriを使用した、URIによるリポジトリ・リソースへのアクセス

DECLARE
res BOOLEAN;
postring VARCHAR2(100):= '<?xml version="1.0"?>
<ROW>
<PO>999</PO>
</ROW>';
BEGIN
res:=DBMS_XDB.createFolder('/public/orders/');
res:=DBMS_XDB.createResource('/public/orders/po1.xml', postring);
END;
/
PL/SQL procedure successfully completed.
 
CREATE TABLE uri_tab (poUrl SYS.URIType, poName VARCHAR2(1000));
Table created.
 
-- Create an abstract type column so any type of URI can be used
-- Insert an absolute URL into poUrl.
-- The factory will create an XDBURIType because there is no prefix.
-- Here, po1.xml is an XML file that is stored in /public/orders/
-- of the XML repository.
INSERT INTO uri_tab VALUES
  (URIFACTORY.getURI('/public/orders/po1.xml'), 'SomePurchaseOrder');
1 row created.
 
-- Get all the purchase orders
SELECT e.poUrl.getCLOB(), poName FROM uri_tab e;
 
E.POURL.GETCLOB()
-----------------
PONAME
------
<?xml version="1.0"?>
<ROW>
<PO>999</PO>
</ROW>
SomePurchaseOrder
 
1 row selected.
 
-- Using PL/SQL, you can access table uri_tab as follows:
CREATE OR REPLACE FUNCTION returnclob
  RETURN CLOB
  IS a URIType;
BEGIN
  -- Get absolute URL for purchase order named like 'Some%'
   SELECT poUrl INTO a FROM uri_tab WHERE poName LIKE 'Some%';
   RETURN a.getCLOB();
END;
/ 
Function created.
 
SELECT returnclob() FROM DUAL;
 
RETURNCLOB()
---------------------
<?xml version="1.0"?>
<ROW>
<PO>999</PO>
</ROW>
 
1 row selected.

PL/SQLメソッドgetXML()XMLTypeインスタンスを戻すため、これをXMLQueryなどのSQL/XML関数とともに使用できます。例20-5の問合せに、これを示します。この問合せは、番号が999のすべての発注書を取得します。

例20-5 XMLCASTおよびXMLQUERYでのPL/SQLメソッドGETXML()の使用

SELECT e.poUrl.getCLOB() FROM uri_tab e
  WHERE XMLCast(XMLQuery('$po/ROW/PO'
                         PASSING e.poUrl.getXML() AS "po"
                         RETURNING CONTENT)
                AS VARCHAR2(24))
        = '999';

E.POURL.GETCLOB()
---------------------
<?xml version="1.0"?>
<ROW>
<PO>999</PO>
</ROW>
 
1 row selected.

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

DBUriは、データベース・データをターゲットとするURIです。URITypeサブタイプのすべてのインスタンスに関して、DBUriはデータにアクセスするためのインダイレクション・メカニズムを提供します。さらに、DBURITypeを使用すると次のことが可能です。

  • XPath表記法を使用したデータベース・データのアドレッシング。これにより、XMLデータの場合と同様にデータベースをビジュアル化してアクセスできます。

    たとえば、DBUriは/HR/EMPLOYEES/ROW[FIRST_NAME="Jack"]といった式を使用し、表HR.employeesの、列first_nameの値がJackである行をターゲットにできます。

  • DBUriを使用してターゲットとされているデータベース・データを含み、データベースの構造を反映した構造を持つXML文書を構成できます。

    たとえばXPathで/HR/DBTAB/ROW/Aと表されたDBUriを使用して、データベース構造を反映しているXML要素内の列Aのデータを囲んでおり、それに応じた名前を持っているXML文書を構成できます。

    <HR><DBTAB><ROW><A>...data_in_column_A...</A></ROW></DBTAB></HR>
    

DBUriは、HTTPUriのようにグローバルな場所を参照することはありません。ただし、DBUriでアドレッシングされているオブジェクトにグローバルにアクセスすることは可能です。それには、DBUriを処理するサーブレットを特定するためのHTTPUriにそのDBUriを追加します。「DBUriServlet」を参照してください。

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

アクセスできるデータベース・スキーマは、アクセス権限を付与されているデータベース・スキーマのみです。データベースのこの部分が、データベースのユーザー独自のビューとなります。

DBURITypeを使用すると、対応するデータベースのXMLビューを持つことができます。これはユーザーがアクセス権限を持っているデータベースの部分で、XMLデータ形式で表示されます。これは、XMLで格納されているデータに限らない、すべての種類のデータベース・データです。この方法でビジュアル化されたデータベース・データはXML要素で効率的に囲まれており、1つまたはそれ以上のXML文書が結果として生成されます。

この種の「XMLビュー」は、技術的な意味ではデータベース・ビューではありません。ここで「ビュー」と呼ばれているものは、DBURITypeの理解に有効な抽象的な観点を示すものにすぎません。DBURITypeを、データベースをXMLデータ同様にビジュアル化し、アクセスを提供するものとみなすことができます。

ただし、DBURITypeは、ビジュアル化を実行し、データベース・データへの別個のアクセス手段を提供するだけのものではありません。各「XMLビュー」はXML文書として実現されます。つまり、DBURITypeを使用すると、データベース・データを基にしてXML文書を生成できます。

以上はすべて、DBURIType ではXPath表記法を使用して(1)アクセス権限のある任意のデータベース・データのアドレッシングとアクセス、および(2)データのXML表現の構成を行うことができるということです。

図20-1はリレーショナル表HR.employees、その表の一部に対応するXMLビュー、および対応するDBUri URI(簡素化されたXPath式)の間の関係を示しています。この場合、XMLとして公開されるデータの部分は、employee_id200である行となります。URIを使用してデータにアクセスし、「XMLビュー」を反映するXML文書を構成することができます。

図20-1 リレーショナル・データのXMLビジュアル化に対応するDBUri

図20-1の説明が続きます
「図20-1 リレーショナル・データのXMLビジュアル化に対応するDBUri」の説明

「XMLビュー」内のXML要素とURI XPath式内のステップは、どちらもデータベース表と列名を反映しています。「XMLビュー」とURI XPath式のどちらにおいても、データベース表の行を示すROWの用法に注意してください。

XPath式にはルート要素ステップoradbが含まれていることにも注意してください。これは、URIが、HTTPUriやXDBUriでなくDBUriに対応していることを示すのに使用されます。この対応がコンテキストから認識されている場合は、XPathステップはスキップ可能です。たとえば、問題のパスがデータベース・データのパスであるとわかっている場合、次のURIは同じ内容になります。

  • /oradb/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/LAST_NAME

  • /HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/LAST_NAME

ただしURIコンテキストが不明確な場合は、接頭辞/oradbを使用して、DBUriに対応するURIであることを示す必要があります。特に、URIFACTORY PL/SQLメソッドやDBUriServletには接頭辞を指定する必要があります。


関連項目:


DBUri URIの構文

XPath式は、1つ以上のXMLノードをアドレッシングするXMLデータへのパスです。DBUriはデータベースの仮想XMLユーザー・ビジュアル化の概念を利用して、簡素化された形式のXPath式を、データベース・データをアドレッシングするURIとして使用します。これは、データの型や、データがXMLかどうかには依存しません。

このため、DBURITypeの場合、Oracle DatabaseはXPathやXPointerの構文を完全にはサポートしません。XDBUri XPath式には構文の制限はありません。DBUriには1つ例外があります。XMLType表内のデータです。XMLType表の場合、データベース内の表自身をアドレッシングするために、簡素化されたXPath形式が使用されます。その後、XPath式の残りの部分では、完全なXPathの構文を使用して表内の特定のXMLデータをアドレッシングできます。この例外はXMLTypeにのみ適用されます。XMLType列には適用されません。

いずれの場合も、XDBUriとは異なり、DBUri URIではシャープ記号(#)を使用してURIのURL部分とフラグメント(XPath)部分を区切ることはありません。DBURITypeではURIフラグメントは使用されません。URI全体が(簡素化された)XPath式とみなされます。

DBUriは、アクセス権限のあるあらゆるデータベース・データに作成できます。次のようなXPath式を使用できます。

  • /database_schema/table

  • /database_schema/table/ROW[predicate_expression]/column

  • /database_schema/table/ROW[predicate_expression]/object_column/attribute

  • /database_schema/XMLType_table/ROW/XPath_expression

最後の例で、XMLType_tableXMLType表で、XPath_expression任意のXPath式です。XMLTypeない表の場合は、DBUri XPath式の末尾は列である必要があります(列の内部の特定のデータをアドレッシングすることはできません)。この制限の対象には、XMLデータを含むXMLType列、LOB列、およびVARCHAR2列が含まれます。

DBUri XPath式には次のことが可能です。

  • 表全体をターゲットとする。

    たとえば、/HR/EMPLOYEESは、データベース・スキーマHRの表employeesをターゲットとしています。

  • データベース・スキーマおよび表ステップ以外のパス内の任意のステップにXPath述語を含める。

    たとえば、/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/EMAILemployee_id200という条件下で、表HR.employeesemail列をターゲットとしています。

  • スカラー・コンテンツを持つデータに対するtext() XPathノード・テスト。これは使用可能な唯一のノード・テストで、表および行ステップには使用できません。

DBUri (XPath)述語式では次のものを使用できます。

  • ブール演算子: andorおよびnot

  • 関係演算子: <><=!=>==moddiv*(乗算)

DBUri XPath式の使用には次の条件があります。

  • child XPath軸のみを使用できます。parentなど、他の軸は使用できません。

  • データベース・スキーマを指定するか、または特定のスキーマを持たない表名を解決するためにPUBLICを指定する必要があります。

  • データベース・ビューまたは表名を指定する必要があります。

  • データベース列がターゲットの場合はROWステップを含めます。

  • 単一のデータ値を識別する必要があります。オブジェクト型のインスタンスまたはコレクションを使用できます。

  • データベース・データを使用して、XMLデータを生成するために使用する場合は、結果は整形式のXMLである必要があります。

    整形式のXMLを結果としないDBUriの例は/HR/EMPLOYEES/ROW/LAST_NAMEです。これは複数の<LAST_NAME>要素フラグメントを、単一のルート要素を伴わずに戻します。

  • 次のものは使用できません

    • *(ワイルドカード)

    • .(それ自身)

    • ..(親)

    • //(子孫またはそれ自身)

    • countなどのXPath関数

DBUri XPath式は、オプションで接頭辞/oradbまたは/dburi (どちらも同じです)を付けて識別できます。この接頭辞では大文字/小文字が区別されません。ただし、DBUri XPath式の残りの部分は、通常のXPath式同様、大文字/小文字が区別されます。このため、たとえば表HR.employeesをDBUri XPath式として指定するには、hr/employees (または大文字と小文字の混合)ではなくHR/EMPLOYEESを使用する必要があります。表や列の名前はデフォルトで大文字だからです。


関連項目:

XPath表記法についてはhttp://www.w3.org/TR/xpath

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

データベースの「XMLビュー」のコンテンツ、つまり構成可能なXML文書のコンテンツは、指定された時点で個別のデータベース・データにアクセスするために持っている権限を反映しています。つまり、DBUriの有効範囲は指定されたデータベース・セッションなので、セッションのコンテキスト(接続しているユーザーおよびユーザーが持っている権限)に応じて、同じDBUriでも異なる結果が得られます。

少し複雑になりますが、データベース・スキーマ修飾がなくてもデータベース・データにアクセスできるXML要素PUBLICもあります。これは便利な機能ですが、混乱を招くこともあります。指定ユーザー用のデータベースのXMLビューが、そのユーザーが指定時点でデータベースに対して持っている特定のアクセス権限に依存していることを忘れないでください。

XML要素PUBLICパブリック・シノニムの使用に対応しています。たとえば、ユーザーquineが問合せを実行する場合、次の問合せは、データベース・スキーマquineの下の表 fooを一致させようと試みますが、そのような表がない場合は、fooという名前のバブリック・シノニムを一致させようとします。

SELECT * FROM foo;

同様に、XML要素PUBLICは、指定のユーザーに表示されるすべてのデータベース・データと、パブリック・シノニムを介してそのユーザーに表示されるすべてのデータを含みます。このため、同一のDBUri URI /PUBLIC/FOOが、ユーザーquineが接続している場合はquine.fooと解決され、ユーザーcurryが接続している場合はcurry.fooと解決されます。

DBUriの例

DBUriが識別できるのは、表、行、行内の列、オブジェクト列の属性のいずれかです。次の項に、様々な種類のオブジェクトをターゲット化する方法を示します。

表のターゲット化

この構文を使用して、完全なデータベース表をターゲットにできます。

/database_schema/table

例20-6では、完全な表をターゲット化するDBUriを使用します。表のコンテンツに対応するXML文書が戻されます。最上位のXML要素の名前は表により決まります。各行の値はROW要素で囲まれます。

例20-6 DBUriを使用した完全な表のターゲット化

CREATE TABLE uri_tab (url URIType);
Table created.
 
INSERT INTO uri_tab VALUES
       (DBURIType.createURI('/HR/EMPLOYEES'));
1 row created.
 
SELECT e.url.getCLOB() FROM uri_tab e;

E.URL.GETCLOB()
---------------
<?xml version="1.0"?>
<EMPLOYEES>
 <ROW>
  <EMPLOYEE_ID>100</EMPLOYEE_ID>
  <FIRST_NAME>Steven</FIRST_NAME>
  <LAST_NAME>King</LAST_NAME>
  <EMAIL>SKING</EMAIL>
  <PHONE_NUMBER>515.123.4567</PHONE_NUMBER>
  <HIRE_DATE>17-JUN-03</HIRE_DATE>
  <JOB_ID>AD_PRES</JOB_ID>
  <SALARY>24000</SALARY>
  <DEPARTMENT_ID>90</DEPARTMENT_ID>
 </ROW>
 <ROW>
  <EMPLOYEE_ID>101</EMPLOYEE_ID>
  <FIRST_NAME>Neena</FIRST_NAME>
  <LAST_NAME>Kochhar</LAST_NAME>
  <EMAIL>NKOCHHAR</EMAIL>
  <PHONE_NUMBER>515.123.4568</PHONE_NUMBER>
  <HIRE_DATE>21-SEP-05</HIRE_DATE>
  <JOB_ID>AD_VP</JOB_ID>
  <SALARY>17000</SALARY>
  <MANAGER_ID>100</MANAGER_ID>
  <DEPARTMENT_ID>90</DEPARTMENT_ID>
 </ROW>
 . . .
 
1 row selected.

表内の行のターゲット化

この構文を使用して、表の1行または複数の行をターゲットにできます。

/database_schema/table/ROW[predicate_expression]

例20-7では、表の中の1行をターゲット化するDBUriを使用します。XPath述語式は、従業員番号200に対応する、表の1行を識別します。結果は、ROWを最上位要素とするXML文書です。

例20-7 DBUriを使用した表内の個別行のターゲット化

CREATE TABLE uri_tab (url URIType);
Table created.
 
INSERT INTO uri_tab VALUES
       (DBURIType.createURI('/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]'));
1 row created.
 
SELECT e.url.getCLOB() FROM uri_tab e;
 
E.URL.GETCLOB()
-------------------------------------------------------
<?xml version="1.0"?>
 <ROW>
  <EMPLOYEE_ID>200</EMPLOYEE_ID>
  <FIRST_NAME>Jennifer</FIRST_NAME>
  <LAST_NAME>Whalen</LAST_NAME>
  <EMAIL>JWHALEN</EMAIL>
  <PHONE_NUMBER>515.123.4444</PHONE_NUMBER>
  <HIRE_DATE>17-SEP-03</HIRE_DATE>
  <JOB_ID>AD_ASST</JOB_ID>
  <SALARY>4400</SALARY>
  <MANAGER_ID>101</MANAGER_ID>
  <DEPARTMENT_ID>10</DEPARTMENT_ID>
 </ROW>
 
1 row selected.

列のターゲット化

この構文を使用して、特定の列をターゲットにできます。

/database_schema/table/ROW[predicate_expression]/column

この構文を使用して、オブジェクト列の特定の属性をターゲットにできます。

/database_schema/table/ROW[predicate_expression]/object_column/attribute

この構文を使用して、属性が特定の値を持つ特定のオブジェクト列をターゲットにできます。

/database_schema/table/ROW[predicate_expression_with_attributes]/object_column

例20-8では、例20-7と同じ従業員について、列last_nameをターゲットするDBUriを使用します。最上位のXML要素の名前はターゲット列により決まります。

例20-8 DBUriを使用した特定の列のターゲット化

CREATE TABLE uri_tab (url URIType);
Table created.
 
INSERT INTO uri_tab VALUES
       (DBURIType.createURI('/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/LAST_NAME'));
1 row created.
 
SELECT e.url.getCLOB() FROM uri_tab e;
 
E.URL.GETCLOB()
------------------------------
<?xml version="1.0"?>
 <LAST_NAME>Whalen</LAST_NAME>
 
1 row selected.

例20-9では、cityおよびpostal code属性が特定の値になっているCUST_ADDRESSオブジェクト列をターゲットとするDBUriを使用します。最上位のXML要素には列の名前が付けられ、オブジェクト属性それぞれに対応する子要素が含まれます。

例20-9 DBUriを使用した、特定の属性値を持つオブジェクト列のターゲット化

CREATE TABLE uri_tab (url URIType);
Table created.
 
INSERT INTO uri_tab VALUES
  (DBURIType.createURI(
     '/OE/CUSTOMERS/ROW[CUST_ADDRESS/CITY="Poughkeepsie" and
                        CUST_ADDRESS/POSTAL_CODE=12601]/CUST_ADDRESS'));
1 row created.
 
SELECT e.url.getCLOB() FROM uri_tab e;
 
E.URL.GETCLOB()
---------------
<?xml version="1.0"?>
 <CUST_ADDRESS>
  <STREET_ADDRESS>33 Fulton St</STREET_ADDRESS>
  <POSTAL_CODE>12601</POSTAL_CODE>
  <CITY>Poughkeepsie</CITY>
  <STATE_PROVINCE>NY</STATE_PROVINCE>
  <COUNTRY_ID>US</COUNTRY_ID>
 </CUST_ADDRESS>
 
1 row selected.

このDBUriは、CITY属性がPoughkeepsieを値に持ち、POSTAL_CODE属性が12601を値に持つオブジェクトを識別します。

列のテキスト値の取出し

多くの場合、囲みタグを取り出さずに、列のテキスト値のみを取り出す方が有効です。たとえば、XSLTスタイルシートがCLOB列に格納されている場合は、文書を列名のタグで囲まなくても、その文書を取り出すことができます。この場合は、text() XPathノード・テストを使用できます。ノードのテキスト値のみを取り出すように指定できます。次の構文を使用します。

/oradb/database_schema/table/ROW[predicate_expression]/column/text()

例20-10は、従業員番号200の従業員のlast_name列のテキスト値を、XMLタグなしで取得します。

例20-10 DBUriを使用したノードのテキスト値のみの取出し

CREATE TABLE uri_tab (url URIType);
Table created.

INSERT INTO uri_tab VALUES
       (DBURIType.createURI(
          '/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/LAST_NAME/text()'));

1 row created.

SELECT e.url.getCLOB() FROM uri_tab e;

E.URL.GETCLOB()
---------------
Whalen
 
1 row selected.

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

Ordered Collection Tableなど、データベース・コレクションをターゲットにできます。ただし、ターゲットはその全体をターゲット化する必要があります。コレクションの個別のメンバーをターゲットにすることはできません。コレクションがターゲット化されると、DBUriにより生成されたXML文書には、各コレクションの全メンバーがそれぞれ、コレクションのに対応する名前の要素で囲まれたXML要素として含まれます。

例20-11では、数値のコレクションをターゲット化するDBUriを使用します。最上位のXML要素はコレクションの名前が付けられ、その子はコレクションの(NUMBER)の名前が付けられます。

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

CREATE TYPE num_collection AS VARRAY(10) OF NUMBER;
/
Type created.
 
CREATE TABLE orders (item VARCHAR2(10), quantities num_collection);
Table created.
 
INSERT INTO orders VALUES ('boxes', num_collection(3, 7, 4, 9));
1 row created.
 
SELECT * FROM orders;
 
ITEM
----
QUANTITIES
----------
boxes
NUM_COLLECTION(3, 7, 4, 9)
 
1 row selected.
 
SELECT DBURIType('/HR/ORDERS/ROW[ITEM="boxes"]/QUANTITIES').getCLOB() FROM DUAL;
 
DBURITYPE('/HR/ORDERS/ROW[ITEM="BOXES"]/QUANTITIES').GETCLOB()
--------------------------------------------------------------
<?xml version="1.0"?>
 <QUANTITIES>
  <NUMBER>3</NUMBER>
  <NUMBER>7</NUMBER>
  <NUMBER>4</NUMBER>
  <NUMBER>9</NUMBER>
 </QUANTITIES>
 
1 row selected.

パッケージURIFACTORYを使用したURITypeの作成

PL/SQLパッケージURIFACTORYを使用すると、URITypeインスタンスの作成以上のことができます。他のPL/SQLメソッドを表20-2にリストします。

表20-2 URIFACTORY PL/SQLメソッド

PL/SQLメソッド 説明
getURI()

URITypeインスタンスのURLを戻します。

escapeURI()

URIで許容されない文字を同等のエスケープ・シーケンスに置換することによって、URI文字列をエスケープします。

unescapeURI()

指定のURIからエスケープを削除します。

registerURLHandler()

特定のURLを処理するための特定の型名を登録します。その型のインスタンスを生成するためにgetURI()によってコールされます。

ブール引数を使用して、適切な型コンストラクタをコールする前に、接頭辞を削除する必要があることを示すことができます。

unregisterURLHandler()

URLハンドラを登録解除します。


特に注意を要するのは、パッケージURIFACTORYを使用して、型がURITypeの新しいサブタイプを定義できることです。そのサブタイプを使用して、URI用の特別な処理を提供することができます。特に、特定のプロトコルに対応するURITypeサブタイプを定義できます。URIFACTORYは、これらのサブタイプのインスタンスを、適切に認識して処理します。

新しい型を定義して、その型に固有のデータベース列を作成する利点は次のとおりです。

  • その列に対して暗黙的な制約を提供して、その型のインスタンスのみを含むようにできます。これは、その列に特定のプロトコルのスペシャライズ・インデックスを実装する場合に有効です。たとえばDBUriの場合、SQL問合せを実行せず、ディスクから直接データをフェッチするスペシャライズ・インデックスを実装することができます。

  • 型に基づいて、それぞれの列に異なる制約を規定できます。たとえばHTTPUriの場合、列に対してプロキシおよびファイアウォールの制約を定義して、HTTPを介したすべてのアクセスでプロキシ・サーバーを使用するようにできます。

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

URI用の特別な処理を提供するには、次のようにして、新しいURITypeのサブタイプを定義および登録します。

  1. SQL文CREATE TYPEを使用して、新しい型を作成します。この方にはPL/SQLメソッドcreateURI()が実装される必要があります。

  2. オプションで、デフォルトのメソッドをオーバーライドして、データを取り出すときに特別な処理を実行するか、またはXMLデータを変換してから表示します。

  3. この特別な処理に使用するURIを識別する新しいURI接頭辞を決定します。

  4. PL/SQLメソッドregisterURLHandler()を使用して、新しい接頭辞を登録します。これによって、定義した新しい接頭辞で始まるURIを受け取ったパッケージURIFACTORYが、新しいサブタイプのインスタンスを作成できるようになります。

新しいサブタイプを定義すると、新しい接頭辞の付いたURIがURIFACTORYメソッドで認識され、また、新しい型のインスタンスを作成して使用できます。

たとえば、新しいプロトコル接頭辞ecom://を作成し、そのプロトコルを処理するためのURITypeのサブタイプを定義する場合を考えます。場合によると新しいサブタイプは、PL/SQLメソッドgetCLOB()用の特別なロジックを実装するか、メソッドgetXML()におけるXMLタグやデータを多少変更します。接頭辞ecom://URIFACTORYで登録すると、getURI()へのコールにより、その接頭辞を伴うURI用に新しいURITypeサブタイプのインスタンスが生成されます。

例20-12では、新しいプロトコルecom://を処理する新しい型ECOMURITypeを作成しています。この例は1つの表に3種類の異なるURI(HTTPUri、DBUri、および新しい型ECOMURITypeのインスタンス)を格納します。この例を実行するには、各ECOMURITypeメンバー関数を定義する必要があります。

例20-12 URIFACTORY: ECOMプロトコルの登録

CREATE TABLE url_tab (urlcol varchar2(80));
Table created.
 
-- Insert an HTTP URL reference
INSERT INTO url_tab VALUES ('http://www.oracle.com/');
1 row created.
 
-- Insert a DBUri
INSERT INTO url_tab VALUES ('/oradb/HR/EMPLOYEES/ROW[FIRST_NAME="Jack"]');
1 row created.
 
-- Create a new type to handle a new protocol called ecom://
-- This is just an example template. For this to run, the implementations
-- of these functions must be specified.
CREATE OR REPLACE TYPE ECOMURIType UNDER SYS.URIType (
  OVERRIDING MEMBER FUNCTION getCLOB RETURN CLOB,
  OVERRIDING MEMBER FUNCTION getBLOB RETURN BLOB,
  OVERRIDING MEMBER FUNCTION getExternalURL RETURN VARCHAR2,
  OVERRIDING MEMBER FUNCTION getURI RETURN VARCHAR2,
  -- Must have this for registering with the URL handler
  STATIC FUNCTION createURI(url IN VARCHAR2) RETURN ECOMURIType);
/
-- Register a new handler for the ecom:// prefixes
BEGIN
  -- The handler type name is ECOMURIType; schema is HR
  -- Ignore the prefix case, so that URIFACTORY creates the same subtype
  -- for URIs beginning with ECOM://, ecom://, eCom://, and so on.
  -- Strip the prefix before calling PL/SQL method createURI(),
  -- so that the string 'ecom://' is not stored inside the
  -- ECOMURIType object. It is added back automatically when
  -- you call ECOMURIType.getURI().
  URIFACTORY.registerURLHandler (prefix => 'ecom://',
                                 schemaname => 'HR',
                                 typename => 'ECOMURITYPE',
                                 ignoreprefixcase => TRUE,
                                 stripprefix => TRUE);
END;
/
PL/SQL procedure successfully completed.
 
-- Insert this new type of URI into the table
INSERT INTO url_tab VALUES ('ECOM://company1/company2=22/comp');
1 row created.
 
-- Use the factory to generate an instance of the appropriate
-- subtype for each URI in the table.

-- You would need to define the member functions for this to work:
SELECT urifactory.getURI(urlcol) FROM url_tab;

-- This would generate:
HTTPURIType('www.oracle.com'); -- an HTTPUri
DBURIType('/oradb/HR/EMPLOYEES/ROW[FIRST_NAME="Jack"]', null); -- a DBUri
ECOMURIType('company1/company2=22/comp'); -- an ECOMURIType instance

SYS_DBURIGEN SQL関数

DBUriを作成するには、XPath式をコンストラクタDBURIType、または適切なURIFACTORY PL/SQLメソッドに対して指定します。Oracle SQL関数sys_DburiGenを使用すると、データベース列とその値から構成されたXPathを使用してDBUriを作成する方法を使用できます。

Oracle SQL関数sys_DburiGenは、引数として1つ以上の列または属性、およびオプションでrowidを取り、特定の列オブジェクトまたは行オブジェクトをターゲットにするDBUriを生成します。関数sys_DburiGenは、ノードのテキスト値が必要かどうかを示す追加のパラメータを取ります。図20-2を参照してください。

図20-2 SYS_DBURIGENの構文

図20-2の説明が続きます
「図20-2 SYS_DBURIGENの構文」の説明

参照するすべての列または属性は、同じ表内に存在する必要があります。それらはそれぞれ一意の値を参照する必要があります。複数の列を指定した場合、最初の列は行を識別し、最後の列はその行内の列を識別します。データベース・スキーマを指定しない場合、表名はパブリック・シノニムとして解釈されます。


関連項目:

『Oracle Database SQL言語リファレンス』

例20-13では、Oracle SQL関数sys_DburiGenを使用して、employee_id206という条件下で表HR.employeesemailをターゲットにするDBUriを生成しています。

例20-13 SYS_DBURIGEN: 列をターゲットとするDBUriの生成

SELECT sys_DburiGen(employee_id, email)
  FROM employees
  WHERE employee_id = 206;

SYS_DBURIGEN(EMPLOYEE_ID,EMAIL)(URL, SPARE)
-------------------------------------------------------------------
DBURITYPE('/PUBLIC/EMPLOYEES/ROW[EMPLOYEE_ID = "206"]/EMAIL', NULL)

1 row selected.

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

Oracle SQL関数sys_DburiGenに渡される列または属性は、次の規則に従う必要があります。

  • 同一の表: 関数sys_DburiGenで参照されるすべての列は、同じ表またはビューから取得する必要があります。

  • 一意のマッピング: 列またオブジェクト属性は、元の表またはビューに一意にマップ可能である必要があります。使用可能な仮想列は、valueおよびrefで作成されたもののみです。列は、SQL TABLEコレクション式(TABLE(...))またはインライン・ビュー(そのインライン・ビューが列の名前を変更しない場合)の副問合せから取得される場合があります。

    SQL TABLEコレクション式の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

  • キー列: ROWIDまたは一連のキー列のいずれかを指定する必要があります。キー列のリストは、列が結果内の特定の行を一意に識別できるかぎり、一意キーまたは主キーとして宣言する必要はありません。

  • PUBLIC要素: ROWIDまたはキー列がターゲットとしている表またはビューがデータベース・スキーマを指定していない場合は、PUBLICキーワードが使用されます。DBUriがアクセスされると、表名は、DBUriの作成時にその名前で参照できた表、シノニムまたはデータベース・ビューに変換されます。

  • オプションのtext()引数: デフォルトでは、DBURITypeはXML文書を構成します。text()sys_DburiGenの第3の引数として使用して、テキスト・ノード(XML要素なし)をターゲットにするDBUriを作成します。次に例を示します。

    SELECT sys_DburiGen(employee_id, last_name, 'text()') FROM hr.employees,
      WHERE employee_id=200;
    

    これにより、次のURIを持つDBUriが構成されます。

    /HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/LAST_NAME/text()
    
  • 単一列の引数: 単一列の引数がある場合、列は、行を識別するキー列と参照列の両方として使用されます。

例20-14の問合せは、employee_idを、キー列と参照列の両方として使用します。employee_idが200の行をターゲットにするDBUriを生成します。

例20-14 SYS_DBURIGENへの単一の引数を持つ列の送信

SELECT sys_DburiGen(employee_id) FROM employees
  WHERE employee_id=200;
 
SYS_DBURIGEN(EMPLOYEE_ID)(URL, SPARE)
-------------------------------------
DBURITYPE('/PUBLIC/EMPLOYEES/ROW[EMPLOYEE_ID=''200'']/EMPLOYEE_ID', NULL)
 
1 row selected.

SYS_DBURIGEN SQL関数: 例

例20-15 SYS_DBURIGENを使用したデータベース参照の挿入

CREATE TABLE doc_list_tab (docno NUMBER PRIMARY KEY, doc_ref SYS.DBURIType);
Table created.

-- Insert a DBUri that targets the row with employee_id=177
INSERT INTO doc_list_tab VALUES(1001, (SELECT sys_DburiGen(rowid, employee_id)
                                         FROM employees WHERE employee_id=177));
1 row created.
 
-- Insert a DBUri that targets the last_name column of table employees
INSERT INTO doc_list_tab VALUES(1002,
                                (SELECT sys_DburiGen(employee_id, last_name)
                                   FROM employees WHERE employee_id=177));
1 row created.
 
SELECT * FROM doc_list_tab;
 
     DOCNO
----------
DOC_REF(URL, SPARE)
-----------------------------------------------------
      1001
DBURITYPE('/PUBLIC/EMPLOYEES/ROW[ROWID=''AAAQCcAAFAAAABSABN'']/EMPLOYEE_ID', NULL)
 
      1002
DBURITYPE('/PUBLIC/EMPLOYEES/ROW[EMPLOYEE_ID=''177'']/LAST_NAME', NULL)
 
2 rows selected.

部分的な結果の取得

大きい列から選択する場合、結果の一部のみを取り出し、かわりに列に対するURLを作成する場合があります。たとえば、旅行体験記についてのWebサイトを考えてみます。表にすべての旅行体験記が格納されていて、ユーザーが関連する一連の体験記を検索する場合、検索結果のページに各体験記の全体をリストするのは不都合です。そのかわりに、各体験記の最初の20文字のみを要点として表示し、体験記全体のURLを戻す方がよいでしょう。これを行うには、次の手順を実行します。

例20-16では、旅行体験記の表を作成します。

例20-16 旅行体験記の表の作成

CREATE TABLE travel_story (story_name VARCHAR2(100), story CLOB);
Table created.

INSERT INTO travel_story
  VALUES ('Egypt', 'This is the story of my time in Egypt....');
1 row created.

例20-17では、旅行体験記の最初の20文字のみを戻す関数を作成します。

例20-17 最初の20文字のみを戻す関数

CREATE OR REPLACE FUNCTION charfunc(clobval IN CLOB) RETURN VARCHAR2 IS
  res VARCHAR2(20);
  amount NUMBER := 20;
BEGIN
  DBMS_LOB.read(clobval, amount, 1, res);
  RETURN res;
END;
/
Function created.

例20-18では、旅行体験記の最初の20文字のみを選択し、story列のDBUriを戻すビューを作成します。

例20-18 SYS_DBURIGENで使用するための旅行体験記ビューの作成

CREATE OR REPLACE VIEW travel_view AS
  SELECT story_name, charfunc(story) short_story,
         sys_DburiGen(story_name, story, 'text()') story_link
  FROM travel_story;
View created.
 
SELECT * FROM travel_view;
 
STORY_NAME
----------
SHORT_STORY
-----------
STORY_LINK(URL, SPARE)
----------------------
Egypt
This is the story of
DBURITYPE('/PUBLIC/TRAVEL_STORY/ROW[STORY_NAME=''Egypt'']/STORY/text()', NULL)
 
1 row selected.

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

DML文のRETURNING句にあるOracle SQL関数sys_DburiGenを使用すると、オブジェクトの挿入時にそのオブジェクトのURLを取得できます。

例20-19では、文書が表clob_tabに挿入されると、そのURLが表uri_tabに常に挿入されます。これを実現するには、INSERT文のRETURNING句でOracle SQL関数sys_DburiGenを使用します。

例20-19 RETURNING句でのSYS_DBURIGENの使用によるURLの取得

CREATE TABLE clob_tab (docid NUMBER, doc CLOB);
Table created.

CREATE TABLE uri_tab (docs SYS.DBURIType);
Table created.

PL/SQLでは、RETURNING句とEXECUTE IMMEDIATEを使用して、挿入された文書のURLの記憶域を挿入操作の中で指定します。

DECLARE
  ret SYS.DBURIType;
BEGIN
  -- execute the insert operation and get the URL
  EXECUTE IMMEDIATE 
    'INSERT INTO clob_tab VALUES (1, ''TEMP CLOB TEST'') 
       RETURNING sys_DburiGen(docid, doc, ''text()'') INTO :1'
    RETURNING INTO ret;
  -- Insert the URL into uri_tab
  INSERT INTO uri_tab VALUES (ret);
END;
/

SELECT e.docs.getURL() FROM hr.uri_tab e;
E.DOCS.GETURL()
------------------------------------------------
/ORADB/PUBLIC/CLOB_TAB/ROW[DOCID='1']/DOC/text()
 
1 row selected.

DBUriServlet

Oracle XML DBリポジトリ・リソースは、Oracle XML DBに組み込まれているHTTPサーバーを使用して取得できます。Oracle Databaseには、あらゆる種類のデータベース・データを、HTTP(S) URLを介して利用できるようにするサーブレットDBUriServletも含まれています。データは、プレーン・テキスト、HTMLまたはXMLとして戻されます。

WebクライアントまたはWebアプリケーションは、SQLや特別なデータベースAPIがなくてもこのデータにアクセスできます。データを取り出すには、Webページ内でそのデータにリンクさせるか、またはJava、PL/SQLまたはPerlの、HTTPを認識するAPIを介してそのデータを要求します。このデータは、Webブラウザや、XML対応スプレッドシートなどのアプリケーションで表示または処理できます。DBUriServletは、XMLデータおよび非XMLデータのコンテンツを生成でき、XSLTスタイルシートを使用して結果を変換できます。

データベース・データをWebからアクセスできるようにするには、サーブレットのアドレス(URL)と、取得するデータベース・データを指定するDBUri URIから構成されているURIを使用します。構文を次に示します。ここで、http://server:portはサーブレットのURL (サーバーとポート)、/oradb/database_schema/tableはDBUri URI (あらゆるDBUri URIを使用可能)です。

http://server:port/oradb/database_schema/table

サーブレットのURLでXPath表記法を使用する場合、一部の文字をエスケープする必要があることがあります。その場合は URIType PL/SQLメソッドgetExternalURL()を使用します。

Oracle XML DBの一部としてあらかじめインストールされているDBUriServletを使用するか、サーブレット・エンジンで実行する独自のサーブレットを作成します。このサーブレットは呼び出すURLのURI部分を読み取り、そのURIを使用してDBUriを作成し、URIType PL/SQLメソッドをコールしてデータを取得し、Webページ、XML文書、プレーン・テキスト文書などと同様の形式で値を戻します。

使用するMIMEタイプは、URIを介してサーブレットに対して指定されます。

  • デフォルトでは、サーブレットはtext/xmlおよびtext/plainのMIMEタイプを作成できます。DBUriパスの末尾がtext()の場合は、text/plainが使用されます。それ以外の場合は、XML文書はMIMEタイプtext/xmlを使用して生成されます。

  • サーブレットに対するcontenttype引数を使用してデフォルトのMIMEタイプをオーバーライドし、binary/x-jpegなどの値に設定できます。


関連項目:

Oracle XML DBのサーブレットの詳細は、第32章「JavaでのOracle XML DBアプリケーションの作成」を参照してください。

表20-3に、出力をカスタマイズするためにDBUriServletに渡すオプションのURLパラメータを示します。

表20-3 DBUriServlet: オプションの引数

引数 説明
rowsettag

XML文書のデフォルトのルート・タグ名を変更します。次に例を示します。

http://server:8080/oradb/HR/EMPLOYEES?rowsettag=OracleEmployees
contenttype

生成されるドキュメントのMIMEタイプを指定します。次に例を示します。

http://server:8080/oradb/HR/EMPLOYEES?contenttype=text/plain
transform

XSLスタイルシートをその位置で取得するURIFACTORYにURLを渡します。このスタイルシートは、サーブレットによって戻されたXML文書に適用されます。次に例を示します。

http://server:8080/oradb/HR/EMPLOYEES?transform=/oradb/QUINE/XSLS/DOC/text()&contenttype=text/html

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

employee表のemployee_id列を取得するには、次のいずれかに類似したURLを使用できます。ここでコンピュータserver.oracle.comがOracle Databaseを実行しており、Webサービスがポート8080でリクエストをリッスンしています。ステップoradbはサーブレットにマップする仮想パスです。

  • http://server.oracle.com:8080/oradb/QUINE/A/ROW[B=200]/C/text()
    

    text/plainのコンテンツ・タイプを生成

  • http://server.oracle.com:8080/oradb/QUINE/A/ROW[B=200]/C
    

    text/xmlのコンテンツ・タイプを生成

コンテンツ・タイプをオーバーライドするには、text/htmlcontenttypeパラメータとしてサーブレットに渡すURLを使用できます。

  • http://server.oracle.com:8080/oradb/QUINE/A/ROW[B=200]/C?contenttype=text/html
    

    text/htmlのコンテンツ・タイプを生成

DBUriServletのカスタマイズ

DBUriServletはデータベースに組み込まれています。サーブレットをカスタマイズするには、Oracle XML DB構成ファイルxdbconfig.xmlを編集する必要があります。これは、WebDAV、FTP、Oracle Enterprise Manager、PL/SQLのいずれかを使用して、データベース・スキーマ(ユーザー・アカウント) XDBで編集できます。FTPまたはWebDAVを使用してファイルを更新するには、文書をダウンロードし、編集し、データベースに再度保存します。


関連項目:


DBUriServletのインストール先は/oradb/*で、これはxdbconfig.xmlservlet-patternタグで指定されているアドレスです。アスタリスク(*)は、oradb以降のすべてのパスが同じサーブレットにマップされることを示すために必要です。oradbは仮想パスとして公開されます。サーブレットにアクセスするために使用するパスを変更できます。

例20-20では、DBUriServletを/dburi/*にインストールするように構成ファイルが変更されています。

例20-20 DBUriServletのインストール先の変更

DECLARE
  doc XMLType;
  doc2 XMLType;
BEGIN
  doc := DBMS_XDB.cfg_get();
  SELECT 
    updateXML(doc,
'/xdbconfig/sysconfig/protocolconfig/httpconfig/webappconfig/servletconfig/
servlet-mappings/servlet-mapping[servlet-name="DBUriServlet"]/servlet-pattern/
text()', 
              '/dburi/*')
    INTO doc2 FROM DUAL;
  DBMS_XDB.cfg_update(doc2);
  COMMIT;
END;
/

セキュリティ・パラメータ、サーブレットの表示名および説明も、xdbconfig.xml構成ファイル内でカスタマイズできます。サーブレットは、servlet-patternを削除することによって削除できます。また、Oracle SQL関数updateXMLを使用してservlet-mapping要素をNULLに更新することによっても削除できます。

DBUriServletのセキュリティ

サーブレットのセキュリティは、Oracle Databaseでロールを使用することによって処理されます。サーブレットにログインするユーザーは、ユーザー自身のデータベース・ユーザー名およびパスワードを使用します。サーブレットは、ログインするユーザーが、構成ファイルに指定されているロールのいずれかを持っているかどうかを、パラメータsecurity-role-refを使用して確認します。デフォルトでは、サーブレットはロールauthenticatedUser、および有効なデータベース・パスワードを使用してサーブレットにログインし、このロールを持っているあらゆるユーザーが利用できます。

ロール・パラメータを変更して、特定のデータベース・ロールにアクセスを制限できます。デフォルトのauthenticatedUserロールから、ユーザーが作成したロールに変更するには、Oracle XML DB構成ファイルを変更します。

例20-21では、デフォルト・ロールauthenticatedUserをロールservlet-users(ユーザーが作成したという想定のもの)に変更します。

例20-21 サーブレット・アクセスのデータベース・ロールへの制限

DECLARE
  doc  XMLType;
  doc2 XMLType;
  doc3 XMLType;
BEGIN
  doc := DBMS_XDB.cfg_get();
  SELECT updateXML(doc,
'/xdbconfig/sysconfig/protocolconfig/httpconfig/webappconfig/servletconfig/
servlet-list/servlet[servlet-name="DBUriServlet"]/security-role-ref/role-name/
text()',
                   'servlet-users')
    INTO doc2 FROM DUAL;
  SELECT updateXML(doc2,
'/xdbconfig/sysconfig/protocolconfig/httpconfig/webappconfig/servletconfig/
servlet-list/servlet[servlet-name="DBUriServlet"]/security-role-ref/role-link/
text()',
                   'servlet-users')
    INTO doc3 FROM DUAL;
  DBMS_XDB.cfg_update(doc3);
  COMMIT;
END;
/

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

http://server/servlets/oradbといったURLはDBUriServlet (またはカスタム・サーブレット)により処理されます。この種のURLがURITypeインスタンスとして格納される場合、サブタイプDBURITypeを使用すると便利です。これは、このURIがデータベース・データをターゲットにしているためです。

ただし、URITypeインスタンスが、パッケージURIFACTORYのPL/SQLメソッドを使用して作成された場合は、デフォルトで使用されるサブタイプは、DBURITypeではなくHTTPURITypeです。これは、URIFACTORYがURI接頭辞のみに注目し、http://を検出して、URIターゲットがWebページであると想定するためです。これにより、不要な通信レイヤーが作成され、無駄な文字変換が行われます。

効率を向上させるには、URIFACTORYに対し、指定された形式のURIはデータベース・アクセスを表しているので、HTTPUriでなくDBUriとして実現すべきだと指示します。そのためには、このURIのハンドラを接頭辞として登録し、生成するインスタンスの型としてDBURITypeを指定します。

例20-22では、URIFACTORYに対して、http://server/servlets/oradbで始まるあらゆるURI文字列がデータベース・アクセスに対応していることを効率的に通知しています。

例20-22 DBUri接頭辞用のハンドラの登録

BEGIN
  URIFACTORY.registerURLHandler('http://server/servlets/oradb',
                             'SYS', 'DBURIType', true, true);
END;
/

このコードを実行すると、同一のセッションにおけるすべてのgetURI()コールにより、接頭辞http://server/servlets/oradbを持つあらゆるURI用のDBUriが自動的に作成されます。


関連項目:

URIFACTORYファンクションの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。