Net.Data – ein Überblick Dokument: Net.Data auf iSeries – ein Überblick Autor: Holger Scherer geschrieben mit: OpenOffice.Org 1.10 Inhalt: Workshop-Unterlagen für die COMMON Jahreskonferenz 2004 in Würzburg Copyright: liegt bei Holger Scherer, München Version: $027; 30. Oktober 2004 Kontakt: mailto:[email protected] http://www.holgerscherer.de AS400Profis.de; Holger Scherer; Milbertshofener Str. 34; 80807 München Net.Data – ein Überblick Seite 1 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Inhaltsverzeichnis INHALTSVERZEICHNIS............................................................................................................... 2 EINLEITUNG............................................................................................................................ 3 Vergleich mit IBM WebSphere Application Server..................................................................................3 Welche Umgebung für welche Anwendung?...........................................................................................4 SYSTEMUMGEBUNG UND TEST................................................................................................... 5 Einrichtung des Systems.........................................................................................................................5 Was passiert?..........................................................................................................................................6 NET.DATA – SCRIPTAUFBAU..................................................................................................... 7 Hinweise..................................................................................................................................................7 Aufbau.....................................................................................................................................................7 Variables und dynamisches.....................................................................................................................9 Neue Funktionen und Variablenreferenzen...........................................................................................11 Fehlersuche – ein Intermezzo...............................................................................................................12 DATENZUGRIFFE PER SQL..................................................................................................... 13 Vorbereitung..........................................................................................................................................13 Erste Auswahl von Daten......................................................................................................................13 Verfeinerung der Ausgabe.....................................................................................................................15 Kleiner Exkurs – HTML-Tabellen...........................................................................................................16 Parameter in Funktionen.......................................................................................................................18 Fehler? Vermeiden oder abfangen!.......................................................................................................19 Mehr Spaß mit Variablen und Parametern............................................................................................20 Eingabefelder in HTML..........................................................................................................................22 Schreiben und Update...........................................................................................................................24 BEISPIELKONFIGURATION FÜR DEN HTTP-SERVER BASIEREND AUF APACHE............................... 26 Net.Data – ein Überblick Seite 2 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Einleitung Net.Data ist eine Scriptsprache von IBM, die für verschiedene Plattformen wie der zSeries, der pSeries unter AIX, der iSeries unter OS/400, sowie unter OS/2 und Windows zur Verfügung steht. Sie konkurriert im Funktionsumfang, in der Einarbeitungsgeschwindigkeit und der einfachen Handhabung mit Sprachen wie PHP, hat jedoch nur im OS/400-Bereich eine gewisse Bedeutung erlangt. Daher hat IBM den Support für alle anderen Plattformen einschlafen lassen, in i5/OS jedoch erweitert und dort auch zur Administration und für Beispiele bei der Suchmaschinen-Funktion verwendet. Unter OS/400 und i5/OS zeigt Net.Data jedoch einige Vorteile gegenüber der Verwendung einer PHPImplementation, da es nativ und ohne Performance-Einbussen durch Emulationsroutinen auf der iSeries läuft. Vergleich mit IBM WebSphere Application Server Zur Abgrenzung zum WebSphere Application Server hier eine Übersicht: Vorteile Net.Data Nachteile Net.Data Einfach zu Erlernen Net.Data ist eine einfache Skriptsprache ähnlich PHP, die sehr schnell erlernt werden kann, so dass sehr schnell einfache bis komplexe Anwendungen für das Intranet oder Internet erstellt werden können. Nicht sehr bekannt Net.Data wird von IBM nicht so sehr in der Presse beworben wie der WebSphere Application Server. Dies bedeutet nicht, dass Net.Data von IBM nicht weiter unterstützt wird oder vom Markt verschwindet. Als kostenlose Zugabe zum http-Server verwendet IBM nur keine grosse Anstrengung auf das Marketing. Leistungsfähigkeit bei geringem Aufwand Die Net.Data-Skriptsprache enthält eine Vielzahl von eingebauten Funktionen, die es zum Beispiel ermöglichen, eine eMail zu senden, Cookies einzurichten oder zu ändern, oder über die mitgelieferten Sprachumgebungen auf verschiedenste Datenbanken zuzugreifen. Net.Data läuft sehr stabil auch auf kleinen Maschinen und wurde zum Beispiel auf den Webseiten der olympischen Winterspiele in Nagano zur Anzeige der Ergebnisse verwendet. Fehlende Tools und Hilfsprogramme Es gibt kaum Hilfsprogramme zum Erstellen von Net.Data-Skripten oder dem Management grösserer Projekte. Net.Data-Skripte bestehen aus einfachen Textdateien, die mit jedem Editor bearbeitet werden können. Mit vorhandenen Tools können SQL- oder HTML-Blöcke erstellt und in Net.Data-Skripte eingebaut werden. Weiterhin kann man das WebSphere Studio anpassen, so dass es Net.Data-Befehlswörter erkennt. Kostenlos Net.Data wird mit dem IBM-Lizenzprogramm HTTPServer kostenlos ausgeliefert. Dieses Programm gehört zu jeder OS/400-Auslieferung, muss jedoch einzeln installiert werden. geringere Geschwindigkeit Net.Data ist eine interpretierte Sprache. Somit muss ein ausgeführtes Script jedesmal interpretiert und geprüft werden, im Gegensatz zu kompilierten Java-Klassen. Bei vielen Anwendern kann eine kleine Maschine hier überlastet sein. Es werden ca. 15CPW pro Internetsitzung empfohlen (gleichzeitig). geringe Ressourcen nötig Net.Data bringt auch auf der kleinsten iSeries Ergebnisse in ausreichender Geschwindigkeit und benötigt nur wenige MB Hauptspeicher. Net.Data – ein Überblick Seite 3 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Vorteile Websphere Nachteile Websphere Java-basiert Der WebSphere Application Server ist eine Javabasierte Umgebung für grosse dynamische Anwendungen zur Ausführung von Servlets, JavaBeans und Java Server Pages. Grosser Lernaufwand Um mit dem WebSphere Application Server umgehen zu können, ist ein grosser Zeitaufwand für die Einarbeitung und Systemumgebung nötig. Auch das Erlernen der Sprache JAVA und aller Sprachkonstrukte sowie der einzelnen Servertechnologien benötigt relativ viel Zeit. Leistungsfähig Mit Java kann fast jede Internet-Technologie verwendet werden. Der WebSphere Application Server beinhaltet viele Möglichkeiten der Systemumgebung, zum Beispiel Load-Balancing. Leistungshungrig Durch die intensive Verwendung von JAVA und der integrierten Systemumgebung benötigt der WebSphere Application Server viele Systemressourcen und eine schnelle CPU. Es wird empfohlen, mindestens 500MB Hauptspeicher nur für den Application Server zu reservieren, besser wäre noch mehr. Bekanntheitsgrad IBMs Marketing für Internet-Technologien konzentriert sich auf den WebSphere Application Server als Schlüsselprodukt. Die Sprache JAVA selbst ist in aller Munde. Somit hat dieses Produkt und diese Umgebung einen sehr hohen Bekanntheitsgrad. Viele Tools und Hilfsprogramme Neben den Tools des WAS gibt es für JAVA eine Unzahl an Hilfsprogrammen und Entwicklungsumgebungen, die das Erstellen grosser Projekte einfacher machen. mehrere Plattformen WAS läuft unter anderem auf Windows, AIX, Solaris, OS/390, OS/400. Welche Umgebung für welche Anwendung? IBM konzentriert sich beim Marketing auf Java und WebSphere Application Server als strategische Produkte und Sprachen für Web-basierte Anwendungen, weiterhin bietet sich diese Umgebung durch die vorhandenen Tools und Kenntnisse an, wenn Grossprojekte realisiert werden sollen. Besonders wenn Zeit wichtig ist und man sich nicht mit Java auseinandersetzen will oder kann, bietet sich Net.Data an, da hier innerhalb weniger Stunden einfache Anwendungen und dynamische Webseiten erstellt werden können, die Erfolgskurve ist sehr steil. Da jedoch WAS und Net.Data parallel auf einem System verwendet werden können, bietet es sich an, kleine und flexible Projekte mit Net.Data zu erstellen, so kann man sich einen Wechsel oder den Parallelbetrieb mit WAS offen halten. Es wird oft behauptet, Net.Data wäre eine aussterbende Technologie, die von IBM nicht weiter unterstützt wird. Dies ist nicht richtig, auch mit Einführung von i5/OS V5R3 erfährt Net.Data Erweiterungen und Verbesserungen, und wird hier auch stellenweise im administrativen Teil des HTTP-Servers verwendet. Net.Data – ein Überblick Seite 4 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Systemumgebung und Test Net.Data benötigt keine besondere Systemumgebung für der iSeries. Es wird einzig ein installierter HTTP-Server benötigt (Produkt 5722DG1(V5) oder 5769DG1(V4)), sei es der original-IBM-HTTPServer oder der HTTP-Server basierend auf Apache. Einrichtung des Systems Wichtig ist jeweils das Programm DB2WWW.PGM, welches nach der Installation des HTTP-Servers in der Bibliothek QHTTPSVR liegt. Je nach Installation oder Umgebung existiert dieses Objekt auch in der Bibliothek QSYSCGI. Wenn Sie ein Net.Data-Projekt starten, empfiehlt es sich, eine eigene Bibliothek für Net.Data-Objekte bzw. Konfigurationsdateien anzulegen. Nehmen wir als Beispiel eine neue Bibliothek namens CGIBIN. Kopieren Sie hier das Objekt DB2WWW.PGM hinein. Warum? Aus Gründen der Sicherheit... Achten Sie auf die Berechtigungen! Alle Aktionen des HTTP-Servers laufen unter dem Benutzerprofil QTMHHTTP, CGI-Jobs (wozu auch der Net.Data-Prozessor gehört) laufen unter QTMHHTP1. Schränken Sie die Berechtigung der Bibliothek CGIBIN und aller darin enthaltenen Objekte ein, dass *PUBLIC ausgeschlossen ist (*EXCLUDE), die beiden oben genannten Benutzerprofile für den Webserver und Net.Data sollten aber *USE haben. Wenn Net.Data auf Datenbank-Dateien ändernd oder schreibend zugreifen soll, muss der Benutzer QTMHHTP1 hier mindestens *CHANGE – Rechte haben. Diese Datenbankdateien können selbstverständlich auch in anderen Bibliotheken liegen. Beispielsweise müssen folgende Zeilen in der Konfiguration des original-HTTP-Servers enthalten sein, um die Ausführung von Net.Data-Makros zu ermöglichen: MAP /CGIBIN/* /QSYS.LIB/CGIBIN.LIB/DB2WWW.PGM/* MAP /cgibin/* /QSYS.LIB/CGIBIN.LIB/DB2WWW.PGM/* EXEC /QSYS.LIB/CGIBIN.LIB/* PASS /* /web/* Konfiguration original-Webserver zum Ausführen von Net.Data (nach der Änderung der Konfiguration mit WRKHTTPCFG muss der Webserver möglicherweise neu gestartet werden). Nun muss noch in der Bibliothek CGIBIN eine Datei erstellt werden, die Konfigurationseinstellungen für Net.Data beinhaltet, z.B. die Pfade für die auszuführenden Net-Data Scriptdateien. Wir erstellen gleich die nötige Teildatei DB2WWW wie folgt: CRTSRCPF FILE(CGIBIN/INI) MBR(DB2WWW) Der Name DB2WWW kann auch anders gewählt werden, dann müssen aber die Einstellungen des Webservers sowie der Links für Ihr Internetprojekt entsprechend angepasst sein! Net.Data – ein Überblick Seite 5 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Mit SEU nun die Teildatei DB2WWW editieren, vorher den Typ auf TXT ändern. Folgender Inhalt ist möglich: Spalten . . . : 1 71 Editieren CGIBIN/INI SEU==> DB2WWW FMT ** ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 0001.00 DTW_SMTP_SERVER 192.168.1.99 0002.00 MACRO_PATH /web;/web/macro 0003.00 INCLUDE_PATH /web;/web/include 0004.00 EXEC_PATH /QSYS.LIB/CGIBIN.LIB Zeile 1 definiert einen SMTP-Server, wenn man mit Net.Data eMails versenden möchte. Sollten Sie die iSeries selbst dafür verwenden, können Sie auch „127.0.0.1“ angeben, dies bedeutet „lokales System“. Die Zeilen 2 und 3 geben an, wo der Befehlsprozessor DB2WWW nach Net.Data-Macrodateien suchen soll. Die vierte Zeile gibt an, wo das Programm DB2WWW zu finden ist (dies kann abweichen von der Einstellung im Webserver, ist aber nicht zu empfehlen). Nun erstellen Sie im IFS im Verzeichnis /web eine Textdatei test01.nd (Endung willkürlich gewählt) mit folgendem Inhalt: %HTML(Hallo) { Hallo! %} Dafür können Sie entweder mit Ihrem PC über den Netserver auf das System zugreifen, oder den seit V4R5 im OS/400 vorhandenen Editor verwenden: EDTF STMF('/WWW/TEST01.ND') Die folgende Adresse im Webbrowser sollte das Wort „Hallo!“ auf den Bildschirm bringen (bitte hier die Adresse Ihrer iSeries angeben!): http://192.168.4.170/cgibin/test01.nd/hallo Was passiert? Net.Data-Makros ruft man also nach folgendem Schema auf: HTTP://(IP-AS400)/logischerordner/scriptname/funktionsblock Ersetzen Sie „(IP-AS400)“ durch den Internet-Namen oder die IP-Adresse Ihrer iSeries. „logischerordner“ ist ein Alias des Webservers, da dieser nie direkt auf einen Ordner im IFS zugreifen sollte. Im oben konfigurierten Beispiel ersetzt der Webserver den von uns angegebenen Pfad „cgibin“ durch den Pfad nach QSYS.LIB/CGIBIN.LIB/DB2WWW.PGM. Somit rufen wir hiermit den Net.DataProzessor auf. Danach folgt mit „scriptname“ der Name unserer Makro-Datei, der dem Net.DataProzessor übergeben wird. Wo der Script-Prozessor danach sucht, wird in der INI-Datei in der Bibliothek CGIBIN angegeben. Der Funktionsblock gibt an, welches %HTML-Konstrukt im Script aufgerufen werden soll. Net.Data – ein Überblick Seite 6 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Net.Data – ein Überblick Seite 7 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Net.Data – Scriptaufbau Hinweise Wie bereits erwähnt sind Net.Data-Scripte einfache Textdateien, die mit jedem Editor (zur Not auch mit EDTF im GreenScreen) bearbeitet werden können. Bei komplexeren Scripts mit vielen eingebundenen HTML-Konstrukten dürfte aber ein komfortablerer Windows-Editor die bessere Wahl sein. Wichtig ist, dass der Editor Zeilennummern anzeigt, das erleichtert die Fehlersuche erheblich! Die Benennung der Textdateien ist beliebig, allerdings sollte man – besonders in Verbindung mit bereits konfigurierten Dateitypen im Webserver – eine noch nicht verwendete Endung nehmen. Die von mir verwendete Endung .ND ist frei gewählt. Sie können auch .NetData als Endung verwenden. Sollten Sie in der Konfiguration des Webservers nicht alle Dateitypen (mit *) freigeben, achten Sie darauf, dass die von Ihnen verwendete Endung aber durchgelassen wird. Bei grösseren Projekten achten Sie bitte darauf, nicht alle Makroblöcke Ihrer Scripts in eine einzige Datei zu packen. Der Net.Data-Prozessor prüft beim Laden und Puffern einer Makrodatei diese komplett, bevor sie ausgeführt wird. Das kann bei grossen Dateien unnötig CPU-Leistung kosten. Besser ist es später, gemeinsame Routinen, Definitionen und Makroblöcke in Include-Dateien zu packen und für einzelne Makrobereiche eigene Dateien zu erstellen. Aufbau Am obigen Beispiel sieht man den simplen, grundlegenden Aufbau eines Net.Data-Makros. Jedes Makro besteht aus einem oder mehreren Blöcken, die mit dem Prozentzeichen % begonnen werden. Nach diesem Zeichen folgt die Angabe, um was für einen Typus von Block es sich handelt. Danach folgt in runden Klammern der Name dieses Blocks, sofern der Typus einen Namen verlangt. Der Inhalt des Blocks schliesslich wird in geschwungenen Klammern eingefügt. Net.Data besteht in den seltensten Fällen auf eine Formatierung, Zeilenumbrüche und Leerzeichen sind Luxus und dienen der Übersicht. Unser Beispiel hätte auch so aussehen können: %HTML(Hallo){Hallo!%} Zusätzliche Leerzeichen werden wie in einem HTML-Dokument ignoriert, sofern sie nicht innerhalb doppelter Anführungszeichen spezifiziert sind, aber an den Webbrowser gesendet (abschaltbar). Experimentieren Sie mit Leerzeichen und betrachten im Browser den Quelltext. Denkaufgabe: Was macht Net.Data aus folgendem Beispiel: %HTML(Hallo) { Hallo Wie geht es Ihnen? %} Und wie sieht es im Browser aus? Net.Data – ein Überblick Seite 8 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Net.Data – ein Überblick Seite 9 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Komplexere Scripts verlangen nach sauberen Kommentierungen, damit der Ablauf nachvollziehbar bleibt. Das Format für einen Kommentar lautet: %{ Ich bin ein Kommentar %} Sie sehen, das Prozentzeichen und die geschwungenen Klammern bilden oftmals eine Einheit. Diese Einheit besteht auch beim oben gezeigten HTML-Block. Hier wird jedoch zwischen % und { qualifiziert angegeben, was für ein Typ Block wir definieren, und wie er benannt wird. Verschachteln ist möglich: %DEFINE { test1 = „Meine Variable“ libnam = „DATALIB“ zeilen = „20“ %} %{ Ein Beispieltext %} %{ unsere Datenbibliothek %} %{ Zeilen pro Seite ausgeben %} Selbstverständlich können wir in einer Datei mehrere %HTML-Blöcke unterbringen. Zum Beispiel: %{ Testscript 2 %} %HTML(Hallo) { Hallo! %} %HTML(Hallo2) { <b>Guten Tag!</b> Wie geht es Ihnen? %} Der Blocktyp „HTML“ lässt darauf vermuten, dass Sie hier HTML-Daten eingeben können. Wie im zweiten Beispiel zu sehen, wurde hier das Tag für Fettschrift eingebaut. Sie können beliebigen HTMLCode in einen HTML-Block einbauen, denn der Inhalt eines HTML-Blocks wird direkt an den HTTPServer und somit an den Client gesendet. Vorher werden selbstverständlich Net.Data-Funktionien ausgeführt. Auch Code für Javascript ist hier denkbar! Um die HTML-Blöcke aufzurufen, ist ein Klick auf einen der folgenden Links nötig: http://192.168.4.170/cgibin/test01.nd/hallo http://192.168.4.170/cgibin/test01.nd/hallo2 Net.Data – ein Überblick Seite 10 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Variables und dynamisches Die Ausgabe statischer HTML-Teile macht Net.Data noch nicht interessant. Wichtig ist uns ja die dynamische Produktion von Web-Seiten. Ein erster Schritt in diese Richtung ist das Verwenden von Variablen. Hier unterstützt uns Net.Data mit vielen Möglichkeiten. Zum Einen kann man globale Variablen definieren, die später im Makro verwendet werden können: %{ Testscript 3 %} %DEFINE{ titel = "Ich bin ein Net.Data-Makro" %} %HTML(start) { Dies ist die Seite: $(titel). %} Ein Net.Data-Script mit Variable. Der Aufruf von http://192.168.4.170/cgibin/test03.nd/start bringt als Ergebnis: Dies ist die Seite: Ich bin ein Net.Data-Makro. Zunächst sehen Sie einen neuen Blocktyp DEFINE, der aber keinen eigenen Namen benötigt. Hiervon können Sie beliebig viele in Ihrer Scriptdatei haben, auch wenn es sinnvoller ist, alle definierten Variablen an einer Stelle zu beschreiben, also zu gruppieren. Nun wird die Variable titel mit einem Inhalt festgelegt. Wie Sie sehen, wird keine Typisierung vorgenommen. Variablen sind in Net.Data ohne Typ, also ohne Unterscheidung zwischen Alpha oder numerisch! Die Umwandlung erledigt der Scriptprozessor je nach Aufruf automatisch. In HTML-Block start wird wieder nur ein Text ausgegeben, allerdings wird innerhalb unseres Textes die Variable titel aufgelöst und deren Inhalt dem Browser zugesendet. Beachten Sie, dass die Referenzierung auf die Variable mit einem Dollarzeichen $ beginnt und der Name der Variablen in runden Klammern stehen muss! Ein Name für eine Variable muss mit einem Buchstaben oder dem Unterstrich beginnen und kann daneben auch Ziffern, Punkte (.) sowie das Gatter (#) beinhalten. Ausserdem wird bei Variablennamen zwischen Gross- und Kleinschreibung unterschieden, sofern nicht ein Datenbankfeld im Format V_feldname referenziert wird. Dies ist leider eine grosse Stolperfalle, da man den Fehler auf den ersten Blick nicht findet. Hier hilft eine gewisse Disziplin bei der Benennung von Variablen. Es empfiehlt sich, ein festes System von Gross- und Kleinbuchstaben zu verwenden! Net.Data – ein Überblick Seite 11 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Das folgende Script: %{ Testscript 4 %} %DEFINE{ titel = "Ich bin ein Net.Data-Makro" Titel = "Das ist ein Untertitel" %} %HTML(start) { Dies ist die Seite: $(titel) mit dem Untertitel $(Titel). %} Vorsicht Falle! ergibt die Ausgabe: Dies ist die Seite: Ich bin ein Net.Data-Makro mit dem Untertitel Das ist ein Untertitel. Es bleiben keine Fragen offen... Man kann Variablen auch dynamisch referenzieren, sprich, den Namen der gewünschten Variable auch aus dem Inhalt einer anderen Variable zusammensetzen. Das sieht so aus: %{ Testscript 5 %} %DEFINE{ morgen = "Morgen!" abend = “Abend!“ zeit = "morgen" tag1 = "Montag" tag2 = "Dienstag" tag3 =" Mittwoch" heute = "2" %} %HTML(start) { Hallo und guten $($(zeit)) Es ist $(tag$(heute)). %} Relative Variablenreferenz – nicht verwirren lassen! Die Ausgabe lautet: Hallo und guten Morgen! Es ist Dienstag. Als erste Variablenreferenz wird der Inhalt der Variable zeit ermittelt. Nun wird das Ergebnis „morgen“ als Variablenname zur Ausgabe verwendet. Der Inhalt von morgen ist „Morgen!“. In der zweiten Referenz wird ein Variablenname zusammengesetzt aus tag sowie dem Inhalt von heute (2). Somit wird der Inhalt der Variablen tag2 ausgegeben. Das ist praktisch, aber man sollte es nicht übertreiben, sonst hilft auch die beste Dokumentation nicht mehr! Net.Data – ein Überblick Seite 12 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Neue Funktionen und Variablenreferenzen Im folgenden Beispiel wird eine Zählervariable wochentag verwendet, um vier Tage durchzuzählen und deren Namen auszugeben: %{ Testscript 6 %} %DEFINE{ tag1 = "Montag" tag2 = "Dienstag" tag3 =" Mittwoch" tag4 = "Donnerstag" %} %HTML(start) { @DTW_ASSIGN(wochentag,"1") %WHILE(wochentag <= "4") { Tag ist $(tag$(wochentag)). <br> @DTW_ADD(wochentag, "1", wochentag) %} %} Die Ausgabe lautet: Tag Tag Tag Tag ist ist ist ist Montag. Dienstag. Mittwoch. Donnerstag. Zunächst kommt ein Funktionsaufruf DTW_ASSIGN. Das voranstehende Zeichen @ zeigt einen Funktionsaufruf an. Dieser Aufruf dient dazu, einer Variablen einen Wert zuzuweisen. Beachten Sie, dass auch numerische Werte in Anführungszeichen stehen müssen! Übrigens ist die hier definierte Variable wochentag eine lokale Variable, da sie nicht ausserhalb des HTML-Blocks start definiert wurde. Die Referenz auf wochentag in einem anderen HTML-Block wird kein Ergebnis herbeiführen. Es folgt eine WHILE-Schleife, die auch ein Funktionsblock darstellt, wie durch die Klammerung innerhalb %{ und %} verdeutlicht. Die Schleife wird aufgerufen, solange wochentag kleiner/gleich dem Wert „4“ ist. Innerhalb dieser Schleife wird dynamisch ein Variablenname aus dem festen Text tag und dem Inhalt von wochentag zusammengesetzt. Dann wird der Wert der so ermittelten Variable ausgegeben. Zuletzt wird mit der Funktion @DTW_ADD der Wert von wochentag um eins erhöht. Wie Sie sehen, beginnt der Name einer internen Net.Data-Funktion stets mit dem Klammeraffen (@). Sie können den Funktionsnamen auch in Kleinbuchstaben schreiben, ich verwende auf Grund der besseren Lesbarkeit hier Grossbuchstaben. Im Gegensatz zu Variablen gibt es bei Funktionsnamen keine Unterscheidung zwischen GROSSkleinschreibung. Schauen Sie sich diese Beispiele genau an, nach der ersten Verwirrung wird sich herausstellen, dass man hiermit sehr flexibel Variablen und Werte ermitteln kann. Puristen werden zu Recht aber davor warnen, von diesen Möglichkeiten zu sehr Gebrauch zu machen. Net.Data – ein Überblick Seite 13 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Fehlersuche – ein Intermezzo Tippfehler sind schneller gemacht als gefunden, und gerade beim Einstieg in die für viel Cobol- oder RPG-Programmierer ungewohnte Umgebung und Syntax von Net.Data-Scripten ist ein einzelnes Zeichen am falschen Ort schwer zu finden, ob es nun fehlt oder zu viel geschrieben wurde. Logikfehler oder Tippfehler, die einen Logikfehler zur Folge haben, lassen sich finden, wenn man sich einige Regeln zum strukturierten Schreiben des Makros erstellt und diese strikt einhält. Nehmen wir als Basis für unsere konstruierten Fehler das Testscript 6. Abbildung 1 - Script 6a - ein Fehler in Zeile 13 Es läuft nicht richtig, der Webbrowser zeigt folgende Ausgabe: WHILE(wochentag <= "4") { Tag ist Montag. NET.DATA Fehler: Falsches Symbol (%}) in Zeile 18 der Datei /web/test06.nd gefunden. Sucht man jetzt im Editor (der hoffentlich Zeilennummern anzeigt) in Zeile 18 nach einem Fehler, wird man hier nicht fündig. Es handelt sich um die letzte Zeile mit dem Abschluss des HTML-Blockes durch %}. Der Script-Prozessor bemängelt, dass er an dieser Stelle diese Blockbeendigung nicht erwartet hat. Beginnen wir die Analyse am Anfang des HTML-Blockes (Fehler innerhalb der Definitionen darüber werden vor Ausführung des aufgerufenen HTML-Blockes erkannt): Der Block wird mit der geschwungenen Klammer in Zeile 11 korrekt geöffnet. In Zeile 12 findet sich die Funktion @DTW_ASSIGN zur Festlegung eines Variablenwertes. Schon in Zeile 13 stolpern wir in die Falle! Hier fehlt vor der Schleifenkonstruktion WHILE das zum Öffnen des Blocks nötige Prozentzeichen %. Somit wird es von Net.Data nicht als interne Funktion (Start mit @), Variablenname (Start mit $) oder Konstrukt (Start mit %) erkannt und als reiner Text ausgegeben. Daher interpretiert Net.Data die Zeile 17 als Beendigung des HTML-Blocks und beschwert sich über die überflüssige Zeile 18. Net.Data – ein Überblick Seite 14 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Korrigieren Sie bitte diesen Fehler, und produzieren Sie einen anderen. Löschen Sie in Zeile 16 das Zeichen @ zur Markierung einer Funktion. Ihr Browser und Ihre iSeries werden es Ihnen nicht danken, vielleicht ahnen Sie, was passiert. (Bitte brechen Sie das laden des Makros nach einigen Sekunden ab und beachten Sie das System!) Net.Data – ein Überblick Seite 15 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Datenzugriffe per SQL Das wichtigste und interessanteste Kapitel von Net.Data ist mit Sicherheit der Zugriff auf Datenbanken. Hier liegt ja auch der Hauptzweck einer Scriptsprache für einen Webserver: das dynamische Präsentieren von Daten aus einer Datenbank. Vorbereitung Net.Data macht uns die Sache relativ leicht. Bevor wir allerdings loslegen können, müssen wir sicherstellen, dass das System uns die Daten auch besorgen kann. Da Net.Data die iSeries als beliebige RDB (relational DataBase) anspricht, und diese Datenbank nicht zwingend die gleiche iSeries sein muss, auf der auch der Webserver läuft, müssen wir sicherstellen, dass das Net.Data ausführende System Zugriff auf eine RDB hat, und sei es die lokale Maschine. Geben Sie im grünen Bildschirm folgenden Befehl ein: WRKRDBDIRE (work with rdb directory entries) Hier sehen wir, welche RDB-Datenbanken unsere iSeries kennt. Je nach verwendeter Version von OS/400 (oder neu: i5/OS) ist hier ein Eintrag für das lokale System bereits vorhanden. Falls nicht, muss ein Eintrag hinzugefügt werden. Geben Sie dann als Name für die relationale Datenbank die Seriennummer Ihres Systems (oder einen anderen eindeutigen Namen) ein. Es empfiehlt sich der Systemname, wie er von DSPNETA angezeigt wird. Der Name oder die Adresse des fernen Standorts muss *LOCAL lauten, die Art ist beliebig. Nun steht den Zugriffen nichts mehr im Wege. Erste Auswahl von Daten Nehmen wir an, auf unserer iSeries liegt in der Bibliothek DATEN eine Adressdatei namens ADRESS. Diese enthält hoffentlich ein paar Sätze und hat beispielsweise folgenden Aufbau: Feld ADRNAME ADRSTR ADRPLZ ADRORT ADRZUS ADRVOR ADRNUM Datei ADRESS ADRESS ADRESS ADRESS ADRESS ADRESS ADRESS Art CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER Länge 60 40 5 35 20 15 25 Der Einfachheit halber sind hier alle Felder vom Typ „Character“, die Länge übersichtlich. Ein warnendes Wort am Anfang: In der Regel (wenn wir also nichts Gegenteiliges angeben), liefert eine SQL-Abfrage in einem Net.Data-Script alle Ergebniszeilen. Das kann je nach Abfrage und Grösse der Datenbank zu einem sehr umfassenden Dokument führen, zu dessen Erstellung die iSeries sehr viel Arbeit verrichten muss. Daher ist es (wie bei jeder SQL-Abfrage) unerlässlich, dass alle Tabellen Indizes für Selektionsfelder haben, und Ihre Abfrage entweder durch einen Umgebungswert eingegrenzt werden (siehe später), oder Sie wenige Daten in der Abfrage selektieren. Net.Data – ein Überblick Seite 16 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Betrachten Sie folgendes Script: %{ Test 07 - Erste Datenausgabe %} %DEFINE RPT_MAX_ROWS="100" %FUNCTION(DTW_SQL) lst_adr() { SELECT * FROM DINFO.ADRESS WHERE ADRNUM LIKE '1%' %} %HTML(start) { Es folgt eine Liste aller Adressen wobei ADRNUM mit 1 anfangen soll:<br> @lst_adr() %} Testscript 7 – mit Satzbegrenzung Zuerst definieren wir eine Variable. In diesem Falle ist RPT_MAX_ROWS eine Systemvariable (siehe Net.Data-Referenz). Diese definiert, wie viele Zeilen in einem Report maximal zurückgegeben werden sollen. Danach definieren wir eine eigene Funktion. Dies geschieht mit dem Blockbeginn %FUNCTION. Wir müssen bei der Definition einer Funktion angeben, in welche Sprachenumgebung sie gehört. Net.Data unterstützt viele verschiedene Sprachen, darunter auch SQL. Der Name der Sprachumgebung (den wir in der Funktionsdeklaration angeben müssen) lautet für SQL in Net.Data daher: „DTW_SQL“. Nach der Angabe der Sprachumgebung folgt der Name unserer Funktion. Hier ist ein striktes Einhalten einer Namenskonvention von Vorteil, damit man diese Funktionen später schnell im Quellcode auffindet. Darauffolgend müssen in runden Klammern eventuelle Ein- und Ausgabeparameter für die Funktion definiert werden. Haben wir keine (wie im ersten Beispiel), müssen die Klammern trotzdem angegeben werden. Schliesslich beginnen wir den Funktionsblock mit der offenen geschwungenen Klammer. Der Hauptblock einer Funktion besteht aus mehreren Teilen: • • • • dem so genannten inline statement-Block, der Befehle in der gewünschten Sprachumgebung enthält, dem exec-Block, mit dem man externe Programmcodes ausführen kann, dem report-Block, der definiert, was auf welche Art mit eventuellen Ergebnissen des inline-statementBlockes passieren soll, und schließlich dem message-Block. Alle diese Blockarten können, müssen aber nicht in einem Funktionsblock vorkommen. Je nach gewünschtem Ergebnis müssen wir einige davon verwenden. Die Reihenfolge wie oben aufgezählt ist jedoch einzuhalten! Wir haben in unserem ersten Beispiel nur einen inline statement-Block, der eine SQL-Selektion aus unserer Beispieltabelle darstellt. Das SQL-Statement wird ohne weitere Kennzeichnung eingegeben, die Formatierung ist beliebig. Nach dieser SQL-Abfrage wird der Block der Funktionsdefinition beendet. Net.Data – ein Überblick Seite 17 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Da jedes Net.Data-Makro nur über einen HTML-Block aufgerufen werden kann, definieren wir noch schnell einen solchen mit dem Namen „start“. In diesem Block wird neben einem Titel nur unsere selbst definierte Funktion aufgerufen. Das Ergebnis ist abhängig von der Datenbank eine einfache Tabelle mit den selektierten Daten. Net.Data verwendet hier eine vorgegebene Formatierung, die zwar praktisch, aber nicht wirklich schön anzusehen ist. (Über notwendige Indexierung wird hier jetzt nicht verhandelt :-) Verfeinerung der Ausgabe Um eine schönere Formatierung des Reports zu erhalten, müssen wir den Report komplett selbst gestalten und HTML-Befehle einbauen, die eine Tabelle und vielleicht ein paar andere Schriftformatierungen produzieren. Net.Data ermöglicht es uns, auch in einem Funktions-Block HTML-Befehle wie in einem normalen HTML-Block zu verwenden. Hierfür gibt es den report-Teil. Betrachten Sie bitte folgende Version unserer Funktion: %FUNCTION(DTW_SQL) lst_adr() { %DEFINE RPT_MAX_ROWS="100" SELECT * FROM DINFO.ADRESS WHERE ADRNUM LIKE '1%' %REPORT { Reporttitel:<br> %ROW { Name: $(V1)<br> %} %} %} Script 7a – mit eigener Ausgaberoutine Nach dem inline-statement, also dem SQL-Befehl, starten wir einen %REPORT-Block innerhalb unserer Funktion. Durch Definition dieses Report-Blocks schalten wir die automatische Tabellenausgabe von Net.Data komplett aus. Daher müssen wir uns jetzt selbst um die gesamte Ausgabe der Tabelle und der Daten kümmern, sonst bleibt der Bildschirm leer! Der Inhalt des Report-Blocks wird ausgeführt, bevor auch nur eine einzige Zeile an Ergebnisdaten ausgegeben wird. Daher ist es die ideale Stelle, um eine Überschrift für die Tabelle, und vielleicht auch ein paar Spaltenüberschriften zu produzieren. Um den Leser jetzt nicht mit zu viel Informationen über HTML zu erschlagen, wird diese Selektion schrittweise aufgebaut: Nach dem Beginn des %REPORT-Blocks verfährt Net.Data mit der Interpretation wie in einem bekannten HTML-Block. Buchstaben, die wir schreiben, werden ausgegeben und an den Browser gesendet, sofern sie nicht mit einem der bekannten Sonderzeichen (%, $, @) für eine Net.Data-interne Behandlung beginnen. Somit wird „Reporttitel:“ ausgegeben. Das folgende <br> ist eine HTML-Funktion für den Zeilenumbruch. Sie wird von Net.Data wie geschrieben an den Browser gesendet. Dieser interpretiert dies als „beginne eine neue Zeile“. Denn auch die Seitenbeschreibungssprache HTML (die Ausgabe unserer Net.Data-Scripte wird wie eine HTML-Datei behandelt) ignoriert Leerzeichen und Zeilenumbrüche, wenn wir sie nicht explizit angeben. Auf die Ausgabe von Spaltenüberschriften habe ich im ersten Beispiel verzichtet. Innerhalb des %REPORT-Blockes kann man (muss aber nicht!) den %ROW-Block angeben. Dieser wird für jede Ergebniszeile unserer SQL-Abfrage ausgeführt. Somit muss man hier definieren, was mit einer Net.Data – ein Überblick Seite 18 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick einzelnen von SQL gefundenen Zeile geschehen soll. Hier können wir Daten aus der Ergebniszeile an den Browser senden, oder weitere Verarbeitungen durchführen. Lassen Sie sich überraschen! In unserem ersten Beispiel geben wir für jede Zeile den Text „Name: „ aus. Danach folgt die Referenz auf eine Variable. Hier sehen wir eine Besonderheit von Net.Data-Variablen: Der inline-Befehl SELECT * FROM ... liefert uns alle Felder in der Datenbankdatei zurück, und zwar in der Reihenfolge, wie sie beim Erstellen der Datei angelegt wurden. Die Variablenreferenz $(Vn) (wobei n für eine Zahl steht) bedeutet, dass Net.Data das n-te Feld aus der Ergebnisliste suchen und dessen Inhalt ausgeben soll. Dies ist zwar praktisch, aber dumm, wenn wir nicht sicher sind, dass das erste Feld in der Ergebnisliste immer das Namensfeld ADRNAM aus unserer Tabelle ist. Oder haben Sie die Reihenfolge Ihrer Datenbankstruktur im Kopf? ;-) Da wir uns gleich einen sauberen Arbeitsstil angewöhnen wollen (wer kennt nicht die Problematik, dass eine Tabelle neu aufgebaut werden musste und hierbei ein paar Felder in der Reihenfolge vertauscht wurden), und Sie in RPG oder Cobol auch in der Regel die Felder über ihre Namen ansprechen, verwenden wir folgende Syntax: %ROW { Name: $(V_ADRNAME)<br> %} Net.Data bietet uns innerhalb des %ROW-Blocks die Möglichkeit, alle selektierten Felder über ihren Namen mit vorangestelltem V_ anzusprechen. Beachten Sie hierbei bitte, dass Sie alles in Großbuchstaben schreiben müssen! Nun schauen wir uns noch schnell an, wie in HTML eine Tabelle produziert wird, dann können wir die Ausgabe unserer Adressliste optisch verfeinern. Net.Data – ein Überblick Seite 19 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Kleiner Exkurs – HTML-Tabellen Die Seitenbeschreibungssprache HTML ist durch so genannte Tags strukturiert. Ein solches Tag ist ein in eckigen Klammern gefasstes Schlüsselwort, welches eine HTML-Definition beginnt oder beendet. Oben haben wir bereits ein solches Tag kennengelernt: <br> (es ist zugleich auch eine Ausnahme, denn es steht alleine und umklammert keinen Definitionsbereich. Eine Tabelle beginnt man in HTML mit <TABLE> und beendet diese später mit </TABLE>. Innerhalb dieser Definition kann man beliebig oft mit <TR> eine Tabellenreihe beginnen und mit </TR> beenden. Und wiederum innerhalb dieser Tabellenreihen kann man beliebig oft mit <TD> ein Tabellendatenfeld beginnen und mit </TD> beenden. Wir müssen aber beim Tag <TABLE> zusätzlich eine Option angeben, damit der Rahmen auch sichtbar ist, im Standard stellen viele Browser eine HTML-Tabelle formatiert, aber ohne Rahmen dar, was für unseren Zweck nicht wünschenswert ist. Betrachten wir folgenden HTML-Code (die Formatierung ist nur der Optik eingebaut): <TABLE border=“1“> <TR> <TD>Spalte 1</TD><TD>Spalte 2</TD> </TR> <TR> <TD>Feld 1</TD><TD>Feld 2</TD> </TR> <TR> <TD>noch ein Feld</TD><TD>wieder ein Feld</TD> </TR> </TABLE> Somit erhalten wir als Ergebnis im Browser ungefähr: Spalte 1 Spalte 2 Feld 1 Feld 2 noch ein Feld wieder ein Feld Nun müssen wir diese HTML-Tags „nur noch“ in unser Net.Data-Makro einbauen. Dies ist an sich gar nicht schwierig. Wir wissen, dass direkt nach Beginn des %REPORT-Blocks und vor dem %ROW-Block Texte und Befehle folgen, die den Tabellenkopf ausmachen. Somit müssen wir das Script wie folgt modifizieren: %REPORT { <TABLE border=“1“> <TR><TD>Name</TD><TD>Nummer</TD></TR> %ROW { ... Net.Data – ein Überblick Seite 20 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Somit wird eine HTML-Tabelle begonnen, und eine neue Zeile mit zwei Tabellenelementen ausgegeben. Nun können wir im %ROW-Block für jede Datenzeile eine Tabellenzeile mit den Datenfeldern ausgeben: %ROW { <TR><TD>$(V_ADRNAME)</TD><TD>$(V_ADRNUM)</TD></TR> %} Hier werden die beiden über den Namen referenzierten Felder in eine Tabellenreihe und jeweils in Tabellenfelder eingebettet. Nun muss nur noch die Tabelle sauber geschlossen bzw. beendet werden. Dies kann zwischen dem Ende des %ROW-Blocks und dem Ende des %REPORT-Blocks erledigt werden, denn auch hier dürfen Daten stehen: Somit sieht unser gesamtes Script wie folgt aus: %{ Test 08 - Datenausgabe %} %DEFINE RPT_MAX_ROWS="100" %FUNCTION(DTW_SQL) lst_adr() { SELECT * FROM DINFO.ADRESS WHERE ADRNUM LIKE '0%' %REPORT { <TABLE BORDER="1"> <TR><TD>Name</TD><TD>Nummer</TD></TR> %ROW { <TR><TD>$(V_ADRNAME)</TD><TD>$(V_ADRNUM)</TD></TR> %} </TABLE> %} %} %HTML(start) { Eine Adressliste:<br> @lst_adr() %} Aufbauend auf dieses Script werden wir jetzt Parameter und die Parametrisierung der SQL-Abfragen kennenlernen. Wir bauen das Script um, so dass die Funktion @lst_adr einen Eingabeparameter erhält und diesen zur Selektion nach dem Feld ADRNAME verwendet. Net.Data – ein Überblick Seite 21 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Parameter in Funktionen Mit Parametern und Funktionen kann man sein Script auf schnelle Art und Weise sehr flexibel gestalten. Im ersten Schritt übertragen wir unserer Funktion @lst_adr einen Suchwert, nach dem im Feld ADRNAM selektiert werden soll. Im nächsten Schritt werden wir den gesamten SQL-Befehl aus Parametern aufbauen. Betrachten Sie die folgenden Zeilen: %{ Test 09 - Datenausgabe mit Parameter %} %FUNCTION(DTW_SQL) lst_adr(IN xsuchenummer) { SELECT * FROM DINFO.ADRESS WHERE ADRNAME LIKE '$(xsuchenummer)' %REPORT { <TABLE BORDER="1"> <TR><TD>Name</TD><TD>Nummer</TD></TR> %ROW { <TR><TD>$(V_ADRNAME)</TD><TD>$(V_ADRNUM)</TD></TR> %} </TABLE> %} %} %HTML(start) { @lst_adr("Maier%") %} Script 9 – Suche mit festem Parameter In der dritten Zeile habe ich die Definition der Funktion erweitert. Nach dem Funktionsnamen folgt nun in den Klammern das Schlüsselwort IN sowie ein Variablenname. Dies bedeutet, dass die Funktion nun einen Eingabeparameter verlangt und den übergebenen Wert in der lokalen Variable xsuchenummer bereitstellt. Diese Variable wird nun im SQL-Befehl als Selektionswert für die LIKE-Selektion verwendet. Beachten Sie, dass Sie bei alphanumerischen Feldern in Ihrer SQL-Tabelle die Variablenreferenz weiterhin in einfachen Anführungszeichen (nach SQL-Konvention) setzen müssen. Beim Auflösen der Referenz erkennt Net.Data sonst nicht den Feldtyp und wird den Inhalt von xsuchenummer als Feldname interpretieren! Die nächste Änderung besteht im HTML-Block in der Verwendung eines festen Parameters beim Aufruf unserer Funktion @lst_adr. Hier könnten Sie selbstverständlich auch eine Variable verwenden, z.B. @DTW_ASSIGN(suchwert, „Maier%“) @lst_adr($(suchwert)) Script 9a – Parameter aus einer Variablen Prüfen Sie das Ergebnis! Net.Data – ein Überblick Seite 22 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Ändern Sie danach den Aufruf der Funktion, so dass garantiert kein Ergebnis zurückgeliefert wird: @lst_adr(„KeinMensch%“) Script 9a – Keine Sätze gefunden, mit oder ohne Fehlermeldung? Das Ergebnis sieht gefährlich aus, ist es aber nicht: Name Nummer NET.DATA DTW_SQL Fehler: Funktion lst_adr: Warnung während Operation FETCH. (SQLSTATE 02000, SQLCODE 100) Hiermit sagt uns Net.Data, dass bei der Ausführung des SQL-Befehls etwas nicht perfekt gelaufen ist. Die Angabe SQLCODE ist eine Fehlernummer, die man in der Net.Data-Referenz nachlesen kann. Für Eilige: SQLCODE 100 bedeutet: keine Sätze gefunden (was ja unser Ziel war). Fehler? Vermeiden oder abfangen! Wie können wir nun eine solche Fehlermeldung abfangen? Es sieht ja reichlich unprofessionell aus, wenn man für den Anwender einen Selektionsbildschirm programmiert, eine Selektion ohne Ergebnis aber eine solch rüde Meldung produziert. Ausserdem wird man dann als Programmierer durch einen vermeidbaren Telefonanruf gestört. Hierfür gibt es innerhalb des Funktions-Blocks den message-Block. Hiermit kann man bestimmte Fehlernummern oder Fehlerbereiche abfangen und darauf reagieren. Sei es, dass eine freundlichere Fehlermeldung ausgegeben wird, oder man eine spezielle Statusvariable belegt, die man im weiteren Script abfragt oder einfach nichts macht. Sobald für eine auftretende Fehlernummer im message-Block eine Behandlungsroutine eingebaut wurde, erscheint die obige Net.Data-Fehlermeldung nicht mehr. Fügen wir also nach dem Abschluss des %REPORT-Blocks folgende Zeilen ein: %MESSAGE{ 100 : { keine Sätze gefunden! %} %} : continue Script 9b – kein Problem mit dem Fehler Es wird ein neuer Block vom Typ %MESSAGE innerhalb des Funktionsblocks angefangen. Nun kann man einen oder mehrere Einträge mit Fehlernummern oder Nummernbereiche definieren. Gefolgt von einem Doppelpunkt und einer einzelnen geschwungenen Klammer auf folgt nun für den spezifizierten Fehler eine Aktion. Sei es – wie im Beispiel – dass nur ein Text ausgegeben wird, oder tiefgreifendere Operationen wie dem Aufruf einer anderen Funktion. Nach Abschluss dieses Teils und einem weiteren Doppelpunkt kann angegeben werden, ob das Makro trotzdem fortgesetzt werden soll (CONTINUE), oder sofort beendet wird (EXIT). Beenden Sie auch diesen %MESSAGE-Block sauber mit %}, sonst kommt es zu wüsten Fehlermeldungen bei der Interpretation des Makros! Beachten Sie weiterhin, dass nach der Fehlernummer un dem Doppelpunkt kein einleitendes Prozentzeichen folgt. Net.Data – ein Überblick Seite 23 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Mehr Spaß mit Variablen und Parametern Funktionen sind nicht nur zur reinen Ausgabe da, sondern auch, um Werte zu ermitteln und diese an das Hauptscript zurückzugeben. Man sollte im Rahmen der Modularität versuchen, in Funktionen so wenig wie möglich feste Texte und direkte Ausgaben unterzubringen, das macht die Wiederverwendbarkeit einfacher. Wir passen unser Demoprogramm nun so an, dass es zu einer gesuchten Anschlussnummer den Namen ermittelt und diesen als Rückgabevariable der aufrufenden Routine zurückgibt. Siehe den Quellcode für Testscript 10: %{ Test 10 - Datensuche und Rückgabe %} %FUNCTION(DTW_SQL) get_adr(IN xsuchenummer) RETURNS(xname) { SELECT * FROM DINFO.ADRESS WHERE ADRNUM = '$(xsuchenummer)' %REPORT { %ROW { @DTW_ASSIGN(xname, $(V_ADRNAME)) %} %} %MESSAGE{ 100 : { @DTW_ASSIGN(xname, "!null!") %} : continue %} %} %HTML(start) { @DTW_ASSIGN(telefonnummer,"73300") @DTW_ASSIGN(ergebnis,@get_adr(telefonnummer)) Die Nummer $(telefonnummer) ist vergeben an $(ergebnis). %} Script 10 – Suche und Ergebnisrückgabe Zunächst ist unsere Funktion (die nun @get_adr heisst) erweitert. In der Definition wird mit dem Schlüsselwort RETURNS() angegeben, dass die Funktion nun einen Rückgabewert hat, der am Ende der Funktion aus der lokalen Variablen xname geholt wird. Diese Variable muss während der Funktionsausführung einen Wert erhalten, sonst kann es zu interessanten Ergebnissen kommen. Im %REPORT-Block sind alle Textausgaben verschwunden. Dafür wurde im %ROW-Block eine Variablenzuweisung vorgenommen, die unserer Ergebnisvariablen xname den Inhalt des Datenbankfelds ADRNAME zuweist. Vorsicht! Wenn das Ergebnis des SQL-Befehls mehrere Zeilen enthält, wird der Variablen der Feldwert der letzten Datenzeile zugewiesen. Diese Methode sollte nur angewandt werden, wenn nach eindeutigem Index gesucht wird! Im %MESSAGE-Block wird auch kein Hinweistext bei nicht gefundenen Daten ausgegeben, sondern unsere Ergebnisvariable erhält einen von mir gewählten Spezialwert, den wir später auswerten können. Der %HTML-Block start wurde nun etwas erweitert. Es wird einer Variablen telefonnummer ein Wert zugewiesen (später erledigen wir das mit einem HTML-Eingabeformular). Danach wird in einer weiteren Zuweisung der Aufruf unserer Funktion @get_adr als Zuweisungswert für die Variable ergebnis verwendet. Danach folgt eine einfache Ausgabe. Net.Data – ein Überblick Seite 24 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Übrigens muss im Funktionsaufruf die Variablenreferenz auf telefonnummer nicht zwingend mit einem Dollarzeichen und in Klammern gekapselt werden. Net.Data erwartet an dieser Stelle entweder einen Variablennamen oder einen in doppelten Anführungszeichen stehenden Text. Da wir keine Anführungszeichen verwendet haben, reicht der Variablenname. Unsere Funktion hat einen Rückgabewert, der im Net.Data-Quellcode während der Interpretation automatisch eingesetzt wird. Somit könnten wir auch folgendes im HTML-Block schreiben: Die Nummer $(telefonnummer) ist vergeben an @get_adr(telefonnummer). Das Ergebnis ist jeweils das Gleiche: Die Nummer 73300 ist vergeben an xxxxxxxxx Was passiert, wenn wir kein Ergebnis haben? Ändern Sie die Variablenzuweisung für telefonnummer von „73300“ auf einen nicht in der Datenbank existierenden Wert wie zum Beispiel „73300x“ (jaja, üblicherweise wäre das Feld "Telefonnummer" numerisch definiert...) Das Ergebnis ist erwartungsgemäß, aber noch nicht schön: Die Nummer 73300x ist vergeben an !null!. Hier greift nun der %MESSAGE-Block und weist der Rückgabevariablen meinen Spezialwert zu. So etwas wollen wir aber einem Anwender nicht zumuten. Lieber werten wir den Rückgabewert aus. Dafür gibt es %IF-Blöcke, die wir an fast jeder Stelle im Net.Data-Script einsetzen können. Ändern wir unser Testscript (es ist jetzt die 11. Version) den HTML-Block wie folgt ab: %HTML(start) { @DTW_ASSIGN(telefonnummer,"73300x") @DTW_ASSIGN(ergebnis,@get_adr(telefonnummer)) %IF($(ergebnis) != "!null!") Die Nummer $(telefonnummer) ist vergeben an $(ergebnis). %ELSE Die Nummer $(telefonnummer) ist nicht vergeben! %ENDIF %} Script 11 – Schönere Fehlermeldungen. Nach dem Aufruf der Funktion @get_adr wird nun das Ergebnis geprüft. Sie sehen zum Einen, dass in einem %IF-Block die Ergebnisabfrage geklammert sein muss, und zum Anderen der Vergleichsoperator für „ungleich“ als != notiert wird. Nun folgt je nach positivem oder negativem Ergebnis eine Ausgabe. Beachten Sie die gezeigte Syntax, die Ausführungsblöcke für positiven oder negativen Vergleich werden nicht in Klammern oder ähnlichem gekapselt. Bei grösseren Blöcken kann dies schnell unübersichtlich werden. Arbeiten Sie daher mit Einrückungen! Leerzeichen stören nicht. Net.Data – ein Überblick Seite 25 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Global denken – lokale Variablen vermeiden Noch ein Hinweis am Rande: Die Zeichenkette mit dem speziellen Wert „!null!“ kommt zwei mal im Quelltext vor. Dies ist unfein und eine Fehlerquelle, falls Sie diesen Wert ändern wollen. Besser ist die globale Definition einer Variable zu Beginn der Skriptdatei: %DEFINE UNBEKANNT = „!UNBEKANNT!“ sowie die Verwendung dieser Variablen an allen Stellen im Programmtext, z.B. : %IF($(ergebnis) != $(UNBEKANNT)) sowie %MESSAGE{ 100 : { @DTW_ASSIGN(xname, $(UNBEKANNT)) %} : continue %} Script 12 – Modulare Fehlerabfrage :) Eingabefelder in HTML Damit ein Benutzer Daten eingeben kann, die in einem Net.Data-Macro verwendet werden können, folgt hier eine sehr grobe Übersicht zum Thema Formulare in HTML: Ein Formular ist eine Sammlung von Eingabefeldern und Interaktionsknöpfen, die mit HTML definiert werden können. Es bietet die Möglichkeit, vom Browser Benutzerdaten an den Server zu senden. Dies kann verwendet werden, um zum Beispiel ein Eingabefeld für die gesuchte Telefonnummer zu bieten, sowie einen Absendeknopf (so etwas wie Datenfreigabe per Mausklick). In HTML beginnt man ein Formular mit dem Tag <FORM>. In diesem Tag müssen zwei Parameter angegeben werden: method als Methode, wie die Daten an den Server gelangen (in unseren Beispielen immer „POST“I, sowie action, eine Angabe, welches Script und welcher HTML-Block nach dem Absenden durch den Benutzer aufgerufen werden sollen. Hier ein Beispiel für ein <FORM>-Tag: <FORM method=“POST“ action=“/cgibin/test13.nd/suche“> Nun kann man ein oder mehrere Eingabefelder definieren. Dies geschieht mit dem Tag <INPUT>. Auch hier gibt es diverse Parameter, die das Verhalten und Aussehen des Eingabefeldes bestimmen. Wichtig sind hier type (Angabe des Daten- und Feldtyps), name (Angabe des Feldnamens, unter diesem Namen ist der Feldinhalt als Variable nach dem Absenden auch im Net.Data-Macro bekannt), size (Länge des Eingabefeldes) und eventuell value (Vorbelegung des Eingabefelds mit einem bestimmten Wert). I Die Methode "GET" wäre besser, da hierbei die Namen und Inhalte der Formularfelder nicht in der Adressleiste erscheinen. Für den Einsteiger ist "POST" aber einfacher zu verstehen. Net.Data – ein Überblick Seite 26 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Hier ein einfaches Beispiel: <INPUT TYPE="text" name="telefonnummer" size="20"> Hier wird ein Text-Eingabefeld mit dem Namen telefonnummer und der Eingabelänge 20 Zeichen definiert. Nun brauchen wir noch einen Knopf zum Absenden des Formulars an den Server: <INPUT type="submit" value="Suche"> Der Typ „submit“ bedeutet „Absenden“. Als value wird die Beschriftung des Knopfes angegeben. Nun wird das Formular mit </FORM> beendet. In unserem Script wird der HTML-Block „start“ wie folgt aufgebaut: %HTML(start) { <B>Welche Telefonnummer wird gesucht?</B> <FORM action="/cgibin/test13.nd/suche" method="POST"> <INPUT TYPE="text" name="telefonnummer" size="20"> <INPUT type="submit" value="Suche"> </FORM> %} Script 13 – Eingabe und Suche Nach der Ausgabe eines Textes zur Abfrage der Telefonnummer wird das oben beschriebene Formular dargestellt. Sendet der Benutzer mit dem Knopf die Daten ab, wird der HTML-Block „suche“ in unserer Macro-Datei aufgerufen und der Inhalt des Eingabefelds „Telefonnummer“ übermittelt. Dies erledigt der Webbrowser für uns automatisch, und Net.Data kümmert sich um die Bereitstellung der Variablen. Wir können also im HTML-Block „suche“ einfach auf „telefonnummer“ zugreifen: Die folgenden Zeilen dürften bekannt vorkommen: %HTML(suche) { Suche nach $(telefonnummer)...<br> @DTW_ASSIGN(ergebnis,@get_adr(telefonnummer)) %IF($(ergebnis) != $(UNBEKANNT)) Die Nummer $(telefonnummer) ist vergeben an $(ergebnis). %ELSE Die Nummer $(telefonnummer) ist nicht vergeben! %ENDIF %} Schon haben wir gelernt, wie man ein Eingabeformular erstellt und die Daten in Net.Data verwendet. Selbstverständlich wäre hier eine Prüfung sinnvoll, ob das Feld ausgefüllt ist oder nicht. Um wirkliche Sicherheit zu erhalten, sollte man den Inhalt aller erhaltenen Variablen prüfen, unerwünschte Zeichen filtern und überlegen, ob durch manipulierte Variablen der Datenschutz umgangen werden könnte. Aber dies ist ein längeres Thema... Net.Data – ein Überblick Seite 27 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Schreiben und Update Kommen wir zum wichtigsten Kapitel in Net.Data: Dem Schreiben und Aktualisieren von Daten. Hier sei als erster Hinweis folgendes rot umrahmt dargestellt: HINWEIS! Tabellen, die Sie mit Net.Data aktualisieren oder erweitern wollen, sollten unbedingt in einem Journal aufgezeichnet und unter Commit-Steuerung gestellt werden. Es ist zwar auch Möglich, ohne Journalisierung mit Net.Data Dateien zu ändern, aber nicht empfohlen! Dazu eine Erläuterung: Ohne weitere Änderungen an der Konfiguration wird Net.Data stets verweigern, nicht-journalisierte Dateien zu ändern. Grund hierfür ist der Sicherheitsgedanke, damit man gezwungen wird, Commit-Steuerung zu verwenden. Denn es gibt nichts unsicheres als den Browser als Client! Verlassen Sie sich auch nie auf die Daten, die von einem Browser kommen, besonders wenn Ihre Anwendung offen im Internet läuft. Wenn Sie ein Bestellformular schreiben und in einem Eingabeformular ein Feld mit einem Artikelpreis belegen, verlassen Sie sich nie darauf, dass dieser Preis richtig ist, wenn er vom Browser wieder zurückgesendet wird. Prüfen Sie lieber doppelt in der Datenbank nach! Auch kommt es oft vor, dass während einer Übermittlung die Verbindung abbricht, und Sie haben unvollständige Daten. Nichts ist schlimmer, als eine nur teilweise abgeschlossene Transaktion! So, gehen wir also davon aus, dass unsere Adressdatei journalisiert ist. Sie sollten den Operations Navigator verwenden, um Ihre SQL-Datenbanken zu verwalten. Hier stehen viele interessante Möglichkeiten offen. Kommen wir zu Testscript 14: Wir erstellen im HTML-Block „Start“ ein kleines Eingabeformular: %HTML(start) { <B>Neuen Eintrag hinzufügen:</B> <FORM action="/cgibin/test14.nd/neu" method="POST"> Name: <INPUT TYPE="text" name="teilnehmer" size="40"><br> Nummer: <INPUT TYPE="text" name="telnummer" size="40"><br> <INPUT type="submit" value="Schreiben"> </FORM> % Hier werden zwei Eingabefelder „teilnehmer“ und „telnummer“ abgefragt. Beim Absenden wird in unserem Script der HTML-Block „neu“ aufgerufen. Dieser sieht so aus: %HTML(neu) { Die Daten werden geprüft...<br> %IF($(teilnehmer) == "") <b>Teilnehmername nicht ausgefüllt!</b><br> %ELSE %IF($(telnummer) == "") <b>Telefonnummer nicht ausgefüllt!</b><br> %ELSE Daten ok, es wird geschrieben!<br> @wrt_adr(teilnehmer, telnummer) %ENDIF %ENDIF %} Sieht wüst aus, ist es aber nicht. Net.Data – ein Überblick Seite 28 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Wir öffnen einen %IF-Block und prüfen, ob das Feld teilnehmer ausgefüllt ist. Wenn nicht, kommt eine Fehlermeldung. Wenn doch, kommt ein zweiter %IF-Block und prüft das Feld telnummer. Ist dieses nicht ausgefüllt, gibt es ebenfalls eine Fehlermeldung. Wenn auch dieses Feld (hoffentlich) ausgefüllt ist, erscheint eine Positiv-Meldung und die Funktion @wrt_adr mit den beiden Feldern als Parameter wird aufgerufen. Diese Funktion ist auch kein Hexenwerk: %FUNCTION(DTW_SQL) wrt_adr(IN xname, xnummer) { INSERT INTO DATEN.ADRESS (ADRNAME, ADRNUM) VALUES ('$(xname)', '$(xnummer)') %} Script 14 – Schreiben! Sie erhält zwei Parameter und setzt diese in eine SQL-Funktion INSERT ein. Es erfolgt in diesem Beispiel keinerlei Fehlerprüfung! Sie könnten den %MESSAGE-Block verwenden. Wenn eine Fehlernummer ungleich 0 gesendet wird, kann eine Aktion passieren, sei es eine Meldung oder ein optionaler Rückgabewert. Beispielsweise: %MESSAGE { -DEFAULT : { Fehler! $(SQL_CODE) %} : CONTINUE +DEFAULT : { Fehler! $(SQL_CODE) %} : CONTINUE %} Im Fehlerfall wird die Fehlernummer ausgegeben. Sie können den SQL-CODE auch als Rückgabewert verwenden. Somit verzichten Sie in der Funktion auf eine Ausgabe. Prüfen Sie lieber in der aufrufenden Routine auf eine Fehlernummer: %FUNCTION(DTW_SQL) wrt_adr(IN xname, xnummer) RETURNS(xerror) { INSERT INTO DATEN.ADRESS2 (ADRNAME, ADRNUM) VALUES ('$(xname)', '$(xnummer)') %MESSAGE { -DEFAULT : { @DTW_ASSIGN(xerror, $(SQL_CODE)) %} : CONTINUE +DEFAULT : { @DTW_ASSIGN(xerror, $(SQL_CODE)) %} : CONTINUE %} %} %HTML(neu) { Die Daten werden geprüft...<br> %IF($(teilnehmer) == "") <b>Teilnehmername nicht ausgefüllt!</b><br> %ELSE %IF($(telnummer) == "") <b>Telefonnummer nicht ausgefüllt!</b><br> %ELSE Daten ok, es wird geschrieben!<br> @DTW_ASSIGN(ergebnis,@wrt_adr(teilnehmer, telnummer)) %IF($(ergebnis) != "") Fehler $(ergebnis) beim Schreiben! %ENDIF %ENDIF %ENDIF %} Net.Data – ein Überblick Seite 29 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Net.Data – ein Überblick Seite 30 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Rerferenz – Interessante Funktionen Hier finden Sie einige Funktionen kurz aufgelistet, die bei weiteren Experimenten mit Net.Data nützlich sein können. Diese Auflistung ist nicht vollständig, dürfte aber dringende Fragen schnell beantworten. Gemeinsam ist allen Aufrufen, dass Funktionsnamen mit einem kleinen "r" zusätzlich am Anfang einen Rückkehrwert liefern, also das Ergebnis der Funktion nicht ein eine Variable schreiben. Die Funktionen können mit dieser Verwendung als Variablen- oder Konstantenersatz dienen. Die Funktionsnamen können im Quelltext in beliebiger GROSSkleinschreibung verwendet werden, allerdings ist dies nicht zu empfehlen, da dies schnell unübersichtlich wird und es einige PTFs von IBM gab, bei denen plötzlich Funktionsnamen in Kleinschreibung nicht richtig funktionierten! Es wird die hier angezeigte Notierung empfohlen. Generelle Funktionen DTW_DATE – Systemdatum zurückliefern @DTW_DATE(Format,Ergebnis) @DTW_DATE(Ergebnis) @DTW_rDATE(Format) @DTW_rDATE() Format Ergebnis Ist ein Eingabestring, der das zurückzuliefernde Datumsformat bestimmt. D Tag im Jahr (001 bis 366) E Europäisches Datumsformat (tt/mm/jj) N Normales Datumsformat (tt mon jjjj) [Monat wird englisch dargestellt] S Standardformat (jjjjmmtt) U US-amerikanisches Format (mm/tt/jj) => N ist Standardwert! Ist ein Ausgabestring, der das aktuelle Systemdatum enthält. DTW_TIME – Systemzeit zurückliefern @DTW_TIME(Format,Ergebnis) @DTW_TIME(Ergebnis) @DTW_rTIME(Format) @DTW_rTIME() Format C L N X H M S => Net.Data – ein Überblick Ist ein Eingabestring, der das zurückzuliefernde Zeitformat bestimmt. US-amerikanisches civil-time Format (hh:mmAM/PM) US-amerikanisches local-time Format (hh:mmss) (12 Stunden Format!) Normales Zeitformat (hh:mm:ss) (24 Stunden Format!) Erweitertes Zeitformat (hh:mm:ss.ttt) (24 Stunden Format!) (ttt ist die Anzahl der Millisekunden) Anzahl der Stunden seit Mitternacht Anzahl der Minuten seit Mitternacht Anzahl der Sekunden seit Mitternacht N ist Standardwert! Seite 31 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick DTW_ADD – Addieren zweier numerischer Werte @DTW_ADD(Zahl1, Zahl2, Stellenzahl, Ergebnis) @DTW_ADD(Zahl1, Zahl2, Ergebnis) @DTW_rADD(Zahl1, Zahl2, Stellenzahl) @DTW_rADD(Zahl1, Zahl2) Zahl1, Zahl2 Stellenzahl zwei Eingabezahlen, die addiert werden sollen wieviele Stellen das Ergenis haben soll. Gibt die Vorkomma- und NachkommaStellen an, das Dezimalkomma wird nicht gezählt. Ausgabezahl, die das Ergebnis enthält Ergebnis DTW_DIVIDE – Dividiert eine Zahl durch eine weitere Zahl => Aufrufe und Parameter: siehe DTW_ADD! DTW_MULTIPLY – Multipliziert zwei Zahlen => Aufrufe und Parameter: siehe DTW_ADD! DTW_SUBTRACT – Zieht von einer Zahl eine weitere Zahl ab. => Aufruf und Parameter: siehe DTW_ADD! DTW_DIVREM – Division mit Rückgabe des mathematischen Rests => Siehe DTW_DIVIDE, liefert aber den Restwert zurück! DTW_EVAL – liefert das Ergebnis eines mathematischen Ausdrucks @DTW_EVAL(Ausdruck, Ergebnis) @DTW_rEVAL(Ausdruck) Ausdruck Ergebnis Ein Eingabetext, der einen mathematischen Ausdruck enthält. Diese Textvariable darf neben Ziffern und Leerzeichen nur die Operatoren + (Addition), - (Subtraktion), / (Divison), * (Produkt), ** (Potenz) sowie % (Modulus) enthalten! Gibt das Ergebnis der in Ausdruck notierten mathematischen Rechenvorschrift zurück. DTW_ASSIGN – Weist einer Variablen einen Wert zu Eine sehr häufig verwendete Funktion. Sie hat keinen Rückgabewert, sondern immer eine Ergebnisvariable: @DTW_ASSIGN(Zielvariable,NeuerInhalt) DTW_CONCAT – Fügt zwei Zeichenketten zusammen @DTW_CONCAT(Eingabe1, Eingabe2, Ausgabe) @DTW_rCONCAT(Eingabe1, Eingabe2) Alle Parameter sind Zeichenketten! Weitere Funktionen in der IBM-Net.Data-Referenz: Http://www.ibm.com/software/netdata sowie http://www.ibm.com/servers/eserver/iseries/software/netdata Net.Data – ein Überblick Seite 32 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Net.Data – ein Überblick Seite 33 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31 Net.Data – ein Überblick Beispielkonfiguration für den HTTP-Server basierend auf Apache Hier eine Beispiel-Konfiguration für den Apache-basierenden HTTP-Server. Diese geht von der StandardKonfiguration aus, mit dem Pfad /www/apachedft wie IBM diesen Server vorinstalliert. # Apache Default server configuration Alias /scripts/ /www/apachedft/scripts/ ScriptAlias /cgibin/ /QSYS.LIB/CGIBIN.LIB/DB2WWW.PGM/ # General setup directives Listen *:80 HotBackup Off HostNameLookups Off CgiConvMode %%MIXED/MIXED%% TimeOut 30000 KeepAlive Off DocumentRoot /www/apachedft/htdocs AccessFileName .htaccess Options -Indexes AddLanguage en .en # Deny most requests for any file DirectoryIndex index.html <Directory /> order allow,deny deny from all Options -Indexes -ExecCGI -includes AllowOverride Limit Options </Directory> # Allow requests for files in document root <Directory /www/apachedft/htdocs> order allow,deny allow from all </Directory> <Directory /QSYS.LIB/CGIBIN.LIB/> order allow,deny allow from all </Directory> Konfigurationsdatei /www/apachedft/conf/httpd.conf In diesem Beispiel legen wir die Net-Data Scripte unter /www/apachedft/scripts ab. Die Aufrufe der Makros erfolgt wie im Dokument angegeben analog zur Konfiguration mit dem Original-Server. ENDE DES DOKUMENTS – VIELEN DANK FÜR's LESEN! Net.Data – ein Überblick Seite 34 von 34 - Exklusive Version für Teilnehmer der COMMON Jahreskonferenz 2004 Stand: 2004-10-31