本章では、Net.Data マクロ・ファイルを構成するさまざまなパーツと、 それらをアプリケーションでどのように動作させるかについて説明します。
この節では、単純な Net.Data マクロによってマクロ言語の要素を説明します。 この例のマクロは、REXX プログラムに渡す情報を表示するフォームを表します。 このマクロは、ユーザーによって入力されたデータを反映する、 OMPSAMP.CMD という名前の外部 REXX プログラムにこの情報を渡します。 結果は、2 番目の HTML ページに表示されます。
最初にマクロ全体を見てから、それぞれのブロックを詳しく検討します。
%{ ********************** Define block ************************%}
%DEFINE {
page_title="Net.Data macro Template"
%}
%{ ********************** Function Definition block ************************%}
%FUNCTION(DTW_REXX) rexx1 (IN input) returns(result)
{ %EXEC{ompsamp.cmd %}
%}
%FUNCTION(DTW_REXX) today () RETURNS(result)
{
result = date()
%}
%{ ********************** HTML Block: Input ************************%}
%HTML (INPUT) {
<html>
<head>
<title>$(page_title)<title>
</head><body>
<h1>Input Form</h1>
Today is @today()
<FORM METHOD="post" ACTION="output">
Type some data to pass to a REXX program:
<INPUT NAME="input_data" TYPE="text" SIZE="30">
<p>
<INPUT TYPE="submit" VALUE="Enter">
<hr>
<p>[<a href="/">Home page]
</body></html>
%}
%{ ********************** HTML Block: Output ************************%}
%HTML (OUTPUT) {
<html>
<head>
<title>$(page_title)</title>
</head><body>
<h1>Output Page</h1>
<p>@rexx1(input_data)
<p><hr>
<p>[<a href="/">Home page</a> |
<a href="input">Previous page</a>]
</body></html>
%}
このマクロは、4 つの主要なブロック、すなわち、DEFINE、FUNCTION、 および 2 つの HTML ブロックから構成されます。1 つの Net.Data マクロに、 複数の DEFINE ブロック、FUNCTION ブロック、および HTML ブロックを含むことができます。
2 つの HTML ブロックには、Web マクロを作成しやすくする、 見慣れた HTML タグが含まれています。 HTML に精通している場合は、マクロの作成は、 サーバーで動的に処理するマクロ・ステートメントと送信する SQL をデータベースに追加するだけで行えます。
このマクロは HTML 文書に類似しているようにみえますが、Web サーバーは、 このマクロに Net.Data を介して、 CGI プログラムまたは Web サーバー API としてアクセスします。Net.Data には、 2 つのパラメーター、つまり処理するマクロの名前と、 そのマクロ内を表示する HTML ブロックが必要です。
このマクロ・ファイルが呼び出されると、 Net.Data はそれを先頭から処理します。 次の節では、Net.Data がこのファイルを処理するときに何が起こるかを検討します。
%{ ********************** Define Block ************************%}
%DEFINE {
page_title="Net.Data macro Template"
%}
第 1 行はコメントです。コメントは、 %{ と %} の間のテキストです。 コメントは、他のマクロ・ブロックの外側になければなりません。 次のステートメントは、DEFINE ブロックを開始します。1 つの Define ブロックで、 複数の変数を定義することができます。 この例では、1 つの変数 page_title だけ定義されています。 いったん定義されれば、 $(page_title) という構文を使用してこのマクロ内の任意の場所でこの変数を参照することができます。 変数を使用すると、あとでマクロへの一括変更を行いやすくなります。 このブロックの最後の行、 %} は DEFINE ブロックの終りを示します。
次のブロックは関数定義ブロックですが、最初に、 この例で INPUT と呼ばれている HTML ブロックを検討します。
%{ ********************** HTML Block: Input ************************%}
%HTML (INPUT) { <--- この HTML ブロックの名前を定義
<html>
<head>
<title>$(page_title)</title> <--- 値が代入される変数
</head><body>
<h1>Input Form</h1>
Today is @today() <--- 関数呼出しを含む行
<FORM METHOD="post" ACTION="output"> <--- このフォームが実行されると
"output" HTML ブロックが呼ばれる
Type some data to pass to a REXX program:
<INPUT NAME="input_data" <--- フォームが実行され、このマクロの中のどこからでも
TYPE="text" SIZE="30"> 参照可能になると、"input_data" が定義される。
これはユーザーがインプット・フィールドに何か入れると
初期化される。
<p>
<INPUT TYPE="submit" VALUE="Enter">
<hr>
<p>
[
<a href="/">Home page</a>]
</body><html>
%} <--- HTML ブロックのクローズ
このブロックには、1 つの入力フィールドを持つ単純なフォームの HTML が含まれています。 ブロック全体は、 HTML ブロック識別子 %HTML (INPUT) { ... %} で囲まれています。 INPUT はこのブロックの名前を識別しています。 これには、任意の名前を与えることができます。 HTML <title> タグには、マクロ置換の例が含まれています。 変数 page_title の内容が、フォームのタイトルに置換されます。
このブロックには関数呼出しの例もあります。 式 @today() は、関数 today の呼出しです。 この関数は、あとで説明する FUNCTION ブロックで定義されています。 today 関数の結果、つまり、現在の日付は、 @today() 式があるのと同じロケーションの HTML テキストに挿入されます。
FORM ステートメントの ACTION パラメーターは、 HTML ブロック間、またはマクロ間のナビゲーションの例です。 ACTION パラメーターで別のブロックの名前を参照すると、 このフォームがサブミットされたときにそのブロックにアクセスします。 HTML フォームからの入力データはすべて、暗黙変数としてブロックに渡されます。 これは、このフォームで定義されている単位の入力フィールドに当てはまります。 フォームがサブミットされると、 このフィールドに入力されたデータが、 変数 input_data で HTML 出力ブロックに渡されます。
マクロ・ファイルが同じ Web サーバー上にあれば、 相対参照によって、他のマクロ・ファイル内の HTML ブロックにアクセスすることができます。 たとえば、ACTION="../othermacro.mac/main" は、 マクロ・ファイル othermacro.mac の main という名前の HTML ブロックにアクセスします。 この場合も、フォームに入力されたデータが、 変数 input_data でこのマクロに渡されます。
Net.Data を呼び出すときに、URL の一部として変数を渡します。たとえば、 次のとおりです。
<a href="/cgi-bin/db2www/othermacro.mac/main?input_data=value">Next macro</a>
ほとんどの CGI プログラムで行うように、 入力データを受け取るために環境変数を処理する必要はありません。 Net.Data がそれらの処理を行います。ユーザーは、変数名を参照するだけで済みます。
この例の次の HTML ブロックは、OUTPUT ブロックです。
%{ ********************** HTML Block: Output ************************%}
%HTML (OUTPUT) {
<html>
<head>
<title>$(page_title)</title> <--- 代入
</head><body>
<h1>Output Page</h1>
<p>@rexx1(input_data) <--- この行は "input_data" 引き数を渡す rexx1
関数への呼び出しを含む
<p>
<hr>
<p>
[
<a href="/">Home page</a> |
<a href="input">Previous page</a>]
%}
INPUT ブロックと同様、このブロックは、 変数および関数呼出しを置換するためのマクロ・ステートメントを持つ標準 HTML です。 この場合も、page_title 変数がタイトル・ステートメントに置換されます。 前と同じく、このブロックには関数呼出しが含まれています。 この場合は、関数 rexx1 を呼び出し、 INPUT フォームから受け取った変数 input_data の内容をそれに渡します。 任意の数の変数を関数との間で受け渡すことができます。 関数定義によって、渡される変数の数とそれらの型を判別します。
関数の詳細については、"関数定義ブロック" を参照してください。
%{ ********************** Function Definition Block ************************%}
%FUNCTION(DTW_REXX) rexx1 (IN input) returns(result) { <-- この関数は1つのパラメーター
を受取り、関連する関数呼出しに
代入される結果を戻す。
%EXEC{ompsamp.cmd %} <-- この関数は "ompsamp.cmd" という外部 REXX
プログラムを実行する
%}
%FUNCTION(DTW_REXX) today () RETURNS(result) {
result = date() <-- この関数の単一ソース・ステートメントはインライン
に含まれる
%}
この関数定義には 2 つの関数宣言が含まれています。 最初の関数宣言 rexx1 は、REXX 関数宣言であり、 これが、ompsamp.cmd という名前の外部 REXX プログラムを実行します。 1 つの入力変数 input がこの関数に受け入れられ、 外部 REXX コマンドに自動的に渡されます。 また、REXX コマンドは、resultという名前の 1 つの変数を返します。 REXX コマンドの中の result 変数の内容が、 OUTPUT ブロックに含まれている呼出し側の @rexx1() 関数呼出しを置き換えます。 変数 input および result は、 ompsamp.cmd のソースに示されているとおり、 REXX プログラムによって直接アクセス可能です。
/* REXX */ result = 'The REXX program received "'input'" from the macro.'
この関数のコードは、関数に渡されたデータを反映しています。 要求側の @rexx1() 関数を通常の HTML スタイル・タグ (たとえば、 <b> または <em>) で囲むことによって、結果のテキストを、 必要な形式にフォーマットすることができます。REXX プログラムは、 result 変数を使用するのでなく、 REXX SAY ステートメントを使用して HTML タグを標準出力に書き込んでいる可能性があります。
2 番目の関数宣言 today も、 REXX プログラムを参照しています。ただし、この場合、 REXX プログラム全体 (1 行全体) は関数宣言そのものに含まれています。 外部プログラムは必要ありません。 動的に解析および実行できる解釈言語であるため、 REXX 関数と PERL 関数の両方にインライン・プログラムが可能です。 インライン・プログラムには、 個別のプログラム・ファイルを管理する必要がないという利点があります。 最初の REXX 関数も、全く同じくインラインで処理することができます。
Net.Data では、Net.Data マクロで変数を定義し、参照することができます。 さらに、これらの変数をマクロから言語環境に渡し、言語環境からマクロに渡すことができます。 変数名および引用符付きのストリングなどの Net.Data トークンには、 最大 64KB までのデータを含むことができます。OS/400 の場合、 最大サイズはシステムによって判別されます。
マクロ変数は、次のような型にカテゴリー化されます。
識別子は、変数または関数呼出しであり、 宣言またはインスタンス化されたときに 可視 になります (つまり、 参照可能になります)。 識別子が可視の領域は、その効力範囲 と呼ばれます。 5 つのタイプの効力範囲があります。
識別子は、ユーザーがマクロ・ファイル内の任意の場所でそれを参照する場合、 グローバル効力範囲を持ちます。 グローバル効力範囲を持つ識別子には次のものがあります。
識別子は、その宣言がブロックの外側に現れる場合、この効力範囲を持ちます。 ブロックは、開始の "{" から始まり、"%}" で終わります。 (DEFINE ブロックは、この定義から除外され、 個別の DEFINE ステートメントとして扱う必要があることに注意してください。) マクロ・ファイル効力範囲を持つ識別子は、それが宣言されたポイントから、 そのマクロ・ファイルの終りまで可視になります。
識別子は、その宣言またはインスタンス化が FUNCTION ブロックの内部にある場合 (たとえば、 OUT 変数)、関数ブロック効力範囲を持ちます。 (これは、関数の REPORT または ROW ブロック内で参照されているが、 マクロ・ファイル内で明示的に定義されなかったか、 Net.Data によって暗黙的に定義された変数にも適用されます。)
識別子は、REPORT ブロック内からのみ参照できる場合、 REPORT ブロック効力範囲を持ちます (たとえば、テーブル列で、 N1、N2、...、Nn が命名される場合)。 そのテーブル処理の一部として Net.Data が暗黙的に定義する変数だけが、 REPORT ブロック効力範囲を持つことができます。 インスタンス化されるその他の変数は、関数ブロック効力範囲を持ちます。
識別子を参照すると、その識別子が、その識別子の値によって置き換えられます。 変数への参照に関連付けられた値がないか、 あるいは関数呼出しから戻り値が返されない場合には、 参照は空のストリングによって置き換えられます。
以下の節では、変数を定義および参照する方法を説明し、 さまざまな変数の型とそれらの変数の使用方法も説明します。
Net.Data マクロで変数を定義する方法には次の 3 つの方法があります。
Net.Data マクロで使用するための変数を定義する一番単純な方法は、 DEFINE ステートメントを使用する方法です。これは、 Net.Data に特有な構文です。
%DEFINE variable_name="variable value"
%DEFINE variable_name={ variable value on multiple
lines of text %}
variable_name は、変数に与える名前です。 変数名は、英字または下線から始まらなければなければなりません。 また、 変数名には任意の英数字または下線を含むことができます。 すべての変数名には大文字と小文字の区別があります。ただし、 N_columnName と V_columnName は、 例外でありこれらはテーブル変数です。
ストリングに引用符を組み込むには、2 つの引用符を連続して使用してください。 2 つの連続引用符だけはヌル・ストリングになります。
%DEFINE HI="say ""hello""" %DEFINE reply="hello" %DEFINE empty=""
表示されるとき、変数 HI は say "hello" を読み取り、 変数 reply は hello を読み取り、変数 empty はヌルです。
1 つの DEFINE ステートメントでいくつかの変数を定義するには、 DEFINE ブロックを使用します。
%DEFINE{
variable1="value1"
variable2="value2"
variable3="value3"
variable4="value4"
%}
この例は、標準 HTML フォーム・タグを使用して変数を定義します。
<INPUT NAME="variable_name" TYPE=...>
または
<SELECT NAME="variable_name">
variable_name は、変数に与える名前であり、 変数の名前は、フォームで受け取った入力データから判別されます。 この型の変数定義が Net.Data マクロでどのように使用されるかを表す例は、 "HTML フォーム" を参照してください。
INPUT または SELECT ステートメントから受け取った変数値によって、 Net.Data マクロの DEFINE で設定された変数値がオーバーライドされます。
Net.Data マクロを URL として呼び出し、ユーザー ID など、 URL に変数を組み込んで Net.Data に送信することができます。たとえば、 次のとおりです。
http://www.ibm.com/cgi-bin/db2www/stdqry1.mac/input?field=custno
追加のデータ (この例の場合は、field=custno) は、 フォーム・データと同じ方法で Net.Data により受け取られ、 同じ方法で処理されます。
Net.Data マクロでは、 $( と ) の中に変数名を指定することで変数を参照します (ただし、 IF ブロックの条件のときは除きます。その場合は、変数名だけを使用します)。 たとえば、次のとおりです。
$(variableName) $(homeURL)
Net.Data が変数参照を検出するし、その変数参照はその値によって置換されます。 循環参照 (または循環) は使用できません。 たとえば、下記の DEFINE ステートメントは認められず、 変数が参照され、最終値が評価されるときにエラーとなります。
%DEFINE a="$(b)" %DEFINE b="$(a)"
変数を HTML の一部として使用することができます。たとえば、 次のような変数 homeURL を定義した場合、
%DEFINE homeURL="http://www.ibm.com/"
次のように、ホーム・ページを $(homeURL) として参照し、 アンカー参照を作成することができます。
<A href="$(homeURL)">Home page</A>
Net.Data マクロのどのパーツでも変数を参照することができます。参照される時点に、 変数がまだ定義されていない場合、Net.Data は変数を定義し、 それにヌルの初期値を与えます。 Net.Data マクロは解析されるので、変数参照が検出されると、 それが評価され、変数の現行値でインライン置換されます。
変数が存在していてしかもヌルでない場合、条件付き変数が判別されます。 変数には、存在する場合、最初の値が与えられ、存在しない場合は、 2 番目の値が与えられます。 条件付き変数の構文は次のとおりです。
varA = varB ? "value_1" : "value_2"
varB が定義されていれば、 varA="value_1" であり、定義されていなければ、 varA="value_2" です。これは、 IF ブロックを使用した例と同等です。
%IF ( varB )
varA = "value_1"
%ELSE
varA = "value_2"
%ENDIF
リスト変数と条件付き変数を使用する例については、 "リスト変数" を参照してください。
Net.Data が実行中のプロセスに存在する Net.Data 環境変数を参照することができます。たとえば、 次のとおりです。
The client is @DTW_rGETENV("SERVER_NAME")
出力は次のようになります。
The HTTPD server is IBM Internet Connection Server/4.1
@DTW_GETENV 関数および @DTW_rGETENV 関数の詳細については、 Net.Data リファレンス・ガイド を参照してください。
実行可能変数フィーチャーを使用して、変数参照から他のプログラムを呼び出すことができます。 実行可能変数は次のように Net.Data マクロで定義されます。
%DEFINE runit=%exec "testProg"
Net.Data は、Net.Data 初期設定ファイルの EXEC_PATH で実行可能プログラムを探します。 詳細については、"EXEC_PATH" を参照してください。
プログラム testProg は、 Net.Data マクロの変数 runit に有効な変数参照が行われると、実行されます。 単純な例は、別の変数定義から実行変数を参照することです。
%DEFINE date=%exec "date" %DEFINE dateRpt="Today is $(date)"
Net.Data マクロに $(dateRpt) が現れると常に、 Net.Data は以下を返します。
Today is Tue 11-07-1995
実行変数は、それが呼び出す実行可能プログラムの出力の値に設定されることはありません。 直前の例を使用すると、日付の値はヌルになります。 これを DTW_ASSIGN 関数呼出しで使用してその値を別の変数に割り当てる場合、 割当て後の新しい変数の値もヌルになります。 実行変数の唯一の目的は、それにより定義するプログラムを呼び出すことです。 また、変数定義でプログラム名とともにパラメーターを指定することで、 実行するプログラムにパラメーターを渡すこともできます。 この例では、距離と時刻の値がプログラム calcMPH に渡されます。
%DEFINE mph=%exec "calcMPH $(distance) $(time)"
次の例では、HTML レポートの一部としてシステム日付が返されます。
%DEFINE database="celdial"
%DEFINE tstamp=%exec "date"
%FUNCTION(DTW_SQL) myQuery() {
SELECT CUSTNO, CUSTNAME from dist1.customer
%REPORT{
%ROW{
<A HREF="/cgi-bin/db2www/exmp.mac/report?value1=$(V1)&value2=$(V2)">
$(V1) $(V2) </A> <BR>
%}
%}
%}
%HTML(report){
<H1>Report made: $(tstamp) </H1>
@myQuery()
%}
それぞれのレポートは、追跡を容易にするため、日付を表示します。 この例では、別の Net.Data マクロのアンカー参照に顧客番号と名前も入れます。 レポートのいずれかの顧客をクリックすると、 exmp.mac Net.Data マクロが呼び出され、 その番号と名前が Net.Data マクロに渡されます。
Web ブラウザーでユーザーの HTML ソースを表示しようとする人々から、 変数の実際の名前を隠すために、隠し変数を使用することができます。
%HTML(INPUT) {
<FORM ...>
<P>Select fields to view:
<SELECT NAME="Field">
<OPTION VALUE="$$(name)"> Name
<OPTION VALUE="$$(addr)"> Address
.
.
.
</FORM>
%}
%DEFINE{
name="customer.name"
addr="customer.address"
%}
%FUNCTION(DTW_SQL) mySelect() {
SELECT $(Field) FROM customer
%}
.
.
.
HTML フォームが Web ブラウザーに表示されるとき、 $$(name) および $$(addr) はそれぞれ、 $(name) と $(addr) によって置き換えられます。そのため、 実際のテーブル名と列名は HTML フォームに現れず、 真の変数名が隠されていることは明らかにされません。 顧客がフォームをサブミットすると、 HTML(REPORT) ブロックが呼び出されます。 @mySelect() が FUNCTION ブロックを呼び出すと、 $(Field) は、SQL 照会の SQL ステートメントで、 customer.name または customer.addr によって置き換えられます。
リスト変数により、値の区切り記号付きのストリングを構築することができます。 リスト変数は、いくつかの WHERE 文節や HAVING 文節で検出されたものなど、 複数の項目を持つ SQL 照会を作成する際に特に有用です。 リスト変数の構文は次のとおりです。
%LIST " value_separator " variable_name
ブランクは有効です。ほとんどの場合、値区切り記号の前後にスペースを入れることをお勧めします。 大半の照会では値区切り記号に、 ブール演算子または数学演算子 (たとえば、AND、OR、または >) を使用します。 この例は、条件付き変数、隠し変数、およびリスト変数の使用法を表しています。
%HTML(INPUT){
<FORM METHOD="POST" ACTION="/cgi-bin/db2www/example2.mac/report">
<H2>Select one or more cities:</H2>
<INPUT TYPE="checkbox" NAME="conditions" VALUE="$$(cond1)">Sao Paola<BR>
<INPUT TYPE="checkbox" NAME="conditions" VALUE="$$(cond2)">Seattle<BR>
<INPUT TYPE="checkbox" NAME="conditions" VALUE="$$(cond3)">Shanghai<BR>
<INPUT TYPE="submit" VALUE="Submit Query">
</FORM>
%}
%DEFINE{
DATABASE="custcity"
%LIST " OR " conditions
cond1="Sao Paolo"
cond2="Seattle"
cond3="Shanghai"
whereClause=Conditions ? "WHERE $(conditions)" : ""
%}
%FUNCTION(DTW_SQL) mySelect(){
SELECT name, city FROM citylist
$(whereClause)
%}
%HTML(REPORT){
@mySelect()
%}
HTML フォームで、ボックスがチェックされない場合、 conditions はヌルになるので、 照会での whereClause もヌルになります。チェックされた場合は、 whereClause は、OR で区切られた、選択値を持ちます。たとえば、 3 つの都市すべてが選択されたとき、SQL 照会は次のようになります。
SELECT name, city FROM citylist WHERE cond1='Sao Paolo' OR cond2='Seattle' OR cond3='Shanghai'
この図は Seattle が選択されたことを示しており、結果は次の SQL 照会になります。
SELECT name, city FROM citylist WHERE cond1='Seattle'
テーブル変数は、関連データの集合を定義します。 テーブル変数には、同一レコード、または行の配列、 および各行のフィールドを記述する列名の配列が含まれます。 Net.Data マクロでは、テーブルは次のようなステートメントで定義されます。
%DEFINE myTable=%TABLE(30)
TABLE のあとの数値は、このテーブルに含むことのできる行数の制限です。 行数に制限のないテーブルを指定するには、デフォルトを使用するか、 次の例のように ALL を指定してください。
%DEFINE myTable2=%TABLE %DEFINE myTable3=%TABLE(ALL)
テーブル変数名を参照することで、関数間でテーブルを渡すことができます。 テーブルの個々の要素を、関数の REPORT ブロックで参照することができます。 テーブル変数は通常、SQL 関数からの出力およびレポートへの入力に使用されますが、 IN、OUT、または INOUT パラメーターとして任意の非 SQL 関数にテーブル変数を渡すことができます。 テーブルは、OUT パラメーターとしてだけ、SQL 関数に渡すことができます。
テーブルの列名およびフィールド値は、起点 1 を持つ配列要素としてアドレス指定され、 0 から配列を開始する標準の C および C++ 言語規則は使用されません。
テーブル変数を定義すると、Net.Data は暗黙的に 2 セットの変数を定義します。ユーザーは、
それらのセットを使用してテーブルの列名およびフィールド内容を参照することができます。
これらの暗黙変数の 1 つのセットは、
Net.Data マクロの FUNCTION ブロックの REPORT ブロックで参照され、
他方のセットは、言語環境から呼び出されるプログラムで参照されます。
これらの変数を、Net.Data マクロのその他のブロックで参照することはできません。
| N1, N2, ..., Nj | j th 列の名前。 |
| N_columnName | 値は、columnName の値。 |
| NLIST | N1 から Nj までのすべての列名の連結。 |
| V1, V2, ..., Vj | 現行の行に jth 列の値を含む。 |
| V_columnName | 現行の行に jth 列の値を含む。 |
| VLIST | 現行の行の V1 から Vj のすべてのフィールド値の連結。 |
| ROW_NUM | 現行の行の行番号を含む。 |
| NUM_COLUMNS | テーブルの列数を含む。 |
| TOTAL_ROWS | テーブルの行数を含む。 |
Net.Data は、Web アプリケーションで役立つ多くの関数を提供しています。 ユーザー独自の関数を作成することも簡単です。
ユーザー独自の関数を定義することも、 Net.Data の関数ライブラリーを使用することもできます。 Net.Data ライブラリーにない関数については、FUNCTION ブロックを使用して、 その関数を Net.Data マクロに定義します。詳細は、 Net.Data 言語環境ガイド にあります。 構文は以下に示すとおりです。
%FUNCTION(
type) function-name([usage
parameter, ...]) [RETURNS(return-var)] {
executable-statements
[report-block]
[message-block]
%}
初期設定ファイルに構成されている言語環境を識別します。 言語環境は、特定の言語処理プログラム (実行可能ステートメントを処理します) を呼び出し、 Net.Data とその言語処理プログラムの間の標準インターフェースを提供します。
Net.Data にはいくつかのデフォルトの言語環境が提供されています。
これは、FUNCTION ブロックの名前です。FUNCTION ブロックは、 Net.Data マクロの任意の場所でこの名前のまえにアットマーク (@) を付けて参照することで、実行されます。 FUNCTION ブロックの実行は関数呼出しです。詳細については、 『関数の呼出し』を参照してください。
同じ名前を持つ複数の FUNCTION ブロックが存在することができます。 それらのブロックはすべて、同じパラメーター・リストをもたなければなりません。 関数が呼び出されると、同じ名前を持つすべての FUNCTION ブロックは、 Net.Data マクロで定義されている順序で実行されます。
関数呼出しに指定された対応する引き数の値によって置き換えられる、 ローカル効力範囲を持つ変数の名前。 実行可能ステートメントまたは REPORT ブロック内のパラメーター参照、 たとえば、$(parm1) は、 パラメーターの実際の値によって置き換えられます。 さらにパラメーターは、言語環境に渡され、 その言語の通常の構文を使用するか、または環境変数として、 実行可能ステートメントにアクセス可能です。 パラメーター変数参照は、FUNCTION ブロックの外側では無効です。
また、ユーザーが指定した型の関数呼出しで暗黙パラメーターを渡すこともできます。 初期設定ファイルの ENVIRONMENT ステートメントにパラメーターを定義しなければなりません。
関数は、最外部の Net.Data マクロ層に、 それらが Net.Data マクロで呼び出されるまえに、定義してください。
Net.Data マクロからの関数の呼出しは、 アットマーク (@) のあとに FUNCTION ブロック名を付けたものを使用して行います。
@function_name([ argument,... ])
FUNCTION ブロックが呼び出されると、Net.Data は次のように進行します。
関数呼出しの FUNCTION ブロックからの変数の使用および変更の規則は、 次のように要約できます。
MESSAGE ブロックおよび REPORT ブロックの処理が行われるとき、 関数呼出しの値を使用して、Net.Data マクロの関数呼出しが置換されます。
ストアード・プロシージャーは単に、SQL 関数として呼び出されます。 ストアード・プロシージャーは、 コンパイル済み SQL ステートメントをデータベース・サーバーで保管することで、 さらに優れたパフォーマンスと保全性を提供することができます。
ほとんどのプラットフォームで、
ストアード・プロシージャーは次のデータ型を使用することができます。
| BLOB | DOUBLEPRECISION | SMALLINT |
| CHAR | FLOAT | TIME |
| CLOB | INTEGER | TIMESTAMP |
| DATE | GRAPHIC | VARCHAR |
| DBCLOB | LONGVARCHAR | VARGRAPHIC |
| DOUBLE | LONGVARGRAPHIC |
|
これらのデータ型についての詳細は、ご使用のデータベースの資料を参照してください。 ご使用のデータベースでサポートされるデータ型が、Net.Data でサポートされないこともあります。 詳細については、 Net.Data リファレンス・ガイド の付録を参照してください。
以下は、stored_proc1 という名前の関数として、 ストアード・プロシージャーを呼び出す例です。
%FUNCTION(DTW_SQL) stored_proc1 ( IN float(7,2) arg1,
INOUT SMALLINT arg2,
OUT VARCHAR(9) retval)
RETURNS (RESULT) {
CALL statsrpt
%}
%HTML(REPORT) {
@stored_proc1(arg1, arg2, retval)
.
.
.
%}
このストアード・プロシージャーの名前は statsrpt であり、 これは CALL ステートメントによって呼び出されます。 関数 stored_proc1 は、 ストアード・プロシージャーを呼び出す関数の名前です。
MESSAGE ブロックでは、 関数呼出しの成否にもとづいて関数呼出し後の進行方法を判別することができ、 また関数の呼出し側に情報を表示することができます。
Net.Data はそれぞれの関数呼出しごとに暗黙変数 RETURN_CODE を設定します。 RETURN_CODE は、その関数が呼び出す言語環境への呼出しの戻りコードに設定されます。 関数呼出しが完了すると、MESSAGE ブロックは RETURN_CODE の値を使用して、 進行方法を判別します。 MESSAGE ブロックは一連のメッセージ・ステートメントから構成され、 それぞれのステートメントで、戻りコード値、メッセージ・テキスト、 およびとるべきアクションが指定されます。 MESSAGE ブロックの構文は以下に示すとおりです。
>>-%message--{-------------------------------------------------------------->
+----------------------------------------------------------------------+
V |
>----+------------------------------------------------------------------+-+->
+-| return code spec |--:--| message text spec |--| action spec |--+
>-%}-----------------------------------------------------------------------><
return code spec
|--+-DEFAULT---------+-----------------------------------------|
+- +DEFAULT-------+
+- -DEFAULT-------+
+-+-----+-number--+
+- - -+
+- + -+
message text spec
+-----------------------+
V |
|---+-"----+--------------------++--"---+----------------------|
| +-string-------------+ |
| +-variable reference-+ |
| +-function call------+ |
| +-----------------------+ |
| V | |
+-{----+--------------------++--%}--+
+-string-------------+
+-variable reference-+
+-function call------+
action spec
|--:--+-EXIT-----+---------------------------------------------|
+-CONTINUE-+
MESSAGE ブロックは、グローバル効力範囲またはローカル効力範囲を持つことができます。 MESSAGE ブロックが FUNCTION ブロック内に定義された場合、 その効力範囲は、その FUNCTION にとってローカルです。 このブロックは、最外部のマクロ層に指定された場合には、グローバル効力範囲を持ち、 Net.Data マクロで実行されるすべての関数呼出しに対してアクティブです。 複数のグローバル MESSAGE ブロックを定義した場合は、 定義された最後のものがアクティブです。
Net.Data は次のような規則を使用して、関数呼出しからの RETURN_CODE を処理します。
以下に示すのは、 関数のグローバル MESSAGE ブロックと MESSAGE ブロックを持つ Net.Data マクロの部分の例です。
%{ global message block %}
%MESSAGE {
-100 : "Return code -100 message" : exit
100 : "Return code 100 message" : continue
+default : {
This is a long message that spans more
than one line. You can use HTML tags, including
anchors and forms, in this message. %} : continue
%}
%{ local message block inside a FUNCTION block %}
%FUNCTION(DTW_REXX) my_function() {
%EXEC { my_command.cmd %}
%MESSAGE {
-100 : "Return code -100 message" : exit
100 : "Return code 100 message" : continue
-default : {
This is a long message that spans more
than one line. You can use HTML tags, including
anchors and forms, in this message. %} : exit
%}
my_function() が、RETURN_CODE を 50 に設定して返すと、 Net.Data は次の順序でエラーを処理します。
Net.Data は、突合せを検出したら、メッセージ・テキストを Web ブラウザーに送信し、 要求されているアクションを検査します。 続行が指定されているので、 Net.Data はメッセージ・テキストの印刷後、Net.Data マクロの処理を続行します。
たとえばこの例で、マクロが my_functions() を 5 回呼び出し、 MESSAGE ブロックの処理中にエラー 100 を検出した場合、 プログラムからの出力は次のようになります。
. . . 11 May 1997 $245.45 13 May 1997 $623.23 19 May 1997 $ 83.02 return code 100 message 22 May 1997 $ 42.67 Total: $994.37
ローカル MESSAGE ブロックの別の例については、 付録 A. "動的照会のサンプル" を参照してください。
Net.Data では、アプリケーション・ユーザーのブラウザー上に、 簡単に標準 HTML を表示することができます。 以下のブロックは、Net.Data マクロで HTML をフォーマットする方法を示しています。
HTML ブロック、および HTML ブロックから起動される関数は、 ブラウザーに対する HTML 出力を生成する Net.Data マクロのブロックです。 Net.Data が起動されるときは常に、HTML ブロックを指定しなければなりません。 このブロックに含まれる内容によって、 Net.Data 起動の残り部分が制御されます。
HTML ブロック内に任意の有効な HTML を現わすことができます。さらに、 INCLUDE ステートメント、関数呼出し、および変数参照を、 HTML ブロックに入れることができます。 Net.Data マクロでの HTML ブロックの一般的な使用法は、 次のサンプル Net.Data マクロで示されているとおりです。
%DEFINE DATABASE="MNS96"
%HTML(INPUT){
<H1>Hardware Query Form</H1>
<HR>
<FORM METHOD="POST" ACTION="/cgi-bin/db2www/equiplst.mac/report">
<dl>
<dt>What hardware do you want to list?
<dd><input type="radio" name="hdware" value="MON" checked>Monitors
<dd><input type="radio" name="hdware" value="PNT">Pointing devices
<dd><input type="radio" name="hdware" value="PRT">Printers
<dd><input type="radio" name="hdware" value="SCN">Scanners
</dl>
<HR>
<input type="submit" value="Submit">
</FORM>
%}
%FUNCTION(DTW_SQL) myQuery() {
SELECT MODNO, COST, DESCRIP FROM EQPTABLE WHERE TYPE=$(hdware)
%REPORT{
<B>Here is the list you requested:</B><BR>
%ROW{
<HR>
$(N1): $(V1) $(N2): $(V2)
<P>
$(V3)
%}
%}
%}
%HTML(REPORT){
@myQuery()
%}
次のようなアンカー参照から Net.Data マクロを起動することができます。
<a href="http://www.ibm.com/cgi-bin/db2www/equiplst.mac/input">List of hardware</a>
アプリケーション・ユーザーがこの参照をクリックすると、 Net.Data が起動され、Net.Data は Net.Data マクロ・ファイルを解析します。 起動で指定された HTML ブロック、この場合は、HTML(INPUT) ブロックに到達すると、 そのブロック内のテキストの処理を開始します。 Net.Data によって Net.Data マクロ言語構成として認識されないものは、 すべて HTML と見なされ、表示されるブラウザーに送信されます。
選択 が行われ、Submit ボタンが押されたあと、 HTML FORM エレメントの ACTION パーツが実行されます。このパーツには、 Net.Data マクロの HTML(REPORT) ブロックへの呼出しが指定されます。次に、 HTML(REPORT) ブロックが、HTML(INPUT) ブロックと全く同様に処理されます。 queryHardware() 関数呼出しまでのすべてのデータが、 HTML としてブラウザーに出力されます。
次に queryHardware() 関数呼出しが処理され、 それによって SQL FUNCTION ブロックが起動されます。SQL ステートメントで、 $(hdware) 変数参照が入力フォームに返された値によって置換されたあと、 照会が実行されます。 この時点に、Net.Data は再度、ブラウザーへの HTML の送信を開始し、 REPORT ブロックに指定された HTML に従って照会の結果を表示します。
REPORT ブロック処理の完了後、もう一度 HTML(REPORT) ブロックに戻り、 queryHardware() 関数呼出しのあとに指定されている残りの HTML を送信して、 処理を完了します。
それぞれの Net.Data 起動ごとに 1 つの HTML ブロックだけが処理されます。 ただし、HTML アンカー参照およびフォームを使用すれば、 アプリケーションの使用者による別の HTML ブロックでの Net.Data の別の起動の開始を、 ユーザーがすべて制御して容易に行わせることができます。
REPORT ブロックは、FUNCTION ブロックからのデータ出力をフォーマットおよび表示するために使用します。 この出力は一般にはテーブル・データですが、 HTML タグ、マクロ変数参照、および関数呼出しの任意の有効な組合せを指定することができます。 REPORT ブロックにテーブル名を指定することはできますが、必須ではありません。 テーブル名を指定しない場合、使用されるテーブル・データは、 この FUNCTION ブロックのパラメーター・リストの最初の出力テーブルのデータになります。 FUNCTION ブロックでテーブルが指定されなかった場合、 デフォルトのテーブル・データが使用されます。
REPORT ブロックは、3 つのパーツから構成され、いずれも任意選択です。
ROW ブロックからの出力を表示したくない場合は、空のままにしてください。
Net.Data が FUNCTION ブロックを処理すると、言語環境への呼出しが行われ、 データが返されます。そのあと、Net.Data は REPORT ブロックを処理します。
REPORT ブロックの内部に、Net.Data は、 ユーザーが Net.Data マクロ結果テーブルのデータにアクセスできるように、 いくつかの暗黙定義変数を提供しています。これらの変数については、 表 1 に説明されています。さらに詳しくは、 『リファレンス・ガイド』の「レポート変数」セクションを参照してください。
ヘッダー情報およびフッター情報は、REPORT ブロックで明示的に指定しません。 Net.Data は単に、ROW ブロックのまえに検出したものすべてをヘッダー情報として処理し、 ROW ブロックのあとに検出したものすべてをフッター情報として処理します。 HTML ブロックと同様、Net.Data マクロ処理プログラムは、ヘッダー・ブロック、 ROW ブロック、およびフッター・ブロック内にあるものすべてを HTML として処理し、 そのデータをブラウザーに送信します。 また、関数および変数を組み込むこともできます。
レポートを回避するには、REPORT ブロックを省略し、 DTW_DEFAULT_REPORT を NO に設定します。これを YES に設定すると、 デフォルトのフォーマットのレポートが表示されます。たとえば、次のとおりです。
SHIPDATE | RECDATE | SHIPNO | ------------------------------------- 25/05/1997 | 30/05/1997 | 1495194B | ------------------------------------- 25/05/1997 | 28/05/1997 | 2942821G | -------------------------------------
デフォルト・レポートの事前フォーマットされたテキストの代わりに HTML タグを使用するには、 DTW_HTML_TABLE を YES に設定してください。
次の例は、特殊な変数と HTML タグを使用して、 レポートのフォーマットをどのようにカスタマイズできるかを示しています。 この例は、テーブル table CustomerTbl から名前、電話番号、およびファックス番号を表示します。
%FUNCTION(DTW_SQL) custlist() {
SELECT Name, Phone, Fax FROM CustomerTbl
%REPORT{
<I>Phone Lookup Results:</I>
<BR>
=====================
%ROW{
Name: <B>$(V1)</B>
Phone: $(V2)
Fax: $(V3)
------------------------------
%}
Total records retrieved: $(ROW_NUM)
%}
%}
この結果得られるレポートは、Web ブラウザーで次のように表示されます。
Phone Query Results: ==================== Name: Doen, David Phone: 422-245-1293 Fax: 422-245-7383 ------------------------------ Name: Ramirez, Paolo Phone: 955-768-3489 Fax: 955-768-3974 ------------------------------ Name: Wu, Jianli Phone: 525-472-1234 Fax: 525-472-1234 ------------------------------ Total records retrieved: 3
Net.Data は次のようにしてレポートを生成しました。
DB2 は、数多くのプラットフォームでラージ・オブジェクト (LOB) をサポートします。 LOB がサポートされるかどうか、DB2 の資料を参照して調べてください。 DB2 でサポートされる LOB は次の 3 つのタイプです。
照会から LOB が返されると、Net.Data はそれを、 HTML_PATH 構成変数に指定されているディレクトリーに保管します。 LOB を使用するときは、LOB はたちまち資源を消費する可能性があるので、 システムの制限を考慮に入れてください。 オーディオ・ファイルなど、一部の LOB には、 特殊なハードウェアおよびソフトウェアを必要とするものがあります。
LOB は一般に、最初の数バイトに、 ファイルにどのタイプの情報が含まれるかを示すファイル・シグニチャーを含んでいます。 LOB が Net.Data によって認識されると、一時ファイルと、 その名前を表す Net.Data マクロ変数に拡張子が追加されます。 REPORT ブロックがない場合、CLOB には、拡張子 .txt が追加されます。 認識される LOB フォーマットは以下のとおりです。
その他のファイル・タイプは認識されず、サポートされません。 UPDATE SQL ステートメントと INSERT SQL ステートメントは、 どのラージ・オブジェクトにもサポートされません。下記の例のうち最初の例は、 ピクチャーをインライン表示します。2 番目の例では、 アプリケーション・ユーザーは、 ビューアーを起動するためにファイル名をクリックしなければなりません。
<IMG SRC="/tmplobs/filename"> <A HREF="/tmplobs/filename">filename</A>
以下に示すのは、アプリケーションでの .WAV ファイルの使用例です。 このファイル・タイプは Net.Data によって認識されないので、 EXEC 変数を使用してファイルに拡張子を付加します。
%DEFINE{
docroot="/usr/lpp/internet/server_root/html"
rename=%EXEC "rename $(docroot)$(V3) $(docroot)$(V3).wav"
%}
%FUNCTION(DTW_SQL) queryData() {
SELECT Name, IDPhoto, Voice FROM RepProfile
%REPORT{
<P>Here are the images you selected:<P>
%ROW{
$(rename)
$(V1) Voice sample <IMG SRC="$(V2)">
<A HREF="$(V3.wav")>Voice sample</A><P>
%}
%}
%}
%HTML(REPORT){
@queryData()
%}
queryData 関数は、次の HTML を返します。
<P>Here are the images you selected:<P> Kinson Yamamoto <IMG SRC="/tmplobs/p2345n1.gif"> <A HREF="/tmplobs/p2345n2.wav">Voice sample</A><P> Merilee Lau <IMG SRC="/tmplobs/p2345n3.gif"> <A HREF="/tmplobs/p2345n4.wav">Voice sample</A><P>
この REPORT ブロックは、暗黙テーブル変数 V1、V2、および V3 を使用します。
Web ブラウザーのすべてがグラフィックとサウンドをサポートするわけではありません。 ここで説明したフィーチャーをサポートするには、サウンド・カードやドライバーなど、 特別なハードウェアおよびソフトウェアが必要なこともあります。