この章では、データベース内にURLを生成および格納して、そのURLが指すデータを取り出す方法を説明します。説明するURIは3種類あります。
DBUri: データベース内のリレーショナル・データのアドレス
XDBUri: Oracle XML DBリポジトリ内のデータのアドレス
HTTPUri: Hyper Text Transfer Protocol(HTTP(S))を使用するWebアドレス
この章の内容は次のとおりです。
この章では、次の2つの主要な機能について説明します。
インダイレクション・メカニズムとしてのパスの使用: パスをデータベースに格納して、そのパスを参照することによって間接的にターゲットにアクセスすることができます。パスの種類としては、様々な種類のUniform Resource Identifier(URI)を使用できます。
そのターゲット・データベース・データを使用したXML文書の生成: インダイレクションで特に使用できるURIの1つの種類であるDBUriは、データベース・データへのアドレッシングで使用できる便利なXPath表記法を提供します。DBUriを使用して、データベース・データを含み、データベースの構造を反映した構造を持つXML文書を構成できます。
WebベースのXMLアプリケーションの開発では、Uniform Resource Identifier(URI)を使用して、ネットワーク上にあるデータを参照することがよくあります。URL(Uniform Resource Locator)は、インターネット・プロトコルを使用してオブジェクトにアクセスするURIです。
URIには次の2つの部分があり、シャープ記号(#)で区切られています。
文書を識別するURL部分。
ドキュメント内のフラグメントを識別するフラグメント部分。フラグメントの表記法は、ドキュメント・タイプによって異なります。HTML文書ではアンカー名となります。XML文書ではXPath式です。
一般的なURIは次のとおりです。
HTML: http://www.url.com/document1#some_anchor。ここでsome_anchorは、HTML文書内の名前付きアンカーです。
XML: http://www.xml.com/xml_doc#/po/cust/custname。ここで、各項目は次のとおりです。
http://www.xml.com/xml_docはXML文書の位置を識別します。
/po/cust/custnameは文書内のフラグメントを識別します。この部分はW3CのXPointer勧告で定義されています。
|
関連項目:
|
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の、列first_nameの値がJackである行の、列employeesへの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におけるルート要素purchaseOrderのlineItem子要素への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の典型的な用途は次のとおりです。
データベースから生成された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に含まれているメソッドを、その各サブタイプで使用できます。これらの各メソッドは、任意のサブタイプによってオーバーライドできます。表20-1にURITypeのメソッドのリストを示します。さらに、各サブタイプには、サブタイプと同名のコンストラクタが含まれます。
表20-1 URITypeメソッド
| URITypeメソッド | 説明 |
|---|---|
getURL() |
URLを直接参照せず、このメソッドを使用します。 |
getExternalURL() |
|
getContentType() |
URIのMIMEコンテンツ・タイプを戻します。 HTTPUri: コンテンツ・タイプを戻すため、URLが後に続き、MIMEヘッダーが検査されます。 DBUri: 戻されるコンテンツ・タイプは XDBUri: リポジトリ・リソースの |
getCLOB() |
URIのターゲットが DBUri: XMLデータが戻されます(ターゲットのデータがそのまま戻される、ノード・テスト |
getBLOB() |
URIのターゲットが DBUri: |
getXML() |
URIのターゲットが |
createURI() |
|
HTTPURITypeメソッドgetContentType()は、ターゲット文書に関するMIME情報を戻します。この情報を使用して、文書をBLOB値とCLOB値のどちらで取得するかを判断できます。たとえば、MIMEタイプx/jpegのWebページをBLOBとして処理し、MIMEタイプtext/plainまたはtext/htmlのWebページをCLOBとして処理できます。
例20-1 HTTPURITypeメソッドgetContentType()の使用
この例では、データをCLOB値とBLOB値のいずれで取得するかを判断するためにHTTPコンテンツ・タイプがテストされています。コンテンツ・タイプ・データはHTTPURITypeの場合はHTTPヘッダー、DBURITypeの場合はデータベース列のメタデータです。
DECLARE
httpuri HTTPURIType;
y CLOB;
x BLOB;
BEGIN
httpuri := HTTPURIType('http://www.oracle.com/object1');
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
メソッドgetContentType()はURLのMIME情報を戻します。DBUriのターゲットがスカラー値の場合、戻されるMIMEコンテンツ・タイプはtext/plainで、それ以外の場合はtext/xmlです。例として表dbtabを参照してください。
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()
メソッド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>
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サブタイプのインスタンスをインダイレクションに使用するには、通常、その種のインスタンスをデータベースに格納し、それを問合せでgetCLOB()などのメソッドとともに使用してターゲットのデータを取得します。この項ではその方法を説明します。
データベース列を作成するには、URITypeまたはそのサブタイプのいずれかを使用するか、各URIのテキストのみを文字列として格納し、その後、URIへのアクセスがあったときに、必要なURITypeインスタンスをオン・デマンドで作成します。様々なURITypeサブタイプのオブジェクトを、同一のURIType データベース列に格納できます。
URITypeサブタイプから継承した独自のオブジェクト型を定義することもできます。新しい型を導出すると、カスタムのテクニックを使用してデータを取得、変換、またはフィルタリングできます。
|
関連項目:
|
例20-2 URI列の作成と問合せ
この例は、HTTPUriおよびDBUri(URITypeサブタイプHTTPURITypeおよびDBURITypeのインスタンス)を、同じデータベース列(URIType型)に格納しています。問合せは、各URIが指しているデータを取得します。最初のURIはWebページのURLで、2番目は標準スキーマhrの表employees内のデータを参照しています。(説明を簡潔にするため、Webページの最初の部分のみを示しています。)
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.01 Transitional//EN"> <HTML> <HEAD> <TITLE>Oracle Corporation</TITLE> . . . <?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-98</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メソッドcreateURI()を使用するには、使用する特定のURITypeサブタイプを把握している必要があります。パッケージURIFACTORYのメソッドgetURI()を使用すると、かわりに遅延バインディングを使用して、実行時に特定の型情報を決定できます。
URIFACTORY.getURI()はURI文字列を引数に取り、適切なサブタイプ(HTTPURIType、DBURIType、またはXDBURIType)のURITypeインスタンスを、URI文字列の形式に基づいて戻します。
URIの先頭がhttp://の場合、getURI()はHTTPUriを作成して戻します。
URIの先頭が/oradb/または/dburi/の場合、getURI()はDBUriを作成して戻します。
それ以外の場合はgetURI()はXDBUriを作成して戻します。
この例は、例20-2に類似しています。しかし、この例では2つの異なる方法を使用してURIのターゲットとなっている文書を取得します。
メソッド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ホームページを使用しています。
この例では、getURI()に渡される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 database 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.01 Transitional//EN"> <HTML> <HEAD> <TITLE>Oracle Corporation</TITLE> . . . AbsURL <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE>Oracle Corporation</TITLE> . . . 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-87</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-87</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.
XDBURITypeは、URIを使用してOracle XML DBリポジトリのリソースを公開する方法を提供するURITypeのサブタイプです。型XDBURITypeのインスタンスはXDBUriと呼ばれます。
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のメソッドgetURI()を使用します。
XDBURITypeは、URIFACTORYメソッド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になります。
例20-4 XDBUriを使用した、URIによるリポジトリ・リソースへのアクセス
この例は、XDBUriを作成し、値を発注書表に挿入し、すべての発注書を選択します。URIFACTORY.getURI()に渡されるURIに特別な接頭辞が付いていないため、作成されるURITypeインスタンスはXDBUriになります。
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.
-- We 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.
例20-5 メソッドgetXML()とEXTRACTVALUEの使用
メソッドgetXML()はXMLTypeインスタンスを戻すので、これをextractValueなどのSQL関数とともに使用することができます。この問合せは、番号が999のすべての発注書を取得します。
SELECT e.poUrl.getCLOB() FROM uri_tab e WHERE extractValue(e.poUrl.getXML(), '/ROW/PO') = '999'; E.POURL.GETCLOB() --------------------- <?xml version="1.0"?> <ROW> <PO>999</PO> </ROW> 1 row selected.
DBUriは、データベース・データをターゲットとするURIです。URITypeサブタイプのすべてのインスタンスに関して、DBUriはデータにアクセスするためのインダイレクション・メカニズムを提供します。さらに、DBURITypeを使用すると次のことが可能です。
XPath表記法を使用したデータベース・データのアドレッシング。これにより、XMLデータの場合と同様にデータベースをビジュアル化してアクセスできます。
たとえば、DBUriは/HR/EMPLOYEES/ROW[FIRST_NAME="Jack"]といった式を使用してデータベース表hrの、列first_nameの値がJackである行の、列employeesをターゲットにすることができます。
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」を参照してください。
アクセスできるデータベース・スキーマは、アクセス権限を付与されているデータベース・スキーマのみです。データベースのこの部分が、データベースのユーザー独自のビューとなります。
DBURITypeを使用すると、対応するデータベースのXMLビューを持つことができます。これはユーザーがアクセス権限を持っているデータベースの部分で、XMLデータ形式で表示されます。これは、XMLで格納されているデータに限らない、すべての種類のデータベース・データです。この方法でビジュアル化されたデータベース・データはXML要素で効率的に囲まれており、1つまたはそれ以上のXML文書が結果として生成されます。
この種の「XMLビュー」は、技術的な意味ではデータベース・ビューではありません。ここで「ビュー」と呼ばれているものは、DBURITypeの理解に有効な抽象的な観点を示すものにすぎません。DBURITypeを、データベースをXMLデータ同様にビジュアル化し、アクセスを提供するものとみなすことができます。
ただし、DBURITypeは、ビジュアル化を実行し、データベース・データへの別個のアクセス手段を提供するだけのものではありません。各「XMLビュー」はXML文書として実現されます。つまり、DBURITypeを使用すると、データベース・データを基にしてXML文書を生成できます。
以上はすべて、DBURIType ではXPath表記法を使用して(1)アクセス権限のある任意のデータベース・データのアドレッシングとアクセス、および(2)データのXML表現の構成を行うことができるということです。
図20-1はリレーショナル表hr.employees、その表の一部に対応する「XMLビュー」、および対応するDBUri URI(簡素化されたXPath式)の間の関係を示しています。この場合、XMLとして公開されるデータの部分は、employee_idが200である行となります。URIを使用してデータにアクセスし、「XMLビュー」を反映するXML文書を構成することができます。
「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メソッドやDBUriServletには接頭辞を指定する必要があります。
XPath式は、1つ以上のXMLノードをアドレッシングするXMLデータへのパスです。DBUriはデータベースの仮想XMLユーザー・ビジュアル化の概念を利用して、簡素化された形式のXPath式を、データベース・データをアドレッシングするURIとして使用します。これは、データの型や、データがXMLかどうかには依存しません。
このため、DBURITypeの場合、Oracle DatabaseはXPathやXPointerの構文を完全にはサポートしません。サブセットのみが許容されます。XDBUri XPath式には構文の制限はありません。DBUriには1つ例外があります。XMLType表内のデータです。XMLType表の場合、データベース内の表自身をアドレッシングするために、簡素化されたXPath形式が使用されます。その後、XPath式の残りの部分では、完全なXPathの構文を使用して表内の個別のXMLデータをアドレッシングできます。この例外はXMLTypeの表にのみ適用されます。XMLType列には適用されません。
いずれの場合も、XDBUriとは異なり、DBUri URIではシャープ記号(#)を使用してURIのURL部分とフラグメント(XPath)部分を区切ることはありません。DBURITypeではURIフラグメントは使用されません。URI全体が(簡素化された)XPath式とみなされます。
DBUriは、アクセス権限のあるあらゆるデータベース・データに作成できます。次のようなXPath式を使用できます。
/database_schema/table
/database_schema/table/ROW[predicate_expression]/column
/database_schema/table/ROW[predicate_expression]/object_column/attribute
/database_schema/XMLType_table/ROW/XPath_expression
最後の例で、XMLType_table はXMLType表で、XPath_expressionは任意のXPath式です。XMLTypeでない表の場合は、DBUri XPath式の末尾は列である必要があります。列の内部の特定のデータをアドレッシングすることはできません。この制限の対象には、XMLデータを含むXMLType列、LOB列、およびVARCHAR2列が含まれます。
DBUri XPath式には次のことが可能です。
表全体をターゲットとする。
たとえば、/HR/EMPLOYEESは、データベース・スキーマhrの表employeesをターゲットとしています。
データベース・スキーマおよび表ステップ以外のパス内の任意のステップにXPath述語を含める。
たとえば、/HR/EMPLOYEES/ROW[EMPLOYEE_ID=200]/EMAILはemployee_idが200という条件下で、表 hr.employeesのemail列をターゲットとしています。
スカラー・コンテンツを持つデータに対するtext() XPathノード・テスト。これは使用可能な唯一のノード・テストで、表および行ステップには使用できません。
DBUri(XPath)述語式では次のものを使用できます。
ブール演算子: and、orおよびnot
関係演算子: <、>、<=、!=、>=、=、mod、div、*(乗算)
DBUri XPath式の使用には次の条件があります。
child XPath軸のみを使用できます。parentなど、他の軸は使用できません。
データベース・スキーマを指定するか、または特定のスキーマを持たない表名を解決するためにPUBLICを指定する必要があります。
データベース・ビューまたは表名を指定する必要があります。
データベース列がターゲットの場合はROWステップを含めます。
単一のデータ値を識別する必要があります。オブジェクト型のインスタンスまたはコレクションを使用できます。
データベース・データを使用して、XMLデータを生成するために使用する場合は、結果は整形式のXMLである必要があります。
整形式のXMLを結果としないDBUriの例は/HR/EMPLOYEES/ROW/LAST_NAMEです。これは複数の<LAST_NAME>要素フラグメントを、単一のルート要素を伴わずに戻します。
次のものは使用できません。
*(ワイルドカード)
.(それ自身)
..(親)
//(子孫またはそれ自身)
countなどのXPath関数
DBUri XPath式は、オプションで接頭辞/oradbまたは/dburi(どちらも同じです)を付けて識別できます。この接頭辞では大文字/小文字が区別されません。ただし、DBUri XPath式の残りの部分は、通常のXPath式同様、大文字/小文字が区別されます。このため、たとえばデータベース列 hr.employeesをDBUri XPath式として指定するには、hr/employees(または大文字と小文字の混合)ではなくHR/EMPLOYEESを使用する必要があります。表や列の名前はデフォルトで大文字だからです。
データベースの「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が識別できるのは、表、行、行内の列、オブジェクト列の属性のいずれかです。次の項に、様々な種類のオブジェクトをターゲット化する方法を示します。
この構文を使用して、完全なデータベース表をターゲットにできます。
/database_schema/table
例20-6 DBUriを使用した完全な表のターゲット化
この例では、DBUriは完全な表をターゲット化しています。表のコンテンツに対応するXML文書が戻されます。最上位のXML要素の名前は表により決まります。各行の値はROW要素で囲まれます。
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-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>
. . .
1 row selected.
この構文を使用して、表の1行または複数の行をターゲットにできます。
/database_schema/table/ROW[predicate_expression]
例20-7 DBUriを使用した表内の個別行のターゲット化
この例では、DBUriは表の中の1行をターゲット化しています。XPath述語式は、従業員番号200に対応する、表の1行を識別します。結果は、ROWを最上位要素とするXML文書です。
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-87</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 DBUriを使用した特定の列のターゲット化
この例では、DBUriは例20-7と同じ従業員について、列last_nameをターゲットにしています。最上位のXML要素の名前はターゲット列により決まります。
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 DBUriを使用した、特定の属性値を持つオブジェクト列のターゲット化
この例では、DBUriは、cityおよびpostal code属性が特定の値になっているCUST_ADDRESSオブジェクト列をターゲットにしています。最上位のXML要素には列の名前が付けられ、オブジェクト属性それぞれに対応する子要素が含まれます。
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 DBUriを使用したノードのテキスト値のみの取出し
この例は、従業員番号200の従業員のlast_name列のテキスト値を、XMLタグなしで取得します。
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を使用したコレクションのターゲット化
この例では、DBUriは数値のコレクションをターゲット化しています。最上位のXML要素はコレクションの名前が付けられ、その子はコレクションの型(NUMBER)の名前が付けられます。
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.
PL/SQLパッケージURIFACTORYを使用すると、URITypeインスタンスの作成以上のことができます。他のメソッドを表20-2にリストします。
表20-2 URIFACTORYメソッド
| メソッド | 説明 |
|---|---|
getURI() |
|
|
|
URLで許容されない文字を同等のエスケープ・シーケンスに置換することによって、URL文字列をエスケープします。 |
|
|
指定のURIからエスケープを削除します。 |
|
|
特定のURLを処理するための特定の型名を登録します。その型のインスタンスを生成するために ブール引数を使用して、適切な型コンストラクタをコールする前に、接頭辞を削除する必要があることを示すことができます。 |
|
|
URLハンドラを登録解除します。 |
特に注意を要するのは、パッケージURIFACTORYを使用して、型がURITypeの新しいサブタイプを定義できることです。そのサブタイプを使用して、URI用の特別な処理を提供することができます。特に、特定のプロトコルに対応するURITypeサブタイプを定義できます。URIFACTORYは、これらのサブタイプのインスタンスを、適切に認識して処理します。
新しい型を定義して、その型に固有のデータベース列を作成する利点は次のとおりです。
その列に対して暗黙的な制約を提供して、その型のインスタンスのみを含むようにできます。これは、その列に特定のプロトコルのスペシャライズ・インデックスを実装する場合に有効です。たとえばDBUriの場合、SQL問合せを実行せず、ディスクから直接データをフェッチするスペシャライズ・インデックスを実装することができます。
型に基づいて、それぞれの列に異なる制約を規定できます。たとえばHTTPUriの場合、列に対してプロキシおよびファイアウォールの制約を定義して、HTTPを介したすべてのアクセスでプロキシ・サーバーを使用するようにできます。
URI用の特別な処理を提供するには、次のようにして、新しいURITypeのサブタイプを定義および登録します。
SQL文CREATE TYPEを使用して、新しい型を作成します。この方にはメソッドcreateURI()が実装される必要があります。
オプションで、デフォルトのメソッドをオーバーライドして、データを取り出すときに特別な処理を実行するか、またはXMLデータを変換してから表示します。
この特別な処理に使用するURIを識別する新しいURI接頭辞を決定します。
メソッドregisterURLHandler()を使用して、新しい接頭辞を登録します。これによって、定義した新しい接頭辞で始まるURIを受け取ったパッケージURIFACTORYが、新しいサブタイプのインスタンスを作成できるようになります。
新しいサブタイプを定義すると、新しい接頭辞の付いたURIがURIFACTORYメソッドで認識され、また、新しい型のインスタンスを作成して使用できます。
たとえば、新しいプロトコル接頭辞ecom://を作成し、そのプロトコルを処理するためのURITypeのサブタイプを定義する場合を考えます。場合によると新しいサブタイプは、メソッドgetCLOB()用の特別なロジックを実装するか、メソッドgetXML()におけるXMLタグやデータを多少変更します。接頭辞ecom://をURIFACTORYで登録すると、getURI()へのコールにより、その接頭辞を伴うURI用に新しいURITypeサブタイプのインスタンスが生成されます。
例20-12 URIFACTORY: ECOMプロトコルの登録
この例では、新しいプロトコルecom://を処理する新しい型ECOMURITypeを作成しています。この例は1つの表に3種類の異なるURI(HTTPUri、DBUri、および新しい型ECOMURITypeのインスタンス)を格納します。この例を実行するには、各ECOMURITypeメンバー関数を定義する必要があります。
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 needs to 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 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
DBUriを作成するには、XPath式をコンストラクタDBURIType、または適切なURIFACTORYメソッドに対して指定します。SQL関数sys_DburiGenを使用すると、データベース列とその値から構成されたXPathを使用してDBUriを作成する方法を使用できます。
SQL関数sys_DburiGenは、引数として1つ以上の列または属性、およびオプションでrowidを取り、特定の列オブジェクトまたは行オブジェクトをターゲットにするDBUriを生成します。関数sys_DburiGenは、ノードのテキスト値が必要かどうかを示す追加のパラメータを取ります。図20-2を参照してください。
参照するすべての列または属性は、同じ表内に存在する必要があります。それらはそれぞれ一意の値を参照する必要があります。複数の列を指定した場合、最初の列は行を識別し、最後の列はその行内の列を識別します。データベース・スキーマを指定しない場合、表名はパブリック・シノニムとして解釈されます。
|
関連項目: 『Oracle Database SQL言語リファレンス』 |
例20-13 SYS_DBURIGEN: 列をターゲットとするDBUriの生成
この例では、SQL関数sys_DburiGenを使用して、employee_idが206という条件下で表hr.employeesのemailをターゲットにする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.
SQL関数sys_DburiGenに渡される列または属性は、次の規則に従う必要があります。
同一の表: 関数sys_DburiGenで参照されるすべての列は、同じ表またはビューから取得する必要があります。
一意のマッピング: 列またオブジェクト属性は、元の表またはビューに一意にマップ可能である必要があります。使用可能な仮想列は、valueおよびrefで作成されたもののみです。列は、SQL関数tableまたはインライン・ビュー(そのインライン・ビューが列の名前を変更しない場合)から取得される場合があります。
キー列: 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 SYS_DBURIGENへの単一の引数を持つ列の送信
この問合せは、employee_idを、キー列と参照列の両方として使用します。employee_idが200の行をターゲットにするDBUriを生成します。
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.
例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=''AAAL3LAAFAAAABSABN'']/EMPLOYEE_ID', NULL)
1002
DBURITYPE('/PUBLIC/EMPLOYEES/ROW[EMPLOYEE_ID=''177'']/LAST_NAME', NULL)
2 rows selected.
大きい列から選択する場合、結果の一部のみを取り出し、かわりに列に対するURLを作成する場合があります。たとえば、旅行体験記についてのWebサイトを考えてみます。表にすべての旅行体験記が格納されていて、ユーザーが関連する一連の体験記を検索する場合、検索結果のページに各体験記の全体をリストするのは不都合です。そのかわりに、各体験記の最初の20文字のみを要点として表示し、体験記全体のURLを戻す方がよいでしょう。これを行うには、次の手順を実行します。
例20-16 ビューの作成およびSYS_DBURIGENを使用した部分的な結果の取得
旅行体験記の表が、次のように定義されているとします。
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文字のみを戻す関数を作成します。
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文字のみを選択し、story列のDBUriを戻すビューを作成します。
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句にあるSQL関数sys_DburiGenを使用すると、オブジェクトの挿入時にそのオブジェクトのURLを取得できます。
例20-17 RETURNING句でのSYS_DBURIGENの使用によるURLの取得
この例では、いつでも文書が表 clob_tabに挿入されると、そのURLが表uri_tabに挿入されます。これを実現するには、INSERT文のRETURNING句でSQL関数sys_DburiGenを使用します。
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.
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メソッドgetExternalURL()を使用します。
Oracle XML DBの一部としてあらかじめインストールされているDBUriServletを使用するか、サーブレット・エンジンで実行する独自のサーブレットを作成します。このサーブレットは呼び出すURLのURI部分を読み取り、そのURIを使用してDBUriを作成し、URITypeメソッドをコールしてデータを取得し、Webページ、XML文書、プレーン・テキスト文書などと同様の形式で値を戻します。
使用するMIMEタイプは、URIを介してサーブレットに対して指定されます。
デフォルトでは、サーブレットはtext/xmlおよびtext/plainのMIMEタイプを作成できます。DBUriパスの末尾がtext()の場合は、text/plainが使用されます。それ以外の場合は、XML文書はMIMEタイプtext/xmlを使用して生成されます。
サーブレットに対するcontenttype引数を使用してデフォルトのMIMEタイプをオーバーライドし、binary/x-jpegなどの値に設定できます。
例20-18 URLを使用したMIMEタイプのオーバーライド
このため、employee表のemployee_id列を取得するには、次のいずれかに類似したURLを使用できます。ここでコンピュータserver.oracle.comはOracle Databaseを実行しており、Webサービスがポート8080でリクエストをリッスンしています。ステップoradbはサーブレットにマップする仮想パスです。
-- Produces a content type of text/plain http://server.oracle.com:8080/oradb/QUINE/A/ROW[B=200]/C/text() -- Produces a content type of text/xml http://server.oracle.com:8080/oradb/QUINE/A/ROW[B=200]/C
コンテンツ・タイプをオーバーライドするには、text/htmlをcontenttypeパラメータとしてサーブレットに渡すURLを使用できます。
-- Produces a content type of text/html http://server.oracle.com:8080/oradb/QUINE/A/ROW[B=200]/C?contenttype=text/html
表20-3に、出力をカスタマイズするためにDBUriServletに渡すオプションのURLパラメータを示します。
表20-3 DBUriServlet: オプションの引数
| 引数 | 説明 |
|---|---|
rowsettag |
XML文書のデフォルトのルート・タグ名を変更します。次に例を示します。 http://server:8080/oradb/HR/EMPLOYEES?rowsettag=OracleEmployees 複数の行を指すURIを囲むタグを挿入するためにも使用できます。次に例を示します。 |
contenttype |
生成されるドキュメントのMIMEタイプを指定します。次に例を示します。 http://server:8080/oradb/HR/EMPLOYEES?contenttype=text/plain |
transform |
XSLスタイルシートをその位置で取得する http://server:8080/oradb/HR/EMPLOYEES?transform=/oradb/QUINE/XSLS/DOC/text()&contenttype=text/html |
DBUriServletはデータベースに組み込まれています。サーブレットをカスタマイズするには、Oracle XML DBの構成ファイルxdbconfig.xmlを編集する必要があります。これは、WebDAV、FTP、Oracle Enterprise Manager、PL/SQLのいずれかを使用して、データベース・スキーマ(ユーザー・アカウント)XDBで編集できます。FTPまたはWebDAVを使用してファイルを更新するには、文書をダウンロードし、編集し、データベースに再度保存します。
|
関連項目:
|
DBUriServletのインストール先は/oradb/*で、これはxdbconfig.xmlのservlet-patternタグで指定されているアドレスです。アスタリスク(*)は、oradb以降のすべてのパスが同じサーブレットにマップされることを示すために必要です。oradbは仮想パスとして公開されます。サーブレットにアクセスするために使用するパスを変更できます。
表20-19 DBUriServletのインストール先の変更
この例では、DBUriServletを/dburi/*にインストールするように構成ファイルが変更されています。
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を削除することによって削除できます。また、SQL関数updateXMLを使用してservlet-mapping要素をNULLに更新することによっても削除できます。
サーブレットのセキュリティは、Oracle Databaseでロールを使用することによって処理されます。サーブレットにログインするユーザーは、ユーザー自身のデータベース・ユーザー名およびパスワードを使用します。サーブレットは、ログインするユーザーが、構成ファイルに指定されているロールのいずれかを持っているかどうかを、パラメータsecurity-role-refを使用して確認します。デフォルトでは、サーブレットはロールauthenticatedUser、および有効なデータベース・パスワードを使用してサーブレットにログインし、このロールを持っているあらゆるユーザーが利用できます。
ロール・パラメータを変更して、特定のデータベース・ロールにアクセスを制限できます。デフォルトのauthenticated-userロールから、ユーザーが作成したロールに変更するには、Oracle XML DB構成ファイルを変更します。
例20-20 サーブレット・アクセスのデータベース・ロールへの制限
この例では、デフォルトのauthenticated-userロールをロールservlet-users(ユーザーが作成したという想定のもの)に変更します。
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; /
http://server/servlets/oradbといったURLはDBUriServlet(またはカスタム・サーブレット)により処理されます。この種のURLがURITypeインスタンスとして格納される場合、サブタイプDBURITypeを使用すると便利です。これは、このURIがデータベース・データをターゲットにしているためです。
ただし、URITypeインスタンスが、getURI()など、パッケージURIFACTORYのメソッドを使用して作成された場合は、デフォルトで使用されるサブタイプは、DBURITypeではなくHTTPURITypeです。これは、URIFACTORYがURI接頭辞のみに注目し、http://を検出して、URIターゲットがWebページであると想定するためです。これにより、不要な通信レイヤーが作成され、無駄な文字変換が行われます。
効率を向上させるには、URIFACTORYに対し、指定された形式のURIはデータベース・アクセスを表しているので、HTTPUriでなくDBUriとして実現すべきだと指示します。そのためには、このURIのハンドラを接頭辞として登録し、生成するインスタンスの型としてDBURITypeを指定します。
例20-21 DBUri接頭辞用のハンドラの登録
この例では、URIFACTORYに対して、http://server/servlets/oradbで始まるあらゆるURI文字列がデータベース・アクセスに対応していることを効率的に通知しています。
BEGIN
URIFACTORY.registerURLHandler('http://server/servlets/oradb',
'SYS', 'DBURIType', true, true);
END;
/
このコードを実行すると、同一のセッションにおけるすべてのgetURI()コールにより、接頭辞http://server/servlets/oradbを持つあらゆるURI用のDBUriが自動的に作成されます。
|
関連項目: URIFACTORYファンクションの詳細は『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |