この章では、Webページに動的コンテンツを含めることを可能にするPL/SQL Server Pages(PSP)の開発方法について説明します。
内容は次のとおりです。
PL/SQL Server Pages(PSP)は、WebページにSQL問合せの結果を含む動的コンテンツを含めるサーバー側スクリプトです。WebページをHTMLオーサリング・ツールで作成し、PL/SQLコード・ブロックを挿入できます。
例11-1に、simple.pspという名前の簡単なPL/SQL Server Pagesを示します。
例11-1 simple.psp
<%@ 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コマンドライン・ユーティリティを使用すると、PL/SQL Server Pagesをコンパイルしてデータベースにロードできます。次のコマンドでは、simple.pspがhrスキーマにロードされ、show_employeesプロシージャが置換されます(すでに存在している場合)。
loadpsp -replace -user hr/password simple.psp
ブラウザ・ユーザーは、URLを介してshow_employeesプロシージャを実行できます。hr.employees表にある従業員の姓名を表示するHTMLページが、PL/SQLゲートウェイを介してブラウザに戻されます。
PL/SQL Server Pagesを介してコンテンツをデプロイする方法には、次のメリットがあります。
PL/SQLをよく理解している開発者にとって、PL/SQL Server Pagesはデータベースにより生成されるコンテンツを含む専門的なWebページを最も容易に作成できる方法です。Webページを通常どおりに開発し、HTMLにPL/SQLコードを埋め込むことができます。
PL/SQL Server Pagesは、HTPパッケージやHTFパッケージを使用してHTMLコンテンツを1行ずつ記述する方法に比べると、多くの点で利便性に優れています。
処理はデータベース・サーバーで実行されるため、クライアント・ブラウザは特別なスクリプト・タグのないプレーンHTMLページを受信します。すべてのブラウザおよびブラウザ・レベルを同等にサポートできます。
PL/SQL Server Pagesを使用するとデータベースのラウンドトリップ数が最小限に抑えられるため、ネットワーク通信量が効率的です。
コンテンツをすばやく作成し、迅速で反復的な開発プロセスに従うことができます。クライアント・システム上にWebブラウザがあれば、ソフトウェアを集中制御できます。
PL/SQL Server Pagesを開発してデプロイするには、次の前提条件を満たす必要があります。
PL/SQL Server Pagesを記述するには、スクリプト作成用のテキスト・エディタまたはHTMLオーサリング・ツールにアクセスする必要があります。他の開発ツールは不要です。
PL/SQL Server Pagesをロードするための要件は、次のとおりです。
PL/SQL Server Pagesをロードするデータベース上のアカウント。
$ORACLE_HOME/binにあるloadpspコマンドライン・ユーティリティの実行権限。
PL/SQL Server Pagesをデプロイするには、mod_plsqlを使用する必要があります。ゲートウェイではPL/SQL Web Toolkitが使用されます。「mod_plsqlゲートウェイを使用したクライアント・リクエストのPL/SQL Webアプリケーションへのマップ」を参照してください。
次の方法で、ブラウザ・ユーザーがHTTPを介してPL/SQLユニットを実行できるようにすることができます。
埋込みPL/SQLコードを使用したHTMLページを作成し、それをPL/SQL Server Pagesとしてコンパイルします。PL/SQL Web Toolkitからサブプログラムを起動することもできますが、HTML出力の各行を生成することはできません。
PL/SQL Web ToolkitにあるHTPパッケージおよびOWA_*パッケージを起動することによって、HTMLを生成する完全なストアド・サブプログラムを作成します。この方法の詳細は、「PL/SQLを使用したHTML出力の生成」を参照してください。
そのため、Webアプリケーションの作成に使用する方法を選択する必要があります。これらの方法を選択する際のキーは、次のとおりです。
開始点として使用するソースの内容
HTMLの本体が大きく、かつ動的コンテンツを含める場合、またはデータベース・アプリケーションのフロントエンドとする場合には、PL/SQL Server Pagesを使用します。
フォーマットされた出力を生成するPL/SQLコードの本体が大きい場合は、出力文を変更してPL/SQL Web ToolkitのHTPパッケージを起動し、HTMLタグを作成する方が有効です。
自分のグループにとって最も迅速で便利なオーサリング環境
作業の大半がHTMLオーサリング・ツールにより処理される場合は、PL/SQL Server Pagesを使用します。
PL/SQLコードを生成するオーサリング・ツールを使用する場合は、PL/SQL Server Pagesを使用すると不便な場合があります。
スクリプティング・ソリューションは、クライアント側とサーバー側で使用できます。JavaScriptは、最も一般的なクライアント側スクリプト言語の1つです。PL/SQL Server Pagesは、JavaScriptを完全にサポートしています。PL/SQL Server Pages(PSP)を使用すると、すべてのタグが変更されずにブラウザに渡されるため、PL/SQL Server Pages(PSP)には、JavaScriptまたはその他のクライアント側のスクリプト・コードを含めることができます。
Java Server Pages(JSP)とActive Server Pages(ASP)は、最も一般的なサーバー側スクリプティング・ソリューションです。PL/SQL Server Pagesと対比すると次のようになります。
JavaServer Pagesは、PL/SQL Server Pagesにほぼ類似していますが、JavaサーブレットはPL/SQLパッケージに類似しています。PL/SQL Server Pagesでは、JSPと同じスクリプト・タグ構文を使用しているため、双方の切替えは簡単です。
PL/SQL Server PagesではASPに類似した構文を使用していますが、同一ではありません。通常は、VBScriptまたはJScriptからPL/SQLに変換する必要があります。移行に最適なのは、Active Data Object(ADO)を使用してデータベース処理を実行するページです。
|
注意: PSPに、サーバー側にあるその他のサーバー側スクリプト機能を混在させることはできません。多くの場合、対応するPL/SQL Server Pages機能を使用することによって、同じ結果を得ることができます。 |
PL/SQL Server Pagesを開発するには、既存のWebページから作業を開始する方法と、既存のストアド・サブプログラムから作業を開始する方法があります。どちらの方法でも、わずかな追加と変更のみで、データベース処理を実行し、結果を表示する動的なWebページを作成できます。
PL/SQL Server Pagesのファイルの拡張子は、.pspである必要があります。PL/SQL Server Pagesには、PL/SQL Server Pagesディレクティブ、宣言およびスクリプトレットとともにテキストまたはタグを配置することによって、選択した内容を含めることができます。PL/SQL Server Pagesには、次の書式を使用できます。
最も簡単な例は、HTMLファイルです。HTMLファイルをPL/SQL Server Pagesとしてコンパイルすると、同じHTMLファイルを出力するストアド・サブプログラムが作成されます。
最も複雑な例では、PL/SQLサブプログラムを使用します。PL/SQLプロシージャを使用して、タイトル、本体およびヘッダーのタグを含むWebページのコンテンツ全体を生成します。
一般的な例では、HTML(ページの静的な部分)とPL/SQL(動的コンテンツを提供)の両方を使用します。
PL/SQL Server Pagesディレクティブと宣言の順序と位置は、通常は重要ではありません。重要になるのは、別のファイルが挿入される場合のみです。メンテナンスを簡単にするために、ディレクティブおよび宣言は、ともにファイルの最初の方に配置することをお薦めします。
表11-1にPL/SQL Server Pagesの要素と使用方法の参照先を示します。各種PL/SQL Server Pages要素に使用される文字列を引用符で囲む方法については、「PSPスクリプトでの文字列の引用符およびエスケープ」を参照してください。
表11-1 PSPの要素
| PSPの要素 | 名前 | 指定 | 参照先 |
|---|---|---|---|
|
|
ページ・ディレクティブ |
PL/SQL Server Pagesの特性 |
|
|
|
パラメータ・ディレクティブ |
PSPストアド・プロシージャによって予測される各パラメータの名前、および(オプションで)型とデフォルト値 |
|
|
|
プロシージャ・ディレクティブ |
PSPファイルによって生成されたストアド・プロシージャの名前 |
|
|
|
インクルード・ディレクティブ |
PSPファイル内の特定のポイントに含めるファイルの名前 |
|
|
|
宣言ブロック |
次の |
|
|
|
コード・ブロック |
ストアド・プロシージャの実行時に実行される一連のPL/SQL文 |
|
|
|
式ブロック |
文字列、算術式、ファンクション・コールまたはこれらの組合せなど、単一のPL/SQL式 |
|
|
|
コメント |
PSPスクリプト内のコメント |
|
内容は次のとおりです。
<%@ page ... %>ディレクティブを使用して、次のようなPL/SQL Server Pagesの特性を指定します。
使用するスクリプト言語
生成する情報のタイプ(MIMEタイプ)
捕捉されなかったすべての例外を処理するために実行するコード。このコードは、わかりやすいメッセージを含むHTMLファイルの場合があり、.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" %>
このディレクティブは、他のスクリプティング環境との互換性を保つためのものです。例11-1に、言語ディレクティブを含む簡単なPL/SQL Server Pagesの例を示します。
オプション:
PL/SQL Server PagesのPL/SQL部分は、特別なデリミタで囲まれています。他のすべての内容は(空白を含めて)、ブラウザにそのまま渡されます。テキストまたはHTMLタグを表示するには、通常のWebページと同じように書き込みます。出力ファンクションを起動する必要はありません。たとえば、例11-1に示したPL/SQL Server Pagesは、例11-2に示すHTMLページを戻しますが、ここでは問い合せた従業員に関する表の行が含まれています。
例11-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行ずつ表示したり属性の値を変更する必要がある場合があります。例11-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ゲートウェイはファイルを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ゲートウェイは、PL/SQLゲートウェイによって定義されたキャラクタ・セットを使用してファイルを送信します。ブラウザに表示するためにデータを別のキャラクタ・セットに変換するには、次のディレクティブを含めます。
<%@ page charset="encoding" %>
Shift_JIS、Big5、UTF-8、またはクライアント・プログラムが認識できるその他のエンコーディングを指定します。
PL/SQLゲートウェイのデータベース・アクセス記述子(DAD)に設定するキャラクタ・セットも構成する必要があります。データが適切に表示されるようにするには、ユーザーが使用するブラウザで同じエンコーディングを選択する必要がある場合があります。たとえば、EUCエンコーディングを使用するデータベース・キャラクタ・セットが日本のデータベースに含まれていることがありますが、Webブラウザは、Shift_JISエンコーディングで表示するように構成されています。
PL/SQL Server Pagesを書き込むときに、次のようなエラーが発生することがあります。
HTML構文エラー
これらのエラーはブラウザで処理されます。loadpspユーティリティは、それらをチェックしません。
PL/SQL構文エラー
loadpspユーティリティが停止し、行番号、列番号および簡単なメッセージを表示します。継続するには、エラーを修正する必要があります。
ストアド・サブプログラムの以前のバージョンを構文エラーを含むスクリプトで置換しようとすると、そのストアド・サブプログラムは消去される場合があります。1つのデータベースをプロトタイプおよびデバック用に使用し、その後、最終的なストアド・サブプログラムを別の本番データベースにロードすることもできます。コマンドライン・フラグを使用すると、どのソース・コードを変更しなくてもデータベースを切り替えることができます。
ランタイム・エラー
スクリプトの実行時に発生するデータベース・エラーを処理するには、PSPファイルにPL/SQL例外処理コードを含め、未処理の例外があれば、特別なPL/SQL Server Pagesに提示させます。ページ名は、<%@ 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"] %>
デフォルトのPL/SQL_typeはVARCHAR2です。次のディレクティブは、パラメータp_employee_idのデータ型がNUMBERであることを指定しています。
<%@ plsql parameter="p_employee_id" type="NUMBER" %>
パラメータにデフォルト値を指定すると、そのパラメータはオプション・パラメータになります。デフォルト値はPL/SQL文に直接代入されるため、すべての文字列を引用符で囲む必要があります。また、NULLなどの特殊な値を使用できます。次のディレクティブは、パラメータp_last_nameのデフォルト値がNULLであることを指定しています。
<%@ plsql parameter="p_last_name" default="NULL" %>
ユーザー入力は、HTMLページを取得するURLにエンコードされます。URLを生成するには、ユーザー入力をHTMLリンクでハードコード化するか、またはHTML形式のアクションとしてページを起動します。これによって、ページは、PL/SQLストアド・サブプログラムへのパラメータとして入力を受け取ります。
例11-3は例11-1と似ていますが、パラメータp_employee_idが使用される点が異なります。http://www.host.com/pls/proc_nameを起動して(proc_nameはプロシージャ名)プロシージャを実行できるようにPL/SQLゲートウェイが構成されている場合は、次のようにパラメータp_employee_idで200を渡すことができます。
http://www.example.com/pls/show_employees?p_employee_id=200
例11-3 simplewithuserinput.psp
<%@ page language="PL/SQL" %> <%@ page contentType="text/html" %> <%@ plsql parameter="p_employee_id" default="null" type="NUMBER" %> <%@ 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 WHERE employee_id = p_employee_id 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>
トップレベルの各PL/SQL Server Pagesは、サーバー内の1つのストアド・プロシージャと対応しています。loadpspを使用してページをロードすると、このユーティリティによりPL/SQLストアド・プロシージャが作成されます。サーバー・ページがname.pspである場合、デフォルトのプロシージャ名はnameです。たとえば、サーバー・ページがhello_world.pspの場合、デフォルトのプロシージャ名はhello_worldです。
プロシージャ名を指定するには、次のディレクティブを使用します。procnameはプロシージャの名前です。
<%@ plsql procedure="procname" %>
例11-1では、次のディレクティブによりストアド・プロシージャにshow_employeesという名前が与えられます。
<%@ plsql procedure="show_employees" %>
これはPSPスクリプト名ではなく、URLに挿入するプロシージャの名前です。
挿入メカニズムを設定することによって、通常、静的HTMLコンテンツまたはより多くのPL/SQLスクリプト・コードのいずれかを含む別のファイルのコンテンツを含めることができます。filenameを挿入するファイルの名前で置き換えて、他のファイルのコンテンツを表示する位置に次のディレクティブを挿入します。
<%@ include file="filename" %>
インクルード・ファイルには、.psp以外の拡張子を付ける必要があります。includeディレクティブおよびloadpspコマンドの両方に、../include/などのすべての関連パス名を含む同じ名前を正確に指定する必要があります。
ファイルは、ストアド・プロシージャをデータベースにロードするときに処理されるため、置換は、ページの提示ごとではなく、1回のみ実行されます。したがって、ページがデータベースにロードされた後に、インクルード・ファイルに変更が発生した場合、変更内容はプロシージャの実行時に表示されません。
挿入機能を使用してナビゲーション・バナー、フッター、目次などのコード・ライブラリに含めると、複数のファイルに挿入できます。また、この機能をマクロ機能として使用し、スクリプト・コードの同じセクションを1つのページの複数の位置に含めることもできます。次の例では、HTMLフッターを含めています。
<%@ include file="footer.htm" %>
インクルード・ファイルを使用する場合:
インクルード・ファイルには、どのような名前および拡張子でも使用できます。たとえば、products.txtというファイルを含めることができます。
インクルード・ファイルにPL/SQLスクリプト・コードが含まれている場合、プロシージャ名やキャラクタ・セットなどを識別するための独自のディレクティブは必要ありません。
loadpspユーティリティにファイル名を指定するときは、すべてのインクルード・ファイルの名前も含める必要があります。インクルード・ファイルの名前は、すべての.pspファイル名より前に指定してください。
<%! ... %>ディレクティブを使用して、次のBEGIN/ENDブロック内のみでなく、ページ全体を通して参照できる、一連のPL/SQL変数を定義できます。通常、この要素は複数行にまたがっており、最後にセミコロンが付いた個々のPL/SQL変数宣言を持ちます。このディレクティブの構文は次のとおりです。
<%! PL/SQL declaration; [ PL/SQL declaration; ] ... %>
標準的なPL/SQL構文は、ブロック内で使用できます。デリミタは略記として機能するため、DECLAREキーワードを省略できます。すべての宣言は、ファイル内のその後のコードに使用できます。例11-1には、次のカーソル宣言が含まれています。
<%! CURSOR emp_cursor IS SELECT last_name, first_name FROM hr.employees ORDER BY last_name; %>
複数の宣言ブロックを内部的に指定できます。それらはすべて、PSPファイルがストアド・プロシージャとして作成されたときに単一ブロックにマージされます。
「PSPスクリプトでの実行可能文の指定」で説明する<% ... %>デリミタ内に明示的なDECLAREブロックを使用することもできます。これらの宣言は、後続のBEGIN/ENDブロックのみが参照できます。
|
注意: すべてのディレクティブおよび宣言をPL/SQL Server Pagesの最初の方にまとめて配置すると、メンテナンスがより簡単になります。 |
<% ... %>コード・ブロック・ディレクティブを使用して、ストアド・プロシージャの実行時に一連の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またはその他のディレクティブを途中に置くことができます。これによって、これら複数のスクリプトレットは、ストアド・プロシージャが実行されたときに、条件付きで実行されます。例11-11から抜粋した次のコードは、この方法を示しています。
<% 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 Server Pages間でプロシージャ、定数および型を共有するには、プレーンなPL/SQLソース・ファイルを使用して、それらをデータベース内のパッケージにコンパイルします。PSPスクリプトからパッケージ・プロシージャ、定数および型を参照できますが、PSPスクリプトで生成できるのは、パッケージではなくスタンドアロン・プロシージャのみです。 |
式ディレクティブは、文字列、算術式、ファンクション・コールまたはこれらの組合せなど、単一のPL/SQL式を出力します。結果は、ストアド・プロシージャによって生成されたHTMLページ内の該当部分で文字列に置き換えられます。式の結果は、文字列値であるか、文字列にキャストできる値である必要があります。DATEなど、暗黙的にキャストできない型の場合、値をPL/SQLのTO_CHARファンクションに渡します。
式ディレクティブの構文は、次のとおりです。expressionプレースホルダを必要な式で置き換えてください。
<%= expression %>
PL/SQL式の最後にセミコロンを付ける必要はありません。
例11-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
例11-4に、3タイプのコメントを含むPSPファイルの断片を示します。
例11-4 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]
[includefile...] [errorfile] pspfile...
CREATE OR REPLACE構文でプロシージャを作成するには、-replaceフラグを使用します。
PSPファイルのロード時に、ローダーにより次のアクションが実行されます。
指定したユーザー名、パスワードおよびネット・サービス名を使用してデータベースにログインします。
ユーザー・スキーマにストアド・プロシージャを作成します。
PL/SQL Server Pages名の前に、すべてのインクルード・ファイルの名前を含めます。さらに、pageディレクティブのerrorPage属性に指定されたファイルの名前も含めます。loadpspコマンドライン上のこれらのファイル名は、../include/などの関連パス名も含めて、PL/SQL Server Pagesのincludeディレクティブおよびpageディレクティブに指定された名前と完全に一致する必要があります。例11-5に、PSPロード・コマンドの例を示します。
例11-5 PL/SQL Server Pagesのロード
loadpsp -replace -user joe/abc123@/db3 banner.inc error.psp display_order.psp
例11-5の内容は次のとおりです。
ストアド・プロシージャは、データベースdb3で作成されます。ストアド・プロシージャを作成および実行するときは、データベースはユーザーjoe、パスワードabc123でアクセスされます。
banner.incは、ボイラープレート・テキストとスクリプト・コードを含むファイルで、.pspファイルに含まれています。banner.incは、ストアド・プロシージャが実行されるときではなく、PL/SQL Server Pagesがデータベースにロードされるときに含まれます。
error.pspは、未処理例外が発生したときに処理されるコードまたはテキスト(あるいはその両方)を含むファイルで、内部エラー・メッセージではなくわかりやすい内容のページを表示します。
display_order.pspには、Webページの主要コードおよびテキストが含まれています。デフォルトでは、対応するストアド・プロシージャはdisplay_orderという名前です。
loadpspによって生成されるコードは、ソース・ファイル内のコードとは異なります。WebページのHTMLタグを生成するHTPパッケージへのコールを含んでいます。
PSPファイルをロードした後、静的データ・ディクショナリ・ビュー*_SOURCEに対して問合せを行うことにより、生成されたソース・コードを表示できます。たとえば、次のコマンドを使用して例11-1のスクリプトをロードするとします。
loadpsp -replace -user hr/password simple.psp
データベースにユーザーhrとしてログインすると、例11-6のようにSQL*Plusで問合せを実行してPSPのソース・コードを表示できます。
例11-6 PL/SQL Server Pageソース・コードの問合せ
SQL> SELECT TEXT 2 FROM USER_SOURCE 3 WHERE NAME = 'SHOW_EMPLOYEES' 4 ORDER BY LINE; 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(' '); 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; 50 rows selected. SQL>
PL/SQL Server Pagesが一度ストアド・プロシージャに変換されると、Webブラウザまたは他のインターネット関連クライアント・プログラムを使用してHTTP URLを取得することによって、そのプロシージャを実行できます。URLの仮想パスは、PL/SQLゲートウェイが構成された方法によって異なります。
ストアド・プロシージャへのパラメータは、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.example.com/pls/show_employees?p_lname=Ashdown&p_fname=Lance
METHOD=POSTを使用した場合、パラメータはURL構文に表示されません。
http://sitename/schemaname/procname
たとえば、次のURLではプロシージャ名は指定されていますが、パラメータは渡されません。
http://www.example.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表を使用します。
SQL> DESCRIBE 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) SQL>
各例の想定は次のとおりです。
「mod_plsqlゲートウェイを使用したクライアント・リクエストのPL/SQL Webアプリケーションへのマップ」の説明に従って、mod_plsqlの設定を完了していること。
OEユーザーの静的認証に使用するDADを作成していること。
OEスキーマに作成したPL/SQLストアド・プロシージャに、URL http://www.example.com/pls/proc_nameを介してアクセスできること(proc_nameはストアド・プロシージャ名)。
例11-7のようにOWA_UTIL.TABLEPRINTをコールして、デバッグのためにSQL表の内容全体を表示できます。後の例では、表示をさらに制御する他の方法を示します。
例11-7 show_prod_simple.psp
<%@ 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>
次のように、例11-7のPSPをコマンドラインでロードします。
loadpsp -replace -user oe/password show_prod_simple.psp
次のURLを介してPSPにアクセスします。
http://www.example.com/pls/show_prod_simple
例11-7では、product_information表の項目をループし、SELECT文を調整して、行または列のサブセットのみを取得します。この例では、一致していない表タグまたはクローズしていない表タグによる問題を回避するために、非常に単純な一連のリスト品目を例として示します。
例11-8 show_catalog_raw.psp
<%@ 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>
例11-9に、より洗練された例11-8のバリエーションを示します。この例では、表示を改善するためにHTMLに書式が追加されています。
例11-9 show_catalog_pretty.psp
<%@ 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>
例11-7、例11-8および例11-9では、PRODUCT_INFORMATION表が更新されないかぎりHTMLページは変わりません。例11-10では次の処理が行われます。
HTMLページに最低価格を入力できるようにし、それよりも高価な品目のみを表示するようにします。(顧客の購買基準は様々です。)
デフォルトの最低価格を100(単位は該当通貨)に設定します。
例11-10 show_product_partial.psp
<%@ 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>
例11-10をデータベースにロードした後、URLを介してshow_product_partialプロシージャにパラメータを渡すことができます。次の例では、最低価格250を指定しています。
http://www.example.com/pls/show_product_partial?p_minprice=250
結果のフィルタリングは、検索結果など、選択肢がユーザーにとって多すぎる可能性があるアプリケーションには有用です。ただし、小売りの場合は、顧客が他の品目も選択できるように、例11-11に示す別の方法を使用する必要があります。
WHERE句を使用して結果をフィルタするかわりに、すべての結果セットを取得し、戻された各行に対して別々のアクションを実行します。
HTMLを変更して、基準に合う出力のみをハイライト表示させます。例11-11では、HTML表の行にバックグラウンド・カラーを使用します。最も重要な行が目立つようにするために、特別なアイコンを挿入したり、フォント・サイズを大きくすることもできます。
結果をHTML表に表示します。
例11-11 show_product_highlighed.psp
<%@ 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>
例11-12に、ユーザーが価格を入力できるHTMLフォームの要点を示します。このフォームは、例11-10に示したshow_product_partialストアド・プロシージャを起動し、入力された値をp_minpriceパラメータとして渡します。
このフォームのACTION=属性で、ストアド・プロシージャのURL全体をコード化することを回避するには、そのストアド・プロシージャが起動するPSPファイルと同じディレクトリに置かれるように、このフォームをPSPファイルとして作成します。このHTMLファイルにはPL/SQLコードが含まれていませんが、これに.psp拡張子を付け、ストアド・プロシージャとしてデータベースにロードできます。URLを介してproduct_formストアド・プロシージャが実行されたとき、HTMLはファイルに表示されるとおりに表示されます。
JavaScriptなどの動的コンテンツを含むような、複雑なHTMLファイルを生成するには、ソース・コードをPL/SQL Server Pagesとして実装することによって単純化します。この方法では、ネストされた引用符、エスケープ文字、連結リテラルや変数および埋込みコンテンツのインデントを考慮する必要がなくなります。
例11-13に例11-10の別バージョンを示します。このバージョンでは、ユーザーがマウスを製品URLに置くと、JavaScriptを使用してブラウザのステータス・バーに注文のステータスが表示されます。
例11-13 show_product_javascript.psp
<%@ 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に取り組み始めた際、および最初の単純なページからより複雑なページに進む過程で、問題が発生した場合は、次のガイドラインに従ってください。
まず、すべてのPL/SQL構文およびPSPディレクティブ構文を正しく作成します。ここで間違っていれば、ファイルはコンパイルできません。
行を終了するには、必要に応じてセミコロンを使用します。
引用符で囲む必要のある値に、引用符が付いているかどうかを確認します。一重引用符で囲まれた値(PL/SQLで必要)を二重引用符(PL/SQL Server Pagesで必要)で囲む必要がある場合もあります。
PSPディレクティブ内の誤りは、通常、PL/SQL構文メッセージによってレポートされます。適切な構文が使用され、適切にクローズされ、内容に応じた適切な要素(宣言、式またはコード・ブロック)が使用されているかどうかについて、ディレクティブをチェックします。
PSP属性名は、大/小文字を区別します。ほとんどの場合、すべて小文字で指定します。contentTypeおよびerrorPageは、大文字と小文字を組み合せて指定する必要があります。
URLを使用してPSPを要求するときに、ファイルが見つからないというエラーが表示される場合があります。その際は次のように対処します。
Webゲートウェイの構成方法に合った、正確な仮想パスを要求しているかどうかを確認します。通常、パスにはホスト名が含まれます。また、オプションで、ポート番号、スキーマ名およびストアド・プロシージャの名前(.psp拡張子なし)が含まれます。
ファイルをコンパイルするときに-replaceオプションを使用した場合、ストアド・プロシージャの古いバージョンは消去されます。そのため、コンパイルに失敗した場合は、エラーを修正しなければページは使用できません。新しいスクリプトを別のスキーマでテストし、その後、本番スキーマにロードするという方法をとることもできます。
ファイルを別のファイルからコピーした場合、ソース内のプロシージャ名ディレクティブを新しいファイル名と一致させるように変更してください。
ファイルが見つからないというエラーが1つでも戻された場合、次回は最新バージョンのページを要求してください。ブラウザがエラー・ページをキャッシュする場合があります。ブラウザに再ロードされるページにキャッシュを強制的にバイパスさせる必要がある場合があります。
PSPスクリプトが実行されると、結果はブラウザに戻されます。標準のデバッグ方法を使用して、出力のチェックおよび修正を行ってください。ここでは、適切な値がページに渡されるように、異なるHTMLフォーム、スクリプト、CGIプログラムの間でインタフェースを構成することが重要です。パラメータが一致しなければ、ページがエラーを戻す場合があります。
ガイドライン:
ページに渡される内容を正確に判別するには、URLでパラメータを参照できるようにFORMタグの中でMETHOD=GETを使用します。
ページを起動するフォームまたはCGIプログラムが適切なパラメータ数を渡すかどうかを確認します。また、フォームのNAME=属性で指定した名前が、PSPファイルのパラメータ名と一致していることも確認します。フォームに非表示の入力フィールドがある場合、あるいは「Submit」ボタンまたは「Reset」ボタンにNAME=属性が使用されている場合、PSPファイルは同等のパラメータを宣言する必要があります。
パラメータが文字列から適切なPL/SQL型にキャストされることを確認します。たとえば、PSPファイルのパラメータがNUMBERで宣言されている場合、アルファベット文字を含めることはできません。
ページへのハードコード・リンクを構成してパラメータを渡す場合は、特に、URLの問合せ文字列が、等号で区切られた名前/値ペアで構成されていることを確認します。
大きい文字列など、多数のパラメータ・データを渡す場合、METHOD=GETで渡すことができるボリュームを超えてしまう場合があります。その場合、PSPファイルを変更せずに、FORMタグの中でMETHOD=POSTに切り替えることができます。
ソース・ファイルに構文エラーがある場合、loadpspコマンドは、行番号を正しくレポートしますが、実行中のエラーに対してレポートされた行番号は、ソースの変換バージョンを参照し、元のソースの行番号とは一致しません。予想したWebページではなくエラー・トレースが表示されるエラーが発生した場合は、例外ハンドラおよびデバッグ出力の表示によって、エラーの位置を特定する必要があります。
PSPアプリケーションを商品化する前に、有用性やダウンロード速度などの問題も考慮する必要があります。
すべてのイメージにHEIGHT=属性およびWIDTH=属性が指定されると、ブラウザがページを生成する速度が速くなります。また、写真のサイズを標準化したり、イメージの高さおよび幅をデータまたはURLとともにデータベースに格納しておくこともできます。
図形を表示しないビューア、またはテキストを音声で読み上げるブラウザを使用しているビューア用には、ALT=属性を使用して重要な図形の説明を含めます。これも、イメージとともにデータベースに格納しておきます。
HTMLの表はデータ表示の方法として有効ですが、大きい表が原因でアプリケーションの速度が遅く感じることがあります。表全体がダウンロードされるまで、ビューアには空白のページが表示されます。HTML表のデータ量が大きければ、出力を複数の表に分割することを考慮してください。
テキスト、フォントまたはバックグランドにそれぞれカラーを設定している場合、アプリケーションをブラウザのカラー設定の様々な組合せでテストします。
ブラウザでフォアグラウンド・カラーのみをオーバーライドした場合、バックグラウンド・カラーのみをオーバーライドした場合、または両方をオーバーライドした場合に、それぞれどのような結果になるかをテストします。
1つのカラー(たとえば、フォアグラウンド・テキスト・カラー)を設定した場合に、白のバックグラウンドに白のテキストなど、読みにくい組合せを回避するために、すべてのカラーを<BODY>タグで設定してください。
バックグランド・イメージを使用する場合、図形をロードしないビューアに対して適切なコントラストを設定できるように、同系色のバックグランド・カラーを指定します。
異なるカラーで表示する情報が重要な意味を持つ場合は、別の方法を使用することを検討します。たとえば、表内の特別な項目の横にアイコンを置いたりします。ユーザーによっては、ページをモノクロ画面で表示する場合や、様々なカラーを表示できないブラウザを使用している場合もあります。
ユーザーに内容の情報を提供すると、ユーザーが迷わなくなります。ページに、わかりやすい<TITLE>タグを含めます。ユーザーが手順の途中にいる場合は、表示されているページがどの手順なのかを示します。手順を継続するか、前の手順に戻るか、または手順を完全に中止するかを示す論理点へのリンクを設定します。多くのページには、インクルード・ディレクティブを使用して埋め込んだ、標準のリンクが使用されています。
ユーザーは、入力フィールドに不適切な値を入力してしまう場合があります。できるだけ、選択肢を示したSELECT構文のリストを使用します。フィールドに入力されたテキストは、SQLに渡す前に、すべて妥当性チェックを行う必要があります。妥当性は早い段階でチェックする方が効果的です。JavaScriptルーチンは、不適切なデータを検出し、ユーザーが「Submit」ボタンを押してデータベースにコールする前に、ユーザーに対して修正を促します。
ブラウザが、間違ったHTMLを表示する場合もあります。あるブラウザでは正常に表示されても、別のブラウザでは正常に表示されなかったり、まったく表示されない場合もあります。
ガイドライン:
引用符、タグのクローズおよび表に関するHTMLルールには注意してください。
単一のブラウザのみでサポートされているタグに依存することは、最小限にしてください。そのようなタグを使用することによって便利な場合もありますが、アプリケーションは他のブラウザでも使用可能である必要があります。
多くのWebサイトで、HTMLの妥当性および(場合によっては)有用性が無償でチェックできます。