注意: この章で説明するテクノロジの使用は、HTTP通信およびHTML生成を厳密に制御する必要があるアプリケーションに適しています。他のアプリケーションの場合、アプリケーション開発を容易にするためにより多くの機能や便利なグラフィカル・インタフェースを備えたOracle Application Expressを使用することをお薦めします。Oracle Application Expressの使用方法の詳細は、Oracle Database 2日でApplication Express開発者ガイドを参照してください。 |
この章では、データベースをイントラネットで利用可能にする、PL/SQL Webアプリケーションの開発方法について説明します。
内容は次のとおりです。
一般的に、PL/SQLで作成されるWebアプリケーションは、HTTPを介してWebブラウザと対話するストアド・サブプログラムの集合です。相互リンクされた一連の動的に作成されたHTMLページが、Webアプリケーションのユーザー・インタフェースになります。
PL/SQL Webアプリケーションのプログラム・フローは、CGI PERLスクリプトのプログラム・フローに似ています。通常、開発者はCGIスクリプトを使用してWebページを動的に作成しますが、多くの場合それらのスクリプトはデータベースへのアクセスに適していません。PL/SQLストアド・サブプログラムでWebコンテンツを配信することによって、強力で柔軟なデータベース処理が実現されます。たとえば、データ操作言語(DML)、動的SQL文およびカーソルを使用できます。また、各HTTPリクエストを処理するために新しいCGIプロセスを指定する際のプロセス・オーバーヘッドが発生しなくなります。
図14-1に、PL/SQL Webアプリケーションの一般的なプロセスを示します。
Webブラウザベースのアプリケーションは、次のOracle Databaseコンポーネントを使用して、PL/SQLで完全に実装できます。
PL/SQLゲートウェイは、WebブラウザがHTTPリスナーを介してPL/SQLストアド・サブプログラムを起動するのを可能にします。ゲートウェイとは、PL/SQLユーザーがPL/SQL Webアプリケーションを開発およびデプロイするプラットフォームのことです。
mod_plsql
は、PL/SQLゲートウェイの実装の一例です。モジュールとはOracle HTTP Serverのプラグインのことで、WebブラウザがPL/SQLストアド・サブプログラムを起動するのを可能にします。Oracle HTTP Serverは、Oracle Application ServerおよびOracle Databaseのコンポートネントです。
mod_plsql
プラグインを使用すると、PL/SQLストアド・サブプログラムを使用して、HTTPリクエストを処理し、レスポンスを作成できます。このコンテキストでは、HTTPリクエストはストアド・サブプログラムに渡されるパラメータ値を含むURLです。PL/SQLゲートウェイではURLを変換し、そのパラメータでストアド・サブプログラムを起動し、クライアントに出力(通常はHTML)を戻します。
PL/SQLゲートウェイの埋込み形式と比較して、mod_plsql
を使用することのメリットには、次のものがあります。
ファイアウォール環境で実行できます。この環境では、Oracle HTTP Serverがファイアウォールに対応するホスト上で実行され、データベースはファイアウォールの内側にホストされます。埋込みゲートウェイではこの構成を使用できません。
埋込みゲートウェイは、動的HTMLキャッシュ、システム監視、共通ログ形式でのロギングなどのmod_plsql
機能をサポートしていません。
データベースのXML DB HTTP Listenerで稼働するPL/SQLゲートウェイの埋込みバージョンを使用できます。これにより、mod_plsql
のコア機能がデータベースに提供されますが、Oracle HTTP Serverは必要ありません。PL/SQL Web ToolkitにあるDBMS_EPG
パッケージを使用して埋込みPL/SQLゲートウェイを構成します。
mod_plsql
と比較して、埋込みゲートウェイを使用することのメリットには次のものがあります。
Oracle HTTP ServerをインストールせずにApplication ExpressなどのPL/SQL Webアプリケーションを起動できるため、PL/SQLベースのWebアプリケーションのインストール、構成および管理を簡素化できます。
使用されているものと同じ構成手法を使用して、FTPリクエストおよびHTTPリクエストに応じて、Oracle XML DBからコンテンツを提供します。
このPL/SQLパッケージのセットは、実行時にmod_plsql
によって起動されるストアド・サブプログラムを使用可能にする汎用インタフェースです。
ブラウザのリクエストに対するレスポンスで、PL/SQLサブプログラムはユーザー入力に従ってOracle Databaseのデータを更新または取得します。続いて、ストアド・プロシージャはブラウザに対するHTTPレスポンスを生成します。通常はダウンロード・ファイルまたはHTML表示になります。PL/SQL Web Toolkit APIを使用すると、ストアド・サブプログラムで次のような処理を実行できます。
HTTPリクエストの情報の取得
コンテンツタイプおよびMIMEタイプなどのHTTPヘッダーの生成
ブラウザのCookieの設定
HTMLページの生成
表14-1に、一般的に使用されるPL/SQL Toolkitパッケージを示します。
表14-1 PL/SQL Web Toolkitで一般的に使用されるパッケージ
パッケージ | 内容の説明 |
---|---|
|
|
|
HTMLタグを生成するサブプログラム。たとえば、プロシージャ |
|
PL/SQLゲートウェイのキャッシュ機能を使用可能にし、PL/SQL Webアプリケーションのパフォーマンスを向上させるサブプログラム。 このパッケージを使用して、PL/SQLゲートウェイ・ファイル・システムを使用した期限切れベースおよび検証ベースのキャッシュを使用可能にできます。 |
|
クライアントWebブラウザとの間でHTTP Cookieを送受信するサブプログラム。Cookieは、HTTPコール間で状態を保持するためにブラウザで使用される文字列です。状態を保持できるのは、クライアント・セッションの終わりまでか、Cookieの期日が含まれる場合はそれ以上の期間です。 |
|
Cookieで使用される権限ファンクション。 |
|
ユーザーがイメージをクリックした座標を取得するサブプログラム。宛先リンクによりPL/SQLゲートウェイが起動されるイメージ・マップがある場合、このパッケージを使用します。 |
|
更新内容が失われるのを防ぐために、データベース・コミット時ロック方法を強制実行するサブプログラム。このサブプログラムを使用しないと、あるユーザーが、それまでに別のユーザーによって値が変更されている行を選択して更新しようとした場合、更新内容が失われる場合があります。 |
|
正規表現により、文字列一致検索および文字列操作を実行するサブプログラム。 |
|
PL/SQLゲートウェイでリクエストの認証に使用されるサブプログラム。 |
|
|
|
次のタイプのユーティリティ・サブプログラム
|
|
DAD構成を使用して定義したドキュメント・リポジトリからドキュメントをダウンロードするサブプログラム。 |
参照: PL/SQL Web Toolkitパッケージの構文、説明および例は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |
『Oracle HTTP Server mod_plsqlユーザーズ・ガイド』で説明しているように、mod_plsql
は、HTTP上でWebクライアント・リクエストをPL/SQLストアド・サブプログラムにマップします。詳細は、このマニュアルを参照してください。
参照:
|
埋込みゲートウェイ機能は、mod_plsql
ゲートウェイに類似しています。ゲートウェイの埋込みバージョンを使用する前に、『Oracle HTTP Server mod_plsqlユーザーズ・ガイド』を参照して熟知しておいてください。情報の大部分が同一のもの、あるいは類似したものです。
内容は次のとおりです。
図14-2に、埋込みゲートウェイによるクライアントHTTPリクエストの処理プロセスを示します。
図14-2の各ステップの内容は次のとおりです。
Oracle XML DB HTTP Listenerは、クライアント・ブラウザからのリクエストを受け取り、PL/SQLサブプログラムを起動するようリクエストします。サブプログラムは、PL/SQLに直接記述されたもの、またはPL/SQL Server Pagesがデータベースにアップロードされ、コンパイルされたときに間接的に生成されたものを使用できます。
XML DB HTTP Listenerは、その仮想パス・マッピング構成に指定されているとおり、埋込みPL/SQLゲートウェイにリクエストをルーティングします。
埋込みゲートウェイではHTTPリクエスト情報およびゲートウェイ構成を使用して、認証にどのデータベース・アカウントを使用するかを決定します。
埋込みゲートウェイはコール・パラメータを準備して、アプリケーション内でPL/SQLサブプログラムを起動します。
PL/SQLサブプログラムは、リレーショナル・データおよびデータベースからアクセスされたPL/SQL Web ToolkitからHTMLページを生成します。
アプリケーションから埋込みゲートウェイにページを送信します。
埋込みゲートウェイからXML DB HTTP Listenerにページを送信します。
XML DB HTTP Listenerからクライアント・ブラウザにページを送信します。
mod_plsql
とは異なり、埋込みゲートウェイはOracle XML DB HTTP Listenerを使用してHTTPリクエストを処理します。このリスナーは、Oracle Net Listenerと同じサーバー側プロセスであり、Oracle Net Services、HTTPおよびFTPをサポートします。
XML DBインタフェースを介して一般HTTPリスナー設定を構成します(手順については、『Oracle XML DB開発者ガイド』を参照してください)。Oracle Enterprise Manager Cloud Control (Cloud Control)を使用するか、xdbconfig
.xml
ファイルを編集することでHTTPリスナーを構成します。DADの属性の作成または設定など、すべての埋込みPL/SQLゲートウェイ構成で、DBMS_EPG
パッケージを使用します。
埋込みゲートウェイでは次のコンポーネントが必要です。
XML DB HTTP Listener
PL/SQL Web Toolkit
埋込みPL/SQLゲートウェイは、Oracle XML DBの一部としてインストールします。インストール時、またはDatabase Configuration Assistant(DBCA)によって作成された事前構成済データベースを使用している場合、Oracle XML DBがインストールされ、構成されます。既存のデータベースへのOracle XML DBの手動による追加については、『Oracle XML DB開発者ガイド』を参照してください。
PL/SQL Web Toolkitはデータベースの標準インストールの一部であるため、追加でインストールする必要はありません。
Oracle HTTP Serverの構成ファイルを編集して、mod_plsql
を構成します。埋込みゲートウェイはOracle XML DB HTTP Listenerの一部としてインストールするため、Oracle XML DBサーブレット管理インタフェースを介してサーブレットとして管理します。
埋込みゲートウェイへの構成インタフェースは、PL/SQLパッケージDBMS_EPG
です。このパッケージは、XML DBで使用される、基礎となるxdbconfig
.xml
構成ファイルを変更します。ほとんどのユーザーにとって、埋込みゲートウェイ構成パラメータはデフォルト値で問題ありません。
内容は次のとおりです。
mod_plsql
と同様、PL/SQLストアド・サブプログラムの各リクエストは、データベース・アクセス記述子(DAD)に関連付けられています。DADとは、データベース・アクセスに使用する構成値の集合です。DADでは次のような情報を指定します。
認証に使用するデータベース・アカウント
ドキュメントのアップロードおよびダウンロードに使用するサブプログラム
埋込みPL/SQLゲートウェイでは、DADは、XML DB HTTP LISTENER構成のサーブレットとして表されます。各DAD属性は、構成ファイルxdbconfig
.xml
のXML要素にマップされます。DAD属性の値は、要素の内容に一致します。たとえば、database-username
DAD属性は、<database-username>
XML要素に一致し、DAD属性の値がHR
である場合、<database-username>HR<database-username>
に一致します。DAD属性名は、大/小文字を区別します。
次の埋込みPL/SQLゲートウェイ構成を実行するには、DBMS_EPG
パッケージを使用します。
DBMS_EPG
.CREATE_DAD
プロシージャを使用してDADを作成します。
DBMS_EPG
.SET_DAD_ATTRIBUTE
プロシージャを使用してDAD属性を設定します。
すべてのDAD属性は、オプションです。属性を指定しない場合は、初期値が使用されます。
表14-2に、埋込みPL/SQLゲートウェイ属性および対応するmod_plsql
DADパラメータを示します。「有効な値」の列挙値は大/小文字を区別します。
表14-2 mod_plsql DAD属性と埋込みPL/SQLゲートウェイDAD属性間のマッピング
mod_plsql DAD属性 | 埋込みPL/SQLゲートウェイDAD属性 | 重複 | 有効な値 |
---|---|---|---|
|
|
なし |
文字列 |
|
|
なし |
On、Offの列挙 |
|
|
なし |
Basic、SingleSignOn、GlobalOwa、CustomOwa、PerPackageOwaの列挙 |
|
|
なし |
文字列 |
|
|
あり |
符号なしの整数 |
|
|
あり |
符号なしの整数 |
|
|
あり |
文字列 |
|
|
なし |
符号なしの整数 |
|
|
なし |
文字列 |
|
|
なし |
文字列 |
|
|
なし |
文字列 |
|
|
なし |
文字列 |
|
|
なし |
文字列 |
|
|
なし |
ApacheStyle、ModplsqlStyle、DebugStyleの列挙 |
|
|
あり |
文字列 |
|
|
なし |
符号なしの整数 |
|
|
なし |
InfoDebugの列挙 |
|
|
なし |
文字列 |
|
|
なし |
符号なしの整数 |
|
|
なし |
文字列 |
|
|
なし |
On、Offの列挙 |
|
|
なし |
文字列 |
|
|
なし |
文字列 |
|
|
なし |
文字列 |
|
|
なし |
文字列 |
|
|
なし |
StatelessWithResetPackageState、StatelessWithFastRestPackageState、StatelessWithPreservePackageStateの列挙 |
|
|
なし |
Char、Rawの列挙 |
|
|
なし |
文字列 |
埋込みゲートウェイのほとんどのユーザーにとって、DAD属性はデフォルト値で問題ありません。mod_plsql
ユーザーには、次の属性は不要です。
PlsqlDatabasePassword
PlsqlDatabaseConnectString
(埋込みゲートウェイで外部データベースへのログオンがサポートされていないため)
DAD属性と同様、グローバル構成パラメータはオプションです。表14-3に、DBMS_EPG
グローバル属性および対応するmod_plsql
グローバル・パラメータを示します。
表14-3 mod_plsqlグローバル属性と埋込みPL/SQLゲートウェイ・グローバル属性間のマッピング
mod_plsql DAD属性 | 埋込みPL/SQLゲートウェイDAD属性 | 重複 | 有効な値 |
---|---|---|---|
|
|
なし |
符号なしの整数 |
|
|
なし |
符号なしの整数 |
参照:
|
XML DB認証スキームを使用するため、埋込みゲートウェイではデータベースの認証方式がmod_plsql
とは異なります。特に、DADにはデータベースのパスワードは格納されません。
注意: PL/SQL Webアプリケーションをインターネット上で提供しても、データベースをファイアウォールの内側に保持する場合は、アプリケーションの実行に埋込みPL/SQLゲートウェイを使用せずに、mod_plsql を使用してください。 |
データベース認証を構成するには、DBMS_EPG
パッケージを使用します。
内容は次のとおりです。
静的認証はデータベースのユーザー名およびパスワードをDADに格納するmod_plsql
ユーザー用であるため、ブラウザ・ユーザーがデータベース認証情報を入力する必要はありません。
静的認証を設定する手順は次のとおりです。
XML DB管理者、つまりXDBADMIN
のロールが割り当てられたユーザーとしてデータベースにログオンします。
DADを作成します。たとえば、次のプロシージャでは、DADによって起動されるHR_DAD
を作成し、仮想パスを/hrweb/
にマップします。
EXEC DBMS_EPG.CREATE_DAD('HR_DAD', '/hrweb/*');
この手順では、ALTER
ANY
USER
システム権限が必要です。DADにより権限が使用される必要があるデータベース・アカウントに、DAD属性database-username
を設定します。たとえば、次のプロシージャでは、DAD名HR_DAD
がHR
アカウントの権限を保持すると指定します。
EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('HR_DAD', 'database-username', 'HR');
DAD属性database-username
は、大/小文字を区別します。
前の手順でユーザーが指定したデータベースの権限をDADに割り当てます。この認可によって、エンドユーザーはプロシージャを起動し、認可されたアカウントの権限のある埋込みPL/SQLゲートウェイを介してドキュメント表にアクセスできます。次に例を示します。
EXEC DBMS_EPG.AUTHORIZE_DAD('HR_DAD', 'HR');
あるいは、XDBADMIN
権限のあるユーザーとしてログオフし、その権限がDADで使用される必要があるデータベース・ユーザーとしてログオンしてから、これらの権限をDADに割り当てる次のコマンドを使用します。
EXEC DBMS_EPG.AUTHORIZE_DAD('HR_DAD');
注意: 複数のユーザーが同一のDADを認可できます。DADのdatabase-username 属性設定によって、どのユーザーの権限を使用するかが決定されます。 |
mod_plsql
とは異なり、埋込みゲートウェイは特殊ユーザーANONYMOUS
としてデータベースに接続しますが、データベース・オブジェクトにはDADに割り当てられたユーザー権限でアクセスします。ブラウザ・ユーザーがHTTP Authorization
ヘッダーで明示的に接続しようとすると、データベースはアクセスを拒否します。
注意: アカウントANONYMOUS は、XML DBのインストール後にロックされます。埋込みPL/SQLゲートウェイで静的認証を使用する場合は、最初にこのアカウントのロックを解除します。 |
動的認証は、DADにデータベースのユーザー名およびパスワードを格納しないmod_plsql
ユーザーのためのものです。
動的認証では、データベース・ユーザーは、データベース・オブジェクトへのアクセス権限を使用するため、埋込みゲートウェイを認可する必要がありません。かわりに、ブラウザ・ユーザーがHTTP Basic認証スキーマを介してデータベース認証情報を指定する必要があります。
埋込みゲートウェイのアクションは、DADに対してdatabase-username
属性が設定されているかどうかによって異なります。この属性が設定されていない場合、埋込みゲートウェイはブラウザ・クライアントによって指定されたユーザーとして、データベースに接続します。属性が設定されている場合、データベースでは、database-username
属性で指定されたユーザーにアクセスを制限します。
動的認証を設定する手順は次のとおりです。
XML DB管理者、つまりXDBADMIN
のロールのあるユーザーとしてデータベースにログオンします。
DADを作成します。たとえば、次のプロシージャでは、DADによって起動されるDYNAMIC_DAD
を作成し、仮想パスを/hrweb/
にマップします。
EXEC DBMS_EPG.CREATE_DAD('DYNAMIC_DAD', '/hrweb/*');
オプションで、DADにより権限が使用される必要があるデータベース・アカウントに、DAD属性database-username
を設定します。ブラウザ・ユーザーはDADアクセスの際、このアカウントのユーザー名およびパスワードを入力するよう要求されます。たとえば、次のプロシージャでは、DAD名DYNAMIC_DAD
がHR
アカウントの権限を保持すると指定します。
EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('DYNAMIC_DAD', 'database-username', 'HR');
属性database-username
は、大/小文字を区別します。
警告: HTTP Basic認証スキームを介して送信されるパスワードは、暗号化されていません。ブラウザ・クライアントによって送信されるパスワードを保護するため、HTTPSプロトコルを使用するよう埋込みゲートウェイを構成します。 |
匿名認証はmod_plsql
ユーザー用であり、このユーザーはデータベース・ログオン用の特殊なDADデータベースを作成しますが、アプリケーション・プロシージャおよびドキュメント表を別のスキーマに格納し、プロシージャおよびドキュメント表へのアクセス権をPUBLICに付与します。
匿名認証を設定する手順は次のとおりです。
XML DB管理者、つまりXDBADMIN
のロールが割り当てられたユーザーとしてデータベースにログオンします。
DADを作成します。たとえば、次のプロシージャでは、DADによって起動されるHR_DAD
を作成し、仮想パスを/hrweb/
にマップします。
EXEC DBMS_EPG.CREATE_DAD('HR_DAD', '/hrweb/*');
DAD属性database-username
をANONYMOUS
に設定します。次に例を示します。
EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('HR_DAD', 'database-username', 'ANONYMOUS');
database-username
およびANONYMOUS
はともに、大/小文字を区別します。
データベース・オブジェクトへのアクセス用ANONYMOUS
権限の使用のために埋込みゲートウェイを認可する必要はありません。ANONYMOUS
にはシステム権限がなく、データベース・オブジェクトを所有していません。
DADの名前がわかっている場合は、このDADの認証モードは次によって決まります。
DADが存在するかどうか。
database-username
属性がDAD用に設定されているかどうか。
DADにdatabase-username
ユーザーの権限の使用が認可されているかどうか。
database-username
属性がDADの使用を認可されているユーザーの名前であるかどうか。
表14-4に、これらの質問の回答に応じた認証モードの決定方法を示します。
表14-4 DADの認証の可能性
DADの有無 | database-username設定の有無 | ユーザー認可の有無 | モード |
---|---|---|---|
あり |
あり |
あり |
静的 |
あり |
あり |
なし |
動的(制限付き) |
あり |
なし |
関連なし |
動的 |
あり |
あり( |
関連なし |
匿名 |
なし |
N/A |
たとえば、DAD名MY_DAD
を作成するとします。MY_DAD
のdatabase-username
属性がHR
に設定されていても、HR
ユーザーがMY_DAD
を認可しない場合、MY_DAD
の認証モードは制限付きで動的になります。ブラウザ・ユーザーがMY_DAD
を介してPL/SQLサブプログラムを実行しようとすると、HR
データベースのユーザー名およびパスワードを入力するよう要求されます。
DBA_EPG_DAD_AUTHORIZATION
ビューでは、どのユーザーがDADの使用を認可しているかを示します。DAD_NAME
列にはDADの名前が表示され、USERNAME
列にはDADに権限が割り当てられたユーザーが表示されます。権限が認められたDADは存在しないことがあります。
参照: DBA_EPG_DAD_AUTHORIZATION ビューの詳細は、『Oracle Databaseリファレンス』を参照してください。 |
例14-1では次の処理が行われます。
データベース・ユーザーHR
用に静的認証のDADを作成し、これを認可するHR
アカウントの権限を割り当てます。
ユーザーを限定しない、動的認証のDADを作成します。
HR
アカウントに限定される、動的認証のDADを作成します。
例14-1 DADの作成および構成
------------------------------------------------------------------------ --- DAD with static authentication ------------------------------------------------------------------------ CONNECT SYSTEM AS SYSDBA PASSWORD: password EXEC DBMS_EPG.CREATE_DAD('Static_Auth_DAD', '/static/*'); EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('Static_Auth_DAD', 'database-username', 'HR'); GRANT EXECUTE ON DBMS_EPG TO HR; -- Authorization CONNECT HR PASSWORD: password EXEC DBMS_EPG.AUTHORIZE_DAD('Static_Auth_DAD'); ------------------------------------------------------------------------ -- DAD with dynamic authentication ------------------------------------------------------------------------ CONNECT SYSTEM AS SYSDBA PASSWORD: password EXEC DBMS_EPG.CREATE_DAD('Dynamic_Auth_DAD', '/dynamic/*'); ------------------------------------------------------------------------- -- DAD with dynamic authentication restricted ------------------------------------------------------------------------- EXEC DBMS_EPG.CREATE_DAD('Dynamic_Auth_DAD_Restricted', '/dynamic/*'); EXEC DBMS_EPG.SET_DAD_ATTRIBUTE ('Dynamic_Auth_DAD_Restricted', 'database-username', 'HR');
DADの作成および認証は独立しているため、次のことができます。
存在していないDADの認証(後で作成が可能)
自分がユーザーでないDADの認証(ただし、この認証はDAD database-user
属性が自分のユーザー名に変更されるまで反映されません)
例14-2では、データベース・ユーザーHR
用に静的認証のDADを作成し、これにHR
アカウントの権限を割り当てます。続いて、次のように操作します。
データベース・ユーザーHR
がそのDADではなく、存在しないDADを認証します。
ユーザーが誤ってこれを実行した場合でも、存在しないDADは後で作成できるため、エラーは発生しません。
データベース・ユーザーOE
が、自分のdatabase-user
属性がHR
に設定されているDADを認証します。
エラーは発生しませんが、DADのdatabase-user
属性がOE
に変更されるまで認証は有効になりません。
例14-2 後で作成または変更されるDADの認証
REM Create DAD with static authentication for database user HR CONNECT SYSTEM AS SYSDBA PASSWORD: password EXEC DBMS_EPG.CREATE_DAD('Static_Auth_DAD', '/static/*'); EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('Static_Auth_DAD', 'database-username', 'HR'); GRANT EXECUTE ON DBMS_EPG TO HR; REM Database user HR authorizes DAD that does not exist CONNECT HR PASSWORD: password EXEC DBMS_EPG.AUTHORIZE_DAD('Static_Auth_DAD_Typo'); REM Database user OE authorizes DAD with database-username 'HR' CONNECT OE PASSWORD: password EXEC DBMS_EPG.AUTHORIZE_DAD('Static_Auth_DAD');
例14-3では、指定されたDADの名称を許容し、その認証モードをレポートするPL/SQLプロシージャshow_dad_auth_status
を作成します。指定したDADが存在しない場合、プロシージャはエラー状態で終了します。
例14-3 DADの認証モードの決定
CREATE OR REPLACE PROCEDURE show_dad_auth_status (p_dadname VARCHAR2) IS v_daduser VARCHAR2(32); v_cnt PLS_INTEGER; BEGIN -- Determine DAD user v_daduser := DBMS_EPG.GET_DAD_ATTRIBUTE(p_dadname, 'database-username'); -- Determine whether DAD authorization exists for DAD user SELECT COUNT(*) INTO v_cnt FROM DBA_EPG_DAD_AUTHORIZATION da WHERE da.DAD_NAME = p_dadname AND da.USERNAME = v_daduser; -- If DAD authorization exists for DAD user, authentication mode is static IF (v_cnt > 0) THEN DBMS_OUTPUT.PUT_LINE ( '''' || p_dadname || ''' is set up for static authentication for user ''' || v_daduser || '''.'); RETURN; END IF; -- If no DAD authorization exists for DAD user, authentication mode is dynamic -- Determine whether dynamic authentication is restricted to particular user IF (v_daduser IS NOT NULL) THEN DBMS_OUTPUT.PUT_LINE ( '''' || p_dadname || ''' is set up for dynamic authentication for user ''' || v_daduser || ''' only.'); ELSE DBMS_OUTPUT.PUT_LINE ( '''' || p_dadname || ''' is set up for dynamic authentication for any user.'); END IF; END; /
例14-1のスクリプトを実行して、各種DADを作成および構成するとします。出力結果は次のようになります。
SET SERVEROUTPUT ON; BEGIN show_dad_auth_status('Static_Auth_DAD'); END; / 'Static_Auth_DAD' is set up for static authentication for user 'HR'.
例14-4の無名ブロックでは、登録したすべてのDADの認証モードがレポートされます。これによって、例14-3のshow_dad_auth_status
プロシージャが起動されます。
例14-4 全DADの認証モードの表示
DECLARE v_dad_names DBMS_EPG.VARCHAR2_TABLE; BEGIN DBMS_OUTPUT.PUT_LINE ('---------- Authorization Status for All DADs ----------'); DBMS_EPG.GET_DAD_LIST(v_dad_names); FOR i IN 1..v_dad_names.count LOOP show_dad_auth_status(v_dad_names(i)); END LOOP; END; /
例14-1のスクリプトを実行して各種DADを作成および構成した場合、例14-4の出力は次のとおりです。
---------- Authorization Status for All DADs ---------- 'Static_Auth_DAD' is set up for static auth for user 'HR'. 'Dynamic_Auth_DAD' is set up for dynamic auth for any user. 'Dynamic_Auth_DAD_Restricted' is set up for dynamic auth for user 'HR' only.
例14-5の無名ブロックでは、無効なDAD認証がレポートされます。DAD認証は、次の場合は無効です。
DADを認可するユーザーが、DADのdatabase-username
属性で指定されたユーザーではない。
DADを認可するユーザーが存在しない。
例14-5 無効なDAD認可の表示
DECLARE v_dad_names DBMS_EPG.VARCHAR2_TABLE; v_dad_user VARCHAR2(32); v_dad_found BOOLEAN; BEGIN DBMS_OUTPUT.PUT_LINE ('---------- DAD Authorizations Not in Effect ----------'); DBMS_EPG.GET_DAD_LIST(v_dad_names); FOR r IN (SELECT * FROM DBA_EPG_DAD_AUTHORIZATION) LOOP -- Outer loop v_dad_found := FALSE; FOR i IN 1..v_dad_names.count LOOP -- Inner loop IF (r.DAD_NAME = v_dad_names(i)) THEN v_dad_user := DBMS_EPG.GET_DAD_ATTRIBUTE(r.DAD_NAME, 'database-username'); -- Is database-username the user for whom DAD is authorized? IF (r.USERNAME <> v_dad_user) THEN DBMS_OUTPUT.PUT_LINE ( 'DAD authorization of ''' || r.dad_name || ''' by user ''' || r.username || '''' || ' is not in effect because DAD user is ' || '''' || v_dad_user || '''.'); END IF; v_dad_found := TRUE; EXIT; -- Inner loop END IF; END LOOP; -- Inner loop -- Does DAD exist? IF (NOT v_dad_found) THEN DBMS_OUTPUT.PUT_LINE ( 'DAD authorization of ''' || r.dad_name || ''' by user ''' || r.username || ''' is not in effect because the DAD does not exist.'); END IF; END LOOP; -- Outer loop END; /
例14-2のスクリプトを実行して各種DADを作成および構成した場合、例14-5の出力ページは次のとおりです(ページ内に収まるように再フォーマット済)。
---------- DAD Authorizations Not in Effect ---------- DAD authorization of 'Static_Auth_DAD' by user 'OE' is not in effect because DAD user is 'HR'. DAD authorization of 'Static_Auth_DAD_Typo' by user 'HR' is not in effect because DAD does not exist.
システム権限のあるユーザーとしてデータベースに接続している場合、次のスクリプトにより、埋込みPL/SQLゲートウェイ構成を調査します。
$ORACLE_HOME/rdbms/admin/epgstat.sql
例14-6に、ANONYMOUS
アカウントがロックされている場合の例14-1のepgstat
.sql
スクリプトの出力を示します。
例14-6 例14-1のepgstat.sqlスクリプトの出力
スクリプトを実行するコマンドは次のとおりです。
@$ORACLE_HOME/rdbms/admin/epgstat.sql
結果:
+--------------------------------------+ | XDB protocol ports: | | XDB is listening for the protocol | | when the protocol port is nonzero. | +--------------------------------------+ HTTP Port FTP Port --------- -------- 0 0 1 row selected. +---------------------------+ | DAD virtual-path mappings | +---------------------------+ Virtual Path DAD Name -------------------------------- -------------------------------- /dynamic/* Dynamic_Auth_DAD_Restricted /static/* Static_Auth_DAD 2 rows selected. +----------------+ | DAD attributes | +----------------+ DAD Name DAD Param DAD Value ------------ --------------------- ---------------------------------------- Dynamic_Auth database-username HR _DAD_Restric ted Static_Auth_ database-username HR DAD 2 rows selected. +---------------------------------------------------+ | DAD authorization: | | To use static authentication of a user in a DAD, | | the DAD must be authorized for the user. | +---------------------------------------------------+ DAD Name User Name -------------------------------- -------------------------------- Static_Auth_DAD HR OE Static_Auth_DAD_Typo HR 3 rows selected. +----------------------------+ | DAD authentication schemes | +----------------------------+ DAD Name User Name Auth Scheme -------------------- -------------------------------- ------------------ Dynamic_Auth_DAD Dynamic Dynamic_Auth_DAD_Res HR Dynamic Restricted tricted Static_Auth_DAD HR Static 3 rows selected. +--------------------------------------------------------+ | ANONYMOUS user status: | | To use static or anonymous authentication in any DAD, | | the ANONYMOUS account must be unlocked. | +--------------------------------------------------------+ Database User Status --------------- -------------------- ANONYMOUS EXPIRED & LOCKED 1 row selected. +-------------------------------------------------------------------+ | ANONYMOUS access to XDB repository: | | To allow public access to XDB repository without authentication, | | ANONYMOUS access to the repository must be allowed. | +-------------------------------------------------------------------+ Allow repository anonymous access? ---------------------------------- false 1 row selected.
埋込みPL/SQLゲートウェイを介してPL/SQLサブプログラムを起動する基本手順は、mod_plsql
ゲートウェイに対するものと同じです。詳細は、『Oracle HTTP Server mod_plsqlユーザーズ・ガイド』を参照してください。mod_plsql
命令は埋込みゲートウェイで使用するため、若干の調整が必要です。たとえば、次の形式でURLを入力し、ブラウザで埋込みゲートウェイを起動します。
protocol://hostname[:port]/virt-path/[[!][schema.][package.]proc_name[?query_str]]
プレースホルダvirt-path
は、DBMS_EPG
.CREATE_DAD
で構成する仮想パスを表します。mod_plsql
のドキュメントでは、virt-path
のかわりにDAD_location
を使用します。
次の項は『Oracle HTTP Server mod_plsqlユーザーズ・ガイド』に説明されており、埋込みゲートウェイにも同様に適用されます。
トランザクション・モード
サポートされているデータ型
パラメータ渡しのスキーム
ファイルのアップロード/ダウンロードのサポート
パスの別名
Common Gateway Interface(CGI)環境変数
埋込みゲートウェイは、mod_plsql
と同じ保護メカニズムを使用します。詳細は、『Oracle HTTP Server mod_plsqlユーザーズ・ガイド』を参照してください。
mod_plsql
の制限事項は『Oracle HTTP Server mod_plsqlユーザーズ・ガイド』の第1章に説明されており、埋込みゲートウェイにも同様に当てはまります。また、ゲートウェイの埋込みバージョンでは、次の機能はサポートされません。
動的HTMLキャッシング
システム監視
Basic以外の認証モード
認証モードの詳細は、『Oracle HTTP Server mod_plsqlユーザーズ・ガイド』を参照してください。
この項では、hr
.employees
表に対して問合せを行い、PL/SQLゲートウェイを介してWebブラウザにHTML出力を供給する簡易アプリケーションを作成する方法について説明します。XML DBおよびサンプル・スキーマの両方がインストールされているものとします。
プログラムを作成して実行する手順は次のとおりです。
ALTER
USER
権限のあるユーザーとしてデータベースにログオンし、データベース・アカウントANONYMOUS
のロックが解除されていることを確認します。ANONYMOUS
アカウントはデフォルトでロックされており、静的認証を必要とします。アカウントがロックされている場合は、次のSQL文を使用してそのロックを解除します。
ALTER USER anonymous ACCOUNT UNLOCK;
XML DB管理者、つまりXDBADMIN
のロールのあるユーザーとしてデータベースにログオンします。
データ・ディクショナリを問い合せ、どのユーザーおよびロールにXDADMIN
のロールが付与されているかを確認します。
SELECT * FROM DBA_ROLE_PRIVS WHERE GRANTED_ROLE = 'XDBADMIN';
DADを作成します。たとえば、次のプロシージャでは、DADによって起動されるHR_DAD
を作成し、仮想パスを/plsql/
にマップします。
EXEC DBMS_EPG.CREATE_DAD('HR_DAD', '/plsql/*');
DADにより権限が使用される必要があるデータベース・ユーザーに、DAD属性database-username
を設定します。たとえば、次のプロシージャでは、DAD HR_DAD
がユーザーHR
権限によってデータベース・オブジェクトにアクセスすることを指定します。
EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('HR_DAD', 'database-username', 'HR');
属性database-username
は、大/小文字を区別します。
DADにより権限が使用される必要のあるデータベース・ユーザーにEXECUTE
権限を付与します(これによって、ユーザーはDADを認証できます)。次に例を示します。
GRANT EXECUTE ON DBMS_EPG TO HR;
XML DB管理者としてログオフし、DADにより権限が使用される必要があるデータベース・ユーザーとして、データベースにログオンします(例: HR
)。
埋込みPL/SQLゲートウェイを認可してプロシージャを起動し、DADを介してドキュメント表にアクセスします。次に例を示します。
EXEC DBMS_EPG.AUTHORIZE_DAD('HR_DAD');
サンプルのPL/SQLストアド・プロシージャによって起動されるprint_employees
を作成します。次のプログラムでは、hr
.employees
の問合せの結果セットを含むHTMLページを作成します。
CREATE OR REPLACE PROCEDURE print_employees IS CURSOR emp_cursor IS SELECT last_name, first_name FROM hr.employees ORDER BY last_name; BEGIN HTP.PRINT('<html>'); HTP.PRINT('<head>'); HTP.PRINT('<meta http-equiv="Content-Type" content="text/html">'); HTP.PRINT('<title>List of Employees</title>'); HTP.PRINT('</head>'); HTP.PRINT('<body TEXT="#000000" BGCOLOR="#FFFFFF">'); HTP.PRINT('<h1>List of Employees</h1>'); HTP.PRINT('<table width="40%" border="1">'); HTP.PRINT('<tr>'); HTP.PRINT('<th align="left">Last Name</th>'); HTP.PRINT('<th align="left">First Name</th>'); HTP.PRINT('</tr>'); FOR emp_record IN emp_cursor LOOP HTP.PRINT('<tr>'); HTP.PRINT('<td>' || emp_record.last_name || '</td>'); HTP.PRINT('<td>' || emp_record.first_name || '</td>'); END LOOP; HTP.PRINT('</table>'); HTP.PRINT('</body>'); HTP.PRINT('</html>'); END; /
Oracle NetリスナーがHTTPリクエストを受け入れられることを確認します。システム・プロンプトで次のコマンドを実行して、LinuxおよびUNIXでのリスナーのステータスを確認できます。
lsnrctl status | grep HTTP
出力は次のとおりです(ページ・サイズによる制限のため単一行から複数行に再フォーマット済)。
(DESCRIPTION= (ADDRESS=(PROTOCOL=tcp)(HOST=example.com)(PORT=8080)) (Presentation=HTTP) (Session=RAW) )
HTTPサービスが起動していないことを確認できた場合は、初期化パラメータ・ファイルに次の行を追加(listener_name
にOracle Netローカル・リスナーを指定)し、データベースおよびリスナーを再起動します。
dispatchers="(PROTOCOL=TCP)"
local_listener=listener_name
Webブラウザからprint_employees
プログラムを実行します。たとえば、host
に自分のホスト・コンピュータ名を指定し、port
に前の手順のPORT
の値を指定すると、次のURLを使用できます。
http://host:port/plsql/print_employees
たとえば、ホストがtest
.com
で、HTTPポートが8080
である場合は、次のように入力します。
http://example.com:8080/plsql/print_employees
Webブラウザに、hr
.employees
表に全従業員の姓名が記載された表のあるHTMLページが戻されます。
一般的に、PL/SQL Webアプリケーションでは、ファンクション・コールを使用して出力用の各HTMLタグを生成します。このファンクションは、Oracle Databaseに付属するPL/SQL Web Toolkitパッケージの一部です。例14-7に、各HTMLタグと対応するHTP
ファンクションをコールして簡単なHTMLページを生成する方法を示します。
例14-7 HTPファンクションを使用したHTMLタグの生成
CREATE OR REPLACE PROCEDURE html_page IS BEGIN HTP.HTMLOPEN; -- generates <HTML> HTP.HEADOPEN; -- generates <HEAD> HTP.TITLE('Title'); -- generates <TITLE>Hello</TITLE> HTP.HEADCLOSE; -- generates </HTML> -- generates <BODY TEXT="#000000" BGCOLOR="#FFFFFF"> HTP.BODYOPEN( cattributes => 'TEXT="#000000" BGCOLOR="#FFFFFF"'); -- generates <H1>Heading in the HTML File</H1> HTP.HEADER(1, 'Heading in the HTML File'); HTP.PARA; -- generates <P> HTP.PRINT('Some text in the HTML file.'); HTP.BODYCLOSE; -- generates </BODY> HTP.HTMLCLOSE; -- generates </HTML> END; /
各タグに対応するファンクション・コールを作成するかわりに、HTP
.PRINT
ファンクションを使用して、テキストとタグを両方とも出力します。例14-8に、その方法を示します。
例14-8 HTP.PRINTを使用したHTMLタグの生成
CREATE OR REPLACE PROCEDURE html_page2 IS BEGIN HTP.PRINT('<html>'); HTP.PRINT('<head>'); HTP.PRINT('<meta http-equiv="Content-Type" content="text/html">'); HTP.PRINT('<title>Title of the HTML File</title>'); HTP.PRINT('</head>'); HTP.PRINT('<body TEXT="#000000" BGCOLOR="#FFFFFF">'); HTP.PRINT('<h1>Heading in the HTML File</h1>'); HTP.PRINT('<p>Some text in the HTML file.'); HTP.PRINT('</body>'); HTP.PRINT('</html>'); END; /
Webアプリケーションを様々な状況で有効に活用するには、対話性を十分に高め、ユーザーによる選択を可能にする必要があります。迅速さを求めるWeb閲覧者に対応するには、対話の効率をよくし、ユーザーが選択項目を簡単に指定できるように、過多な決定事項やデータ入力を避ける必要があります。
PL/SQL Webアプリケーションにパラメータを渡す主な方法は、次のとおりです。
HTMLフォーム・タグを使用します。ユーザーが1つのWebページ上のフォームに記入して、「Submit
」ボタンをクリックすると、すべてのデータおよび選択項目がストアド・サブプログラムに転送されます。
URLにハードコード化します。ユーザーがリンクをクリックすると、一連の事前定義パラメータがストアド・サブプログラムに転送されます。通常、ユーザーが選択する可能性があるすべての選択項目には、Webページ上に個別のリンクを挿入します。
内容は次のとおりです。
リスト・ボックスおよびドロップダウン・リストは、HTMLタグ(<SELECT>
)を使用して実装されます。
選択項目の数を多くする、または複数の選択を可能にする必要がある場合は、リスト・ボックスを使用します。リスト・ボックスは、項目をアルファベット順に表示する場合に適しています。これによって、ユーザーは、すべての項目を読まなくても目的の項目を短時間で検索できます。
次の場合にドロップダウン・リストを使用します。
選択項目が少ない
画面のスペースがかぎられている
選択項目の順序が特殊
ドロップダウン・リストは、初めてアクセスするユーザーの注意を引き、選択項目を読ませることができます。選択項目および順序を固定することで、ユーザーはドロップダウン・リストから項目を選択するときの動作に慣れ、素早く選択できるようになります。例14-9に、簡単なドロップダウン・リストを示します。
オプション・ボタンによって、NULL値(グループ内のいずれのオプションもチェックされていない場合)、またはチェックされたオプションに指定されている値のいずれかが渡されます。
一連のオプションのデフォルト値を指定するには、INPUT
タグにCHECKED
属性を含めるか、ストアド・サブプログラム内のパラメータにDEFAULT
句を含めます。オプションのグループを設定するときは、「どちらでもない」ことを示す選択項目を含める必要があります。これは、オプションを選択した後では、別のボタンを選択することはできますが、選択を完全に取り消すことができないためです。たとえば、あるユーザーが選択を行った後に、それが間違っていたことに気付くという状況を考慮して、「はい」および「いいえ」とともに「興味なし」または「わからない」という選択項目を含めます。
チェック・ボックスでは、ストアド・サブプログラムがNULL値、単一の値、または複数の値を受け取る場合があるため、特別な処理が必要です。
同じNAME
属性を持つチェック・ボックスはすべて、チェック・ボックス・グループを構成します。グループ内のいずれのチェック・ボックスもチェックされていない場合、ストアド・サブプログラムは、対応するパラメータに対してNULL値を受け取ります。
グループ内のチェック・ボックスの1つがチェックされている場合、ストアド・サブプログラムは単一のVARCHAR2
パラメータを受け取ります。
グループ内の複数のチェック・ボックスがチェックされている場合、ストアド・サブプログラムはPL/SQLのTABLE
OF
VARCHAR2
データ型のパラメータを受け取ります。TABLE
OF
VARCHAR2
のようなデータ型を宣言するか、OWA_UTIL
.IDENT_ARR
のような事前定義のデータ型を使用する必要があります。値を検索するには、次のようにループを使用します。
CREATE OR REPLACE PROCEDURE handle_checkboxes ( checkboxes owa_util.ident_arr ) AS BEGIN FOR i IN 1..checkboxes.count LOOP htp.print('<p>Check Box value: ' || checkboxes(i)); END LOOP; END; /
入力フィールドでは、ユーザーが誤った形式のデータや範囲外のデータなどを入力する可能性があるため、最も厳密な妥当性チェックが必要です。可能な場合、クライアント側JavaScript関数を使用してクライアント側でデータの妥当性チェックを行い、ユーザーにかわって正しいフォーマットにするか、ユーザーに再入力を促します。
次に例を示します。
ユーザーが数値入力フィールドにアルファベット文字を入力したり、文字数制限を超えた後に文字を入力することができないようにします。
クレジット・カード番号から空白およびハイフンを暗黙的に削除します(ストアド・サブプログラムでこの形式の値が要求されている場合)。
ユーザーが最大値を超える数値を入力した場合、すぐに通知して、ユーザーに再入力を促します。
これらの妥当性チェックが成功するとはかぎらないため、このような状況に対応できるようにストアド・サブプログラムをコーディングします。ユーザーが誤ったデータを入力したときに「Back
」ボタンを押さなくて済むように、エラー・メッセージと他のすべての値が記入された元のフォームを、1つのページに表示します。
パスワードなどの機密性の高い情報の場合、入力フィールドの<INPUT TYPE=PASSWORD>
という特殊なフォームによって、入力されたテキストが非表示になります。
例14-10のプロシージャは、入力として2つの文字列を受け入れます。このプロシージャが初めて起動された場合、値を入力するための単純なフォームのプロンプトが表示されます。ユーザーが情報を送ると、同じプロシージャが再起動され、入力が正しいかどうかが確認されます。入力が正しい場合、プロシージャは入力を処理します。正しくない場合、プロシージャは、再入力するためのプロンプトを、最初の値が入力された状態で表示します。
例14-10 HTMLフォームからの入力フィールド・パラメータ渡し
DROP TABLE name_zip_table; CREATE TABLE name_zip_table ( name VARCHAR2(100), zipcode NUMBER ); -- Store a name and associated zip code in the database. CREATE OR REPLACE PROCEDURE associate_name_with_zipcode (name VARCHAR2 := NULL, zip VARCHAR2 := NULL) AS BEGIN -- Each entry field must contain a value. Zip code must be 6 characters. -- (In a real program you perform more extensive checking.) IF name IS NOT NULL AND zip IS NOT NULL AND length(zip) = 6 THEN INSERT INTO name_zip_table (name, zipcode) VALUES (name, zip); HTP.PRINT('<p>The person ' || HTP.ESCAPE_SC(name) || ' has the zip code ' || HTP.ESCAPE_SC(zip) || '.'); -- If input was OK, stop here. User does not see form again. RETURN; END IF; -- If user entered incomplete or incorrect data, show error message. IF (name IS NULL AND zip IS NOT NULL) OR (name IS NOT NULL AND zip IS NULL) OR (zip IS NOT NULL AND length(zip) != 6) THEN HTP.PRINT('<p><b>Please reenter data. Fill all fields, and use 6-digit zip code.</b>'); END IF; -- If user entered no data or incorrect data, show error message -- & make form invoke same procedure to check input values. HTP.FORMOPEN('HR.associate_name_with_zipcode', 'GET'); HTP.PRINT('<p>Enter your name:</td>'); HTP.PRINT('<td valign=center><input type=text name=name value="' || HTP.ESCAPE_SC(name) || '">'); HTP.PRINT('<p>Enter your zip code:</td>'); HTP.PRINT('<td valign=center><input type=text name=zip value="' || HTP.ESCAPE_SC(zip) || '">'); HTP.FORMSUBMIT(NULL, 'Submit'); HTP.FORMCLOSE; END; /
ユーザーが同じ選択項目を毎回指定しなくても、一連のストアド・サブプログラムを介して情報を渡すには、ストアド・サブプログラムを起動するフォームに非表示パラメータを含める方法があります。最初のストアド・サブプログラムによって、このストアド・サブプログラムで生成されたHTMLフォームにユーザー名などの情報が入力されます。非表示パラメータの値は、ユーザーがその値をオプションまたは入力フィールドを介して入力した場合と同様に、次のストアド・サブプログラムに渡されます。
1つのストアド・サブプログラムから別のサブプログラムに情報を渡すには、次の方法もあります。
永続情報を含む「Cookie」をブラウザに送信します。ブラウザは、同じサイトから他のWebページにアクセスするときに、同じ情報をサーバーに戻します。Cookieは、各WebページのHTMLテキストの前に、ブラウザとWebサーバーの間で転送されるHTTPヘッダーを介して設定され、検索されます。
データベース自体に情報を格納し、後でストアド・サブプログラムが検索できるようにします。この方法ではデータベース・サーバーに余分なオーバーヘッドが発生し、複数のユーザーがサーバーに同時アクセスしたときに、各ユーザーを追跡する方法を見つける必要があります。
HTMLフォームを使用して、クライアント・システム上のファイルを選択し、これをサーバーに転送できます。ストアド・サブプログラムにより、CLOB
、BLOB
または大量のデータを保持できるその他のデータ型として、データベースにファイルを挿入できます。
PL/SQL Web ToolkitおよびPL/SQLゲートウェイには、アップロードされたファイルを保持する「ドキュメント表」の概念があります。
参照: 『mod_plsqlユーザーズ・ガイド』 |
デフォルトでは、HTMLフォームには、データをHTMLフォームからストアド・サブプログラムまたはCGIプログラムに転送するための送信(Submit
)ボタンが必要です。このボタンには、「検索」や「登録」など任意の名前を指定できます。
1つのページに複数のフォームを挿入し、各フォームに独自のフォーム要素と送信(Submit
)ボタンを設定できます。非表示パラメータのみで構成されるフォームも作成できます。このフォームでは、ユーザーはボタンをクリックする以外の選択は行いません。
JavaScriptなどのスクリプト言語を使用すると、送信ボタンを削除して、ドロップダウン・リストからの選択など、別のアクションに応答してフォームが送られるようにすることができます。この方法は、ユーザーが選択する項目が1つで、送信(Submit
)ボタンで確認する手順が必要でない場合に最適です。
HTMLフォームが送られると、ストアド・サブプログラムは、記入されていないフォーム要素に対してNULLパラメータを受け取ります。NULLパラメータの原因には、入力フィールドが空である、一連のチェック・ボックス、オプションまたはリスト項目がチェックされていない、またはVALUE
パラメータの値が""(空の引用符)である、などがあります。
クライアント側で実行する妥当性チェックの内容にかかわらず、ストアド・サブプログラムのコードを使用して、いくつかのパラメータがNULLになる状況に対処します。
すべてのパラメータ宣言に初期値を指定して、フォーム・パラメータが欠落した状態でストアド・サブプログラムが起動されたときに発生する例外を回避します。数値に対する初期値は0(ゼロ)に設定できます(適切な場合)。ユーザーが値を指定したかどうか確認するには、NULL
を使用します。
初期値NULL
を持つ入力パラメータ値を使用する前に、その値がNULLかどうかを確認します。
一部の入力パラメータが指定されていないときでも、サブプログラムが有効な結果を生成するようにします。レポートから一部のセクションを除外するか、パラメータが指定されていない場所を示すテキスト文字列またはイメージをレポート内に表示します。
欠落している値を結果ページから直接入力することで、ストアド・サブプログラムを再実行できるようにします。たとえば、追加パラメータを指定して同じストアド・サブプログラムを起動するリンクを含めたり、出力の一部として値を挿入して元のフォームを表示させることができます。
Webアプリケーションでは、状態(特定の時点における現行のデータ・セット)の概念が特に重要です。Webページを切り替えると状態情報が簡単に失われ、ユーザーに何度も同じ選択をさせることになる場合があります。
状態情報は、HTMLフォームを使用して動的Webページ間で渡されます。情報は一連の名前/値ペアとして渡され、ストアド・サブプログラムのパラメータになります。
ユーザーが複数の選択をする必要がある場合、多くの選択項目から1つを選択する必要がある場合、または偶然に誤って選択することを回避することが重要な場合は、HTMLフォームを使用します。ユーザーは、すべての選択を行って、選択した項目を再確認すると、「Submit
」ボタンを押して選択を決定します。それ以降のページでは、非表示パラメータ(<INPUT TYPE=HIDDEN>
タグ)を含むフォームを使用して、これらの選択項目をページからページへと渡すことができます。
ユーザーが1つまたは2つの選択項目に関心がある場合、または選択事項がWebページ内に散在している場合、アクションをハイパーリンクとして表し、必要な名前/値ペアを問合せ文字列(URL内の「?
」の後に続く部分)に含めることによって、ユーザーが送信(Submit
)ボタンを簡単に見つけられるようにできます。
状態情報は、Oracle Application Serverおよびそのmod_ose
モジュールを使用して保持することもできます。この方法では、状態情報をパッケージ変数に格納して、ユーザーがWebサイトを移動しても、情報を使用可能のままにできます。
参照: Oracle Application Serverのマニュアル・セット:
|
PL/SQLサブプログラムで次のネットワーク操作を実行するためのパッケージが提供されています。
IPv6(Internet Protocol version 6)のサポート
Oracle Database 11gリリース2(11.2.0.1)では、PL/SQLネットワーク・ユーティリティ・パッケージがIPv6アドレスをサポートします。パッケージ・インタフェースは変更されていません。ネットワーク・ホストを指定できるすべてのインタフェース・パラメータはIPv6アドレスを文字列形式で受け入れ、IPアドレスを返すすべてのインタフェースはIPv6アドレスを返します。
ただし、ネットワーク・アドレスを使用するアプリケーションでは、IPv6アドレスを処理するために、わずかな変更と再コンパイルが必要になる場合があります。IPv6アドレスは128ビットですが、IPv4アドレスは32ビットです。IPv6アドレスは、URL内では大カッコで囲む必要があります。次に例を示します。
http://[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]/
参照:
|
例14-11のように、PL/SQLサブプログラムはUTL_SMTP
パッケージを使用して電子メールを送信できます。
例14-11 PL/SQLからの電子メールの送信
CREATE OR REPLACE PROCEDURE send_test_message IS mailhost VARCHAR2(64) := 'mailhost.example.com'; sender VARCHAR2(64) := 'me@example.com'; recipient VARCHAR2(64) := 'you@example.com'; mail_conn UTL_SMTP.CONNECTION; BEGIN mail_conn := UTL_SMTP.OPEN_CONNECTION(mailhost, 25); -- 25 is the port UTL_SMTP.HELO(mail_conn, mailhost); UTL_SMTP.MAIL(mail_conn, sender); UTL_SMTP.RCPT(mail_conn, recipient); UTL_SMTP.OPEN_DATA(mail_conn); UTL_SMTP.WRITE_DATA(mail_conn, 'This is a test message.' || chr(13)); UTL_SMTP.WRITE_DATA(mail_conn, 'This is line 2.' || chr(13)); UTL_SMTP.CLOSE_DATA(mail_conn); /* If message were in single string, open_data(), write_data(), and close_data() could be in a single call to data(). */ UTL_SMTP.QUIT(mail_conn); EXCEPTION WHEN OTHERS THEN -- Insert error-handling code here RAISE; END; /
参照: UTL_SMTP パッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |
PL/SQLサブプログラムは、UTL_INADDR
パッケージを使用して、ローカル・システムのホスト名または特定のホスト名のIPアドレスを判別できます。
参照: UTL_INADDR パッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |
PL/SQLサブプログラムは、UTL_TCP
パッケージを使用して、ネットワーク上のシステムにTCP/IP接続をオープンし、対応するソケットへの読込みまたは書込みを行います。
参照: UTL_TCP パッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |
PL/SQLサブプログラムは、UTL_HTTP
パッケージを使用して次の操作を実行できます。
HTTP URLのコンテンツの取得
通常、コンテンツはHTMLタグ・テキストの形式ですが、Webサーバーからダウンロード可能な種類のファイル(たとえば、プレーン・テキストまたはJPEGイメージ)であることもあります。
HTTPセッションの詳細(ヘッダー、cookie、リダイレクト、プロキシ・サーバー、保護サイトのIDとパスワード、CGIパラメータなど)の管理
HTTP 1.1永続接続を使用した同じWebサイトへの同時アクセスの高速化
PL/SQLサブプログラムは、ファンクションUTL_URL
.ESCAPE
やUTL_URL
.UNESCAPE
を使用して、UTL_HTTP
パッケージで使用するためにURLの構築と解釈を行うことができます。
例14-12のPL/SQLプロシージャは、UTL_HTTP
パッケージを使用してHTTP URLのコンテンツを取得します。
例14-12 PL/SQLからのHTTP URLコンテンツの取得
CREATE OR REPLACE PROCEDURE show_url (url IN VARCHAR2, username IN VARCHAR2 := NULL, password IN VARCHAR2 := NULL) AS req UTL_HTTP.REQ; resp UTL_HTTP.RESP; name_ VARCHAR2(256); value_ VARCHAR2(1024); data_ VARCHAR2(255); my_scheme VARCHAR2(256); my_realm VARCHAR2(256); my_proxy BOOLEAN; BEGIN -- When going through a firewall, pass requests through this host. -- Specify sites inside the firewall that do not need the proxy host. UTL_HTTP.SET_PROXY('proxy.example.com', 'corp.example.com'); -- Ask UTL_HTTP not to raise an exception for 4xx and 5xx status codes, -- rather than just returning the text of the error page. UTL_HTTP.SET_RESPONSE_ERROR_CHECK(FALSE); -- Begin retrieving this web page. req := UTL_HTTP.BEGIN_REQUEST(url); -- Identify yourself. -- Some sites serve special pages for particular browsers. UTL_HTTP.SET_HEADER(req, 'User-Agent', 'Mozilla/4.0'); -- Specify user ID and password for pages that require them. IF (username IS NOT NULL) THEN UTL_HTTP.SET_AUTHENTICATION(req, username, password); END IF; -- Start receiving the HTML text. resp := UTL_HTTP.GET_RESPONSE(req); -- Show status codes and reason phrase of response. DBMS_OUTPUT.PUT_LINE('HTTP response status code: ' || resp.status_code); DBMS_OUTPUT.PUT_LINE ('HTTP response reason phrase: ' || resp.reason_phrase); -- Look for client-side error and report it. IF (resp.status_code >= 400) AND (resp.status_code <= 499) THEN -- Detect whether page is password protected -- and you didn't supply the right authorization. IF (resp.status_code = UTL_HTTP.HTTP_UNAUTHORIZED) THEN UTL_HTTP.GET_AUTHENTICATION(resp, my_scheme, my_realm, my_proxy); IF (my_proxy) THEN DBMS_OUTPUT.PUT_LINE('Web proxy server is protected.'); DBMS_OUTPUT.PUT('Please supply the required ' || my_scheme || ' authentication username for realm ' || my_realm || ' for the proxy server.'); ELSE DBMS_OUTPUT.PUT_LINE('Web page ' || url || ' is protected.'); DBMS_OUTPUT.PUT('Please supplied the required ' || my_scheme || ' authentication username for realm ' || my_realm || ' for the web page.'); END IF; ELSE DBMS_OUTPUT.PUT_LINE('Check the URL.'); END IF; UTL_HTTP.END_RESPONSE(resp); RETURN; -- Look for server-side error and report it. ELSIF (resp.status_code >= 500) AND (resp.status_code <= 599) THEN DBMS_OUTPUT.PUT_LINE('Check if the website is up.'); UTL_HTTP.END_RESPONSE(resp); RETURN; END IF; -- HTTP header lines contain information about cookies, character sets, -- and other data that client and server can use to customize each -- session. FOR i IN 1..UTL_HTTP.GET_HEADER_COUNT(resp) LOOP UTL_HTTP.GET_HEADER(resp, i, name_, value_); DBMS_OUTPUT.PUT_LINE(name_ || ': ' || value_); END LOOP; -- Read lines until none are left and an exception is raised. LOOP UTL_HTTP.READ_LINE(resp, value_); DBMS_OUTPUT.PUT_LINE(value_); END LOOP; EXCEPTION WHEN UTL_HTTP.END_OF_BODY THEN UTL_HTTP.END_RESPONSE(resp); END; /
次のブロックでは、例14-12のプロシージャのコールの例を示していますが、そのURLは存在しないページのものです。自分のWebブラウザからURLを代入します。
BEGIN show_url('http://www.oracle.com/no-such-page.html'); show_url('http://www.oracle.com/protected-page.html'); show_url ('http://www.oracle.com/protected-page.html','username','password'); END; /
参照:
|
PL/SQLサブプログラムは、Oracle提供のパッケージやOracle HTTP Server(OHS)のmod_plsql
プラグインを使用して、問合せ結果のHTML表としての書式設定、イメージ・マップの生成、HTTP cookieの取得、CGI変数の値の確認、その他の一般的なWeb操作の実行を行います。
これらのパッケージのドキュメントは、データベース・ドキュメント・ライブラリの一部ではありません。ドキュメントの場所は、アプリケーション・サーバーによって異なります。これらのパッケージを使用するには、次に示すSQL*PlusのDESCRIBE
文を使用して、サブプログラム名およびパラメータを確認します。
DESCRIBE HTP; DESCRIBE HTF; DESCRIBE OWA_UTIL;