mod_plsqlは、Web上でのPL/SQLベースのデータベース・アプリケーションの配置をサポートします。mod_plsqlはOracle HTTP Serverの一部であり、Oracle Fusion MiddlewareおよびOracle Databaseとともに出荷されています。Oracle HTTP Serverの一部として、WebブラウザからWebサーバーに送信されたURLを解析し、適切なPL/SQLサブプログラムをコールしてブラウザ・リクエストを処理した後、生成されたレスポンスをブラウザに返すことがmod_plsqlの仕事です。通常、mod_plsqlは表示するHTMLページを構成して、WebブラウザのHTTPリクエストにレスポンスを返します。mod_plsqlの用途は他にもありますが、その中の2つを次に示します。
クライアント・マシンおよびOracle Database間でのファイルの送信。テキスト・ファイルまたはバイナリ・ファイルをアップロードおよびダウンロードできます。
Webアプリケーションでのカスタム・ユーザーの認証の実行。
Oracle HTTP Serverへのプラグインとして、mod_plsqlは、HTTPリクエストへのレスポンスでストアド・プロシージャが実行されるようにします。mod_plsqlは、処理されるURLごとに、接続プールのデータベース・セッションを使用するか、または新規セッションを実行中に作成してプールします。mod_plsqlが適切なデータベースPL/SQLプロシージャをURL処理セッションで起動するには、まず、仮想パスを設定し、そのパスとデータベース・アクセス記述子(DAD)を関連付ける必要があります。
DADは、名前付きの設定値のセットで、特定のデータベースのセッションを作成するために必要な情報と、特定のデータベース・ユーザーおよびパスワードを指定します。セッションのデータベース・サービス名およびグローバリゼーション・サポート設定(言語など)が含まれます。詳細は、3.2項「データベース・アクセス記述子(DAD)」を参照してください。
実行時にmod_plsqlによって実行されるストアド・プロシージャを開発するには、PL/SQL Web Toolkitを使用します。PL/SQL Web Toolkitは一連のPL/SQLパッケージで、これを使用すると、HTTPリクエストに関する情報の取得、HTTPレスポンス・ヘッダー(HTTPヘッダーのCookie、コンテンツ・タイプ、MIMEタイプなど)の指定、Cookieの設定、およびHTMLページを作成するための標準HTMLタグの生成が可能です。詳細は、『Oracle Fusion Middleware PL/SQL Web Toolkitリファレンス』を参照してください。
この章の内容は、次のとおりです。
mod_plsqlは、データベースと通信を行うOracle HTTP Serverのプラグインです。これによって、ブラウザ・リクエストが、SQL*Net接続を通じてデータベース・ストアド・プロシージャ・コールにマッピングされます。通常、仮想パスの/pls
で示されます。
次に、サーバーがクライアント・リクエストを受信するときのステップの概要(図3-1)を説明します。
Oracle HTTP Serverが、mod_plsqlで処理されるように構成されている仮想パスを含むリクエストを受信します。
Oracle HTTP Serverは、そのリクエストをmod_plsqlにルーティングします。
mod_plsqlは、DADに格納された設定情報を使用して、データベースに接続します。mod_plsqlは、リクエストをOracle Databaseに転送します。
mod_plsqlは、コール・パラメータを準備して、アプリケーション内のPL/SQLプロシージャを実行します。
PL/SQLプロシージャは、データベースからアクセスしたデータおよびPL/SQL Web Toolkitを使用して、HTMLページを生成します。
レスポンスがmod_plsqlに返されます。
Oracle HTTP Serverは、そのレスポンスをクライアント・ブラウザに送信します。
mod_plsqlから実行されたプロシージャは、HTTPレスポンスをクライアントに返します。この作業を簡単にするために、mod_plsqlにはPL/SQL Web Toolkitが含まれています。PL/SQL Web Toolkitには、OWAパッケージと呼ばれるパッケージのセットが含まれています。これらのパッケージをストアド・プロシージャ内で使用して、リクエスト情報の取得、HTMLタグの作成およびクライアントへのヘッダー情報の返信を行います。すべてのユーザーがアクセスできるように、このツールキットは共通スキーマにインストールしてください。
各mod_plsqlリクエストは、データベース・アクセス記述子(DAD)に関連付けられています。DADは、データベース・アクセスに使用される設定値のセットです。DADにより、次のような情報が指定されます。
データベース別名(Oracle Netサービス名)
データベースがリモートの場合、その接続文字列
ドキュメントのアップロードおよびダウンロード用のプロシージャ
また、DADにはユーザー名とパスワードの情報を指定できます。指定がない場合には、URLの実行時にユーザー名とパスワードを入力するプロンプトが表示されます。
関連資料: DADパラメータの説明とmod_plsql構成ファイルの概要は、『Oracle Fusion Middleware Oracle HTTP Server管理者ガイド』を参照してください。 |
mod_plsqlをWebブラウザで実行するには、次の形式でURLを入力します。
protocol://hostname[:port]/DAD_location/[[!][schema.][package.]proc_name[?query_string]]
表3-1に、mod_plsql実行時のパラメータを示します。
表3-1 mod_plsql実行時のパラメータ
パラメータ | 説明 |
---|---|
protocol |
|
hostname |
Webサーバーが稼働しているマシン。 |
port (オプション) |
Webサーバーがリスニングしているポート。指定しない場合、ポート80が使用されます。 |
DAD location |
Webサーバーで設定したPL/SQLリクエストを処理するための仮想パス。DAD locationに使用できるのはASCII文字のみです。 |
(オプション) |
柔軟なパラメータの受渡しスキームを使用することを示します。詳細は、3.6.2項「柔軟なパラメータの受渡し」を参照してください。 |
schema (オプション) |
データベース・スキーマ名。指定しない場合、 |
package (オプション) |
PL/SQLストアド・プロシージャを含んだパッケージ。指定しない場合、プロシージャはスタンドアロンになります。 |
proc_name |
実行するPL/SQLストアド・プロシージャ。ファンクションではなく、プロシージャを指定する必要があります。IN引数のみ使用可能です。 |
?query_string (オプション) |
ストアド・プロシージャのパラメータ。この文字列は、GETメソッドの書式に従います。たとえば、次のようになります。
|
例3-1、例3-2および例3-3で、各種プロシージャがどのように実行されるかを説明します。
例3-1 引数をとらないプロシージャの実行
http://www.acme.com:9000/pls/mydad/mypackage.myproc
この場合、www.acme.com
で稼働し、ポート9000
でリスニングしているWebサーバーがリクエストを処理します。Webサーバーは、リクエストを受信すると、そのリクエストをmod_plsqlに渡します。これは、そのWebサーバーがmod_plsqlを実行するように設定されていることが、/pls/mydad
により示されるためです。次に、mod_plsqlは、/pls/mydad
に関連付けられているDADを使用して、mypackage
に格納されているmyproc
プロシージャを実行します。
例3-2 引数をとるプロシージャの実行
http://www.acme.com:9000/pls/mydad/mypackage.myproc?a=v&b=1
この場合、www.acme.com
で稼働し、ポート9000
でリスニングしているWebサーバーがリクエストを処理します。Webサーバーは、リクエストを受信すると、/pls/mydad
に関連付けられているDADを使用して、mypackage
に格納されているmyproc
プロシージャを実行し、2つの引数a
およびb
(それぞれの値はv
および1
)をプロシージャに渡します。
例3-3 DAD設定に格納されているデフォルト・プロシージャの実行
http://www.acme.com:9000/pls/mydad
この場合、www.acme.com
で稼働し、ポート9000
でリスニングしているWebサーバーがリクエストを処理します。Webサーバーは、リクエストを受信すると、/pls/mydad
に関連付けられているDADを使用して、DADに設定されているデフォルト・プロシージャを実行します。たとえば、DAD /pls/mydad
の構成パラメータPlsqlDefaultPage
がmyschema.mypackage.myproc
に設定されている場合、プロシージャmyschema.mypackage.myproc
がリクエストに対して実行されます。
この例では、DAD設定に指定されているmydad
というDADのデフォルトのホームページが表示されます。
HTTPプロトコルのPOSTメソッド、GETメソッドおよびHEADメソッドは、パラメータ・データをアプリケーションに渡す方法(通常は名前/値ペア形式)をブラウザに対して指示します。パラメータ・データはHTMLフォームによって生成されます。
mod_plsqlアプリケーションでは、いずれのメソッドも使用できます。各メソッドの保護レベルは、使用する転送プロトコル(HTTPまたはHTTPS)によって決定されます。
POSTメソッドを使用する場合、パラメータはRequest Body内で渡されます。大量のパラメータ・データをサーバーに渡す場合は、通常、POSTメソッドを使用します。
GETメソッドを使用する場合、パラメータは問合せ文字列を使用して渡されます。このメソッドには、使用するオペレーティング・システムにより、名前/値ペアの値の長さが環境変数の値の最大長を超えることができないという制限があります。さらに、オペレーティング・システムにより、定義できる環境変数の数も制限されます。
HEADメソッドを使用する場合、GETメソッドと同じ機能を使用できます。違いは、HTTPステータス行およびHTTPヘッダーのみが返されることです。コンテンツ・データは、ブラウザに返信されません。このメソッドは、リクエストが正しく処理されているかどうかの確認のみを行うモニタリング・ツールで有効です。
複合モードでの使用: mod_plsqlでは、一部のパラメータを問合せ文字列で渡し、それ以外のパラメータをPOSTデータとして渡すことができます。たとえば、プロシージャfoo
(a varchar2、b number)で、値vと1をそれぞれaとbに渡す場合は、次の3つの方法で値を渡してURLを作成できます。
すべての値を問合せ文字列の一部として指定します。
http://host:port/pls/DAD/foo?a=v&b=1
すべての値をPOSTデータの一部として指定します。
http://host:port/pls/DAD/foo, POST data="a=v&b=1"
一部のパラメータはURLで指定し、それ以外のパラメータはPOSTデータで指定します。
http://host:port/pls/DAD/foo?a=v, POST data="b=1"
注意: POSTデータは、HTMLフォーム上の入力フィールドの一部として生成されます。PL/SQLプロシージャまたはURLに、POST文字列を手動で作成しないでください。HTMLフォームの送信操作により、POSTリクエストが生成され、プロシージャに値が渡されます。 |
プロシージャを実行するためにURLリクエストを処理した後、エラーがあれば、mod_plsqlによりロールバックが実行されます。そうでない場合は、コミットが実行されます。このメカニズムでは、トランザクションが複数のHTTPリクエストにまたがることはできません。この状態を保持しないモデルの場合、アプリケーションは、通常HTTP Cookieまたはデータベース表を使用して状態を維持します。
HTTPでサポートされるのはキャラクタ・ストリームのみのため、mod_plsqlではPL/SQLデータ型の次のサブセットがサポートされます。
NUMBER
VARCHAR2
TABLE OF NUMBER
TABLE OF VARCHAR2
レコードはサポートされません。
mod_plsqlは、次の処理をサポートしています。
名前によるパラメータの受渡し
プロシージャまたはファンクションを起動するURL内の各パラメータは、一意の名前により識別されます。パラメータのオーバーロードがサポートされています。詳細は、3.6.1項「名前によるパラメータの受渡し(パラメータのオーバーロード)」を参照してください。
柔軟なパラメータの受渡し
プロシージャの先頭に感嘆符!
が付加されます。詳細は、3.6.2項「柔軟なパラメータの受渡し」を参照してください。
大きなパラメータ(最大32KB)の受渡し
詳細は、3.6.3項「大きなパラメータの受渡し」を参照してください。
注意: mod_plsqlでは、値をPL/SQL表に格納することで複数の値をとる変数が処理されます。これにより、ユーザーが選択できる値の数を柔軟に設定し、ユーザーによる選択を1単位として簡単に処理できます。それぞれの値は、PL/SQL表の1行に、索引1から順番に格納されます。複数の値をとる変数の最初の値(問合せ文字列に指定されている順)は索引1、同じ変数の2番目の値は索引2に格納されます。mod_plsqlによって渡される引数の順序に、PL/SQLアプリケーションが依存しないようにしてください。引数の順序は突然変わることがあるためです。PL/SQL表の値の順序がプロシージャにとって大きな意味がある場合、PL/SQLアプリケーションを変更して、順序付けを内部的に実行する必要があります。複数の値をとる変数がない場合、変数値はプロシージャのパラメータに位置ではなく名前で渡されるため、変数の順序は重要ではありません。 mod_plsql環境でパラメータとして使用するPL/SQL表は、ベース型を PL/SQL表に対して1つ以上の値が送信されるという保証がない場合(ユーザーがオプションをまったく選択しなくてもよい場合など)は、HIDDENフォーム・エレメントを使用して最初の値を提供します。PL/SQL表に値を提供しないとエラーが生成されます。また、PL/SQL表にはデフォルト値を提供できません。 |
オーバーロードにより、名前が同じでパラメータの数、順序またはデータ型のファミリが異なる複数のサブプログラム(プロシージャまたはファンクション)を使用できます。オーバーロードされたサブプログラムをコールすると、PL/SQLコンパイラは渡されたデータ型に基づいて、どのサブプログラムをコールするかを決定します。
PL/SQLでは、ローカル・サブプログラムとパッケージ・サブプログラムをオーバーロードできます。スタンドアロン・サブプログラムはオーバーロードできません。
パラメータ数が同じサブプログラムをオーバーロードする場合は、パラメータに違う名前を付ける必要があります。HTMLデータはデータ型に関連付けられないため、mod_plsqlは、どのバージョンのサブプログラムをコールすればよいか判断できません。
たとえば、PL/SQLでは、次の例に示すように、プロシージャに対して同じパラメータ名を使用して2つのプロシージャを定義できますが、これをmod_plsqlで使用するとエラーが発生します。
-- legal PL/SQL, but not for mod_plsql CREATE PACKAGE my_pkg AS PROCEDURE my_proc (val IN VARCHAR2); PROCEDURE my_proc (val IN NUMBER); END my_pkg;
エラーを回避するには、パラメータに異なる名前を付けます。たとえば、次のようになります。
-- legal PL/SQL and also works for mod_plsql CREATE PACKAGE my_pkg AS PROCEDURE my_proc (valvc2 IN VARCHAR2); PROCEDURE my_proc (valnum IN NUMBER); END my_pkg;
最初のバージョンのプロシージャを実行するURLは次のようになります。
http://www.acme.com:9000/pls/mydad/my_pkg.my_proc?valvc2=input
2番目のバージョンのプロシージャを実行するURLは次のようになります。
http://www.acme.com:9000/pls/mydad/my_pkg.my_proc?valnum=34
パラメータ名が同じで、1つのプロシージャのデータ型がowa_util.ident_arr
(varchar2の表)、もう1つのプロシージャのデータ型がスカラー型のオーバーロードPL/SQLプロシージャがあるとします。このような場合でも、mod_plsqlはこの2つのプロシージャを区別できます。たとえば、次のプロシージャがあるとします。
CREATE PACKAGE my_pkg AS PROCEDURE my_proc (val IN VARCHAR2); -- scalar data type PROCEDURE my_proc (val IN owa_util.ident_arr); -- array data type END my_pkg;
これらのプロシージャには、それぞれval
という同じ名前のパラメータが1つあります。
mod_plsqlは、val
パラメータの値を1つだけ持つリクエストを受け取ると、例3-4に示すように、スカラー・データ型のプロシージャを実行します。
例3-4 URL送信によるスカラー・バージョンのプロシージャの実行
次のURLを送信して、スカラー・バージョンのプロシージャを実行します。
http://www.acme.com:9000/pls/mydad/my_proc?val=john
mod_plsqlは、val
パラメータの値が複数存在するリクエストを受け取ると、例3-5に示すように、配列データ型のプロシージャを実行します。
ユーザーがエレメントを必要な数だけ選択可能なHTMLフォームを使用できます。これらのエレメントにそれぞれ異なる名前が付いている場合は、オーバーロード・プロシージャを作成して可能な組合せを個別に処理する必要があります。または、問合せ文字列に含まれる名前が、ユーザーが選択するエレメントに関係なく確実に毎回一貫したものになるように、HIDDENフォーム・エレメントを挿入できます。mod_plsqlは、ユーザーが任意の数のエレメントを選択できるHTMLフォームを処理するために、柔軟なパラメータの受渡しをサポートすることで、この操作を容易にします。
URLベースのプロシージャの実行で柔軟なパラメータの受渡しを使用するには、URL内でプロシージャ名の先頭に感嘆符(!)を付加します。2パラメータまたは4パラメータを使用できます。2パラメータ・インタフェースによって、mod_plsqlのパフォーマンスが改善されます。4パラメータ・インタフェースは、互換性維持のためにサポートされています。
procedure [proc_name] (name_array IN [array_type], value_array IN [array_type]);
表3-2に、2パラメータ・インタフェースのパラメータを示します。
表3-2 2パラメータ・インタフェースのパラメータ
パラメータ | 説明 |
---|---|
(必須) |
実行するPL/SQLプロシージャの名前。 |
|
問合せ文字列から取り出される名前(1から順番に索引付けされる)を送信された順序で示します。 |
|
問合せ文字列から取り出される値(1から順番に索引付けされる)を送信された順序で示します。 |
(必須) |
varchar2型(owa.vc_arrなど)の表による任意のPL/SQL索引。 |
例3-6に、2パラメータ・インタフェースの使用例を示します。
例3-6 2パラメータ・インタフェース
次のURLを送信します。
http://www.acme.com:9000/pls/mydad/!scott.my_proc?x=john&y=10&z=doe
感嘆符(!)接頭辞により、柔軟なパラメータの受渡しを使用することがmod_plsqlに指示されます。これにより、プロシージャscott.myproc
が実行され、次の2つの引数が渡されます。
name_array ==> ('x', 'y', 'z') value_array ==> ('john', '10', 'doe')
注意: このスタイルの柔軟なパラメータの受渡しを使用する場合は、パラメータname_array およびvalue_array を使用してプロシージャを定義する必要があります。これらの引数のデータ型は、例に示したデータ型と一致する必要があります。 |
4パラメータ・インタフェースは、互換性維持のためにサポートされています。
procedure [proc_name] (num_entires IN NUMBER, name_array IN [array_type], value_array IN [array_type], reserved in [array_type]);
表3-3に、4パラメータ・インタフェースのパラメータを示します。
表3-3 4パラメータ・インタフェースのパラメータ
パラメータ | 説明 |
---|---|
(必須) |
実行するPL/SQLプロシージャの名前。 |
|
問合せ文字列内の名前/値ペアの数。 |
|
問合せ文字列から取り出される名前(1から順番に索引付けされる)を送信された順序で示します。 |
|
問合せ文字列から取り出される値(1から順番に索引付けされる)を送信された順序で示します。 |
|
未使用。今後使用するために予約されています。 |
(必須) |
varchar2型(owa.vc_arrなど)の表による任意のPL/SQL索引。 |
例3-7に、4パラメータ・インタフェースの使用例を示します。
例3-7 4パラメータ・インタフェース
query_stringで名前「x」が重複している次のURLを送信します。
http://www.acme.com:9000/pls/mydad/!scott.my_pkg.my_proc?x=a&y=b&x=c
感嘆符(!)接頭辞により、柔軟なパラメータの受渡しを使用することがmod_plsqlに指示されます。これにより、プロシージャscott.my_pkg.myproc
が実行され、次の引数が渡されます。
num_entries ==> 3 name_array ==> ('x', 'y', 'x'); value_array ==> ('a', 'b', 'c') reserved ==> ()
注意: このスタイルの柔軟なパラメータの受渡しを使用する場合は、パラメータnum_entries 、name_array 、value_array およびreserved を使用してプロシージャを定義する必要があります。これらの引数のデータ型は、例に示したデータ型と一致する必要があります。 |
スカラー引数として渡される値と、varchar2引数の索引付き表の要素として渡される値に使用できるサイズは、最大32KBです。
たとえば、柔軟なパラメータの受渡し(3.6.2項「柔軟なパラメータの受渡し」を参照)を使用する場合、URLのquery_string
部分の名前または値は、それぞれ実行されるプロシージャのname_array
またはvalue_array
引数のエレメントとして渡されます。これらの名前または値に使用できるサイズは、最大32KBです。
mod_plsqlでは、次の機能を提供します。
キャラクタ・セットを変換せずに、ファイルをロー・バイト・ストリームとしてアップロードおよびダウンロードすることができます。ファイルは、ドキュメント表にアップロードされます。PL/SQLアップロード・ハンドラ・ルーチンが適切な表の列を取得できるよう、主キーが渡されます。
異なるアプリケーションのアップロード対象ファイルを混同しないよう、DADごとにドキュメント表を1つ指定することができます。また、バイナリ・ラージ・オブジェクト(BLOB)のダイレクト・ダウンロード機能を使用すると、データベース表からコンテンツをダウンロードできます。
問合せ文字列を使用しない形式のURL経由でこれらの表のファイルにアクセスすることができます。たとえば、次のようになります。
http://www.acme.com:9000/pls/mydad/docs/cs250/lecture1.htm
これは、URLの相互参照を含んだファイル・セットのアップロードをサポートするために必要です。
フォーム送信ごとに複数のファイルをアップロードすることができます。
ドキュメント表のLONG RAWおよびBLOB型の列にファイルをアップロードすることができます。
この項の内容は、次のとおりです。
DADごとにドキュメント格納表を指定できます。ドキュメント格納表には、次の定義が必要です。
CREATE TABLE [table_name] ( NAME VARCHAR2(256) UNIQUE NOT NULL, MIME_TYPE VARCHAR2(128), DOC_SIZE NUMBER, DAD_CHARSET VARCHAR2(128), LAST_UPDATED DATE, CONTENT_TYPE VARCHAR2(128), [content_column_name] [content_column_type] [ , [content_column_name] [content_column_type]] );
table_name
は、ユーザーが選択できます。content_column_type
型には、LONG RAWまたはBLOBのいずれかを使用します。
content_column_name
は、対応するcontent_column_type
によって異なります。
content_column_typeがLONG RAWの場合、content_column_name
はCONTENTにする必要があります。
content_column_typeがBLOBの場合、content_column_name
はBLOB_CONTENTにする必要があります。
次に、有効なドキュメント表の定義例を示します。
CREATE TABLE MYDOCTABLE ( NAME VARCHAR(256) UNIQUE NOT NULL, MIME_TYPE VARCHAR(128), DOC_SIZE NUMBER, DAD_CHARSET VARCHAR(128), LAST_UPDATED DATE, CONTENT_TYPE VARCHAR(128), CONTENT LONG RAW, BLOB_CONTENT BLOB ; );
表の内容は、CONTENT列に格納されます。ドキュメント表には、複数のCONTENT列を含めることが可能です。ただし、ドキュメント表の各行について、使用されるCONTENT列は1つのみです。その他のCONTENT列はNULLに設定されます。
CONTENT_TYPE
列は、ドキュメントが格納されているCONTENT列を追跡するために使用されます。ドキュメントがアップロードされると、mod_plsqlにより、この列の値が型名に設定されます。
たとえば、ドキュメントがBLOB_CONTENT列にアップロードされた場合、ドキュメントのCONTENT_TYPE
列には文字列BLOBが設定されます。
LAST_UPDATED
列には、ドキュメントの作成日時または最終更新日時が反映されます。ドキュメントがアップロードされると、mod_plsqlにより、ドキュメントのLAST_UPDATED
列にデータベース・サーバーの時間が設定されます。
その後、アプリケーションがドキュメントの内容または属性を変更する場合、LAST_UPDATED
の時間も更新されるようにする必要があります。
mod_plsqlでは、LAST_UPDATED
列を使用して、HTTPクライアント(ブラウザ)がドキュメントのキャッシュ済バージョンを使用できるかどうかをチェックし、HTTPクライアントに結果を知らせます。これにより、ネットワークの通信量が削減され、サーバーのパフォーマンスが改善されます。
WebDBリリース2.xより前のリリースで使用されているドキュメント・モデルとの下位互換性を維持するために、mod_plsqlでは、CONTENT_TYPE、DAD_CHARSETおよびLAST_UPDATED列が存在しない、以前のドキュメント格納表の定義もサポートしています。
/* older style document table definition (DEPRECATED) */ CREATE TABLE [table_name] ( NAME VARCHAR2(128), MIME_TYPE VARCHAR2(128), DOC_SIZE NUMBER, CONTENT LONG RAW
);
DADの次の設定パラメータが、ドキュメントのアップロードまたはダウンロード操作に影響します。
例3-8に、構成パラメータの使用例とその結果を示します。
例3-8 ドキュメントのアップロード/ダウンロードのパラメータ
DADでこれらのパラメータが次のように設定されているとします。
PlsqlDocumentTablename scott.my_document_table PlsqlUploadAsLongRaw html PlsqlDocumentPath docs PlsqlDocumentProcedure scott.my_doc_download_procedure
この場合は次のようになります。
mod_plsqlは、scottスキーマのmy_document_tableデータベース表からデータを取得するか、この表にデータを格納します。
.html
を除くすべてのファイル拡張子は、ドキュメント表にBLOBとしてアップロードされます。.html
拡張子が付いたファイルはすべてLong Rawとしてアップロードされます。
DAD locationの直後にdocsキーワードを含むすべてのURLでは、scott.my_doc_download_procedureプロシージャが実行されます。
通常、このプロシージャはwpg_docload.download_fileをコールして、URL指定に基づく名前を持ったファイルのダウンロードを開始します。
次に前述の構成の単純な例を示します。
http://www.acme.com:9000/pls/dad/docs/index.html
この場合は、scott.my_document_tableデータベース表のLong Raw列からindex.html
ファイルがダウンロードされます。アプリケーション・プロシージャは、開始するファイルのダウンロードを完全に制御し、ファイル・レベルのアクセス制御とバージョニングを実装する、より複雑なPlsqlDocumentProcedure
を柔軟に定義します。
注意: アプリケーション定義プロシージャscott.my_doc_download_procedureは引数なしで定義し、CGI環境変数に応じてリクエストを処理する必要があります。 |
PlsqlDocumentTablename
パラメータは、このDADによってファイルがアップロードされたときにドキュメントを格納する表を指定します。
構文:
PlsqlDocumentTablename [document_table_name] PlsqlDocumentTablename my_documents
または
PlsqlDocumentTablename scott.my_document_table
PlsqlDocumentPath
パラメータは、ドキュメントにアクセスするためのパス・エレメントを指定します。PlsqlDocumentPath
パラメータは、URL内でDAD名の後に付加されます。たとえば、ドキュメント・アクセス・パスがdocs
の場合、URLは次のようになります。
http://www.acme.com:9000/pls/mydad/docs/myfile.htm
mydad
はDAD名で、myfile.htm
はファイル名です。
構文:
PlsqlDocumentPath [document_access_path_name]
PlsqlDocumentProcedure
プロシージャは、アプリケーション指定のプロシージャです。このプロシージャはパラメータがなく、ドキュメント・アクセス・パスを持つURLリクエストを処理します。ドキュメント・アクセス・プロシージャは、ファイルをダウンロードするために、wpg_docload.download_file(filename)
をコールします。ドキュメント・アクセス・プロシージャは、URL指定に基づいてファイル名を認識します。たとえば、アプリケーションでこれを使用して、ファイル・レベルのアクセス制御やバージョン管理を実装することが可能です。このようなアプリケーションの例は、3.7.7項「ファイルのダウンロード」にあります。
構文:
PlsqlDocumentProcedure [document_access_procedure_name]
例3-9に、PlsqlDocumentProcedureプロシージャの使用例を示します。
DADパラメータPlsqlUploadAsLongRaw
は、ファイル拡張子に基づいてファイルのアップロードを設定します。PlsqlUploadAsLongRaw
DADパラメータの値は、1行に1つのエントリがあるファイル拡張子のリストです。これらの拡張子を持つファイルは、mod_plsqlにより、ドキュメント表のLONG RAW
型のCONTENT列にアップロードされます。他の拡張子を持つファイルは、BLOB CONTENT列にアップロードされます。
ファイル拡張子には、テキスト・リテラル(jpeg、gifなど)またはアスタリスク(*)を使用できます。アスタリスクは、PlsqlUploadAsLongRaw
設定でリストされていない拡張子を持つすべてのファイルと一致します。
構文:
PlsqlUploadAsLongRaw [file_extension] PlsqlUploadAsLongRaw *
例3-10に示すように、[file_extension]
はファイル拡張子(ピリオド(.)の有無は関係なく、たとえば、txtまたは.txtが使用できます)またはワイルド・カード文字(*)です。
例3-10に、PlsqlUploadAsLongRawプロシージャの使用例を示します。
クライアント・マシンからデータベースにファイルを送信する場合は、次に示す内容を含んだHTMLページを作成します。
enctype
属性にmultipart/form-data
が設定され、action
属性に「アクション・プロシージャ」と呼ばれるmod_plsqlプロシージャ・コールが関連付けられているFORMタグ。
type属性とname属性にfileが設定されたINPUTエレメント。INPUT type="file"
エレメントを使用すると、ユーザーはファイル・システムのファイルを参照して、そこからファイルを選択できます。
ユーザーが「Submit」ボタンをクリックすると、次のイベントが発生します。
ブラウザは、ユーザーが指定したファイルとその他のフォーム・データをサーバーにアップロードします。
mod_plsqlは、ファイルの内容をデータベースのドキュメント格納表内に格納します。表の名前は、PlsqlDocumentTablename
DAD設定から取得されます。
FORMのaction
属性で指定したアクション・プロシージャが、ファイルのアップロードを行わずにmod_plsqlプロシージャを実行する場合と同じように実行されます。
注意: HTMLドキュメントの解析は、mod_plsqlでは非推奨となりました。以前は、HTMLファイルのアップロード時にmod_plsqlを使用してその内容が解析され、HTMLドキュメントが参照している他のファイルが識別されていました。その後、この情報が表に格納されていました。表の名前は、ドキュメント表の名前にpartを追加したものが使用されていました。この機能は、カスタマにとって有用でないことが判明したため、リリース9.0.4のmod_plsqlから非推奨となりました。 |
次の例に、アップロードするファイルをユーザーがファイル・システムから選択できるHTMLフォームを示します。このフォームには、ファイルに関する情報を入力できるその他のフィールドも含まれています。
<html> <head> <title>test upload</title> </head> <body> <FORM enctype="multipart/form-data" action="pls/mydad/write_info" method="POST"> <p>Author's Name:<INPUT type="text" name="who"> <p>Description:<INPUT type="text" name="description"><br> <p>File to upload:<INPUT type="file" name="filename"><br> <p><INPUT type="submit"> </FORM> </body> </html>
ユーザーがフォームの「Submit」ボタンをクリックすると、次の処理が実行されます。
ブラウザにより、INPUT type="file"
エレメントにリストされたファイルがアップロードされます。
次に、write_info
プロシージャが実行されます。
このプロシージャは、フォームのフィールドの情報をデータベース内の表に書き込み、ページをユーザーに返します。
注意: アクション・プロシージャでは、ユーザーにレスポンスを返す必要はありませんが、次に示すように、送信が成功したか失敗したかをユーザーに知らせるようにすることをお薦めします。 |
procedure write_info ( who in varchar2, description in varchar2, filename in varchar2) as begin insert into myTable values (who, description, filename); htp.htmlopen; htp.headopen; htp.title('Filename Uploaded'); htp.headclose; htp.bodyopen; htp.header(1, 'Upload Status'); htp.print('Uploaded ' || filename || ' successfully'); htp.bodyclose; htp.htmlclose; end;
名前の競合の可能性を低減するために、ブラウザから取得したファイル名の先頭に、生成されたディレクトリ名が付加されます。フォームで指定されたアクション・プロシージャにより、この名前が変更されます。このため、たとえば/private/minutes.txt
がアップロードされた場合、mod_plsqlによって表に格納される名前は、F9080/private/minutes.txt
となります。アプリケーションは、コールしたストアド・プロシージャの中で、この名前を変更できます。たとえば、アプリケーションにより、名前をscott/minutes.txt
に変更できます。
関連資料: RFC 1867『Form-Based File Upload in HTML』(IETF) |
ストアド・プロシージャは、アップロード・ファイルの名前を変更する以外にも、他のファイル属性を変更できます。たとえば、3.7.4項「ファイルのアップロード」に示した例のフォームでは、アップロードされるドキュメントのMultipurpose Internet Mail Extension(MIME)タイプをユーザーが入力可能なフィールドとして表示できます。
MIMEタイプは、write_info
のパラメータとして受信できます。その場合、ドキュメント表には、ファイルのアップロード時にmod_plsqlがマルチパート・フォームから解析したデフォルトのMIMEタイプではなく、そのドキュメントのMIMEタイプが格納されます。
1回の送信で複数のファイルを送信する場合は、アップロード・フォームに適切な"name"属性がある複数の<INPUT type="file"エレメントが含まれている必要があります。複数のファイルのINPUTエレメントで、name
に同じ名前を定義する場合、アクション・プロシージャでパラメータ名をowa.vc_arr
型として宣言する必要があります。ファイルのINPUTエレメントに一意の名前を定義することも可能で、その場合、アクション・プロシージャでそれぞれをvarchar2として宣言する必要があります。たとえば、フォームに次のエレメントが含まれているとします。
<INPUT type="file" name="textfiles"> <INPUT type="file" name="textfiles"> <INPUT type="file" name="binaryfile">
この場合、アクション・プロシージャに次のパラメータを含める必要があります。
procedure handle_text_and_binary_files(textfiles IN owa.vc_arr, binaryfile IN varchar2).
ファイルをデータベースにアップロードした後、次に説明する3つの方法で、それらのファイルをデータベースからダウンロードできます。
wpg_docload.download_file(file_name)
をコールしてファイルfile_name
をダウンロードするPL/SQLプロシージャを定義します。
ドキュメント・ダウンロード用の仮想パス(PlsqlDocumentPath
)をDAD設定に定義し、ユーザー定義のプロシージャ(PlsqlDocumentProcedure
)とそのパスを関連付けます。mod_plsqlは、DAD名のすぐ後ろにPlsqlDocumentPath
で指定された仮想パスを検出すると、ユーザー定義のプロシージャ(PlsqlDocumentProcedure
)を自動的に起動します。このプロシージャは、wpg_docload.download_file(file_name)
をコールしてファイルfile_name
のダウンロードを開始する必要があります。追加の引数を渡さずに起動されるように、このユーザー定義のプロシージャにはプロトタイプが必要です。
たとえば、DADのmydadでPlsqlDocumentPath
がdocs
として、PlsqlDocumentProcedure
がmyschema.pkg.process_download
として構成されている場合、URLの形式がhttp://www.acme.com:9000/pls/mydad/docs/myfile.htm
のときは常に、mod_plsqlはプロシージャmyschema.pkg.process_download
を実行します。
次に、process_downloadの実装例を示します。
procedure process_download is v_filename varchar2(255); begin -- getfilepath() uses the SCRIPT_NAME and PATH_INFO cgi -- environment variables to construct the full path name of -- the file URL, and then returns the part of the path name -- following '/docs/' v_filename := getfilepath; select name into v_filename from plsql_gateway_doc where UPPER(name) = UPPER(v_filename); -- now we call docload.download_file to initiate -- the download. wpg_docload.download_file(v_filename); exception when others then v_filename := null; end process_download;
バイナリ・ラージ・オブジェクト(BLOB)のダイレクト・ダウンロード・メカニズムを使用して、BLOBをデータベース表からダウンロードします。このためには、次に示すように、標準のHTTPヘッダー(MIMEタイプやコンテンツ長など)を返すPL/SQLプロシージャをコールし、wpg_docload.download_file(blob_name)
を起動してBLOBのblob_name
をダウンロードします。
wpg_docload.download_file(blob)
をコールするストアド・プロシージャを作成します。blob
はBLOBデータ型です。mod_plsqlにはBLOBの内容に関する情報が含まれていないため、情報を入力する必要があります。
Content-Typeおよびその他のヘッダーを設定します。
次の例では、プロシージャは引数の名前を使用して表からBLOBを選択し、BLOBのダイレクト・ダウンロードを開始します。
create or replace procedure download_blob(name in varchar2) is myblob blob; begin
name引数を使用して、mytableからBLOBを選択します。
select blob_data into myblob from mytable where blob_name = name;
コンテンツを記述するヘッダーを設定します。
owa_util.mime_header('text/html', FALSE); htp.p('Content-Length: ' || dbms_lob.getlength(myblob)); owa_util.http_header_close;
BLOBのダイレクト・ダウンロードを開始します。
wpg_docload.download_file(myblob); end;
mytable
表の構造は、次のとおりです。
create table mytable ( blob_name varchar2(128), blob_data blob );
ドキュメント・ダウンロードが開始されても、BLOBのダイレクト・ダウンロードが使用されない場合は、wpg_docload.download_file
に渡される引数により、ファイル名を一意に識別してドキュメント表からダウンロードできるようにする必要があります。このようなドキュメントの内容の返信時に、mod_plsqlは、そのファイル名に対するドキュメント表エントリの他の列に格納された情報に基づいて、HTTPレスポンス・ヘッダーを生成します。MIME_TYPE列、DOC_SIZE列およびLAST_UPDATED列はそれぞれ、レスポンス・ヘッダーのContent-Typeヘッダー、Content-LengthヘッダーおよびIf-Modified-Sinceヘッダーを追加するために使用されます。
注意: wpg_docload.download_file APIをプロシージャからコールするたびに、ファイル・ダウンロード操作がmod_plsqlにより開始されます。このような操作では、プロシージャによって生成される他のHTMLコンテンツは、ブラウザには渡されません。 |
マルチバイト・キャラクタを使用するドキュメントのダウンロード
Windowsプラットフォームでmod_plsqlを使用しており、マルチバイト・キャラクタ・セット(日本語または韓国語)の一部として特殊文字0x5cを含むマルチバイト・データベースに対して実行している場合、ファイルdads.conf
を変更して、アプリケーションへのアクセスに使用されるDADを編集する必要があります。このためには、次の手順を実行します。
ORACLE_INSTANCE\config\OHS\ohs1\mod_plsql\dads.conf
ファイルを開きます。
アプリケーションのアクセスに使用されるDADを探します。
WindowsFileConversion Off
の行をこのDADエントリに追加します。
ファイルを保存します。
Oracle HTTP Serverを再起動します。
DAD設定を更新しないと、ファイル名に0x5cが含まれるドキュメントのダウンロード時に障害が発生します。たとえば、次のようになります。
Oracle Portalで、次のダウンロード・エラーが示されます。
Error: Document not found (WWC-46000)
ユーザー独自のPL/SQLアプリケーションに対してmod_plsqlを使用すると、ファイルのダウンロードで次のエラーが発生します。
HTTP-404 Not Found
パスのエイリアシングにより、mod_plsqlを使用するアプリケーションは、単純なURLによるアプリケーション内のオブジェクトへの直接参照を提供できます。この機能は、ドキュメント・ダウンロード機能の提供方法を汎用化するものです。パスのエイリアシングには、DADの次の設定パラメータを使用します。
PlsqlPathAlias
PlsqlPathAliasProcedure
たとえば、DADでこれらのパラメータが次のように設定されているとします。
PlsqlPathAlias myalias PlsqlPathAliasProcedure scott.my_path_alias_procedure
この場合、DAD locationの直後にmyaliasキーワードを含むすべてのURLで、scott.my_path_alias_procedure
プロシージャが実行されます。このプロシージャは、URL指定に基づいて適切なレスポンスを開始できます。
注意: アプリケーション定義プロシージャscott.my_path_alias_procedure は、varchar2 型のp_pathという引数を1つとるように定義する必要があります。この引数は、PlsqlPathAlias に使用されているキーワードに続くすべてを受け取ります。
たとえば、前述の構成で次のURLがあるとします。
このURLにより、scott.my_path_alias_procedureプロシージャはMyFolder/MyItem引数を受け取ります。 |
OWA_UTILパッケージには、CGI環境変数の値を取得するためのAPIが付属しています。CGI環境変数の値は、mod_plsqlによって実行されるプロシージャにコンテキストを提供します。mod_plsqlはCGIによって処理されませんが、mod_plsqlから実行されるPL/SQLアプリケーションは、これらのCGI環境変数にアクセス可能です。
CGI環境変数のリストは次のとおりです。
HTTP_AUTHORIZATION
DAD_NAME
DOC_ACCESS_PATH
HTTP_ACCEPT
HTTP_ACCEPT_CHARSET
HTTP_ACCEPT_LANGUAGE
HTTP_COOKIE
HTTP_HOST
HTTP_PRAGMA
HTTP_REFERER
HTTP_USER_AGENT
PATH_ALIAS
PATH_INFO
HTTP_ORACLE_ECID
DOCUMENT_TABLE
REMOTE_ADDR
REMOTE_HOST
REMOTE_USER
REQUEST_CHARSET(3.9.2.1項「REQUEST_CHARSET CGI環境変数」を参照)
REQUEST_IANA_CHARSET(3.9.2.2項「REQUEST_IANA_CHARSET CGI環境変数」を参照)
REQUEST_METHOD
REQUEST_PROTOCOL
SCRIPT_NAME
SCRIPT_PREFIX
SERVER_NAME
SERVER_PORT
SERVER_PROTOCOL
PL/SQLアプリケーションは、owa_util.get_cgi_envインタフェースを使用してCGI環境変数の値を取得できます。
構文:
owa_util.get_cgi_env(param_name in varchar2) return varchar2;
param_nameは、CGI環境変数の名前です。param_nameには大/小文字の区別があります。
PlsqlCGIEnvironmentList
DADパラメータは、1行に1つのエントリがある、名前/値ペアのリストです。任意の環境変数のオーバーライドや、新規の環境変数の追加ができます。名前が付属の環境変数(3.9項「Common Gateway Interface(CGI)環境変数」のリストを参照)の1つである場合、その環境変数は指定した値でオーバーライドされます。名前が付属の環境変数のリストにない場合は、パラメータで指定された名前および値と同じ新規の環境変数がリストに追加されます。
注意: mod_plsqlの設定ファイルについては、『Oracle Fusion Middleware Oracle HTTP Server管理者ガイド』を参照してください。 |
パラメータの値が指定されていない場合は、Oracle HTTP Serverから値が取得されます。Oracle HTTP Serverの場合は、次のように指定してCGI環境変数のDOCUMENT_ROOTを渡すことができます。
PlsqlCGIEnvironmentList DOCUMENT_ROOT
この設定パラメータから渡された新規の環境変数は、owa_util.get_cgi_envインタフェースを経由してPL/SQLアプリケーションで使用できます。
例3-11に、環境変数のオーバーライドが指定されたPlsqlCGIEnvironmentListの使用例を示します。
例3-11 環境変数のオーバーライドが指定されたPlsqlCGIEnvironmentList
PlsqlCGIEnvironmentList SERVER_NAME=myhost.mycompany.com PlsqlCGIEnvironmentList REMOTE_USER=testuser
この例では、CGI環境変数のSERVER_NAMEとREMOTE_USERが付属の環境変数リストに含まれているため、これらの環境変数が指定の値にオーバーライドされます。
例3-12に、新規の環境変数が指定されたPlsqlCGIEnvironmentListの使用例を示します。
例3-12 新規の環境変数が指定されたPlsqlCGIEnvironmentList
PlsqlCGIEnvironmentList MYENV_VAR=testing PlsqlCGIEnvironmentList SERVER_NAME= PlsqlCGIEnvironmentList REMOTE_USER=user2
この例では、SERVER_NAME変数とREMOTE_USER変数がオーバーライドされます。SERVER_NAME変数は、値が指定されていないため、削除されます。MYENV_VARという新規の環境変数は、付属の環境変数のリストに含まれていないため追加されます。この環境変数には、「testing」という値が割り当てられます。
mod_plsqlでは、PlsqlNLSLanguage
のDADレベルの設定により、グローバリゼーション・サポート設定が制御されます。DADレベルでPlsqlNLSLanguageが設定されていない場合、グローバリゼーション・サポート設定にはOracleのNLS_LANGパラメータの環境設定が使用されます。このパラメータの詳細は、『Oracle Fusion Middleware Oracle HTTP Server管理者ガイド』の「mod_plsql」を参照してください。
CGI環境変数REQUEST_CHARSETは、PlsqlNLSLanguage
の設定に基づいて設定されます。DADレベルでPlsqlNLSLanguage
が設定されていない場合、グローバリゼーション・サポート設定にはOracleのNLS_LANGパラメータの環境設定が使用されます。
PL/SQLアプリケーションは、ファンクション・コールによってこの情報にアクセスできます。たとえば、次のようになります。
owa_util.get_cgi_env('REQUEST_CHARSET');
キャッシングを使用すると、PL/SQLベースのWebアプリケーションのパフォーマンスを向上させることができます。パフォーマンスを向上させるために、中間層のPL/SQLプロシージャによって生成されたWebコンテンツをキャッシュして、データベースのワークロードを減少させることができます。
この項では、次のようなキャッシングの方式について説明します。
検証方式の使用: アプリケーションは、ページが最後に提示されてから変更があったかどうかをサーバーに確認します。
期限方式の使用: PL/SQLベースのWebアプリケーションは、特定の時間間隔に基づいて、ページをキャッシュするか、または再度生成する必要があるかを決定します。
PL/SQLベースのWebアプリケーションでのシステム・レベルおよびユーザー・レベルのキャッシング: 検証方式または期限方式を使用している場合に有効です。キャッシングのレベルは、ページが特定のユーザーに対してキャッシュされるのか、システム内のすべてのユーザーに対してキャッシュされるのかによって決まります。
これらの方式およびレベルは、PL/SQL Web Toolkitに含まれるowa_cache
パッケージを使用して実装されます。
関連資料: 『Oracle Fusion Middleware PL/SQL Web Toolkitリファレンス』 |
通常、検証方式では、ページが最後に提示されてから変更があったかどうかをサーバーに確認します。ページが変更されていない場合、キャッシュされたページがユーザーに提示されます。ページが変更されている場合、新しいコピーを取得してユーザーに提示した後、それをキャッシュします。
検証方式を使用する方法には、Last-Modified方法およびEntity Tag方法の2つがあります。次の2つの項では、これらの方式がHTTPプロトコルでどのように使用されるかを示します。PL/SQL GatewayではHTTPプロトコルを使用しませんが、多くの同じ原則が使用されます。
WebページがHTTPプロトコルを使用して生成されると、そのページにはLast-Modifiedレスポンス・ヘッダーが含まれます。このヘッダーは、リクエストされたコンテンツの日付(サーバーを基準とする)を示しています。ブラウザは、この日付情報をコンテンツとともに保存します。後続のリクエストがWebページのURLに対して作成されると、ブラウザは次の処理を行います。
キャッシュされているバージョンがあるかどうかを確認します。
日付情報を抽出します。
リクエスト・ヘッダーのIf-Modified-Sinceを生成します。
リクエストをサーバーに送信します。
キャッシュ対応のサーバーは、If-Modified-Sinceヘッダーを探し、それをコンテンツの日付と比較します。この2つが一致する場合は、「HTTP/1.1 304 Not Modified」などのHTTPレスポンス・ステータス・ヘッダーが生成され、コンテンツは返されません。このステータス・コードを受け取ると、キャッシュ・エントリは有効であるため、ブラウザはそれを再利用できます。
この2つが一致しない場合は、「HTTP/1.1 200 OK」などのHTTPレスポンス・ヘッダーが生成され、新しいコンテンツが、新しいLast-Modifiedレスポンス・ヘッダーとともに返されます。このステータス・コードを受け取ると、ブラウザはキャッシュ・エントリを新しいコンテンツおよび新しい日付情報で置き換える必要があります。
HTTPプロトコルによって提供されるもう1つの検証方法は、ETag(Entity Tag)レスポンス/リクエスト・ヘッダーです。このヘッダーの値は、ブラウザに対して不明瞭な文字列です。サーバーは、この文字列をアプリケーションのタイプに基づいて生成します。この方法は、日付値のみを含めることができるIf-Modified-Sinceヘッダーよりも一般的な検証方法です。
ETag方法は、Last Modified方法とよく似ています。サーバーは、レスポンス・ヘッダーの一部としてETagを生成します。ブラウザは、この不明瞭なヘッダー値を返されたコンテンツとともに格納します。このコンテンツに対する次のリクエストを受信すると、ブラウザは、格納された不明瞭な値をIf-Matchヘッダーに設定してサーバーに渡します。サーバーがこの不明瞭な値を生成しているため、何をブラウザに返すかを判別できます。その他は、前述したLast-Modified検証方法とまったく同じです。
HTTP検証キャッシングをフレームワークとして使用すると、mod_plsqlの検証モデルは次のようになります。
処理されるコンテンツを制御するPL/SQLベースのWebアプリケーションでは、この種のキャッシングを使用する必要があります。この方式を使用すると、適度にパフォーマンスが改善されます。たとえば、常に変わる動的コンテンツを処理するWebアプリケーションがこれに該当します。この場合、Webアプリケーションには、処理対象に対する完全な制御が必要です。検証キャッシングでは、キャッシュされたコンテンツが古いものか、またはブラウザに返された後のものであるかをWebアプリケーションに常に確認します。
図3-2は、mod_plsqlで検証方式が使用される仕組みを表したものです。
Oracle HTTP Serverがクライアント・サーバーからPL/SQLプロシージャ・リクエストを受信します。Oracle HTTP Serverは、そのリクエストをmod_plsqlにルーティングします。
mod_plsqlはリクエストを準備します。
mod_plsqlはWebアプリケーションでPL/SQLプロシージャを起動し、通常のCommon Gateway Interface(CGI)環境変数をWebアプリケーションに渡します。
PL/SQLプロシージャは、返すためのコンテンツを生成します。PL/SQLプロシージャが生成されたコンテンツをキャッシュ可能であると判断した場合、PL/SQL Web Toolkitのowa_cache
プロシージャをコールし、タグおよびキャッシュ・レベルを設定します。
owa_cache.set_cache(p_etag, p_level);
表3-4に、検証モデルのパラメータを示します。
表3-4 検証モデルのパラメータ
パラメータ | 説明 |
---|---|
|
返されたコンテンツがキャッシュできることをmod_plsqlに通知するためのヘッダーを設定します。その後、コンテンツがブラウザに返される際に、mod_plsqlは、タグおよびキャッシング・レベル情報とともにコンテンツをローカル・ファイル・システムにキャッシュします。 |
|
コンテンツをタグ付けするためにプロシージャが生成する文字列。 |
|
キャッシング・レベル: |
HTMLがmod_plsqlに返されます。
mod_plsqlは、次のリクエストのために、キャッシュ可能なコンテンツをファイル・システムに格納します。
Oracle HTTP Serverは、そのレスポンスをクライアント・ブラウザに送信します。
mod_plsqlの検証方式を使用し、クライアント・ブラウザによって、同じPL/SQLプロシージャに対する2番目のリクエストが作成されます。
図3-3に、検証方式を使用した2番目のリクエストを示します。
mod_plsqlは、リクエストに対してキャッシュされたコンテンツがあることを検出します。
mod_plsqlは、(最初のリクエストからの)同じタグおよびキャッシング・レベル情報をCGI環境変数の一部としてPL/SQLプロシージャに転送します。
PL/SQLプロシージャは、これらのキャッシングCGI環境変数を使用して、コンテンツが変更されているかどうかを確認します。そのために、PL/SQL Web Toolkitの次のowa_cache
ファンクションをコールします。
owa_cache.get_etag; owa_cache.get_level;
これらのowaファンクションが、タグおよびキャッシング・レベルを取得します。
Webアプリケーションは、このキャッシング情報をmod_plsqlに送信します。
この情報に基づいて、コンテンツを再生成する必要があるか、またはキャッシュから取得できるかを判別します。
コンテンツが同じである場合は、プロシージャはowa_cache.set_not_modified
プロシージャをコールし、コンテンツを生成しません。このため、mod_plsqlではキャッシュされたコンテンツを使用します。このキャッシュされたコンテンツは、ブラウザに直接返されます。
コンテンツが変更されている場合は、新しいコンテンツを新しいタグおよびキャッシング・レベルとともに生成します。mod_plsqlは古いキャッシュのコピーを新しいものに置き換え、タグおよびキャッシング・レベル情報を更新します。新しく生成されたコンテンツが、ブラウザに返されます。
検証モデルでは、mod_plsqlは、キャッシュからコンテンツを提供できるかどうかを常にPL/SQLプロシージャに確認します。期限モデルでは、プロシージャはコンテンツの有効期間をあらかじめ設定します。そのため、mod_plsqlは、プロシージャに確認することなくキャッシュからコンテンツを提供できます。この方式では、データベースとのやり取りが必要ないため、パフォーマンスが一層向上します。
このキャッシング方式を使用すると、最高のパフォーマンスが得られます。PL/SQLベースのWebアプリケーションにおいて、古いコンテンツの提供が問題にならない場合に使用します。たとえば、ニュースを毎日生成するアプリケーションがこれに該当します。ニュースは24時間有効に設定できます。24時間以内であれば、アプリケーションとやり取りせずにキャッシュされたコンテンツが提供されます。これは、基本的にファイルの提供と同じです。24時間を経過すると、mod_plsqlは再度新しいコンテンツをアプリケーションから取得します。
検証モデルで説明したものと同じシナリオを考えてみます。ただし、プロシージャではキャッシングに期限モデルを使用します。
図3-4は、mod_plsqlで期限方式が使用される仕組みを表したものです。
Oracle HTTP Serverがクライアント・サーバーからPL/SQL Server Pageリクエストを受信します。Oracle HTTP Serverは、そのリクエストをmod_plsqlにルーティングします。
mod_plsqlは、リクエストをOracle Databaseに転送します。
mod_plsqlはアプリケーションでPL/SQLプロシージャを起動し、通常のCommon Gateway Interface(CGI)環境変数をアプリケーションに渡します。
PL/SQLプロシージャは、返すためのコンテンツを生成します。PL/SQLプロシージャが生成されたコンテンツをキャッシュ可能であると判断した場合、PL/SQL Web Toolkitのowa_cache
プロシージャをコールし、有効期間およびキャッシュ・レベルを設定します。
owa_cache.set_expires(p_expires, p_level);
表3-5に、期限モデルのパラメータを示します。
表3-5 期限モデルのパラメータ
パラメータ | 説明 |
---|---|
|
期限キャッシングを使用していることをmod_plsqlに通知するためのヘッダーを設定します。その後、mod_plsqlは、有効期間およびキャッシング・レベル情報とともにコンテンツをファイル・システムにキャッシュします。 |
|
コンテンツが有効な分数。 |
|
キャッシング・レベル。 |
HTMLがmod_plsqlに返されます。
mod_plsqlは、次のリクエストのために、キャッシュ可能なコンテンツをファイル・システムに格納します。
Oracle HTTP Serverは、そのレスポンスをクライアント・ブラウザに送信します。
期限方式を使用した2番目のリクエスト
前述の同じ期限モデルを使用し、クライアント・ブラウザによって、同じPL/SQLプロシージャに対する2番目のリクエストが作成されます。
図3-5に、期限方式を使用した2番目のリクエストを示します。
mod_plsqlは、期限ベースの、キャッシュされたコンテンツのコピーがあることを検出します。
mod_plsqlは、現在の時刻とこのキャッシュ・ファイルが作成された時刻の差を取得してコンテンツの有効性を確認します。
この差が有効期間内にある場合は、キャッシュされたコピーはまだ新しいものであるため、データベースとやり取りせずに使用されます。このキャッシュされたコンテンツは、ブラウザに直接返されます。
この差が有効期間内にない場合は、キャッシュされたコピーは古くなっています。mod_plsqlは、PL/SQLプロシージャを起動して、新しいコンテンツを生成します。次に、プロシージャが期限ベースのキャッシングを再度使用するかどうかを決定します。使用する場合は、この新しいコンテンツの有効期間も決定します。新しく生成されたコンテンツが、ブラウザに返されます。
PL/SQLプロシージャは、生成されたコンテンツがシステム・レベルのコンテンツか、ユーザー・レベルのコンテンツかを判断します。これにより、複数のユーザーが同じコンテンツを参照している場合、PL/SQL Gatewayキャッシュによる重複ファイルの格納を減らすことができます。判断は、次の基準で行われます。
システム・レベル・コンテンツの場合、プロシージャは、文字列SYSTEM
をキャッシング・レベル・パラメータとしてowa_cache
ファンクションに渡します(検証モデルの場合はset_cache
、期限モデルの場合はset_expires
)。これは、キャッシュを共有するすべてのユーザーに対して行われます。
システム・レベル・キャッシングを使用すると、ファイル・システムの領域とシステム内のすべてのユーザーに費やす時間の両方を節約できます。たとえば、そのWebアプリケーションを使用しているすべてのユーザーを対象としたコンテンツを生成するWebアプリケーションがこれに該当します。システム・レベル設定でコンテンツをキャッシングすると、コンテンツのコピーは1つのみファイル・システムにキャッシュされます。さらに、コンテンツはキャッシュからディレクトリに提供されるため、そのシステムのすべてのユーザーにメリットがあります。
ユーザー・レベル・コンテンツの場合、プロシージャは、文字列USER
をキャッシング・レベルのパラメータとして渡します。これは、ログインしている特定のユーザーに対して行われます。格納されるキャッシュはそのユーザー独自のものです。そのユーザーのみがキャッシュを使用できます。ユーザーのタイプは、認証モードによって決まります。様々なユーザーのタイプは、表3-6を参照してください。
表3-6 認証モードにより決定されるユーザーのタイプ
認証モード | ユーザーのタイプ |
---|---|
Single Sign-On(SSO) |
軽量ユーザー |
Basic |
データベース・ユーザー |
カスタム |
リモート・ユーザー |
たとえば、PL/SQLベースのWebアプリケーションをカスタマイズしているユーザーがいない場合、出力はシステム・レベル・キャッシュに格納できます。システムのすべてのユーザーに対してキャッシュ・コピーは1つしかありません。複数のユーザーがキャッシュを使用できるため、ユーザー情報は使用されません。
ただし、ユーザーがアプリケーションをカスタマイズしている場合、ユーザー・レベル・キャッシュはそのユーザーに対してのみ格納されます。他のユーザーはすべて、引き続きシステム・レベル・キャッシュを使用します。ユーザー・レベル・キャッシュ・ヒットにおいては、ユーザー情報が基準となります。ユーザー・レベル・キャッシュは、常にシステム・レベル・キャッシュをオーバーライドします。
PL/SQL Web Toolkitのファンクション(owa_cacheパッケージ)
検証方式または期限方式のどちらを使用するのかによって、コールするowa_cache
のファンクションが決まります。
owa_cache
パッケージには、特別なキャッシング・ヘッダーと環境変数を設定および取得するプロシージャが含まれます。開発者は、これらのプロシージャを使用すると、PL/SQL Gatewayキャッシュをより簡単に使用できます。このパッケージは、すでにデータベースにインストールされています。
表3-7に、コール対象の主要なファンクションを示します。
表3-7 主要なowa_cacheのファンクション
owaファンクション | 目的 |
---|---|
|
検証モデル: ヘッダーを設定します。
|
|
検証モデル: キャッシュされたコンテンツを使用するようにmod_plsqlに通知するためのヘッダーを設定します。検証ベースのキャッシュ・ヒットが発生する場合のみ使用されます。 |
|
検証モデル: キャッシング・レベルの |
|
検証モデル: キャッシュされたコンテンツと関連付けられているタグを取得します。キャッシュがヒットしない場合はNULLを返します。 |
|
期限モデル: ヘッダーを設定します。
|
PL/SQLベースのWebアプリケーションのパフォーマンスを向上させるためにmod_plsqlをチューニングする場合、mod_plsqlの内部的な動作に精通していることが重要です。この項では、mod_plsqlのいくつかの機能について概要を説明します。
この項の内容は、次のとおりです。
UNIXプラットフォームでは、mod_plsqlでのデータベース・サーバー接続プーリングのロジックは、例をあげることで最もよく説明できます。次の一般的な例を考えてみます。
Oracle HTTP Serverリスナーが起動されます。mod_plsqlによって保持されている接続プールにデータベース接続はありません。
ブラウザが、データベース・アクセス記述子(DAD)D1に対してmod_plsqlリクエスト(R1)を作成します。
プロセスP1のmod_plsqlが接続プールを確認し、このユーザー・リクエストに対するデータベース接続がプールにないことがわかります。
DAD D1の情報に基づいて、プロセスP1のmod_plsqlが、新しいデータベース接続をオープンし、PL/SQLリクエストを処理して、プールにそのデータベース接続を追加します。
この時点から、DAD D1のプロセスP1に対する後続のすべてのリクエストは、mod_plsqlによってプールされたデータベース接続を使用できます。
注意: 11g UNIXリリースでは、Oracle HTTP Serverはプロセスごとの複数のスレッドをサポートしています。複数の同時mod_plsqlリクエストが1つのOracle HTTP Serverプロセスで処理される場合、mod_plsqlは、必要に応じて同時mod_plsqlリクエストを処理するために追加のデータベース接続をオープンします。 |
DAD D1に対するリクエストが別のプロセス(プロセスP2)で取得された場合、プロセスP2のmod_plsqlは独自のデータベース接続をオープンし、リクエストを処理して、プールにそのデータベース接続を追加します。
この時点から、DAD D1のプロセスP2に対する後続のすべてのリクエストは、mod_plsqlによってプールされたデータベース接続を使用できます。
注意: 複数の同時mod_plsqlリクエストがプロセスP2で処理される場合、必要に応じて同時mod_plsqlデータベース・リクエストに対応するために、追加のデータベース接続がオープンされます。 |
ここで、リクエストR2がDAD D2に対して作成され、このリクエストがプロセスP1にルーティングされるとします。
プロセスP1のmod_plsqlには、DAD D2用にプールされたデータベース接続がないため、新しいデータベース・セッションがDAD D2用に作成され、リクエストを処理した後にプールされます。この時点で、プロセスP1には、2つのデータベース接続がプールされています。1つはDAD D1用、もう1つはDAD D2用です。
ステップ1〜10に示されたこの例で、重要な詳細は次のとおりです。
各Oracle HTTP Serverプロセスは、静的ファイル・リクエスト、サーブレット・リクエストおよびmod_plsqlリクエストなど、すべてのタイプのリクエストを処理します。どのOracle HTTP Serverプロセスが次のリクエストを処理するかは制御できません。
あるOracle HTTP Serverプロセスでは、別のプロセスで作成された接続プールの使用や共有はできません。
各Oracle HTTP Serverプロセスは、DADごとに最大でn
個のmod_plsql接続をプールできます。n
は、データベース・アクティビティの実行に必要な同時mod_plsqlリクエストの合計数です。
ユーザー・セッションは、DADに対してプールされたデータベース接続内で切り替えられます。Oracle Application Server Single Sign-On(SSO)に基づくDADの場合、プロキシ認証を使用してユーザー・セッションが切り替えられます。SSO以外のユーザーの場合、DADにはないユーザー名およびパスワードによるHTTP Basic認証を使用して、ユーザーは同じ接続で再度認証されます。
複数のDADが同じデータベース・インスタンスを指すことがありますが、データベース接続は同じプロセス内であってもDAD間で共有されません。
未使用のDADには、データベース接続がありません。
最悪のシナリオでは、各DADにプールされるデータベース接続の合計数は、Oracle HTTP Server(httpd
)プロセスの合計数と、単一プロセス内の同時mod_plsqlリクエストの最大数を掛けた数になります。Oracle HTTP Serverプロセスを大きい数に設定した場合、それに相当する数のデータベース・セッションを処理するように、バックエンド・データベースを設定する必要があります。この設定値には、バックエンド・データベースを使用するOracle HTTP Serverインスタンスの数を掛ける必要があります。mod_plsqlで必要なデータベース接続最大数を減らす場合は、Oracle HTTP Serverプロセス数の低減を考慮し、必要な同時実効性を達成するように各プロセス内でより多くのスレッドを実行する必要があります。単一プロセス内でより多くのプロセスを実行することの短所の1つとして、あるプロセスの失敗がプロセス内で実行されているすべてのスレッドに影響を与えることがあげられます。
たとえば、Oracle HTTP Serverインスタンスが3つあり、それぞれプロセスごとに1つのスレッドを持つ最大50のhttpd
プロセスを作成するように設定されているとき、アクティブなDADが2つある場合、300(3*50*2
)セッションを処理できるようにデータベースを設定する必要があります。この数には、他のWebアプリケーションが接続するのに必要なセッションは含まれていません。mod_plsqlで必要なデータベース接続最大数を減らす場合は、各インスタンスで50のhttpd
プロセスを実行するのではなく、かわりに各プロセスで5つのスレッドを持つようにOracle HTTP Serverをチューニングして、HTTPDプロセス数を10に減らすことができます。このような設定で、データベース接続数の要求を減らすことができます。mod_plsqlの必要なデータベース接続数は、60(3*10*2
)まで減らすことが可能です。実際には、各プロセスで実際に処理される同時mod_plsqlリクエスト数だけ減ります。
Windowsプラットフォームでは、Oracle HTTP Serverはシングル・プロセスとして実行されます。このようなシステムでは、mod_plsqlの接続プールはスレッド間で共有され、データベース接続の合計数は、各DADに対する同時リクエストの数になります。データベース接続がスレッド間で共有されるため、4.3.4項「2リスナー方針」はWindowsシステムには適用されません。
プールされたデータベース・セッションは、次の状況下でクローズされます。
プールされた接続が、設定された数のリクエストを処理するために使用されている場合。
デフォルトでは、mod_plsqlによってプールされた各接続は、最大1000リクエストを処理するために使用されます。その後、データベース接続は停止され、次のmod_plsqlリクエストで再確立されます。これは、PL/SQLベースのWebアプリケーションまたはOracleのクライアント/サーバー側でのリソース・リークがシステムに悪影響を及ぼさないようにするために行われます。デフォルト値の1000
は、DAD設定パラメータのPlsqlMaxRequestsPerSession
をチューニングして変更します。
プールされた接続が長期間アイドル状態である場合。
デフォルトでは、mod_plsqlのクリーンアップ・スレッドにより、プールされた各接続は、アイドル時間が15分を経過するとクリーンアップされます。アイドル・セッションのタイムアウト値は、構成設定のPlsqlIdleSessionCleanupInterval
によって制御されます。サイトでmod_plsqlのコンテンツにアクセスする頻度が低いほど、アイドル・セッションのクリーンアップはより頻繁に発生するため、ユーザーはあまり使用されないデータベース接続を確立することになります。このような状況では、パフォーマンスを向上させるためにPlsqlIdleSessionTimeoutInterval
のデフォルト設定を大きくすることを検討します。プールされたデータベース接続を長時間オープンにしておくことは、より多くのセッションで使用できるようにするために、データベースに余分な負荷が発生することを意味します。
UNIXシステムで、Oracle HTTP Serverプロセスが停止する場合。
UNIXシステムでは、Oracle HTTP Server構成パラメータのMaxRequestsPerChild
によってOracle HTTP Serverプロセスが停止するタイミングが制御されます。たとえば、このパラメータが5000
に設定されている場合、各Oracle HTTP Serverプロセスは、正確に5000リクエストを処理した後、停止します。また、Oracle HTTP Serverプロセスは、構成パラメータのMinSpareServers
、MaxSpareServers
およびMaxClients
に基づいて、Oracle HTTP Serverのメンテナンスの一環として起動および停止することがあります。
Oracle HTTP Serverが正しく設定されていないと、Oracle HTTP Serverプロセスが頻繁に起動および停止するようになり、その結果、無駄なmod_plsqlの接続プーリングが発生します。最高のパフォーマンスにするには、各Oracle HTTP Serverプロセスが一定時間アクティブの状態を維持し、プロセスが停止しないように、Oracle HTTP Serverを設定します。
関連資料: 『Oracle Fusion Middleware Oracle HTTP Server管理者ガイド』の「mod_plsql」を参照してください。 |
mod_plsqlが接続プールで停止中の接続を検出した場合。
詳細は、3.11.3項「接続プールでの停止中のデータベース接続の検出」を参照してください。
mod_plsqlは、データベースへの接続のプールを保持し、確立されたデータベース接続を後続のリクエストに再利用します。接続プールのデータベース接続からレスポンスがない場合、mod_plsqlはそれを検出して、その停止中の接続を破棄し、新しいデータベース接続を後続のリクエストのために確立します。
mod_plsqlの停止中のデータベース接続の検出機能により、データベース・ノードまたはインスタンスが停止したときのランダムなエラーの発生がなくなります。また、この機能は、Real Application Cluster(RAC)のような高可用性の構成では非常に有効です。あるRACクラスタのノードが停止していると、mod_plsqlはそれを検出し、他のRACノードを使用してリクエストの処理をすぐに開始します。
デフォルトでは、RACノードまたはデータベース・インスタンスが停止し、mod_plsqlがノードへの接続をすでにプールしていた場合、プール内の停止中の接続を使用する最初のmod_plsqlリクエストは、HTTP-503の障害レスポンスがエンド・ユーザーに返されます。mod_plsqlはこの障害を使用して、プール内のすべての停止中の接続の検出および削除をトリガーします。mod_plsqlは、ノード障害が発生する前に作成されたすべての接続プールをpingします。このping操作は、プールされた接続を使用する次のリクエストの処理時に実行されます。ping操作が失敗した場合、そのデータベース接続は破棄され、新しい接続が確立されて処理されます。
注意: ノード障害後、複数のmod_plsqlリクエストを同時に受信し、mod_plsqlがまだ最初の停止中の接続を検出していない場合、その時点では複数の障害が発生する可能性があります。 |
関連項目: mod_plsqlリクエストがサーバーに対して作成されていない場合でも、mod_plsqlが停止中のデータベース接続をクローズする他の状況の詳細は、3.11.2項「プールされたデータベース・セッションのクローズ」を参照してください。 |
mod_plsqlでは、停止中のデータベース接続の検出機能をチューニングするための構成オプションを2つ提供しています。
mod_plsqlは、データベース・ノードの停止が原因と考えられる障害を検出すると接続を修正します。これは、PlsqlConnectionValidation
パラメータによって制御されます。PlsqlConnectionValidationパラメータの詳細は、『Oracle Fusion Middleware Oracle HTTP Server管理者ガイド』の「mod_plsql」を参照してください。
PlsqlConnectionValidation
パラメータがAutomatic
またはAlwaysValidate
に設定されていると、mod_plsqlはプールされているデータベース接続をテストしようとします。
mod_plsqlが接続プール内の不良なデータベース接続をテストするための、タイムアウト期間を指定できます。これは、PlsqlConnectionTimeout
パラメータによって制御されます。このパラメータは、mod_plsqlが、接続が使用できないと判断するまでテスト・リクエストが完了するのを待つ最大時間を指定します。
PlsqlConnectionTimeoutパラメータの詳細は、『Oracle Fusion Middleware Oracle HTTP Server管理者ガイド』の「mod_plsql」を参照してください。
HTTP Cookieヘッダーの最大長は32000バイトです。このバイト数を超えるとエラーが発生します。
HTTP Cookie内にある各Cookieの最大長は3990バイトです。このバイト数を超えるとエラーが発生します。この制限は、配列内の文字列のOCI配列バインド制限によるものです。
mod_plsqlでは、一度に設定できるCookieの最大数は制限されており、変更できません。この制限は、最大数20に設定されています。20を超えると、それ以降のCookieは削除されます。
PL/SQL Gatewayは、OUTパラメータを含むプロシージャをWebインタフェースからコールすることをサポートしていません。この方法でコールするとORA-6502エラーが発生します。OUT変数を含むプロシージャはコールしないことをお薦めします。ただし、現行のアーキテクチャでは、変更後の値が受渡し時の長さを超えないかぎり値を変更できます。この問題が発生する既存のアプリケーションは、次のいずれかの方法で変更する必要があります。
OUTパラメータを含むプロシージャがブラウザURL経由で直接実行されないように、この種のプロシージャのラッパーを実装します。
渡されるパラメータの値が割り当てられるローカル変数を作成し、それを内部的なすべての変更に使用します。
PL/SQLプロシージャに渡すことのできる名前/値ペアの合計数は2000です。
mod_plsqlでは、1つのプロシージャに渡すことのできる1つのパラメータのサイズが32512バイトに制限されます。
同じDAD locationを異なる仮想ホストで使用することはできません。
PlsqlCacheMaxSize
およびPlsqlCacheTotalSize
パラメータに使用できる最大値は、4294967296バイト(4GB)です。これより大きい値を指定すると、mod_plsqlで警告が発生し、内部で値が4GBに設定されます。
mod_plsqlでは、以下はサポートされません。
TYPE.PROCEDUREフォームのWeb-callableプロシージャ。
ブラウザからTYPEオブジェクトのメンバー・プロシージャのコール。
例3-13 Web Callableプロシージャ
CREATE OR REPLACE TYPE wpro06_type AS object ( atr1 VARCHAR2(100), static PROCEDURE sp1 (a VARCHAR2), member PROCEDURE mp1 ); / show errors CREATE OR REPLACE TYPE BODY wpro06_type AS static PROCEDURE sp1 (a VARCHAR2) IS v wpro06_type; BEGIN htp.print('From wpro06_type.sp1 : '|| a ); v := wpro06_type(a); v.mp1; END; member PROCEDURE mp1 IS BEGIN htp.print('From wpro06_type.mp1 : ' || self.atr1); END; END; / show errors
前述の例として、次のURLはサポートされません。
http://<host>:<port>/pls/<DAD>/mytype.sp1?a=HelloWorld
http://<host>:<port>/pls/<DAD>/mytype.mpl