| Oracle Database アプリケーション開発者ガイド-基礎編 10gリリース2(10.2) B19248-02 |
|
この項の内容は次のとおりです。
この項の内容は次のとおりです。
PL/SQL Server Pages(PSP)は、WebページにSQL問合せの結果を含めて動的な内容を含めるサーバー側スクリプトです。WebページをHTMLオーサリング・ツールで作成し、PL/SQLコード・ブロックを挿入できます。
例12-1に、simple.pspという単純なPL/SQL Server Pagesを示します。
<%@ page language="PL/SQL" %> <%@ page contentType="text/html" %> <%@ plsql procedure="show_employees" %> <%-- This example displays the last name and first name of every employee in the hr.employees table. --%> <%! CURSOR emp_cursor IS SELECT last_name, first_name FROM hr.employees ORDER BY last_name; %> <html> <head> <meta http-equiv="Content-Type" content="text/html"> <title>List of Employees</title> </head> <body TEXT="#000000" BGCOLOR="#FFFFFF"> <h1>List of Employees</h1> <table width="40%" border="1"> <tr> <th align="left">Last Name</th> <th align="left">First Name</th> </tr> <% FOR emp_record IN emp_cursor LOOP %> <tr> <td> <%= emp_record.last_name %> </td> <td> <%= emp_record.first_name %> </td> </tr> <% END LOOP; %> </table> </body> </html>
このスクリプトをコンパイルし、loadpspコマンドライン・ユーティリティを使用してOracleデータベースにロードできます。次の例では、このPL/SQL Server Pagesをhrスキーマにロードし、すでに存在する場合はshow_employeesプロシージャを置き換えます。
loadpsp -replace -user hr/hr simple.psp
ブラウザ・ユーザーは、URLを介してshow_employeesプロシージャを実行できます。hr.employees表にある従業員の姓名を表示するHTMLページが、PL/SQLゲートウェイを介してブラウザに戻されます。
PL/SQL Server Pagesを介してコンテンツを配置する方法には、次のメリットがあります。
HTPおよびHTFパッケージを使用してHTMLコンテンツを1行ずつ記述する方法に比べて、PSPの方が便利です。
PL/SQL Server Pagesを開発して配置するには、次の前提条件を満たす必要があります。
次の方法で、ブラウザ・ユーザーがHTTPを介してPL/SQLプログラム・ユニットを実行できるようにすることができます。
HTPおよびOWA_*パッケージをコールすることによって、HTMLを生成する完全なストアド・プロシージャを作成します。この方法については、「PL/SQLを使用したHTML出力の生成」を参照してください。
そのため、Webアプリケーションの作成に使用する方法を選択する必要があります。これらの方法を選択する際のキーは、次のとおりです。
スクリプティング・ソリューションは、クライアント側とサーバー側で使用できます。JavaScriptは、最も一般的なクライアント側スクリプト言語の1つです。PSPは、JavaScriptを完全にサポートしています。PL/SQL Server Pages(PSP)を使用すると、すべてのタグが変更されずにブラウザに渡されるため、PL/SQL Server Pages(PSP)には、JavaScriptまたはその他のクライアント側のスクリプト・コードを含めることができます。
JavaServer Pages(JSP)とActive Server Pages(ASP)は、最も一般的なサーバー側スクリプティング・ソリューションです。PSPとの対比上、次の点に注意してください。
PL/SQL Server Pagesを作成するには、既存のWebページから作業を開始する方法と、既存のストアド・プロシージャから作業を開始する方法があります。どちらの方法でも、わずかな追加と変更のみで、データベース処理を実行し、結果を表示する動的なWebページを作成できます。
PL/SQL Server Pagesのファイルの拡張子は、.pspである必要があります。PL/SQL Server Pagesには、PSPディレクティブ、宣言およびスクリプトレットとともにテキストまたはタグを配置することによって、選択した内容を含めることができます。PL/SQL Server Pagesには、次の書式を使用できます。
PSPディレクティブと宣言の順序と位置は、通常は重要ではありません。重要になるのは、別のファイルが挿入される場合のみです。メンテナンスを簡単にするために、ディレクティブおよび宣言は、ともにファイルの最初の方に配置することをお薦めします。
表12-1に、PSPの要素と使用方法の参照先を示します。各種PSP要素に使用される文字列を引用符で囲む方法については、「PSPスクリプトでの文字列の引用符およびエスケープ」を参照してください。
<%@ page ...%>ディレクティブを使用して、次のようなPL/SQL Server Pagesの特性を指定します。
.pspファイルに名前が変更されます。主なPSPファイルをコンパイルするloadpspコマンドにも同じファイル名を指定する必要があります。errorPageディレクティブおよびloadpspコマンドの両方に、../include/などのすべての関連パス名を含む同じ名前を正確に指定する必要があります。
次のコードは、pageディレクティブの構文を示しています(属性名contentTypeおよびerrorPageには大/小文字区別があることに注意してください)。
<%@ page [language="PL/SQL"] [contentType="content type string"] charset="encoding" [errorPage="file.psp"] %>
ファイルをPL/SQL Server Pagesとして識別するには、ファイルのどこかに次のディレクティブを挿入します。
<%@ page language="PL/SQL" %>
このディレクティブは、他のスクリプティング環境との互換性を保つためのものです。言語ディレクティブを含む簡単なPL/SQL Server Pagesの例は、例12-1を参照してください。
クライアント・ブラウザに戻すデータの型を指定するときには、次の基本的なオプションから選択できます。
PL/SQL Server PagesのPL/SQL部分は、特別なデリミタで囲まれています。他のすべての内容は(空白を含めて)、ブラウザに逐次渡されます。テキストまたはHTMLタグを表示するには、通常のWebページと同じように書き込みます。出力ファンクションをコールする必要はありません。たとえば、例12-1に示したPL/SQL Server Pagesは、例12-2に示すHTMLページを戻しますが、ここでは問い合せた従業員に関する表の行が含まれています。
<html> <head> <meta http-equiv="Content-Type" content="text/html"> <title>List of Employees</title> </head> <body TEXT="#000000" BGCOLOR="#FFFFFF"> <h1>List of Employees</h1> <table width="40%" border="1"> <tr> <th align="left">Last Name</th> <th align="left">First Name</th> </tr> <!-- result set of query of hr.employees inserted here --> </table> </body> </html>
条件によって、出力を1行ずつ表示したり属性の値を変更する必要がある場合があります。例12-1から抜粋した次のコード部分のように、PSPデリミタ内に制御構造と置換変数を含めることができます。
<% FOR emp_record IN emp_cursor LOOP %> <tr> <td> <%= emp_record.last_name %> </td> <td> <%= emp_record.first_name %> </td> </tr> <% END LOOP; %>
デフォルトでは、PL/SQL GatewayはファイルをHTMLドキュメントとして送信します。そのため、ブラウザはHTMLタグを解析します。ブラウザに、ドキュメントをXML、プレーン・テキスト(書式なし)またはその他のドキュメント・タイプとして解析させるには、次のディレクティブを含めます。
<%@ page contentType="MIMEtype" %>
属性名は大/小文字が区別されます。contentTypeのように、正確に大文字を使用してください。text/html、text/xml、text/plain、image/jpeg、またはブラウザやその他のクライアント・プログラムが認識できるその他のMIMEタイプを挿入します。MIMEタイプの中には、ユーザーがブラウザの設定を変更しないと認識されないものもあります。次に、Excelスプレッドシートに使用するディレクティブの例を示します。
<%@ page contentType="application/vnd.ms-excel" %>
通常、PL/SQL Server Pagesは、Webブラウザで表示されるように作られています。また、JavaやPerlクライアントなど、HTTP要求を作成可能なプログラムによって取得または解析されることもあります。
デフォルトでは、PL/SQL Gatewayは、PL/SQL Gatewayによって定義されたキャラクタ・セットを使用してファイルを送信します。ブラウザに表示するためにデータを別のキャラクタ・セットに変換するには、次のディレクティブを含めます。
<%@ page charset="encoding" %>
Shift_JIS、Big5、UTF-8、またはクライアント・プログラムが認識できるその他のエンコーディングを指定します。
PL/SQL Gatewayのデータベース・アクセス記述子(DAD)に設定するキャラクタ・セットも構成する必要があります。データが適切に表示されるようにするには、ユーザーが使用するブラウザで同じエンコーディングを選択する必要がある場合があります。たとえば、EUCエンコーディングを使用するデータベース・キャラクタ・セットが日本のデータベースに含まれていることがありますが、Webブラウザは、Shift_JISエンコーディングで表示するように構成されています。
PL/SQL Server Pagesの作成自には、次のタイプのエラーに注意してください。
loadpspユーティリティは、それらをチェックしません。
loadpspユーティリティは停止し、行番号、列番号および簡潔なメッセージが表示されます。継続するには、エラーを修正する必要があります。ストアド・プロシージャの以前のバージョンを構文エラーを含むスクリプトで置換しようとすると、そのストアド・プロシージャは消去されるので注意してください。1つのデータベースをプロトタイプおよびデバック用に使用し、その後、最終的なストアド・プロシージャを別の本番データベースにロードすることもできます。コマンドライン・フラグを使用すると、どのソース・コードを変更しなくてもデータベースを切り替えることができます。
<%@ page ...%>ディレクティブのerrorPage属性(名前には大/小文字区別があることに注意)を使用して、ページ名を指定してください。未処理の例外用のページは、拡張子.pspを持つPL/SQL Server Pagesです。エラー・プロシージャは、どのパラメータも受け取りません。そのため、エラーの原因を判断するには、SQLCODEファンクションおよびSQLERRMファンクションをコールします。また、エラーが発生した場合は、スクリプトを使用しない標準HTMLページを表示することもできます。ただし、拡張子を.pspとし、ストアド・プロシージャとしてデータベースにロードする必要があります。
次の例に、エラー発生時に実行されるページとしてerrors.pspを指定するディレクティブを示します。
<%@ page language="PL/SQL" contentType="text/html" errorPage="errors.psp" %>
PL/SQL Server Pagesへのパラメータ渡しを設定するには、次の構文のディレクティブを含めます。
<%@ plsql parameter="parameter name" [type="PL/SQL type"] [default="value"] %>
パラメータ・ディレクティブを含むスクリプトの例は、例12-9を参照してください。
デフォルトでは、パラメータはVARCHAR2型です。異なる型を使用するには、次の例のように、ディレクティブにtype="PL/SQL type"属性を含めます。
<%@ plsql parameter="p_employee_id" type="NUMBER" %>
パラメータがオプションになるようにデフォルト値を設定するには、default="expression"属性をディレクティブに含めます。この属性の値は、直接PL/SQL文に置き換えられます。そのため、すべての文字列を一重引用符で囲む必要があります。また、次の例のように、NULLなどの特別な値を使用することもできます。
<%@ plsql parameter="p_last_name" default="null" %>
ユーザー入力は、HTMLページを取得するURLにエンコードされます。URLを生成するには、ユーザー入力をHTMLリンクでハードコード化するか、またはHTML形式のアクションとしてページをコールします。これによって、ページは、PL/SQLストアド・プロシージャへのパラメータとして入力を受け取ります。たとえば、例12-1の最初の数行を変更して次のようなパラメータ・ディレクティブを挿入してから、データベースにロードするとします。
<%@ page language="PL/SQL" %> <%@ page contentType="text/html" %> <%@ plsql parameter="p_employee_id" default="null" type="NUMBER" %> <%@ plsql procedure="show_employees" %> <%! CURSOR emp_cursor IS SELECT last_name, first_name FROM hr.employees WHERE employee_id = p_employee_id ORDER BY last_name; %>
http://www.host.com/pls/proc_nameをコールして(proc_nameはプロシージャ名)プロシージャを実行できるようにPL/SQL Gatewayが構成されている場合は、次のようにパラメータp_employee_idで200を渡すことができます。
http://www.host.com/pls/show_employees?p_employee_id=200
トップレベルの各PL/SQL Server Pagesは、サーバー内の1つのストアド・プロシージャと対応しています。loadpspを使用してページをロードすると、このユーティリティによりPL/SQLストアド・プロシージャが作成されます。デフォルトでは、プロシージャにはPSPスクリプトと同じ名前が、拡張子.pspなしで付いています。そのため、スクリプト名がhello_world.pspであれば、ユーティリティではデフォルトでhello_worldというプロシージャが作成されます。
プロシージャにスクリプト名とは異なる名前を付けるには、次のディレクティブを含めます。procnameはプロシージャ名です。
<%@ plsql procedure="procname" %>
例12-1には、ストアド・プロシージャにshow_employeesという名前を与える次のディレクティブが含まれています。
<%@ plsql procedure="show_employees" %>
そのため、ファイルにempnames.pspまたは*.pspで終わる他の名前を付けることはできますが、プロシージャはshow_employeesとして作成されます。これはPSPスクリプト名ではなく、URLに挿入するプロシージャの名前であることに注意してください。
挿入メカニズムを設定することによって、通常、静的HTMLコンテンツまたはより多くのPL/SQLスクリプト・コードのいずれかを含む別のファイルのコンテンツを含めることができます。filenameを挿入するファイルの名前で置き換えて、他のファイルのコンテンツを表示する位置に次のディレクティブを挿入します。
<%@ include file="filename" %>
インクルード・ファイルには、.psp以外の拡張子を付ける必要があります。includeディレクティブおよびloadpspコマンドの両方に、../include/などのすべての関連パス名を含む同じ名前を正確に指定する必要があります。
ファイルは、ストアド・プロシージャをデータベースにロードするときに処理されるため、置換は、ページの提示ごとではなく、1回のみ実行されます。したがって、ページがデータベースにロードされた後に、インクルード・ファイルに変更が発生した場合、変更内容はプロシージャの実行時に表示されません。
挿入機能を使用してナビゲーション・バナー、フッター、目次などのコード・ライブラリに含めると、複数のファイルに挿入できます。また、この機能をマクロ機能として使用し、スクリプト・コードの同じセクションを1つのページの複数の位置に含めることもできます。次の例では、HTMLフッターを含めています。
<%@ include file="footer.htm" %>
インクルード・ファイルの次の特性に注意してください。
products.txtというファイルを含めるとします。
loadpspユーティリティにファイル名を指定するときは、すべてのインクルード・ファイルの名前も含める必要があります。インクルード・ファイルの名前は、すべての.pspファイル名より前に指定してください。
<%!... %>ディレクティブを使用して、次のBEGIN/ENDブロック内のみでなく、ページ全体を通して参照できる、一連のPL/SQL変数を定義できます。通常、この要素は複数行にまたがっており、最後にセミコロンが付いた個々のPL/SQL変数宣言を持ちます。このディレクティブの構文は次のとおりです。
<%! PL/SQL declaration; [ PL/SQL declaration; ] ... %>
標準的なPL/SQL構文は、ブロック内で使用できます。デリミタは略記として機能するため、DECLAREキーワードを省略できます。すべての宣言は、ファイル内のその後のコードに使用できます。例12-1には、次のカーソル宣言が含まれています。
<%! CURSOR emp_cursor IS SELECT last_name, first_name FROM hr.employees ORDER BY last_name; %>
複数の宣言ブロックを内部的に指定できます。それらはすべて、PSPファイルがストアド・プロシージャとして作成されたときに単一ブロックにマージされます。
「PSPスクリプトでの実行可能文の指定」で説明する<% ... %>デリミタ内に明示的なDECLAREブロックを使用することもできます。これらの宣言は、後続のBEGIN/ENDブロックのみが参照できます。
<% ...%>コード・ブロック・ディレクティブを使用して、ストアド・プロシージャの実行時に一連のPL/SQL文を実行できます。次のコードは、実行可能文の構文を示しています。
<% PL/SQL statement; [ PL/SQL statement; ] ... %>
通常、この要素は複数行にまたがっており、最後にセミコロンが付いた個々のPL/SQL変数宣言を持ちます。この文は、次の例に示すように、OWA_UTIL.TABLEPRINTプロシージャをコールする完全なブロックを含むこともできます。
<% OWA_UTIL.TABLEPRINT(CTABLE => 'hr.employees', CATTRIBUTES => 'border=2', CCOLUMNS => 'last_name,first_name', CCLAUSES => 'WHERE employee_id > 100'); %>
また、この文はIF/THEN/ELSEまたはBEGIN/ENDブロックの大カッコで囲まれた部分になることもできます。コード・ブロックが複数のディレクティブに分割されると、HTMLまたはその他のディレクティブを途中に置くことができます。これによって、これら複数のスクリプトレットは、ストアド・プロシージャが実行されたときに、条件付きで実行されます。例12-10から抜粋した次のコードは、この方法を示しています。
<% FOR ITEM IN (SELECT product_name, list_price, catalog_url FROM product_information WHERE list_price IS NOT NULL ORDER BY list_price DESC) LOOP IF item.list_price > p_minprice THEN v_color := '#CCCCFF'; ELSE v_color := '#CCCCCC'; END IF; %> <TR BGCOLOR="<%= v_color %>"> <TD><A HREF="<%= item.catalog_url %>"><%= item.product_name %></A></TD> <TD><BIG><%= item.list_price %></BIG></TD> </TR> <% END LOOP; %>
標準的なすべてのPL/SQL構文は、ブロック内で使用できます。デリミタは略記として機能するため、DECLAREキーワードを省略できます。すべての宣言は、ファイル内のその後のコードに使用できます。
式ディレクティブは、文字列、算術式、ファンクション・コールまたはこれらの組合せなど、単一のPL/SQL式を出力します。結果は、ストアド・プロシージャによって生成されたHTMLページ内の該当部分で文字列に置き換えられます。式の結果は、文字列値であるか、文字列にキャストできる値である必要があります。DATEなど、暗黙的にキャストできない型の場合、値をPL/SQLのTO_CHARファンクションに渡します。
式ディレクティブの構文は、次のとおりです。expressionプレースホルダを必要な式で置き換えてください。
<%= expression %>
PL/SQL式の最後にセミコロンを付ける必要はないことに注意してください。
例12-1には、次のように変数値を1つのカーソル行に出力するディレクティブが含まれています。
<%= emp_record.last_name %>
この例を、次の例に示す同等のhtp.printコールと比較してください(特に、文の終わりのセミコロンに注意してください)。
<% HTP.PRN (emp_record.last_name); %>
<%= ...%>デリミタ内の内容は、HTP.PRNファンクションによって処理されます。ここでは、先行または後続の空白はすべて切り捨てられ、リテラル文字列を引用符で囲むことが要求されます。
PL/SQLの場合と同様に、二重パイプ記号(||)を使用すると連結できることに注意してください。次のディレクティブに連結例を示します。
<%= 'The employee last name is ' || emp_record.last_name %>
PSP属性では、データのデリミタとして二重引用符が使用されます。PSP属性に指定された値がPL/SQL処理に使用された場合、それらはPSPファイルに指定されたとおりに渡されます。そのため、PL/SQLが一重引用符付き文字列を要求する場合、その文字列を一重引用符で囲み、すべてを二重引用符で囲んで指定する必要があります。
たとえば、PL/SQLプロシージャで変数のデフォルト値として文字列Babe Ruthを使用するとします。この文字列はPL/SQLで使用されるため、'Babe Ruth'のように一重引用符で囲む必要があります。このように一重引用符で囲んだ文字列をPSPディレクティブのdefault属性に指定する場合は、次の例に示すように二重引用符で囲む必要があります。
<%@ plsql parameter="in_players" default="'Babe Ruth'" %>
一重引用符の中に一重引用符付きの文字列をネストすることもできます。この場合、シーケンス¥'を指定してネストされた一重引用符をエスケープする必要があります。次に例を示します。
<%@ plsql parameter="in_players" default="'Walter ¥'Big Train¥' Johnson'" %>
ほとんどの文字および文字列は、PSPローダーで変更しなくてもPSPファイルに含めることができます。シーケンス%>を含めるには、エスケープ・シーケンス%¥>を指定します。シーケンス<%を含めるには、エスケープ・シーケンス<¥%を指定します。次に例を示します。
<%= 'The %¥> sequence is used in scripting language: ' || lang_name %> <%= 'The <¥% sequence is used in scripting language: ' || lang_name %>
PL/SQL Server PagesのHTML部分にコメントを挿入する場合、PSPソース・コードが簡単に読めるように次の構文を使用します。
<%-- PSP comment text --%>
前述した書式のコメントはPSPからのHTML出力には表示されず、USER_OBJECTS内のPL/SQLソース・コードを問い合せても表示されません。
HTML出力およびUSER_OBJECTSソースに表示されるコメントを作成するには、HTMLにコメントを挿入して、次のような通常のHTMLコメント構文を使用します。
<!-- HTML comment text -->
PSP内でPL/SQLブロックの中にコメントを挿入し、HTML出力では参照できないがUSER_OBJECTS内では参照できるようにするには、次の例に示すように通常のPL/SQLコメント構文を使用します。
-- Comment in PL/SQL code
例12-3に、3タイプのコメントを含むPSPファイルの断片を示します。
<p>Today we introduce our new model XP-10. <%-- This is the project with code name "Secret Project". Users viewing the HTML page will not see this PSP script comment. The comment is not visible in the USER_OBJECTS source code. --%> <!-- Some pictures of the XP-10. Users viewing the HTML page source will see this comment. The comment is also visible in the USER_OBJECTS source code. --> <% FOR image_file IN (SELECT pathname, width, height, description FROM image_library WHERE model_num = 'XP-10') -- Comments interspersed with PL/SQL statements. -- Users viewing the HTML page source will not see these PL/SQL comments. -- These comments are visible in the USER_OBJECTS source code. LOOP %> <img src="<%= image_file.pathname %>" width=<% image_file.width %> height=<% image_file.height %> alt="<% image_file.description %>"> <br> <% END LOOP; %>
$ORACLE_HOME/binにあるloadpspユーティリティを使用して、1つ以上のPSPファイルをストアド・プロシージャとしてデータベースにロードします。各.pspファイルは1つのストアド・プロシージャと対応します。開発サイクルを短くするために、ページのコンパイルおよびロードは1手順で行われます。loadpspユーティリティの構文は、次のとおりです。
loadpsp [ -replace ] -user username/password[@connect_string]
[ include_file_name ... ] [ error_file_name ] psp_file_name ...
CREATE OR REPLACE構文でプロシージャを作成するには、-replaceフラグを使用します。
PSPファイルのロード時に、ローダーにより次のアクションが実行されます。
PL/SQL Server Pages名の前に、すべてのインクルード・ファイルの名前を含めます。さらに、pageディレクティブのerrorPage属性に指定されたファイルの名前も含めます。loadpspコマンドライン上のこれらのファイル名は、../include/などの関連パス名も含めて、PL/SQL Server Pagesのincludeディレクティブおよびpageディレクティブに指定された名前と完全に一致する必要があります。例12-4に、PSPロード・コマンドの例を示します。
loadpsp -replace -user hr/hr@orcl banner.inc error.psp display_order.psp
例12-4の次の特性に注意してください。
orclで作成されます。ストアド・プロシージャを作成および実行するときは、データベースはユーザーhr、パスワードhrでアクセスされます。
banner.incは、ボイラープレート・テキストとスクリプト・コードを含むファイルで、.pspファイルに含まれています。banner.incは、ストアド・プロシージャが実行されるときではなく、PL/SQL Server Pagesがデータベースにロードされるときに含まれます。
error.pspは、未処理例外が発生したときに処理されるコードまたはテキスト(あるいはその両方)を含むファイルで、内部エラー・メッセージではなく分かりやすい内容のページを表示します。
display_order.pspには、Webページの主要コードおよびテキストが含まれています。デフォルトでは、対応するストアド・プロシージャはdisplay_orderという名前です。
PSPファイルをロードした後、データ・ディクショナリにあるUSER_SOURCE表またはDBA_SOURCE表内のソース・コードを表示できます。たとえば、次のコマンドを使用して例12-1のスクリプトをロードするとします。
loadpsp -replace -user hr/hr simple.psp
データベースにユーザーhrとしてログインすると、SQL*Plusで次の問合せを実行してPSPのソース・コードを表示できます。
SET HEADING OFF SELECT TEXT FROM USER_SOURCE WHERE NAME = 'SHOW_EMPLOYEES' ORDER BY LINE;
例12-5にサンプル出力を示します。loadpspによって生成されるコードが、ソース・ファイル内のコードとは異なることに注意してください。loadpspユーティリティは、PSPコードに追加コード(主にHTPパッケージのコール)を追加しています。HTPパッケージにより、Webページ用のHTMLタグが生成されます。
PROCEDURE show_employees AS CURSOR emp_cursor IS SELECT last_name, first_name FROM hr.employees ORDER BY last_name; BEGIN NULL; owa_util.mime_header('text/html'); htp.prn(' '); htp.prn(' '); htp.prn(' '); htp.prn(' <html> <head> <meta http-equiv="Content-Type" content="text/html"> <title>List of Employees</title> </head> <body TEXT="#000000" BGCOLOR="#FFFFFF"> <h1>List of Employees</h1> <table width="40%" border="1"> <tr> <th align="left">Last Name</th> <th align="left">First Name</th> </tr> '); FOR emp_record IN emp_cursor LOOP htp.prn(' <tr> <td> '); htp.prn( emp_record.last_name ); htp.prn(' </td> <td> '); htp.prn( emp_record.first_name ); htp.prn(' </td> </tr> '); END LOOP; htp.prn(' </table> </body> </html> '); END;
PL/SQL Server Pagesが一度ストアド・プロシージャに変換されると、Webブラウザまたは他のインターネット関連クライアント・プログラムを使用してHTTP URLを取得することによって、そのプロシージャを実行できます。URLの仮想パスは、PL/SQL Gatewayが構成された方法によって異なります。
ストアド・プロシージャへのパラメータは、HTTPプロトコルのPOSTメソッドまたはGETメソッドのいずれかを使用して渡されます。POSTメソッドの場合、パラメータはHTMLフォームから直接渡され、URLには表示されません。GETメソッドの場合、パラメータはURLの問合せ文字列で名前/値ペアとして渡されます。URLの問合せ文字列は、エンコード形式のほとんどの英数字以外の文字(たとえば、空白は%20)で、&文字で区切られています。PSPページをHTMLフォームからコールするには、GETメソッドを使用します。また、特定のパラメータ・セットを持つストアド・プロシージャをコールするには、ハードコード化されたHTMLリンクを使用します。
METHOD=GETを使用する場合、URLの構文は次のようになります。
http://sitename/schemaname/procname?parmname1=value1&parmname2=value2
たとえば、次のURLにはp_lnameおよびp_fnameパラメータが含まれています。
http://www.host.com/pls/show_employees?p_lname=Ashdown&p_fname=Lance
METHOD=POSTを使用した場合、パラメータはURL構文に表示されません。
http://sitename/schemaname/procname
たとえば、次のURLではプロシージャ名は指定されていますが、パラメータは渡されません。
http://www.host.com/pls/show_employees
METHOD=GET形式は、デバッグに有効です。また、ページの閲覧者がブックマークを使用して再度ページを開く際、同じパラメータを渡すことができます。
METHOD=POST形式は、さらに大きいパラメータ・データを扱えます。また、URLに表示してはならない機密情報を渡す場合に適しています。(URLは、ブラウザの履歴リスト、および次のアクセス・ページに渡されるHTTPヘッダーの中に残ります。)この方法でコールされたページにブックマークを付けるのは、効果的ではありません。
この項では、非常に単純なPL/SQL Server Pagesから始め、徐々に複雑なバージョンを作成していく方法を説明します。
各手順を行いながら、「データベースへのPL/SQL Server Pagesのロード」および「URLを介したPL/SQL Server Pagesの実行」の指示に従って例をテストしてください。
この項の内容は次のとおりです。
各例では、後述のように、oeスキーマ内のproduct_information表を使用します。
Table PRODUCT_INFORMATION Name Null? Type ----------------------------------------- -------- ---------------------------- PRODUCT_ID NOT NULL NUMBER(6) PRODUCT_NAME VARCHAR2(50) PRODUCT_DESCRIPTION VARCHAR2(2000) CATEGORY_ID NUMBER(2) WEIGHT_CLASS NUMBER(1) WARRANTY_PERIOD INTERVAL YEAR(2) TO MONTH SUPPLIER_ID NUMBER(6) PRODUCT_STATUS VARCHAR2(20) LIST_PRICE NUMBER(8,2) MIN_PRICE NUMBER(8,2) CATALOG_URL VARCHAR2(50)
各例の想定は次のとおりです。
oeユーザーの静的認証に使用するDADを作成していること。
oeスキーマに作成したPL/SQLストアド・プロシージャに、URL http://www.host.com/pls/proc_nameを介してアクセスできること(proc_nameはストアド・プロシージャ名)。
デバッグのために、SQL表の内容全体を表示できます。このためには、例12-6に示すようにOWA_UTIL.TABLEPRINTを1回コールします。後続の反復では、他の方法でより詳細に表示を制御します。
<%@ plsql procedure="show_prod_simple" %> <HTML> <HEAD><TITLE>Show Contents of product_information (Complete Dump)</TITLE></HEAD> <BODY> <% DECLARE dummy BOOLEAN; BEGIN dummy := OWA_UTIL.TABLEPRINT('oe.product_information','border'); END; %> </BODY> </HTML>
次のように、例12-6のPSPをコマンドラインでロードします。
loadpsp -replace -user oe/oe show_prod_simple.psp
次のURLを介してPSPにアクセスします。
http://www.host.com/pls/show_prod_simple
例12-6では、product_information表の項目をループし、SELECT文を調整して、行または列のサブセットのみを取得します。この例では、一致していない表タグまたはクローズしていない表タグによる問題を回避するために、非常に単純な一連のリスト品目を例として示します。
<%@ plsql procedure="show_prod_raw" %> <HTML> <HEAD><TITLE>Show Products (Raw Form)</TITLE></HEAD> <BODY> <UL> <% FOR item IN (SELECT product_name, list_price, catalog_url FROM product_information WHERE list_price IS NOT NULL ORDER BY list_price DESC) LOOP %> <LI> Item = <%= item.product_name %><BR> Price = <%= item.list_price %><BR> URL = <%= item.catalog_url %><BR> <% END LOOP; %> </UL> </BODY> </HTML>
例12-8に、より洗練された例12-7のバリエーションを示します。この例では、表示を改善するためにHTMLに書式が追加されています。
<%@ plsql procedure="show_prod_pretty" %> <HTML> <HEAD><TITLE>Show Products (Better Form)</TITLE></HEAD> <BODY> <UL> <% FOR item IN (SELECT product_name, list_price, catalog_url FROM product_information WHERE list_price IS NOT NULL ORDER BY list_price DESC) LOOP %> <LI> Item = <A HREF=<%= item.catalog_url %>><%= item.product_name %></A><BR> Price = <BIG><%= item.list_price %></BIG><BR> <% END LOOP; %> </UL> </BODY> </HTML>
前述の例では、product_information表が更新されないかぎりHTMLページは変化しません。例12-9では、このページを次の方法で活用しやすいものにします。
<%@ plsql procedure="show_product_partial" %> <%@ plsql parameter="p_minprice" default="100" %> <HTML> <HEAD><TITLE>Show Items Greater Than Specified Price</TITLE></HEAD> <BODY> <P>This report shows the items whose price is greater than <%= p_minprice %>. <UL> <% FOR ITEM IN (SELECT product_name, list_price, catalog_url FROM product_information WHERE list_price > p_minprice ORDER BY list_price DESC) LOOP %> <LI> Item = <A HREF="<%= item.catalog_url %>"><%= item.product_name %></A><BR> Price = <BIG><%= item.list_price %></BIG><BR> <% END LOOP; %> </UL> </BODY> </HTML>
例12-9をデータベースにロードした後、URLを介してshow_product_partialプロシージャにパラメータを渡すことができます。次の例では、最低価格250を指定しています。
http://www.host.com/pls/show_product_partial?p_minprice=250
結果をフィルタするこの方法は、検索結果として得られる選択肢がユーザーにとって多すぎる可能性があるアプリケーションなどには有用です。ただし、小売りの場合は、顧客が他の品目も選択できるように、例12-10に示す別の方法を使用する必要があります。この例の次の機能に注意してください。
WHERE句を使用して結果をフィルタするかわりに、すべての結果セットを取得し、戻された各行に対して別々のアクションを実行します。
<%@ plsql procedure="show_product_highlighted" %> <%@ plsql parameter="p_minprice" default="100" %> <%! v_color VARCHAR2(7); %> <HTML> <HEAD><TITLE>Show Items Greater Than Specified Price</TITLE></HEAD> <BODY> <P>This report shows all items, highlighting those whose price is greater than <%= p_minprice %>. <P> <TABLE BORDER> <TR> <TH>Product</TH> <TH>Price</TH> </TR> <% FOR ITEM IN (SELECT product_name, list_price, catalog_url FROM product_information WHERE list_price IS NOT NULL ORDER BY list_price DESC) LOOP IF item.list_price > p_minprice THEN v_color := '#CCCCFF'; ELSE v_color := '#CCCCCC'; END IF; %> <TR BGCOLOR="<%= v_color %>"> <TD><A HREF="<%= item.catalog_url %>"><%= item.product_name %></A></TD> <TD><BIG><%= item.list_price %></BIG></TD> </TR> <% END LOOP; %> </TABLE> </BODY> </HTML>
例12-11に、ユーザーが価格を入力できるHTMLフォームの要点を示します。このフォームは、例12-9に示したshow_product_partialストアド・プロシージャをコールし、入力された値をp_minpriceパラメータとして渡します。
このフォームのACTION=属性で、ストアド・プロシージャのURL全体をコード化することを回避するには、そのストアド・プロシージャがコールするPSPファイルと同じディレクトリに置かれるように、このフォームをPSPファイルとして作成します。このHTMLファイルにはPL/SQLコードが含まれていませんが、これに.psp拡張子を付け、ストアド・プロシージャとしてデータベースにロードできます。URLを介してproduct_formストアド・プロシージャが実行されたとき、HTMLはファイルに表示されるとおりに表示されます。
<HTML> <BODY> <FORM method="POST" action="show_product_partial"> <P>Enter the minimum price you want to pay: <INPUT type="text" name="p_minprice"> <INPUT type="submit" value="Submit"> </FORM> </BODY> </HTML>
JavaScriptなどの動的コンテンツを含むような、複雑なHTMLファイルを生成するには、ソース・コードをPL/SQL Server Pagesとして実装することによって単純化します。この方法では、ネストされた引用符、エスケープ文字、連結リテラルや変数および埋込みコンテンツのインデントを考慮する必要がなくなります。
例12-12に、例12-9の別バージョンを示します。このバージョンでは、ユーザーがマウスを製品URLに置くと、JavaScriptを使用してブラウザのステータス・バーに注文のステータスを表示します。
<%@ plsql procedure="show_product_javascript" %> <%@ plsql parameter="p_minprice" default="100" %> <HTML> <HEAD> <TITLE>Show Items Greater Than Specified Price</TITLE> <SCRIPT language="JavaScript"> <!--hide var text=" "; function overlink (text) { window.status=text; } function offlink (text) { window.status=text; } //--> </SCRIPT> </HEAD> <BODY> <P>This report shows the items whose price is greater than <%= p_minprice %>. <P> <UL> <% FOR ITEM IN (SELECT product_name, list_price, catalog_url, product_status FROM product_information WHERE list_price > p_minprice ORDER BY list_price DESC) LOOP %> <LI> Item = <A HREF="<%= item.catalog_url %>" onMouseover="overlink('PRODUCT STATUS: <%= item.product_status %>');return true" onMouseout="offlink(' ');return true"> <%= item.product_name %> </A> <BR> Price = <BIG><%= item.list_price %></BIG><BR> <% END LOOP; %> </UL> </BODY> </HTML>
PL/SQL Server Pagesに取り組み始めた際、および最初の単純なページからより複雑なページに進む過程で、問題が発生した場合は、次のガイドラインに従ってください。
contentTypeおよびerrorPageは、大文字と小文字を組み合せて指定する必要があります。
.psp拡張子なし)が含まれます。
-replaceオプションを使用した場合、ストアド・プロシージャの古いバージョンは消去されます。そのため、コンパイルに失敗した場合は、エラーを修正しなければページは使用できません。新しいスクリプトを別のスキーマでテストし、その後、本番スキーマにロードするという方法をとることもできます。
METHOD=GETを使用します。
NAME=属性で指定した名前が、PSPファイルのパラメータ名と一致していることも確認します。フォームに非表示の入力フィールドがある場合、あるいは「Submit」ボタンまたは「Reset」ボタンにNAME=属性が使用されている場合、PSPファイルは同等のパラメータを宣言する必要があります。
NUMBERで宣言されている場合、アルファベット文字を含めることはできません。
METHOD=GETで渡すことができるボリュームを超えてしまう場合があります。その場合、PSPファイルを変更せずに、FORMタグの中でMETHOD=POSTに切り替えることができます。
loadpspコマンドは、行番号を正しくレポートしますが、実行中のエラーに対してレポートされた行番号は、ソースの変換バージョンを参照し、元のソースの行番号とは一致しません。予想したWebページではなくエラー・トレースが表示されるエラーが発生した場合は、例外ハンドラおよびデバッグ出力の表示によって、エラーの位置を特定する必要があります。
PSPアプリケーションを商品化する前に、有用性やダウンロード速度などの問題も考慮する必要があります。
HEIGHT=属性およびWIDTH=属性が指定されると、ブラウザがページを生成する速度が速くなります。また、写真のサイズを標準化したり、イメージの高さおよび幅をデータまたはURLとともにデータベースに格納しておくこともできます。
ALT=属性を使用して重要な図形の説明を含めます。これも、イメージとともにデータベースに格納しておきます。
<BODY>タグで設定する必要があります。
<TITLE>タグを含めます。ユーザーが手順の途中にいる場合は、表示されているページがどの手順なのかを示します。手順を継続するか、前の手順に戻るか、または手順を完全に中止するかを示す論理点へのリンクを設定します。多くのページには、インクルード・ディレクティブを使用して埋め込んだ、標準のリンクが使用されています。
Submit」ボタンを押してデータベースにコールする前に、ユーザーに対して修正を促します。
|
![]() Copyright © 2006 Oracle Corporation. All Rights Reserved. |
|