In diesem Abschnitt werden die unterschiedlichen Teile beschrieben, aus denen eine Net.Data-Makrodatei aufgebaut ist, sowie die Art und Weise, wie diese in einer Anwendung zusammenwirken.
Im folgenden Abschnitt werden anhand eines einfachen Net.Data-Makros die Elemente der Makrosprache verdeutlicht. Dieses Beispielmakro zeigt ein Formular, das Informationen anfordert, die an ein REXX-Programm übergeben werden. Das Makro leitet diese Informationen an ein externes REXX-Programm (OMPSAMP.CMD) weiter, das die vom Benutzer eingegebenen Daten zurückmeldet. Die Ergebnisse werden im Anschluß daran auf einer zweiten HTML-Seite angezeigt.
Sehen Sie sich zunächst das gesamte Makro an. Im folgenden wird dann auf jeden Block näher eingegangen.
%{ ********************** 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>
%}
Das Makro besteht aus vier Hauptblöcken: DEFINE, FUNCTION sowie den beiden HTML-Blöcken. Ein Net.Data-Makro kann auch mehrere DEFINE-, FUNCTION- und HTML-Blöcke aufweisen.
Die beiden HTML-Blöcke enthalten bekannte HTML-Befehle, wodurch das Schreiben von Web-Makros erheblich vereinfacht wird. Wenn Ihnen der Umgang mit HTML vertraut ist, müssen Sie zum Erstellen eines Makros lediglich Makroanweisungen hinzufügen, die auf dem Server dynamisch verarbeitet werden sowie SQL-Anweisungen, die an die Datenbank gesendet werden.
Obwohl das Makro einem HTML-Dokument ähnelt, greift der Web-Server über Net.Data als CGI-Programm oder Web-Server-API darauf zu. Net.Data erfordert zwei Parameter: den Namen des zu verarbeitenden Makros und den anzuzeigenden HTML-Block in diesem Makro.
Wenn die Makrodatei aufgerufen wird, beginnt Net.Data mit der Verarbeitung am Anfang der Datei. In den nächsten Abschnitten wird die Verarbeitung der einzelnen Blöcke beschrieben.
%{ ********************** Define Block ************************%}
%DEFINE {
page_title="Net.Data macro Template"
%}
Die erste Zeile ist ein Kommentar. Ein Kommentar ist jeder Text innerhalb von %{ und %}. Kommentare müssen außerhalb von anderen Makroblöcken angegeben sein. Die nächste Anweisung beginnt einen DEFINE-Block. Sie können mehrere Variablen in einem DEFINE-Block definieren. Im vorliegenden Beispiel wird lediglich eine Variable, page_title, definiert. Nach der Definition kann von jeder Stelle innerhalb des Makros mit folgender Syntax auf diese Variable verwiesen werden: $(page_title). Mit Hilfe der Variablen können Sie zu einem späteren Zeitpunkt mühelos globale Änderungen an Ihrem Makro vornehmen. Die letzte Zeile dieses Blocks, %}, kennzeichnet das Ende des DEFINE-Blocks.
Bei dem nächsten Block handelt es sich um den Funktionsdefinitionsblock. Beachten Sie jedoch zunächst den HTML-Block INPUT im Beispiel.
%{ ********************** HTML Block: Input ************************%}
%HTML (INPUT) { <--- Gibt den Namen dieses HTML-Blocks an.
<html>
<head>
<title>$(page_title)</title> <--- Beachten Sie die Variablensubstitution.
</head><body>
<h1>Input Form</h1>
Today is @today() <--- Diese Zeile enthält den Aufruf einer Funktion.
<FORM METHOD="post" ACTION="output"> <--- Bei Übergabe dieses Formulars
wird der HTML-Block "Output" aufgerufen.
Type some data to pass to a REXX program:
<INPUT NAME="input_data" <--- "input_data" wird bei Übergabe des Formulars
TYPE="text" SIZE="30"> definiert; auf diese Variabel kann von anderer
Stelle des Makros verweisen werden. Die Initialisierung
erfolgt gemäß den Eingaben des Benutzers im Eingabefeld.
<p>
<INPUT TYPE="submit" VALUE="Enter">
<hr>
<p>
[
<a href="/">Home page</a>]
</body><html>
%} <--- Beendet den HTML-Block.
Dieser Block enthält das HTML für ein einfaches Formular mit einem Eingabefeld. Der gesamte HTML-Block befindet sich innerhalb der HTML-Blockkennungen %HTML (INPUT) { ... %}. INPUT gibt den Namen dieses Blocks an. Sie können hierfür einen beliebigen Namen vergeben. Das HTML-Kennzeichen <title> enthält ein Beispiel für die Makrosubstitution. Der Inhalt der Variablen page_title wird durch den Titel des Formulars ersetzt.
Des weiteren enthält dieser Block ein Beispiel für einen Funktionsaufruf. Der Ausdruck @today() ruft die Funktion today auf. Diese Funktion wird im Block FUNCTION definiert, auf den im folgenden noch näher eingegangen wird. Das Ergebnis der Funktion today, das aktuelle Datum, wird in den HTML-Text an derselben Position eingefügt, an der sich der Ausdruck @today() befindet.
Der Parameter ACTION der Anweisung FORM ist ein Beispiel für die Navigation zwischen HTML-Blöcken bzw. zwischen Makros. Durch den Verweis auf den Namen eines anderen Blocks in einem Parameter ACTION wird bei der Übergabe des Formulars auf diesen Block zugegriffen. Alle Eingabedaten werden als implizite Variablen an den neuen Block übergeben. Dies gilt für das einzelne Eingabefeld, das in diesem Formular definiert ist. Bei der Übergabe des Formulars werden die Daten, die in diesem Feld eingegeben wurden, an den HTML-Block "Output" in der Variablen input_data übergeben.
Sie können über einen relativen Verweis auf HTML-Blöcke in anderen Makrodateien zugreifen, wenn sich diese Makrodateien auf demselben Web-Server befinden. So greift ACTION="../othermacro.mac/main" beispielsweise auf den HTML-Block mit dem Namen main in der Macrodatei othermacro.mac zu. Auch hier werden Daten, die im Formular eingegeben wurden, in der Variablen input_data an dieses Makro übergeben.
Beim Aufrufen von Net.Data wird die Variable als Teil der URL weitergegeben. Beispiel:
<a href="/cgi-bin/db2www/othermacro.mac/main?input_data=value">Next macro</a>
Es besteht keine Notwendigkeit, Umgebungsvariablen zum Empfangen von Eingabedaten (wie es bei den meisten CGI-Programmen der Fall ist) zu verwenden. Net.Data nimmt Ihnen diese Aufgabe ab. Sie müssen lediglich auf die Variablennamen verweisen.
Der nächste HTML-Block im Beispiel ist der OUTPUT-Block.
%{ ********************** HTML Block: Output ************************%}
%HTML (OUTPUT) {
<html>
<head>
<title>$(page_title)</title> <--- Weitere Substitutionen
</head><body>
<h1>Output Page</h1>
<p>@rexx1(input_data) <--- Diese Zeile enthält einen Aufruf der Funktion rexx1,
die das Argument "input_data" übergibt.
<p>
<hr>
<p>
[
<a href="/">Home page</a> |
<a href="input">Previous page</a>]
%}
Wie der INPUT-Block besteht dieser Block ebenfalls aus Standard-HTML mit Makroanweisungen zur Variablensubstitution. Auch hier wird die Variable page_title durch die Titelanweisung ersetzt. Außerdem enthält dieser Block ebenfalls einen Funktionsaufruf. In diesem Fall wird die Funktion rexx1 aufgerufen und der Inhalt der vom INPUT-Formular empfangenen Variablen input_data an diese Funktion weitergegeben. Sie können Variablen in beliebiger Zahl an eine Funktion bzw. von einer Funktion übergeben. Die Funktionsdefinition bestimmt die Anzahl der übergebenen Variablen sowie deren Art.
Weitere Informationen dazu finden Sie im Abschnitt "Funktionsdefinitionsblock".
%{ ********************** Function Definition Block ************************%}
%FUNCTION(DTW_REXX) rexx1 (IN input) returns(result) { <-- Diese Funktion
akzeptiert einen Parameter
und gibt ein Ergebnis zurück,
das den zugeordneten
Funktionsaufruf ersetzt.
%EXEC{ompsamp.cmd %} <-- Diese Funktion führt das externe REXX-Programm
"ompsamp.cmd" aus.
%}
%FUNCTION(DTW_REXX) today () RETURNS(result) {
result = date() <-- die einzelne Quellenanweisung für
diese Funktion ist inline.
%}
Dieser Funktionsdefinitionsblock umfaßt zwei Funktionsdeklarationen. Die erste Deklaration rexx1 ist eine REXX-Funktionsdeklaration, die wiederum ein externes REXX-Programm namens ompsamp.cmd ausführt. Eine Eingabevariable input wird von dieser Funktion akzeptiert und automatisch an den externen REXX-Befehl übergeben. Der REXX-Befehl gibt ebenfalls eine Variable zurück, result. Der Inhalt der Variablen result im REXX-Befehl ersetzt den aufrufenden Funktionsaufruf @rexx1(), der im OUTPUT-Block enthalten ist. Auf die Variablen input und result kann direkt vom REXX-Programm aus zugegriffen werden, wie in der Quelle für ompsamp.cmd gezeigt wird:
/* REXX */ result = 'The REXX program received "'input'" from the macro.'
Der Code in dieser Funktion gibt die übergebenen Daten wieder. Sie können den Ergebnistext nach Belieben formatieren, indem Sie den anfordernden Funktionsaufruf @rexx1() zwischen normale HTML-Befehle (wie z. B. <b> oder <em>) setzen. Anstatt die Variable result zu verwenden, könnte das REXX-Programm auch HTML-Befehle unter Verwendung der REXX-Anweisungen SAY in die Standardausgabe schreiben.
Die zweite Funktionsdeklaration today verweist ebenfalls auf ein REXX-Programm. In diesem Fall befindet sich das gesamte REXX-Programm (eine ganze Zeile) selbst innerhalb der Funktionsdeklaration. Ein externes Programm ist nicht erforderlich. Inline-Programme sind für REXX- und PERL-Funktionen zulässig, da sie als Sprachen interpretiert werden, die syntaktisch analysiert und dynamisch ausgeführt werden können. Inline-Programme bieten den Vorteil der Einfachheit, da sie keine separat zu verwaltende Programmdatei erfordern. Die erste REXX-Funktion könnte auch inline bearbeitet werden.
Mit Net.Data können Sie Variablen in einem Net.Data-Makro definieren und auf diese Variablen verweisen. Darüber hinaus können Sie diese Variablen ausgehend vom Makro an die Sprachumgebungen übergeben und umgekehrt. Net.Data-Token wie Variablennamen und Zeichenfolgen in Anführungszeichen können Daten von bis zu 64 KB enthalten. Bei OS/400 ist die maximale Größe durch das System festgelegt.
Es gibt drei Arten von Makrovariablen:
Eine Kennung, die aus einer Variablen oder einem Funktionsaufruf besteht, wird sichtbar (das heißt, daß auf sie verwiesen werden kann), sobald sie deklariert oder verwirklicht wird. Eine Kennung ist in einem bestimmten Bereich sichtbar. Es gibt vier Bereichsarten:
Eine Kennung weist einen globalen Bereich auf, wenn auf sie von jeder Stelle in der Makrodatei aus verwiesen werden kann. Kennungen mit globalem Bereich sind:
Eine Kennung weist diesen Bereich auf, wenn ihre Deklaration außerhalb eines Blocks liegt. Ein Block beginnt mit "{" und endet mit "%}". (Beachten Sie hierbei, daß DEFINE-Blöcke von dieser Definition ausgeschlossen sind und als separate DEFINE-Anweisungen behandelt werden sollten.) Eine Kennung mit Makrodateibereich ist von der Stelle, an der sie deklariert ist, bis zum Ende der Makrodatei sichtbar.
Eine Kennung weist diesen Bereich auf, wenn sich ihre Deklaration oder Verwirklichung innerhalb eines FUNCTION-Blocks befindet (wie beispielsweise eine Variable OUT). (Dies gilt auch für Variablen, auf die innerhalb von REPORT- oder ROW-Blöcken von Funktionen verwiesen wird, die jedoch innerhalb der Makrodatei nicht explizit bzw. nicht implizit durch Net.Data definiert worden sind.)
Eine Kennung weist diesen Bereich auf, wenn auf sie nur von einem REPORT-Block aus verwiesen werden kann (zum Beispiel Tabellenspaltennamen N1, N2, ..., Nn). Nur solche Variablen, die Net.Data implizit als Teil der Tabellenverarbeitung definiert, können den REPORT-Blockbereich aufweisen. Alle anderen verwirklichten Variablen weisen den FUNCTION-Blockbereich auf.
Wird auf eine Kennung verwiesen, so wird diese Kennung durch den Wert der Kennung ersetzt. Wenn beim Verweis auf eine Variable dieser kein Wert zugeordnet ist, oder ein Funktionsaufruf keinen Rückgabewert aufweist, wird der Verweis durch eine leere Zeichenfolge ersetzt.
Die folgenden Abschnitte beschreiben, wie Variablen definiert und auf sie verwiesen wird. Außerdem werden die unterschiedlichen Variablenarten und ihre Verwendung beschrieben.
Es gibt drei Möglichkeiten, Variablen in einem Net.Data-Makro zu definieren
Die einfachste Möglichkeit, eine Variable zur Verwendung in einem Net.Data-Makro zu definieren, ist der Einsatz der Anweisung DEFINE. Folgende Syntax wird für Net.Data angegeben:
%DEFINE varname="variablenwert"
%DEFINE varname={ Variablenwert über mehrere
Textzeilen %}
varname ist der Name, den Sie der Variablen geben. Variablen müssen mit einem Buchstaben oder Unterstreichungszeichen beginnen und können jedes beliebige alphanumerische Zeichen oder ein Unterstreichungszeichen enthalten. Bei allen Variablennamen muß auf Groß-/Kleinschreibung geachtet werden, mit Ausnahme von N_spaltenname und V_spaltenname, bei denen es sich um Tabellenvariablen handelt.
Sollen Anführungszeichen in einer Zeichenfolge verwendet werden, setzen Sie jeweils zwei Anführungszeichen. Zwei aufeinanderfolgende Anführungszeichen entsprechen einer leeren Zeichenfolge.
%DEFINE HI="say ""hello""" %DEFINE reply="hello" %DEFINE empty=""
In der Anzeige lautet die Variable HI dann say "hello", die Variable reply lautet hello und die Variable empty zeigt eine Null.
Verwenden Sie einen Block DEFINE, wenn Sie mehrere Variablen mit einer Anweisung DEFINE definieren wollen:
%DEFINE{
variable1="wert1"
variable2="wert2"
variable3="wert3"
variable4="wert4"
%}
Dieses Beispiel zeigt die Standard-HTML-Formularbefehle zum Definieren einer Variablen:
<INPUT NAME="varname" TYPE=...>oder
<SELECT NAME="varname">
Hierbei ist varname der Name, den Sie der Variablen zuordnen. Der Wert der Variablen wird in der im Formular empfangenen Eingabe bestimmt. Im Abschnitt "HTML-Formulare" finden Sie ein Beispiel dafür, wie diese Art der Variablendefinition in einem Net.Data-Makro verwendet wird.
Ein Variablenwert, der von einer Anweisung INPUT oder SELECT empfangen wird, überschreibt einen mit DEFINE in einem Net.Data-Makro definierten Variablenwert.
Sie können Net.Data-Makros als URLs aufrufen und in dem URL Variablen wie beispielsweise eine Benutzer-ID aufnehmen, die an Net.Data gesendet werden sollen. Beispiel:
http://www.ibm.com/cgi-bin/db2www/stdqry1.mac/input?field=custno
Net.Data empfängt und verarbeitet die zusätzlichen Daten, in diesem Fall field=custno auf dieselbe Weise wie Formulardaten.
In Net.Data-Makros wird auf Variablen verwiesen, indem der Variablenname zwischen $( und ) angegeben wird (außer bei Bedingungen eines Blocks IF; in diesem Fall wird nur der Variablenname verwendet). Beispiel:
$(varname) $(homeURL)
Wenn Net.Data einen Verweis auf eine Variable findet, wird dieser Verweis durch den entsprechenden Wert ersetzt. Rückbezügliche Verweise (oder Zyklen) sind nicht zulässig. Die im folgenden gezeigten Anweisungen DEFINE sind beispielsweise nicht zulässig und verursachen einen Fehler, wenn auf die Variable verwiesen wird und die Endwerte ausgewertet werden:
%DEFINE a="$(b)" %DEFINE b="$(a)"
Sie können die Variablen als Teil Ihrer HTML verwenden. Zum Beispiel wenn Sie die Variable homeURL folgendermaßen definiert haben:
%DEFINE homeURL="http://www.ibm.com/"Sie können auf die Home Page als $(homeURL) verweisen und wie folgt einen Ankerverweis erstellen:
<A href="$(homeURL)">Home page</A>
Auf Variablen kann in jedem Teil eines Net.Data-Makros verwiesen werden. Beim Verweis auf eine Variable, die noch nicht definiert wurde, definiert Net.Data diese Variable und ordnet ihr den Anfangswert null zu. Wenn bei der Syntaxanalyse des Net.Data-Makros ein Verweis auf eine Variable gefunden wird, wird dieser ausgewertet und inline durch den aktuellen Wert der Variablen ersetzt.
Über Bedingungsvariablen wird festgestellt, ob eine Variable existiert und nicht leer ist. Existiert die Variable, erhält sie den ersten Wert. Die Syntax für eine Bedingungsvariable ist wie folgt:
varA = varB ? "wert_1" : "wert_2"
Wenn varB definiert ist, gilt varA="wert_1", andernfalls gilt varA="wert_2". Dies entspricht dem folgenden Beispiel, in dem ein Block IF verwendet wird:
%IF ( varB )
varA = "wert_1"
%ELSE
varA = "wert_2"
%ENDIF
Ein Beispiel für die Verwendung von Bedingungsvariablen mit Listenvariablen finden Sie im Abschnitt Listenvariablen.
Sie können auf Net.Data-Umgebungsvariablen verweisen, die in dem Prozeß existieren, in dem Net.Data ausgeführt wird; zum Beispiel:
The client is @DTW_rGETENV("SERVER_NAME")
Die Ausgabe sieht wie folgt aus:
The HTTPD server is IBM Internet Connection Server/4.1
Weitere Informationen zu den Funktionen @DTW_GETENV und @DTW_rGETENV finden Sie im Handbuch Net.Data Reference Guide.
Sie können andere Programme über einen Verweis auf eine Ausführungsvariable aufrufen. Eine Ausführungsvariable wird in einem Net.Data-Makro wie folgt definiert:
%DEFINE runit=%exec "testProg"Net.Data sucht unter EXEC_PATH in der Net.Data-Initialisierungsdatei nach dem ausführbaren Programm. Nähere Informationen hierzu finden Sie unter "EXEC_PATH".
Das Programm testProg wird ausgeführt, wenn ein Net.Data-Makro einen gültigen Verweis auf die Variable runit enthält. So kann z. B. auf einfache Weise über eine andere Variablendefinition auf eine Ausführungsvariable verwiesen werden:
%DEFINE date=%exec "date" %DEFINE dateRpt="Today is $(date)"
Jedesmal, wenn $(dateRpt) im Net.Data-Makro erscheint, gibt Net.Data folgenden Wert aus:
Today is Tue 11-07-1995
Eine Ausführungsvariable erhält nie den Wert der Ausgabe des ausführbaren Programms, das sie aufruft. Im vorherigen Beispiel ist der Wert des Datums null. Wenn Sie sie in einem Funktionsaufruf DTW_ASSIGN verwenden, um den Wert einer anderen Variablen zuzuordnen, ist der Wert der neuen Variablen nach der Zuordnung ebenfalls null. Der Zweck einer Ausführungsvariablen besteht darin, das Programm aufzurufen, das sie definiert. Außerdem können Sie Parameter an das auszuführende Programm übergeben, indem Sie sie bei der Variablendefinition mit dem Programmnamen angeben. Im folgenden Beispiel werden die Werte für distance und time an das Programm calcMPH übergeben.
%DEFINE mph=%exec "calcMPH $(distance) $(time)"
Im nächsten Beispiel wird das Systemdatum als Teil des HTML-Berichts zurückgegeben:
%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()
%}
Jeder Bericht zeigt zur besseren Übersicht das Datum an. In dem Beispiel werden auch die Kundennummer und der Kundenname in Ankerverweise für ein anderes Net.Data-Makro gestellt. Durch Anklicken eines Kunden in dem Bericht wird das Net.Data-Makro exmp.mac aufgerufen, und die Nummer und der Name werden an das Net.Data-Makro übergeben.
Verdeckte Variablen können als zusätzliche Sicherheitsmaßnahme verwendet werden, damit ein Kunde, der sich Ihre HTML-Quelle mit seinem Web-Browser anzeigen läßt, den tatsächlichen Namen der Variablen nicht erkennen kann.
%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
%}
Wenn das HTML-Formular im Web-Browser des Kunden angezeigt wird, werden $$(name) und $$(addr) durch $(name) bzw. $(addr) ersetzt, so daß die tatsächlichen Tabellen- und Spaltennamen nie auf dem HTML-Formular angezeigt werden. Infolgedessen ist dem Kunden nicht bekannt, daß die wahren Variablennamen verdeckt sind. Wenn der Kunde das Formular übergibt, wird der Block HTML(REPORT) aufgerufen. Wenn @mySelect() den Block FUNCTION aufruft, wird $(Field) in der SQL-Anweisung durch customer.name bzw. customer.addr in der SQL-Abfrage ersetzt.
Mit Listenvariablen können Sie eine begrenzte Zeichenfolge von Werten erstellen. Diese Variablenart ist besonders hilfreich beim Erstellen einer SQL-Abfrage mit mehreren Elementen, die in einigen Klauseln WHERE oder HAVING auftreten. Die Syntax für eine Listenvariable ist wie folgt:
%LIST " wertetrennzeichen " variablenname
Leerzeichen sind signifikante Zeichen. In den meisten Fällen empfiehlt es sich, vor und nach dem Wertetrennzeichen ein Leerzeichen einzufügen. Einige Abfragen verwenden boolesche oder mathematische Operatoren (z. B. AND, OR oder >) für das Wertetrennzeichen. Das folgende Zeichen zeigt die Verwendung von Bedingungsvariablen, verdeckten Variablen und Listenvariablen:
%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()
%}
Wenn keine Felder markiert werden, ist conditions null, so daß whereClause in der Abfrage auch null ist. Andernfalls enthält whereClause die ausgewählten Werte, getrennt durch OR. Wenn beispielsweise alle drei Städte ausgewählt werden, lautet die SQL-Abfrage:
SELECT name, city FROM citylist WHERE cond1='Sao Paolo' OR cond2='Seattle' OR cond3='Shanghai'Wenn wie im folgenden Seattle ausgewählt ist, lautet die SQL-Abfrage:
SELECT name, city FROM citylist WHERE cond1='Seattle'
Die Tabellenvariable definiert eine Sammlung zusammengehöriger Daten. Sie enthält eine Feldgruppe identischer Datensätze oder Zeilen sowie eine Feldgruppe von Spaltennamen, die die Felder in jeder Zeile beschreiben. Eine Tabelle wird in einem Net.Data-Makro mit einer Anweisung wie der folgenden definiert:
%DEFINE myTable=%TABLE(30)
Die Zahl hinter TABLE gibt die maximale Anzahl der Zeilen an, die diese Tabelle enthalten kann. Wenn Sie eine Tabelle ohne Zeilenbegrenzung angeben wollen, müssen Sie den Standardwert bzw. ALL angeben:
%DEFINE myTable2=%TABLE %DEFINE myTable3=%TABLE(ALL)
Sie können eine Tabelle zwischen Funktionen übergeben, indem Sie auf den Namen der Tabellenvariablen verweisen. Auf die einzelnen Elemente einer Tabelle kann in einem Block REPORT bzw. einer Funktion verwiesen werden. Tabellenvariablen werden normalerweise für die Ausgabe einer SQL-Funktion und für die Eingabe eines Berichts verwendet. Sie können sie jedoch auch als Parameter IN, OUT oder INOUT an eine Nicht-SQL-Funktion übergeben. Tabellen können nur als Parameter OUT an SQL-Funktionen übergeben werden.
Die Spaltennamen und Feldwerte in einer Tabelle werden als Feldgruppenelemente mit einem Ursprung von 1 adressiert. Dies entspricht nicht der Standardkonvention der Sprachen C und C++, bei denen Feldgruppen mit 0 beginnen.
Das Definieren einer Tabellenvariablen bewirkt, daß Net.Data implizit
zwei Gruppen von Variablen definiert, die Sie verwenden können, um auf
Spaltennamen und Feldinhalte der Tabelle zu verweisen. Auf eine Gruppe dieser
impliziten Variablen wird in einem Net.Data-Makro im Block REPORT eines Blocks
FUNCTION verwiesen. In Programmen, die von den Sprachumgebungen aufgerufen
werden, wird auf die andere Variablengruppe verwiesen. Es ist nicht möglich,
in einem anderen Block des Net.Data-Makros auf diese Variablen zu verweisen.
| N1, N2, ..., Nj | Der Name der jten Spalte. |
| N_spaltenname | Der Wert ist der von spaltenname. |
| NLIST | Eine Verknüpfung aller Spaltennamen von N1 bis Nj. |
| V1, V2, ..., Vj | Enthält den Wert der jten Spalte in der aktuellen Zeile. |
| V_spaltenname | Enthält den Wert der jten Spalte in der aktuellen Zeile. |
| VLIST | Eine Verknüpfung aller Feldwerte für V1 bis Vj in der aktuellen Zeile. |
| ROW_NUM | Enthält die Zeilennummer der aktuellen Zeile. |
| NUM_COLUMNS | Enthält die Anzahl der Spalten in der Tabelle. |
| TOTAL_ROWS | Enthält die Anzahl der Zeilen in der Tabelle. |
Net.Data stellt eine Vielzahl nützlicher Funktionen für Ihre Web-Anwendungen zur Verfügung. Außerdem können Sie hiermit problemlos auch eigene Funktionen schreiben.
Sie können eigene Funktionen definieren oder die Funktionen aus der Net.Data-Bibliothek verwenden. Verwenden Sie für Funktionen, die nicht in der Net.Data-Bibliothek enthalten sind, einen Block FUNCTION, um die Funktion für das Net.Data-Makro zu definieren. Nähere Informationen finden Sie im Handbuch Net.Data Language Environment Guide. Die Syntax sieht wie folgt aus:
%FUNCTION(art) funktionsname([verwendung parameter, ...]) [RETURNS(rückkehrvar)] {
ausführbare_anweisungen
[berichtsblock]
[nachrichtenblock]
%}
Identifiziert eine Sprachumgebung, die in der Initialisierungsdatei konfiguriert wird. Die Sprachumgebung ruft einen speziellen Sprachprozessor auf (der die ausführbaren Anweisungen verarbeitet) und stellt eine Standardschnittstelle zwischen Net.Data und dem Sprachprozessor bereit.
Mit Net.Data werden verschiedene Standardsprachumgebungen bereitgestellt.
Dies ist der Name des Blocks FUNCTION. Der Block FUNCTION wird dadurch ausgeführt, daß an anderer Stelle im Net.Data-Makro auf diesen Namen verwiesen und dabei ein kommerzielles A (@) vorangestellt wird. Das Ausführen eines Blocks FUNCTION ist ein Funktionsaufruf. Weitere Informationen dazu finden Sie unter ""Aufrufen von Funktionen"".
Mehrere Blöcke FUNCTION können denselben Namen aufweisen. In diesem Fall müssen ihre Parameterlisten identisch sein. Wenn die Funktion aufgerufen wird, werden alle namensgleichen Blöcke FUNCTION in der Reihenfolge ausgeführt, in der sie im Net.Data-Makro definiert sind.
Der Name einer Variablen mit lokalem Bereich, der durch den Wert eines entsprechenden Arguments, angegeben in einem Funktionsaufruf, ersetzt wird. Parameterverweise, z. B. $(parm1), in den ausführbaren Anweisungen oder Berichtsblöcken werden durch den Wert des Parameters ersetzt. Zudem werden die Parameter an die Sprachumgebung übergeben. Ausführbare Anweisungen, die die natürliche Syntax dieser Sprache verwenden, können darauf zugreifen oder sie als Umgebungsvariablen verwenden. Verweise auf Parametervariablen sind außerhalb des Blocks FUNCTION nicht zulässig.
Sie können auch implizite Parameter an einen Funktionsaufruf der von Ihnen angegebenen Art übergeben. Sie müssen dazu die Parameter in der Anweisung ENVIRONMENT in der Initialisierungsdatei definieren.
Definieren Sie Funktionen in der äußersten Net.Data-Makroebene, bevor diese im Net.Data-Makro aufgerufen werden.
Sie rufen eine Funktion in einem Net.Data-Makro auf, indem Sie das kommerzielle A (@) gefolgt vom Namen eines Blocks FUNCTION eingeben:
@funktionsname([ argument,... ])
Wenn ein Block FUNCTION aufgerufen wird, geht Net.Data wie folgt vor:
Für das Verwenden und Ändern der Variablen eines Blocks FUNCTION in einem Funktionsaufruf gelten folgende Regeln:
Im Anschluß an die Verarbeitung der Blöcke MESSAGE und REPORT wird der Wert des Funktionsaufrufs verwendet, um den Funktionsaufruf im Net.Data-Makro zu ersetzen.
Gespeicherte Prozeduren lassen sich ebenso problemlos aufrufen wie eine SQL-Funktion. Gespeicherte Prozeduren bieten jedoch eine bessere Leistung und Integrität, da die kompilierten SQL-Anweisungen beim Datenbank-Server verbleiben.
Gespeicherte Prozeduren können folgende Datentypen für die meisten
Plattformen verwenden:
Tabelle 2. Datentypen für gespeicherte Prozeduren
| BLOB | DOUBLEPRECISION | SMALLINT |
| CHAR | FLOAT | TIME |
| CLOB | INTEGER | TIMESTAMP |
| DATE | GRAPHIC | VARCHAR |
| DBCLOB | LONGVARCHAR | VARGRAPHIC |
| DOUBLE | LONGVARGRAPHIC |
|
Weitere Informationen zu diesen Datentypen finden Sie in der Datenbankdokumentation. Net.Data unterstützt möglicherweise nicht alle Datentypen, die für Ihre Datenbank unterstützt werden. Nähere Informationen finden Sie im Anhang des Handbuchs Net.Data Reference Guide.
Es folgt ein Beispiel für den Aufruf einer gespeicherten Prozedur als eine Funktion mit dem Namen 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)
%}
Der Name der gespeicherten Prozedur lautet statsrpt, und sie wird mit der Anweisung CALL aufgerufen. stored_proc1 ist der Name der Funktion, die die gespeicherte Prozedur aufruft.
Anhand des Blocks MESSAGE können Sie die weitere Vorgehensweise bestimmen, nachdem ein Funktionsaufruf erfolgreich bzw. fehlerhaft ausgeführt wurde, und Informationen zum Aufruf der Funktion anzeigen.
Net.Data definiert RETURN_CODE, eine implizite Variable, für jeden Funktionsaufruf. RETURN_CODE wird auf den Rückkehrcode des Aufrufs der Sprachumgebung gesetzt, die von der Funktion aufgerufen wird. Nach Beendigung des Funktionsaufrufs bestimmt der Block MESSAGE anhand des Werts von RETURN_CODE die weitere Vorgehensweise. Ein Block MESSAGE setzt sich aus einer Reihe von Nachrichtenanweisungen zusammen, wobei jede Anweisung einen Rückkehrcodewert, Nachrichtentext und die auszuführende Aktion angibt. Die Syntax eines Blocks MESSAGE sieht wie folgt aus:
>>-%message--{-------------------------------------------------->
+-----------------------------------------------------------+
V |
>----+-------------------------------------------------------+-+->
+-| rückkehrcode |--:--| nachrichtentext |--| aktion |--+
>-%}-----------------------------------------------------------><
rückkehrcode
|--+-DEFAULT-------+-------------------------------------------|
+- +DEFAULT-----+
+- -DEFAULT-----+
+-+---+-nummer--+
+---+
+-+-+
nachrichtentext
+---------------------+
V |
|---+-"----+------------------++--"---+------------------------|
| +-zeichenfolge-----+ |
| +-variablenverweis-+ |
| +-funktionsaufruf--+ |
| +---------------------+ |
| V | |
+-{----+------------------++--%}--+
+-zeichenfolge-----+
+-variablenverweis-+
+-funktionsaufruf--+
aktion
|--:--+-EXIT-----+---------------------------------------------|
+-CONTINUE-+
Ein Block MESSAGE kann für einen globalen oder lokalen Bereich gelten. Wenn der Block MESSAGE in einem Block FUNCTION definiert ist, gilt sein Bereich lokal für diesen Block FUNCTION. Wenn er in der äußeren Makroebene angegeben wird, ist er global gültig und für alle Funktionsaufrufe aktiv, die im Net.Data-Makro ausgeführt werden. Wenn Sie mehrere globale Blöcke MESSAGE definiert haben, ist der zuletzt definierte Block aktiv.
Bei der Verarbeitung des RETURN_CODE eines Funktionsaufrufs gelten folgende Regeln:
Das folgende Beispiel zeigt einen Teil eines Net.Data-Makros mit einem globalen Block MESSAGE und einem Block MESSAGE für eine Funktion:
%{ 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
%}
Wenn my_function() den Wert 50 für RETURN_CODE zurückgibt, setzt Net.Data die Verarbeitung in der folgenden Reihenfolge fort:
Da eine Übereinstimmung gefunden wurde, sendet Net.Data den Nachrichtentext an den Web-Browser und überprüft die angeforderte Aktion. Net.Data setzt nach Ausgabe des Nachrichtentexts die Verarbeitung fort, da continue angegeben ist.
Angenommen, ein Makro ruft my_functions() fünf Mal auf und bei der Verarbeitung mit dem Block MESSAGE aus obigem Beispiel wird der Fehler 100 gefunden. In diesem Fall könnte die Ausgabe des Programms folgendermaßen aussehen:
. 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
Ein weiteres Beispiel für einen lokalen Nachrichtenblock finden Sie in Anhang A. "Beispiel einer dynamischen Abfrage".
Mit Net.Data können Sie problemlos Standard-HTML auf dem Browser des Benutzers darstellen, der die Anwendung einsetzt. In den folgenden Abschnitten erfahren Sie, wie HTML in Net.Data-Makros formatiert wird.
Der Block HTML und die Funktionen, die von einem HTML-Block aufgerufen werden, sind die Blöcke des Net.Data-Makros, die die HTML-Ausgabe für einen Browser generieren. Jedesmal, wenn Net.Data aufgerufen wird, muß ein HTML-Block angegeben werden. Der Inhalt dieses Blocks steuert den weiteren Net.Data-Aufruf.
Ein HTML-Block kann jede gültige HTML enthalten. Darüber hinaus können sich in einem HTML-Block INCLUDE-Anweisungen, Funktionsaufrufe und Verweise auf Variablen befinden. Das folgende Beispiel eines Net.Data-Makros demonstriert eine allgemeine Verwendung der HTML-Blöcke:
%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()
%}
Sie können das Net.Data-Makro von einem Ankerverweis wie dem folgenden aus aufrufen:
<a href="http://www.ibm.com/cgi-bin/db2www/equiplst.mac/input">List of hardware</a>
Wenn der Anwendungsbenutzer diesen Verweis anklickt, wird Net.Data aufgerufen und führt die Syntaxanalyse der Net.Data-Makrodatei aus. Bei Erreichen des im Aufruf angegebenen HTML-Blocks (im vorliegenden Fall ist dies der Block HTML(INPUT)) beginnt Net.Data mit der Verarbeitung des innerhalb des Blocks befindlichen Texts. Alle Elemente, die Net.Data nicht als Sprachkonstrukt des Net.Data-Makros erkennt, werden als HTML angesehen und zur Anzeige an den Browser gesendet.
Nachdem Sie eine Auswahl getroffen und den Knopf Submit gedrückt haben, wird der Teil ACTION des HTML-Elements FORM ausgeführt, wodurch der Block HTML(REPORT) des Net.Data-Makros aufgerufen wird. Der Block HTML(REPORT) wird daraufhin ebenso verarbeitet wie der Block HTML(INPUT). Alle Daten bis zum Funktionsaufruf queryHardware() werden als HTML an den Browser ausgegeben.
Der Funktionsaufruf queryHardware() wird daraufhin verarbeitet und ruft wiederum den SQL-Block FUNCTION auf. Nachdem der Verweis auf die Variable $(hdware) in der SQL-Anweisung durch den Wert, der vom Eingabeformular zurückgegeben wurde, ersetzt wurde, wird die Abfrage ausgeführt. Zu diesem Zeitpunkt beginnt Net.Data wieder damit, HTML an den Browser zu senden. Die Ergebnisse der Abfrage werden entsprechend der im Block REPORT angegebenen HTML angezeigt.
Im Anschluß an die Verarbeitung des Blocks REPORT wird wieder mit dem Block HTML(REPORT) fortgefahren, und die Verarbeitung wird abgeschlossen, indem die verbleibende HTML gesendet wird, die nach dem Funktionsaufruf queryHardware() angegeben wurde.
Für jeden Net.Data-Aufruf wird lediglich ein HTML-Block verarbeitet. Allerdings können Sie mit Hilfe der HTML-Ankerverweise und -Formulare auf einfache Weise dem Benutzer einer Anwendung einen weiteren Aufruf von Net.Data für einen anderen HTML-Block ermöglichen, wobei die komplette Steuerung bei Ihnen liegt.
Der Block REPORT wird verwendet, um die Datenausgabe eines Blocks FUNCTION zu formatieren und anzuzeigen. Diese Ausgabe besteht in der Regel aus Tabellendaten, es kann sich dabei jedoch auch um eine gültige Kombination aus HTML-Befehlen, Makrovariablenverweisen und Funktionsaufrufen handeln. Im Block REPORT kann ein Tabellenname angegeben werden, dies ist jedoch nicht unbedingt erforderlich. Wenn Sie keinen Tabellennamen angeben, werden die Tabellendaten der ersten Ausgabetabelle in der Parameterliste dieses Blocks FUNCTION verwendet. Wenn im Block FUNCTION keine Tabelle definiert ist, wird die Standardtabelle verwendet.
Der Block REPORT besteht aus drei wahlfreien Komponenten:
Wenn Sie keine Tabellenausgabe des Blocks ROW anzeigen wollen, nehmen Sie einfach keine Angaben vor.
Wenn Net.Data einen Block FUNCTION verarbeitet, erfolgt der Aufruf einer Sprachumgebung und die Rückgabe von Daten. Net.Data verarbeitet dann den Block REPORT.
Innerhalb des Blocks REPORT stellt Net.Data mehrere implizit definierte Variablen zur Verfügung, damit Sie auf die Daten in der Ergebnistabelle des Net.Data-Makros zugreifen können. Diese Variablen sind in Tabelle 1 beschrieben. Weitere Informationen dazu finden Sie im Abschnitt "Report Variables" im Handbuch Net.Data Reference Guide.
Kopf- und Fußzeilendaten werden in einem Block REPORT nicht explizit angegeben. Net.Data verarbeitet einfach alle Angaben vor einem Block ROW als Kopfdaten und alle Angaben nach einem Block ROW als Fußzeile. Wie bei einem HTML-Block behandelt der Net.Data-Makroumwandler alle Daten in den Kopf-, ROW- und Fußzeilenblöcken als HTML und sendet diese Daten an den Browser. Sie können auch Funktionen und Variablen selbst einfügen.
Wenn Sie keinen Bericht wünschen, übergehen Sie den Block REPORT und setzen Sie DTW_DEFAULT_REPORT auf NO. Wenn Sie DTW_DEFAULT_REPORT auf YES setzen, wird ein Bericht im Standardformat angezeigt. Zum Beispiel:
SHIPDATE | RECDATE | SHIPNO | ------------------------------------- 25/05/1997 | 30/05/1997 | 1495194B | ------------------------------------- 25/05/1997 | 28/05/1997 | 2942821G | -------------------------------------
Setzen Sie DTW_HTML_TABLE auf YES, wenn Sie HTML-Tabellenbefehle anstatt des vorformatierten Textes für den Standardbericht verwenden wollen.
Das vorliegende Beispiel verdeutlicht, wie Sie Ihre Berichtsformate mit Hilfe von Sondervariablen und HTML-Befehlen anpassen können. Die Namen, Telefonnummern und Faxnummern aus der Tabelle CustomerTbl werden angezeigt:
%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)
%}
%}
Der hieraus erstellte Bericht sieht im Web-Browser wie folgt aus:
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
Der Bericht wurde von Net.Data wie folgt generiert:
DB2 unterstützt große Objekte (LOBs) auf einer zunehmenden Anzahl von Plattformen. Stellen Sie anhand der DB2-Dokumentation fest, ob LOBs auf der Plattform unterstützt werden. DB2 unterstützt folgende drei Arten von LOBs:
Wenn eine Abfrage ein LOB zurückgibt, speichert Net.Data dieses in dem Verzeichnis, das in der Konfigurationsvariablen HTML_PATH angegeben ist. Bei der Verwendung von LOBs ist die jeweilige Systemausstattung zu berücksichtigen, da diese Objekte die Systemressourcen schnell aufbrauchen können. Einige LOBs, wie beispielsweise Audiodateien, erfordern spezielle Hardware und Software.
LOBs enthalten in der Regel in den ersten Byte eine Dateikennung, die die Art der in der Datei enthaltenen Informationen angibt. Wenn Net.Data ein LOB erkennt, wird der temporären Datei und der Net.Data-Makrovariablen, die für den Namen der Datei steht, die Erweiterung hinzugefügt. Ist kein REPORT-Block vorhanden, erhalten CLOBs die Erweiterung .txt. Folgende LOB-Formate werden unterstützt:
Andere Dateitypen werden nicht erkannt und nicht unterstützt. Die SQL-Anweisungen UPDATE und INSERT sind für große Objekte (LOBs) nicht zulässig. Das erste der im folgenden gezeigten Beispiele zeigt ein Inline-Bild. Im zweiten Beispiel muß der Benutzer der Anwendung den Dateinamen anklicken, um die Anzeigefunktion aufzurufen.
<IMG SRC="/tmplobs/dateiname"> <A HREF="/tmplobs/dateiname">dateiname</A>
Es folgt ein Beispiel für die Verwendung von .WAV-Dateien in einer Anwendung. Dieser Dateityp wird von Net.Data nicht erkannt; also wird eine Variable EXEC verwendet, um die Erweiterung an die Datei anzuhängen.
%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()
%}
Die Funktion queryData gibt folgende HTML zurück:
<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>
Dieser Block REPORT verwendet die impliziten Tabellenvariablen V1, V2 und V3.
Nicht alle Web Browser unterstützen Grafik und Ton. Zur Unterstützung der hier beschriebenen Funktionen wird möglicherweise spezielle Hardware und Software benötigt, wie zum Beispiel eine Audiokarte mit Treiber.
Net.Data verfügt über zahlreiche integrierte Funktionen, die die Entwicklung von Web-Seiten vereinfachen. Diese Funktionen sind von Net.Data bereits definiert, so daß Sie diese Funktionen nicht mehr in einem FUNCTION-Block definieren müssen. Rufen Sie diese Funktionen einfach in einem Makro an einer beliebigen Stelle auf, an der eine benutzerdefinierte Funktion aufgerufen werden kann.
Es gibt drei Methoden, mit denen integrierte Funktionen ihre Ergebnisse zurückgeben können. An dem zugehörigen Präfix können Sie erkennen, wie eine Funktion ihre Ergebnisse ausgibt:
Einige integrierte Funktionen unterstützen nicht jede Art. Weitere Informationen finden Sie im Handbuch Net.Data Reference Guide.
Mit Hilfe dieser Gruppe von Funktionen können Sie Web-Seiten durch Ändern von Daten oder Zugreifen auf Systemservices entwickeln. Hiermit können Sie Umgebungsvariablen abfragen und einstellen, HTML-Escape-Codes verwenden, und andere nützliche Informationen vom System abrufen.
Diese Funktionen führen mathematische Operationen aus, über die Sie numerische Daten berechnen und ändern können. Neben den mathematischen Standardoperationen können auch Modulus-Divisionen ausgeführt, eine Ergebnisgenauigkeit angegeben und Exponentialschreibweise verwendet werden.
Mit diesen Funktionen können Sie Zeichenfolgen ändern. So können Sie zum Beispiel eine Zeichenfolge von Klein- in Großschreibung (oder umgekehrt) umsetzen, Zeichen einfügen oder löschen, einen Zeichenfolgewert einer anderen Variablen zuordnen und noch andere nützliche Funktionen ausführen.
Diese Funktionen können zum Bearbeiten von Wörtern in Zeichenfolgen verwendet werden. Die meisten dieser Funktionen arbeiten auf dieselbe Weise wie die Zeichenfolgefunktionen, jedoch bezogen auf ganze Wörter. Hiermit können Sie die Anzahl der Wörter in einer Zeichenfolge zählen, Wörter entfernen, eine Zeichenfolge nach einem Wort durchsuchen, um nur einige zu nennen.
Mit diesen Funktionen können Sie Net.Data-Tabellenvariablen bearbeiten. Tabellenvariablen enthalten einen Wertebereich mit den zugehörigen Spaltennamen. Sie bieten eine bequeme Möglichkeit, ganze Wertegruppen an eine Funktion weiterzugeben.
Wenn Sie unstrukturierte Textdateien (oder Dateien mit unverschlüsseltem Text) als Datenquelle verwenden wollen, können Sie über die FFI-Schnittstelle (FFI - Flat File Interface) und den zugehörigen Net.Data-Funktionen Dateien auf Ihrem Web-Server öffnen, schließen, lesen, schreiben und löschen. Sie müssen für die Variable FFI_PATH einen Pfad in der Initialisierungsdatei angeben.
Bei Anforderung durch den Web-Client über den Browser verwendet die Dateisprachenunterstützung die FFI-Funktionen für Lese- bzw. Schreibvorgänge für Dateien auf dem Web-Server. Die Datei wird von FFI als eine Satzdatei angesehen, wobei jeder Datensatz einer Zeile in einer Tabellenvariablen und jeder Wert in einem Datensatz einem Feldwert in einer Tabellenvariablen eines Net.Data-Makros entspricht. FFI liest Datensätze aus einer Datei in Zeilen einer Net.Data-Makrotabelle ein und schreibt Zeilen aus einer Tabelle in Datensätze.
Sie können mit der Anweisung FFI_PATH in der Net.Data-Initialisierungsdatei angeben, auf welche Dateien FFI-Funktionen zugreifen dürfen. FFI durchsucht ausschließlich die in der Anweisung angegebenen Pfade, so daß kein Zugriff auf Dateien in anderen Verzeichnissen möglich ist. Beispiel für eine Anweisung:
FFI_PATH C:\public;.\;E:\WWW;E:\guest;A:
Die Pfade in der Anweisung FFI_PATH werden vom ersten bis zum letzten Pfad durchsucht. Die zuerst gefundene Kopie wird verwendet. Wenn sich die Anweisung FFI_PATH nicht in der Initialisierungsdatei befindet, versucht FFI die Datei im aktuellen Verzeichnis oder im angegebenen Pfad, sofern vorhanden, zu finden (z. B. ../reports/nov96.txt). Bei Lieferung ist in der Net.Data-Initialisierungsdatei keine Anweisung FFI_PATH enthalten.
Der Einrichtung von FFI sollte eine sorgfältige Planung vorausgehen. Beachten Sie dabei folgende Aspekte:
Allgemeine Überlegungen
Aktuelles Verzeichnis
Parameter DELIMITER
FFI_PATH
Funktion DTWF_SEARCH
Parameter STARTROW und ROWS
Parameter TABLE
Parameter TRANSFORM
Die auf einigen Plattformen verfügbare Web-Registrierdatenbank von Net.Data stellt einen ständigen Speicher für anwendungsbezogene Daten bereit. In einer Web-Registrierdatenbank können Konfigurationsdaten und andere Daten gespeichert werden, auf die auf dem Web-basierende Anwendungen zur Laufzeit dynamisch zugreifen können. Sie können auf eine Web-Registrierdatenbank nur über Net.Data-Makros zugreifen, die Net.Data und die integrierte Unterstützung der Web-Registrierdatenbank verwenden, sowie über zu diesem Zweck geschriebene CGI-Programme.
Die Entwicklung standardmäßiger Web-Seiten setzt voraus, daß die URLs direkt in die HTML-Quelle für diese Seite aufgenommen werden. Infolgedessen wird es jedoch schwierig, Änderungen an Hyperlinks vorzunehmen. Darüber hinaus schränkt die statische Struktur die Art der Hyperlinks ein, die sich auf einfache Weise in eine Web-Seite integrieren lassen. In diesem Fall kann es hilfreich sein, eine Web-Registrierdatenbank zum Speichern anwendungsrelevanter Daten (z. B. URLs) beim Erstellen von HTML-Seiten mit dynamisch gesetzten Hyperlinks zu verwenden.
Anwendungsentwickler und Web-Administratoren, die Schreibzugriff auf die Registrierdatenbank haben, können Informationen in dieser Registrierdatenbank speichern und verwalten. Anwendungen rufen die Informationen zur Laufzeit aus den zugehörigen Registrierdatenbanken ab. Dies erleichtert das Entwerfen flexibler Anwendungen und ermöglicht das Versetzen von Anwendungen und Servern. Mit Hilfe von Net.Data-Makros können Sie HTML-Seiten unter Verwendung dynamisch gesetzter Hyperlinks erstellen.
Die Informationen werden in Form von Registriereinträgen in einer Web-Registrierdatenbank gespeichert. Jeder Eintrag in der Registrierdatenbank besteht aus einem Zeichenfolgenpaar: der Zeichenfolge RegistryVariable sowie der zugehörigen Zeichenfolge RegistryData. Die Variablenzeichenfolge wird als Suchkriterium zum Lokalisieren und Abrufen spezieller Einträge einer Registrierdatenbank verwendet.
Tabelle 3 zeigt einen Ausschnitt aus einer Web-Registrierdatenbank.
Tabelle 3. Beispiel einer Web-Registrierdatenbank
| CompanyName | WorldConnect |
| Server | ftp.einet.net |
| JohnDoe/foreground | Green |
| CompanyURL/IBM Corp. | http://www.ibm.com |
| CompanyURL/Sun Microsystems Corp. | http://www.sun.com |
| CompanyURL/Digital Equipment Corp. | http://www.dec.com |
| JaneDoe/Home_page | http://jane.info.net |
Es folgen einige Gründe, die für die Verwendung einer Web-Registrierdatenbank sprechen:
Indexierte Einträge in der Web-Registrierdatenbank sind Einträge, deren
RegistryVariable-Zeichenfolgen zusätzlich mit der Zeichenfolge Index versehen
werden wie z. B. in "RegistryVariable/Index". Der Benutzer stellt den
Wert der Indexzeichenfolge in einem separaten Parameter einer integrierten
Funktion bereit, die zum Einsatz mit indexierten Einträgen konzipiert ist.
Mehrere indexierte Einträge in der Registrierdatenbank können denselben
RegistryVariable-Zeichenfolgenwert aufweisen, wobei ihre Eindeutigkeit durch
unterschiedliche Werte für die Indexzeichenfolge gewahrt werden kann.
Tabelle 4. Beispiel einer indexierten Web-Registrierdatenbank
| Smith/Company_URL | http://www.ibmlink.ibm.com |
| Smith/Home_page | http://www.advantis.com |
Die zwei indexierten Einträge in diesem Beispiel weisen zwar denselben Zeichenfolgewert RegistryVariable "Smith", aber unterschiedliche Indexzeichenfolgen auf. Sie werden daher von den Funktionen der Web-Registrierdatenbank als zwei verschiedene Einträge behandelt.
Net.Data stellt mehrere Sprachumgebungen zur Verfügung, über die Sie Informationen an Datenquellen übergeben bzw. von diesen empfangen können. Mit der SQL-Sprachumgebung können Sie zum Beispiel eigene SQL-Abfragen an eine Datenbank übergeben und die REXX-Sprachumgebung ermöglicht Ihnen das Aufrufen von REXX-Programmen.
Net.Data ist so konzipiert, daß neue Sprach- und Datenbankschnittstellen wie steckbare Elemente hinzugefügt werden können. Der Zugriff auf diese Sprachumgebungen erfolgt über Bibliotheken für dynamisches Verbinden (DLLs - Dynamic Link Libraries) oder gemeinsam benutzte Bibliotheken, die separat vom ausführbaren Hauptprogramm von Net.Data verfügbar sind. Die Namen der DLLs sind in der Net.Data-Initialisierungsdatei angegeben und sind einem Sprachumgebungsnamen zugeordnet. Jede Sprachumgebung muß eine Standardgruppe der von Net.Data definierten Schnittstellen unterstützen. Net.Data lädt die in der Initialisierungsdatei angegebene DLL erstmals, wenn ein Funktionsaufruf für einen Block FUNCTION, der diese Sprachumgebung angibt, gefunden wird.
Ausführliche Informationen zu Sprachumgebungen finden Sie im Handbuch Net.Data Language Environment Guide.
Zur Optimierung der Leistung gibt es verschiedene Möglichkeiten:
Die beiden effektivsten Methoden zur Leistungssteigerung von Net.Data bilden normalerweise die Verwendung einer Direktverbindung und einer Anwendungsprogrammierschnittstelle (API) wie z. B. NSAPI, ICAPI oder ISAPI. Im Handbuch Net.Data Language Reference Guide können Sie nachlesen, welche dieser Methoden von Ihrer Plattform unterstützt wird.
Auf einigen Servern kann die Leistung mit Hilfe der Direktverbindung optimiert werden, um ständige Datenbankverbindungen aufrechtzuerhalten. Für einige Net.Data-Aktionen ist eine lange Startzeit erforderlich. Bevor eine Datenbankabfrage abgesetzt werden kann, muß sich z. B. der Prozeß für das Datenbankverwaltungssystem (DMBS) identifizieren und eine Verbindung zur Datenbank herstellen. Net.Data-Makros, die auf eine Datenbank zugreifen, nehmen oftmals einen beträchtlichen Teil der Verarbeitungszeit in Anspruch. Eine virtuelle Java-Maschine, die für die Ausführung von Java-Anwendungen (keine Java-Applets) erforderlich ist, stellt ein weiteres Beispiel für eine kostenintensive Startzeit dar. Aufgrund der Arbeitsweise der CGI-Programme fallen diese Startkosten bei jeder Anfrage an den Web-Server an.
Mit Hilfe einer Direktverbindung kann eine entscheidende Leistungssteigerung erzielt werden, da sie diesen Startaufwand verringert. Der Spareffekt ist darauf zurückzuführen, daß ständig mindestens ein Prozeß ausgeführt wird, der die Startfunktionen übernimmt. Diese Prozesse warten dann auf Serviceanforderungen. Sie können Direktverbindungen ausführen, wenn Sie Net.Data als ein CGI-Programm verwenden. Bei einer Web-Server-API muß die Direktverbindung verwendet werden.
Die Direktverbindung verwendet Connection Manager und Cliettes. Cliettes sind Einzel-Thread-Prozesse, die von Connection Manager gestartet werden und aktiv bleiben, während der Server aktiv ist. Cliettes verarbeiten Daten und kommunizieren mit Net.Data-Sprachumgebungen in der Initialisierungsdatei über das Schlüsselwort CLIETTE. Jede Cliette-Art ist für die Bearbeitung einer spezifischen Ausgabefunktion konzipiert, z. B. die DB2-Cliette, die die Verbindung zur Datenbank herstellt und Operationen zur Ausführung von SQL-Aufrufen bereitstellt, bevor Net.Data-Makros von Net.Data verarbeitet werden. Die ausführbare Datei wird in der Konfigurationsdatei dtwcm.cnf angegeben.
Eine Verwendung der Direktverbindung empfiehlt sich aufgrund der folgenden drei Hauptvorteile:
Der wiederholte Einsatz von bestehenden Verbindungen ist effizienter als die Verbindungen immer wieder neu herstellen zu müssen. Überlegen Sie sich genau, wie teuer Ihre Verbindungszeit im Vergleich zur gesamten Verarbeitungszeit ist. In der Regel schlägt die Verbindungszeit zu Buche, wenn Sie kleine SQL-Anweisungen anfordern (z. B. einfache Abfragen einer Datenbank mit weniger als 100.000 Zeilen) oder wenn Ihre Verbindung kompliziert ist (z. B. ferne Server).
Über eine Direktverbindung können Sie mit einem Net.Data-Makro zu mehreren Datenbanken gleichzeitig eine Verbindung herstellen. Dies wird dadurch möglich, daß jede Datenbank über eindeutige Cliettes verfügt, d. h., Net.Data kommuniziert einfach mit mehreren Cliettes.
Connection Manager ist in der Lage, Anweisungen SELECT zu verarbeiten und die ersten N Zeilen zu löschen. Dadurch ist es möglich, eine Anwendung zu verwenden, die die Optionen "next" und "previous" zum Navigieren in umfangreichen Listen bereitstellt. Indem Sie die Variable START_ROW_NUM auf N setzen, können Sie umfangreiche Abfragen in überschaubaren Teilen anzeigen. Die Anwendungsbenutzer können dann NEXT anklicken, um die nächste Zeilengruppe abzurufen.
Sie müssen eine Direktverbindung verwenden, wenn Sie für die Kommunikation mit Ihrer Datenbank eine API (anstatt CGI) gewählt haben. Die Vorzüge der Direktverbindung können Sie nutzen, wenn Ihre Anwendung folgende Bedingungen erfüllt:
Für zahlreiche Anwendungen sind Leistungssteigerungen ohne Direktverbindung möglich, wenn der Befehl ACTIVATE DATABASE oder START DATABASE verwendet wird, um Zeit beim Herstellen von Datenbankverbindungen zu sparen. Nähere Angaben zu dem von Ihrer Datenbank verwendeten Befehl finden Sie in der Datenbankdokumentation. Prüfen Sie außerdem anhand der Dokumentation zu Ihrer Plattform, ob weitere Möglichkeiten zur Optimierung der Leistung beschrieben sind.
Connection Manager ist eine separate ausführbare Net.Data-Datei mit dem Namen dtwcm. Starten Sie Connection Manager, wenn Sie den Web-Server starten. Connection Manager liest nach dem Start eine Konfigurationsdatei und erzeugt eine Gruppe von Prozessen, die Daten verarbeiten. In jedem Prozeß beginnt Connection Manager mit der Ausführung einer bestimmten Cliette.
Sobald alle Komponenten konfiguriert und aktiv sind (einschließlich Datenbank, Web-Server und Connection Manager), besteht die Net.Data-Verarbeitung im Normalfall aus folgenden Schritten, wenn die Direktverbindung aktiviert ist:
Wenn in der Initialisierungsdatei zwar eine Cliette angegeben, Connection Manager jedoch nicht gestartet ist, lädt Net.Data die DLL und verarbeitet das Makro. Wenn Sie mit einer API arbeiten, treten wahrscheinlich Fehler auf, und Sie sollten Connection Manager erneut starten.
Die Direktverbindung verwendet eine Konfigurationsdatei, dtwcm.cnf, um festzustellen, welche Cliettes gestartet werden müssen. Die Konfigurationsdatei im folgenden Beispiel besteht aus folgenden Blöcken:
Die Zeilen sind zu Referenzzwecken numeriert:
1 CONNECTION_MANAGER{
2 MAIN_PORT=7100
3 ADMIN_PORT1=7101
4 ADMIN_PORT2=7102
5 }
6
7 CLIETTE DTW_SQL:CELDIAL{
8 MIN_PROCESS=1
9 MAX_PROCESS=5
10 START_PRIVATE_PORT=7200
11 START_PUBLIC_PORT=7210
12 EXEC_NAME=./cltdb2
13 DATABASE=CELDIAL
14 BINDFILE=/usr/... .../d2wsql.bnd
15 LOGIN=marshall
16 PASSWORD=stlpwd
17 }
18
19 CLIETTE DTW_APPLET{
20 MIN_PROCESS=1
21 MAX_PROCESS=5
22 START_PRIVATE_PORT=7300
23 START_PUBLIC_PORT=7310
24 EXEC_NAME=./javaapp
25 }
Die Zeilen 1 - 5 sind für die Konfigurationsdatei erforderlich. Die Zeilen 7 - 12 und 17 sind für alle SQL-Cliettes erforderlich. Wenn Sie eine Verbindung zu einer DB2-Datenbank herstellen, können Sie zusätzliche Informationen angeben (z. B. Benutzer-ID und Kennwort). Diese zusätzlichen Werte sind in den Zeilen 13 - 16 enthalten. Die Zeilen 19 - 25 sind alle erforderlich, wenn Sie mit Java-Anwendungen arbeiten.
Sie können angeben, daß für die Variablen LOGIN und PASSWORD die Standardwerte verwendet werden sollen. Dies bedeutet, daß Net.Data dieselbe Benutzer-ID verwendet, über die auch Connection Manager gestartet wurde, um die Verbindung zur DB2-Datenbank herzustellen. Auf diese Weise müssen Sie diese Informationen nicht in die Konfigurationsdatei eingeben. Ersetzen Sie zum Beispiel die Zeilen 15 und 16 durch folgende Zeilen:
LOGIN=*USE_DEFAULT PASSWORD=*USE_DEFAULT
Sie müssen die auf Ihrem System zu verwendenden Anschlußnummern feststellen. Außerdem sollten Sie die Werte für MIN_PROCESS und MAX_PROCESS kennen. Die Werte, die Sie verwenden, können die Leistung beeinflussen. Alle durch MIN_PROCESS angegebenen Prozesse werden zusammen mit Connection Manager gestartet. Wenn im Anschluß daran simultane Prozesse empfangen werden, startet Connection Manager weitere Cliettes. Bei Bedarf wird jeweils eine Cliette hinzugefügt, bis der für MAX angegebene Wert erreicht ist. Die Werte, die Sie verwenden, können die Leistung beeinflussen. Sie können sie jedoch zu einem späteren Zeitpunkt ändern.
Zur Verwendung einer Direktverbindung müssen Sie für DTW_SQL (und u. U auch für DTW_ODBC) ENVIRONMENT-Anweisungen in die Net.Data-Initialisierungsdatei einfügen. Weitere Informationen hierzu finden Sie im Handbuch Net.Data Language Environment Guide.
Machen Sie sich mit folgenden Fakten vertraut, bevor Sie Ihre Konfigurationsdatei ändern:
CLIETTE DTW_SQL:D1{ ...}
CLIETTE DTW_SQL:D2{....}
CLIETTE DTW_SQL:D3{....}
START_PUB_PORT=1000 START_PRIV_PORT=1010 MAX_NUM_PROC=5In diesem Beispiel werden folgenden Anschlüsse verwendet:
| 1000 | 1010 |
| 1001 | 1011 |
| 1002 | 1012 |
| 1003 | 1013 |
| 1004 | 1014 |
Eine häufig auftretende Fehlerquelle besteht darin, daß für zwei Cliette-Gruppen sich überlappende Anschlüsse angegeben wurden. Erkundigen Sie sich daher beim Systemadministrator, ob die Anschlüsse, die Sie verwenden wollen, zur Verfügung stehen. Die Datei README für Ihre Plattform enthält allgemeine Richtlinien zu den Anschlüssen, die für Ihr Betriebssystem gültig sind.
Wenn Sie CGI verwenden, und nur einige Datenbanken die Direktverbindung verwenden sollen, listen Sie die gewünschten Datenbanken einfach in der Konfigurationsdatei auf. Wenn Net.Data bei der Verarbeitung eines Net.Data-Makros einen SQL-Abschnitt findet, fordert das Programm eine bestimmte Cliette bei Connection Manager an. Steht die gewünschte Cliette-Art nicht zur Verfügung, gibt Connection Manager die Nachricht NO_CLIETTE_AVAIL aus. Net.Data verarbeitet die Anforderung statt dessen mit einer DLL-Version.
Die Verwendung von ICAPI (Internet Connection API) verbessert die Leistung, da die CGI-Verarbeitung entfällt. Weitere Informationen zur Internet-Verbindung finden Sie im Handbuch Web Programming Guide:
http://www.ics.raleigh.ibm.com/pub/icswpg.htm
Angaben dazu, welche Systeme ICAPI verwenden können, sowie zusätzliche Informationen finden Sie in der Datei README. Führen Sie folgende Schritte aus, um Net.Data für die Ausführung mit ICAPI auf Ihrem Server zu konfigurieren:
WWW\CGI-BIN\
Die anderen Net.Data-DLLs oder gemeinsam benutzten Bibliotheken müssen sich im DLL-Verzeichnis bzw. im Verzeichnis der gemeinsam benutzten Bibliotheken des Servers befinden.
Service /cgi-bin/db2www* c:\www\cgi-bin/dtwicapi:dtw_icapi*
Angaben dazu, welche Systeme ISAPI verwenden können, sowie zusätzliche Informationen finden Sie in der Datei README. Führen Sie folgende Schritte aus, um Net.Data für die Ausführung mit ISAPI zu konfigurieren:
Zum Lieferumfang von Net.Data gehört eine DLL für die Verwendung mit ISAPI. Diese DLL befindet sich im Unterverzeichnis des Servers. Beispiel:
/inetsrv/scripts/dtwisapi.dll
ISAPI umgeht die CGI-Verarbeitung. Aus diesem Grund müssen Sie Ihre Web-Seiten und Web-Makros ändern, die über CGI-Aufrufe zu Net.Data verfügen. Entfernen Sie in Formularen und Ankerverweisen den cgi-bin/db2www/-Teil des URL, und ersetzen Sie ihn durch dtwisapi.dll. Der folgende URL ist ein Beispiel für den Aufruf von Net.Data als CGI-Programm:
http://server1.stl.ibm.com/cgi-bin/db2www/test1.mac/reportDer folgende URL verwendet Net.Data als ISAPI-Anwendung:
http://server1.stl.ibm.com/scripts/dtwisapi.dll/test1.mac/report
Wenn Sie Ihre Net.Data-Makros in verschiedenen Verzeichnissen speichern, folgen die Verzeichnisnamen dem DLL-Namen. Beispielsweise ruft der folgende URL ein Net.Data-Makro auf, das im Verzeichnis /orders/ gespeichert ist:
http://server1.stl.ibm.com/cgi-bin/db2www/orders/test1.mac/reportDer aktualisierte URL behält den Verzeichnisnamen bei:
http://server1.stl.ibm.com/scripts/dtwisapi.dll/orders/test1.mac/report
Ihr Web-Server benötigt eine Direktverbindung, um NSAPI (Netscape API) für alle Sprachumgebungen verwenden zu können. Die Verwendung von NSAPI (Internet Server API) verbessert die Leistung, da die CGI-Verarbeitung entfällt. Weitere Informationen dazu finden Sie auf der Seite Netscape Server API:
http://home.netscape.com/newsref/std/server_api.html
Angaben dazu, welche Systeme NSAPI verwenden können, sowie zusätzliche Informationen finden Sie in der Datei README. Führen Sie folgende Schritte aus, um Net.Data für die Ausführung mit NSAPI auf Ihrem Server zu konfigurieren:
/netscape/server/bin/httpd/dtwnsapi.dll
| obj.conf | Fügen Sie am Anfang der Datei folgende Angaben hinzu:
Init fn="load-modules" shlib="dtwnsapi.dll" funcs=dtw_nsapi |
| obj.conf | Fügen Sie Anweisung Service folgende Angaben hinzu:
Service fn="dtw_nsapi" method=(GET|HEAD|POST) type="magnus-internal/d2w" |
| mime.types | Fügen Sie folgende Angabe hinzu:
type=magnum-internal/dtw exts=mac |
/netscape/server/docs/
http://server1.stl.ibm.com/cgi-bin/db2www/test1.mac/reportDieser URL verwendet Net.Data als NSAPI-Anwendung:
http://server1.stl.ibm.com/test1.mac/report
Wenn Sie Ihre Net.Data-Makros in verschiedenen Verzeichnissen speichern, ändern sich einige Schritte geringfügig:
http://server1.stl.ibm.com/cgi-bin/db2www/orders/test1.mac/reportDer aktualisierte URL ist kürzer, behält aber den Verzeichnisnamen bei:
http://server1.stl.ibm.com/orders/test1.mac/report