この章では、データベース内に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パッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |