Multimedia und Internet, Teil 2

Werbung
Multimedia und Internet (MI)
Teil 2: Internet und Datenbanken
Vorlesungsskript
Wintersemester 2000/01
Prof. Dr. Edwin Schicker
FH Regensburg
1
2
3
4
5
Überblick ......................................................................................................................................... 2
1.1
Rechnerumgebung ................................................................................................................... 3
Hypertext Markup Language (HTML) ............................................................................................ 3
2.1
HTML-Grundlagen.................................................................................................................. 3
2.2
HTML-Formulare .................................................................................................................... 5
2.3
Einfaches Beispiel zu Formularen ........................................................................................... 7
Active Server Pages......................................................................................................................... 8
3.1
Installation eines eigenen WWW-Servers ............................................................................... 8
3.2
Active Server Pages (ASP) ...................................................................................................... 9
3.3
Ein- und Ausgabe in Active Server Pages ............................................................................. 11
3.4
Javascript ............................................................................................................................... 12
3.5
Übungsaufgaben .................................................................................................................... 12
ActiveX Data Objects .................................................................................................................... 12
4.1
ODBC, OLE DB.................................................................................................................... 12
4.2
ActiveX Data Objects (ADO)................................................................................................ 14
4.3
Erster Zugriff auf Datenbanken ............................................................................................. 14
4.4
Suche mehrerer Daten in Datenbanken ................................................................................. 16
4.5
Mehrfacher Zugriff auf Datenbank........................................................................................ 18
4.6
Transaktionen ........................................................................................................................ 22
4.7
Weitere Möglichkeiten .......................................................................................................... 25
4.8
Übungsaufgaben .................................................................................................................... 26
Überblick über weitere Möglichkeiten .......................................................................................... 26
5.1
Das Application-Objekt ......................................................................................................... 26
5.2
Die Datei Global.asa.............................................................................................................. 27
5.3
Das Command-Objekt in ADO.............................................................................................. 28
5.4
Die Methode Redirect des Session-Objekts........................................................................... 29
5.5
Providerangaben .................................................................................................................... 30
2
1 Überblick
Datenbanken, insbesondere relationale Datenbanken, sind heute weit verbreitet. Sie finden in den
letzten Jahren auch ein sehr stark zunehmendes Interesse im Internet. Nicht nur ECommerce, sondern
auch viele andere Internetanwendungen greifen auf Datenbanken zu. Wir wollen im zweiten Teil dieser Vorlesung zeigen, wie einfach die dazu erforderliche Programmierung heute ist.
Es gibt mehrere Möglichkeiten, vom Internet aus auf Datenbanken zuzugreifen. Und wir werden sehen, dass diese Zugriffsweise in manchen Punkten sogar einfacher ist als manche herkömmliche Remote-Zugriffe.
Internetzugriffen liegt immer das Client/Server-Konzept zugrunde. Wir benötigen einen WWW-Server
und zahlreiche Clients, die alle mit einem Browser ausgestattet sind. Kommen Datenbanken hinzu, so
brauchen wir zusätzlich einen Datenbank-Server. Auf diesen Datenbank-Server greift der WWW-Server als Datenbank-Client zu. Der WWW-Server ist also Server bezüglich der Client-Browser und ist
selbst Client, wenn er die Datenbankanforderungen des Client-Browsers ausführt und auf die Datenbank zugreift. Wir erhalten in einer etwas vereinfachten Form folgende Zugriffsreihenfolge:
Browser
Der Browser wird vom Benutzer gestartet. Von hier aus greift also der Benutzer auf die Internet-Datenbank zu.
WebServer
Der WWW-Server ist das Bindeglied zwischen Browser und Datenbank. Auf
dem WWW-Server wird die Datenbankverbindung (ODBC, OLE DB, JDBC)
hergestellt.
DB-Server
Der Datenbank-Server verwaltet die Datenbank selbstständig. Auf kleineren
Datenbanken und WWW-Servern sind häufig WWW-Server und DB-Server
auf dem selben Rechner installiert.
Mit dem Aufruf der WWW-Seite durch den Browser des Benutzers wird der WWW-Server aktiv und
liefert dem Browser die gewünschte Seite. Diese liest der Benutzer und gibt gegebenenfalls in entsprechenden Feldern Daten ein. Durch einen Klick auf einen Button oder einen speziellen Link wird der
WWW-Server aufgerufen und bearbeitet diese Aktion. Ist ein Datenbankzugriff erforderlich, um benötigte Informationen zu holen, so wird eine entsprechende Anforderung an den DB-Server gestellt. Dieser bearbeitet diese und reicht die gewünschten Daten an den WWW-Server zurück. Diese bereitet der
WWW-Server auf und schickt die komplette Seite mit den gewünschten Daten an den Client zurück.
Der Browser stellt diese Daten dann dar, der Benutzer liest die Seite.
Der mit Abstand am weitesten verbreitete WWW-Server ist der Apache-Server, gefolgt vom Microsoft Internet Information Server (Microsoft IIS). Zugriffssprachen sind beispielsweise Perl, verschiedene Basic-Dialekte, Java, Javascript, PHP.
Wir wollen in dieser Vorlesung einige Grundlagen kennenlernen. Die Umgebung spielt eine untergeordnete Rolle, die Arbeitsweise ist wichtiger. Da wir Zugriff auf einen Win2000-Server mit Microsoft IIS haben, werden wir mit der Microsoft-Umgebung ADO/ASP und der Zugriffssprache Javascript den Zugriff auf Datenbanken via Internet üben.
Literatur:
Online-Hilfe zum Option Pack von Microsoft (empfehlenswert)
Krause: Microsoft Active Server Pages, Addison Wesley, 99,90 DM
Weltner: Active Server Pages lernen und beherrschen, Microsoft Press, 89 DM
Millier, Mezick: Active Server Pages – Programmierung, Microsoft Press, 89 DM
Multimedia Entwicklung (Teil2)
Edwin Schicker
3
Internet:
Software:
1.1
Selfhtml 7.0, www.teamone.de/selfaktuell/
www.microsoft.com (sehr viele Zusatzinfos zu ADO/ASP mit vielen Beispielen)
Frontpage 2000 (umfangreiches HTML-Werkzeug im Office-Paket)
Dreamweaver (Macromedia, sehr gutes HTML- und Design-Werkzeug)
Arachnophilia (kostenlose SW)
HTMLEDIT (kostenlose SW, www.meybohm.de)
Rechnerumgebung
Übungsraum sind auch in diesem Vorlesungsteil die Räume 512 und 513 mit Windows95/NT. Als
Server wird der Windows2000-Server rfhpc8322 im Raum 511 verwendet. Da die ASP-Seiten vom
Server interpretiert werden müssen, müssen diese Seiten auch dort unterhalb des wwwroot-Verzeichnisses hinterlegt werden. Um dies für alle Studenten zur Verfügung zu stellen, sind im Raum 511 auf
den Windows2000-Rechnern Kennungen aller Studenten eingetragen. Dabei besitzt jeder Student
unterhalb des Verzeichnisses Dokumente und Einstellungen das Unterverzeichnis public_html. Diese
lokalen Verzeichnisse werden auch auf dem Server gehalten und bei jedem Herunterfahren abgeglichen. Der IIS-Server interpretiert diese Verzeichnisse als Internet-Root-Verzeichnisse des Benutzers.
Damit diese Einstellungen auch wirksam werden, muss sich ein Benutzer mindestens einmal im Raum
511 unter Windows2000 eingeloggt haben. Im Folgenden wird dies vorausgesetzt.
Es kann nun auf den Windows2000-Server zugegriffen werden. Sollen HTML- oder ASP-Seiten oder
eine kleine Datenbank dort abgelegt werden, so verwenden wir dazu einfach den Explorer. Mittels
Netzwerk verbinden im Menü Extras geben wir folgenden Pfad ein:
\\rfhpc8322\user\XXXXXXXX
eventuell nur:
\\rfhpc8322\user
‚XXXXXXXX’ ersetzen wir durch die eigene Benutzerkennung. Nach einer Autorisierung sind wir
mit dem entsprechenden Homeverzeichnis des Benutzers auf dem Windows2000-Server verbunden.
Im Unterverzeichnis public_html können wir jetzt unsere HTML-/ASP-Seiten ablegen!
Diese ASP-Seiten werden jetzt beim Zugriff vom IIS-Server interpretiert und als HTML-Seite an den
Aufrufenden zurückgegeben. Im Browser lautet die URL zu diesen Seiten:
http://bt-win2k-server/~XXXXXXXX
Wieder ist ‚XXXXXXXX’ durch die eigene Benutzerkennung zu ersetzen. Beachten Sie auch das
Zeichen ‚~’ (Tilde) vor der Kennung! Im obigen Fall wird eine Datei namens index.html, index.htm
oder default.htm erwartet. Natürlich kann gegebenenfalls auch eine andere Datei aufgerufen werden,
indem diese im obigen Aufruf einfach mit angegeben wird (dazwischen steht ein Schrägstrich /).
Weitere Hinweise, etwa zum erstmaligen Einloggen werden in der Vorlesung gegeben.
2 Hypertext Markup Language (HTML)
Um auf Datenbanken über das Internet zuzugreifen, benötigen wir Wissen über SQL, Programmiersprachen (hier: Javascript) und HTML-Dokumente. Die ersten beiden werden vorausgesetzt. Mit
HTML-Dokumenten wollen wir uns daher nur kurz auseinandersetzen.
2.1
HTML-Grundlagen
Hier erfolgt nur eine sehr knappe Zusammenfassung zu HTML. Die meisten Beispiele wurden dem
Programm Selfhtml 7.0 von Stefan Münz entnommen. Ich kann das kostenlose Produkt Selfhtml nur
wärmstens weiterempfehlen. Selfhtml enthält neben einer ausführlichen Beschreibung von HTMLBefehlen und StyleGuides auch eine gute Einführung in Javascript.
Multimedia Entwicklung (Teil2)
Edwin Schicker
4
HTML ist ein normaler Text, der sogenannte Tags enthält. Dies sind Bezeichner, die in spitze Klammern eingeschlossen sind. Diese Tags wirken auf den folgenden Bereich, bis diese durch einen entsprechenden Ende-Tag beendet werden. Dieser Ende-Tag unterscheidet sich vom Tag-Bezeichner
durch einen vorangestellten Schrägstrich (‚/’). Das Grundgerüst eines HTML-Programms enthält einen
Kopf, in dem globale Informationen zu dem Programm angegeben werden und einen Rumpf, der die
eigentlichen Texte und Grafiken enthält. Ein HTML-Dokument hat somit folgendes Aussehen:
<html>
<head>
<title>Text des Titels</title>
</head>
<body>
Text, Verweise, Grafikreferenzen usw.
</body>
</html>
Der Titel erscheint in der Titelleiste des Browsers. Der eigentliche Text muss noch strukturiert werden. Hier stehen zahlreiche Tags zur Verfügung. Eine erste Auswahl ist:
<hi>Text</hi>
<p>Text</p>
Text<br>Text
<b>Text</b>
<i>Text</i>
<u>Text</u>
Überschrift der Ordnung i mit i=1,…,6
Textabschnitt (Ende-Tag ist nicht zwingend)
Zeilenumbruch
Fettdruck
Kursivschrift
Unterstreichung
Auch Nummerierungen lassen sich in HTML-Dokumenten durchführen:
<ol>
<li>Listeneintrag</li>
<li>Listeneintrag</li>
</ol>
Diesen geordneten Listen (ol=ordered list) stehen Aufzählungslisten (ul=unordered list) gegenüber.
Wird also in obigem Beispiel der Tag ol durch ul ersetzt, so wird eine reine Aufzählung ohne Nummerierung erzeugt.
Wichtig sind für uns Tabellen. Auch hier wollen wir nur die Grundkonzepte ansprechen. Tabellen
enthalten Zeilen, jede Zeile enthält Spalten. Wir geben daher in einer Tabelle eine Zeile nach der anderen aus. Innerhalb jeder Zeile werden die Spalten nacheinander angegeben. Es muss nicht jede Zeile
die gleiche Spaltenanzahl besitzen. Das Grundgerüst sieht daher wie folgt aus:
<table border>
<tr>
<th>Kopfzelle</th>
<th>Kopfzelle</th>
</tr>
<tr>
<td>Datenzelle</td>
<td>Datenzelle</td>
</tr>
</table>
Diese Tabelle besitzt eine Kopfzeile mit zwei Spalten und eine weitere Zeile mit ebenfalls zwei Zeilen. Eine Tabelle wird in das Tag table eingeschlossen. Wird die Angabe border im Tag verwendet, so
erhält die Tabelle einen Rahmen, ansonsten wird kein Rahmen ausgegeben. Zu weitergehenden Tabellen-Formatierungen sei beispielsweise auf Selfhtml verwiesen. Eine Zeile wird in das Tag tr eingeschlossen, eine Spalte in das Tag td. Die erste Zeile darf stattdessen auch das Tag th enthalten. Diese
Multimedia Entwicklung (Teil2)
Edwin Schicker
5
Spalten werden dann als Spalten einer Kopfzeile interpretiert. Die Darstellung dieser Kopfzeilen hängt
vom verwendeten Browser ab (meist Fettdruck, Zentrierung und größere Spaltenhöhe).
Beim Auslesen von Datenbankinhalten mit dem Select-Befehl werden wir häufig auf Tabellen zugreifen müssen. Doch auch der Verweis auf Referenzen im Internet, auf Bilder oder auf andere HTMLSeiten sind häufig erforderlich. Die Syntax von Referenzen lautet:
<a href="URL">Verweistext</a>
Als URL kann entweder eine Internetadresse oder eine lokale Datei angegeben werden. Beispiele:
<a href="http:/homepages.fh-regensburg.de/~sce39014">
Homepage von Edwin Schicker</a>
<a href="superbild.jpg">Verweis auf ein Superbild</a>
<a href="weiter.html">Nächste Html-Seite</a>
Das erste Beispiel enthält einen Verweis auf eine Internetseite, das zweite einen Verweis auf ein Bild,
das dritte einen Verweis auf eine andere HTML-Seite. Zu beachten ist, dass diese Verweise existieren
sollten. In den beiden letzten Beispielen sollten also im gleichen Verzeichnis, in dem sich die aktuelle
HTML-Seite befindet, auch die beiden angegebenen Dateien stehen.
Ein Problem stellen deutsche Umlaute dar. Viele HTML-Editoren setzen die deutschen Umlaute automatisch in den notwendigen Code um. Im Folgenden ist dieser Code angegeben:
ä
ö
ü
ß
statt
statt
statt
statt
ä
ö
ü
ß
Ä
Ö
Ü
statt
statt
statt
Ä
Ö
Ü
Natürlich sollten auch Kommentare in einem HTML-Dokument nicht fehlen. Diese werden wie folgt
geschrieben:
<!-- Dies ist ein Kommentar -->
2.2
HTML-Formulare
Während zum Auslesen von Daten aus Datenbanken häufig Tabellen verwendet werden, müssen zur
Auswahl der gewünschten Daten meist Formulare ausgefüllt werden. Im Bereich von ECommerce
müssen persönliche Angaben einschließlich der Kreditkartennummer erfasst werden. Auch bei der
Suche von bestimmten Daten wie Büchern oder CDs müssen Suchbegriffe und Rubriken eingegeben
werden. Hier unterstützen auch Auswahllisten die Suche erheblich. Weiter müssen die eingegebenen
Daten durch entsprechende Buttons bestätigt oder widerrufen werden. Hierzu verwenden wir HTMLFormulare. Das Formulargerüst lautet (die Gänsefüßchen bei Stringangaben sind hier und auch später
nur notwendig, wenn die Strings Leerzeichen oder andere Steuerzeichen enthalten):
<form action="Programm" method=post>
<!-- Formularelemente -->
</form>
Ein Formular ruft ein Programm auf, das nach Eingabe der Formulardaten aufgerufen wird. Nur in
wenigen Fällen reichen hier HTML-Dokumente als Ziel aus, da die eingegebenen Daten meist überprüft und weiterverarbeitet werden müssen. Wir verwenden in der Vorlesung ausschließlich ASP-Programme, es können aber genauso CGI-, Perl-, PHP- oder andere Programme eingesetzt werden. Die
Methode post gibt an, dass die übergebenen Formularinhalte auf dem WWW-Server in stdin zur Verfügung gestellt werden. ASP-Programme können diese Eingaben auf einfache Art und Weise lesen.
Wahlweise steht auch die Methode get zur Verfügung. Hier werden die Formularinhalten zusammen
mit dem Programmnamen verschickt und sind für den Benutzer im Browserfenster sichtbar. Auf diese
Multimedia Entwicklung (Teil2)
Edwin Schicker
6
Methode werde ich im Weiteren verzichten. Werden keine Formularinhalte weitergereicht, so ist die
Angabe einer Methode nicht erforderlich.
Ein Formular kann unterschiedliche Eingabemöglichkeiten verwenden, etwa:
•
•
•
•
Einzeiliges Eingabefeld
Auswahlliste
Absendebutton
Abbruchbutton
Weitere Möglichkeiten sind mehrzeilige Eingabefelder, Radiobuttons oder Checkboxen und einige
Neuerungen, die erst ab HTML V4.0 zur Verfügung stehen und daher nicht auf allen Browsern ablauffähig sind (z.B. allgemeine Klickbuttons und Gruppierung). Wieder wird dazu auf Selfhtml verwiesen.
Wir stellen kurz die HTML-Tags vor, die die obigen Eingabemöglichkeiten beschreiben. Beginnen wir
mit den einzeiligen Eingabefeldern:
<input size=x maxlength=x name="Elementname" value="Text">
Size gibt die Größe des Eingabefeldes in Anzahl von Zeichen an. Maxlength beschreibt die maximale
Anzahl von Zeichen, die eingegeben werden dürfen. Überschreitet die Eingabe die Größe size, so wird
die Eingabe gescrollt. Der Name des Eingabefeldes ist für die Weiterverarbeitung wichtig. Das im
Form-Tag angegebene Programm findet die Eingabe unter diesem Namen. Die Angabe value ist wahlfrei und gibt eine Vorbelegung an. Variationen sind beispielsweise:
<input readonly size=x maxlength=x name="Elementname" value="Text">
<input type=password size=x maxlength=x name="Elementname">
Im ersten Fall ist das Eingabefeld nicht veränderlich, die Angabe value muss hier angegeben werden.
Im zweiten Fall erfolgt die Eingabe ohne Echo, um etwa Passwörter eingeben zu können.
Auswahllisten, auch als Comboboxen bezeichnet, können auf einfache Weise in HTML erstellt werden. Der Aufbau dieser Listen sieht wie folgt aus:
<select multiple name="Elementname" size=x>
<option> Eintrag
<option> anderer Eintrag
</select>
Das Select-Tag enthält Option-Tags. Die Größe der Auswahlliste entspricht also der Anzahl der Option-Tags. Die wahlfreie Angabe size bewirkt, wie viele Elemente angezeigt werden. Ist x=1, so wird
eine Drop-Down-Box generiert. Dies ist die Standardeinstellung. Die ebenfalls wahlfrei Angabe multiple bewirkt, dass mehrere Elemente ausgewählt werden können. Standardmäßig ist nur eine Auswahl
erlaubt. Betrachten wir noch zwei interessante Varianten.
<option selected> noch ein Eintrag
<option value="Wert"> weiterer Eintrag
Die Angabe selected bewirkt eine Vorauswahl. Die Angabe value gibt einen Ersatzwert an, der statt
des Listeneintrags an das Programm (im Form-Tag angegeben) weitergereicht wird.
Innerhalb eines Form-Tag-Bereichs können auch noch zwei Buttons verwendet werden, ein Button
zum Absenden der Daten und ein Button zum Rücksetzen. Diese Buttons werden wie folgt definiert:
<input type=submit value="Beschriftung">
<input type=reset value="Beschriftung">
Die innerhalb eines Formularbereichs eingetragenen Daten werden erst durch Drücken des SubmitButtons abgeschickt. Umgekehrt werden alle Einträge wieder zurückgesetzt, wenn der Reset-Button
Multimedia Entwicklung (Teil2)
Edwin Schicker
7
angeklickt wird. In HTML 4.0 können auch weitere Buttons definiert werden. Ältere Browser unterstützen diese Buttons aber noch nicht. Radiobuttons und Checkboxen existieren dafür bereits seit Langem. Die Definitionen lauten:
<input type=radio name="Name" value="Wert"> Text
<input type=checkbox name="Name" value="Wert"> Text
Es ist zu beachten, dass alle Radiobuttons mit dem gleichen Namen zusammengehören. Es kann also
immer nur ein Radiobutton dieser Gruppe angeklickt sein. Der angegebene Wert wird beim Klicken
des Submit-Buttons übertragen. Das Gleiche gilt sinngemäß auch für Checkboxen, nur können hier
kein, ein oder mehrere Elemente einer Gruppe markiert sein.
2.3
Einfaches Beispiel zu Formularen
Nach so viel Stoff wollen wir ein kleines Beispiel folgen lassen. Bisher haben wir aber noch nicht
kennengelernt, wie wir innerhalb eines Formulars eingegebene Werte im Ziel-Dokument auswerten
können. Aus diesem Grund wollen wir uns mit einem recht einfachen Formular begnügen. Dieses
Formular ist Ausgangspunkt unserer Vorlesung und die Defaultseite auf dem Server (default.htm). Wir
definieren mehrere Buttons. Ein Klick auf einen dieser Buttons führt auf von mehreren Beispielseiten,
die wir alle im Laufe der Vorlesung noch kennenlernen werden. Betrachten wir den HTML-Code in
leicht gekürzter Form:
<html>
<head>
<title>Erstes Beispiel einer Formularseite</title>
</head>
<body>
<center><h1>Vorlesung MI</h1></center>
<center><h3>Edwin Schicker</h3></center>
Diese Seite ist die Einstiegsseite zur Vorlesung Multimedia und Internet
(MI) von Edwin Schicker. Von hier kann durch Klick auf den entsprechenden
Button zu den einzelnen Beispielen der Vorlesung verzweigt werden.
<p>
Folgende Seiten stehen zur Verfügung:
<p>
<table cellpadding=10>
<tr>
<td align=right> <form action="name.html">
<input type="Submit" value="Erstes ASP-Beispiel">
</form>
</td>
<td valign=top> Die Datei <i>name.html</i> wird angesprungen
</td>
</tr>
<tr>
<!-- Die folgenden Tabellenzeilen sind analog aufgebaut -->
</tr>
</table>
<p>
Ende der HTML-Datei
</body>
</html>
Die Tabellenausgabe wurde leicht optimiert, indem einige Optionen hinzugefügt wurden. Cellpadding
gibt den Abstand des Textes vom Zellrand (in Pixeln) an, so dass Spalten und Zeilen einen gewissen
Abstand voneinander haben. Mit der Option Align kann die horizontale Ausrichtung und mit Valign
die vertikale Ausrichtung beeinflusst werden.
Es ist zu beachten, dass hier und auch in allen weiteren Beispielen die deutschen Umlaute nicht umschrieben wurden. Wir hätten an Stelle des Wortes gewünschten das Wort gewünschten schreiMultimedia Entwicklung (Teil2)
Edwin Schicker
8
ben müssen. Wir haben aus Gründen der Übersichtlichkeit aber darauf bewusst verzichtet. Viele
HTML-Editoren, wie auch der von Uli Meyborn, setzen deutsche Umlaute automatisch um. Wir können hier also wie gewohnt arbeiten.
Jedes Formular-Tag enthält genau einen Submit-Button. Im Formular-Tag wurde mit der Option
Action eingetragen, wohin beim Klick auf den Submit-Button verzweigt werden soll.
In der Regel soll jedoch nicht nur verzweigt werden. Es sollen auch eingetragene Daten ausgelesen
werden. Dies ist aber nur noch mittels Programmierung möglich, z. B. mit DHTML (Dynamic
HTML). Wir wollen diese Möglichkeiten am Beispiel von Active Server Pages aufzeigen.
3 Active Server Pages
Internetprogramme sind oft in der Sprache Perl geschrieben. Dies liegt vor allem daran, dass Perl auf
allen Plattformen (Windows, Unix, Mac) verfügbar ist und dass WWW-Server meist auf Unix-Rechnern (etwa Linux) zusammen mit der Software von Apache installiert sind. In der Windows-Welt dominieren hingegen Active Server Pages. Inzwischen wurden Active Server Pages auch auf Unix portiert. Die Entscheidung obliegt jedem Einzelnen und ist auch Geschmackssache. Prinzipielle Unterschiede gibt es kaum. Das mit Perl oft benutzte CGI-Interface ist allerdings veraltet und sollte nicht
mehr verwendet werden. In letzter Zeit verdrängt PHP die Sprache Perl. Inwieweit sich PHP durchsetzt, wird die Zukunft zeigen.
Da ich in meinem letzten Industriesemester einige Erfahrung mit Active Server Pages gesammelt
habe, werde ich in der Vorlesung auf diese Erfahrungen zurückgreifen.
3.1
Installation eines eigenen WWW-Servers
Um die Beispiele der Vorlesung auch auf dem eigenen Rechner nachvollziehen zu können, benötigen
wir einen WWW-Server. Ein WWW-Server benötigt entweder das Betriebssystem Unix oder Windows NT/2000, zur Not auch Windows95/98.
Beginnen wir mit WinNT. Hier haben wir die Auswahl: entweder wir verwenden den Personal Web
Server oder die Peer Web Services. Die Unterschiede:
Peer Web Service wird zusammen mit Windows NT Workstation und Server ausgeliefert. Es ist beispielsweise auf der Installations CD zu Windows NT Workstation im Verzeichnis /i386/inetsrc enthalten. Die Installation erfolgt durch Start der Datei inetstp.exe in diesem Verzeichnis, Administratorrechte werden vorausgesetzt. Der Peer Web Service ist ein einfacher WWW-Server. Zum Aufruf von
HTML-Seiten ist dieser Service aber ausreichend. Active Server Pages hingegen kann dieser Server
nicht verarbeiten. Für diese Vorlesung reicht dieser Service also nicht aus.
Alternativ kann von Microsoft kostenlos das Option Pack 4.0 heruntergeladen werden. Microsoft fordert lediglich eine Registrierung. Dieses Option Pack gibt es sowohl für Windows NT Server als auch
für NT Workstation. Die Workstation-Version hat einen wesentlich geringeren Umfang (35 MBytes)
als die Server-Version (ca 80 MBytes), reicht für unsere Zwecke jedoch vollkommen aus. Active Server Pages (ASP) werden unterstützt, ebenso der Zugriff auf Datenbanken mittels ActiceX Data Objects (ADO). Eine umfangreiche Dokumentation zu ASP, ADO, MTS (Microsoft Transaction Server),
Visual Basic und Javascript ist enthalten, zahlreiche Beispiele erleichtern die Einarbeitung.
Die Installation unter Win2000 Workstation ist erheblich einfacher. Die Installations-CD bietet beim
Einlegen im Anfangsmenü gleich die Möglichkeit der Installation des IIS-Servers an. Es ist einfach
den Anweisungen zu folgen. Die Dokumentation ist allerdings nicht ganz so umfangreich wie beim
Option Pack 4.0.
Auch Windows 98 enthält auf der Installations-CD einen kleinen IIS-Server, der für unsere Zwecke
ebenfalls voll ausreicht. Natürlich können unter Fat32 keine Zugriffsrechte vergeben werden, so dass
dieser IIS-Server ausschließlich zum Experimentieren verwendet werden sollte.
In allen Fällen muss auf dem Rechner ein Netzwerk mit TCP/IP-Protokoll eingerichtet werden, etwa
mit der Netzwerkadresse 192.168.255.1. Die WWW-Installation richtet ein WWW-Root-Verzeichnis
ein, standardmäßig c:\inetpub\wwwroot. Wird ein HTML-Dokument namens default.htm in diesem
Multimedia Entwicklung (Teil2)
Edwin Schicker
9
Verzeichnis abgelegt, so ist dieses Dokument auf allen Rechnern, die mit diesem Server verbunden
sind, unter der Adresse http://192.168.255.1/default.html zu erreichen. Sind Client und Server identisch, greifen wir also lokal auf den Server zu, so können wir statt der IP-Adresse auch schreiben:
http://localhost/default.html. Ein erster Vorteil eines kleinen WWW-Servers liegt darin, dass wir Default-Verzeichnisse für Bilder und andere Sourcen angeben können. Dort können wir dann diese ablegen und benötigen nicht jeweils den vollständigen Pfad in unserem HTML-Dokument. Doch insbesondere bei Active Server Pages sind wir auf den WWW-Server sogar angewiesen. Dieser interpretiert
nämlich den vorhandenen Code und gibt als Ergebnis den erzeugten HTML-Text an den Browser
weiter. Diese serverseitige Interpretation erfolgt aber nur, wenn diese Seite nicht direkt als Datei, sondern über den Server in den Browser kopiert wird.
3.2
Active Server Pages (ASP)
Active Server Pages wurden von der Firma Microsoft eingeführt. Hier handelt es sich um HTML-Seiten, die um einen Programmcode erweitert sind. Diese Dateien besitzen zur Unterscheidung von reinen HTML-Seiten die Endung .asp. Wir müssen nur ganz wenige Regeln hinzulernen:
•
In der ersten Zeile muss mitgeteilt werden, welche Programmiersprache verwendet wird. Wir
schreiben daher eine der folgenden Zeile, je nachdem ob wir mit Javascript oder Visual Basic
arbeiten wollen:
<%@ LANGUAGE = "JScript" %>
<%@ LANGUAGE = "VBScript" %>
•
Der Programmcode wird eingeklammert in <% … %> . Die Klammern wirken über beliebig
viele Zeilen.
Der WWW-Server gibt den in diesen Klammern stehenden Code nicht aus, sondern interpretiert diesen zunächst. Erst das Ergebnis dieser Interpretation wird an den Browser weitergeleitet und dort als
HTML-Code behandelt. Auf dem Server sollten daher ASP-Dateien keine Lese-, sondern nur Ausführungsrechte besitzen.
In Javascript und Visual Basic können mittels der Methode POST übergebene Werte mit dem in ASP
definierten Objekt Request mittels der Methode Form ausgegeben werden. Diese Methode benötigt als
String-Parameter den Name des Formularfeldes und liefert den Inhalt dieses Feldes als Funktionswert
zurück.
Betrachten wir ein Beispiel: Wir fordern in einem HTML-Dokument einen Namen in einem Eingabefeld an. Weiter wollen wir die Anrede wissen. Hier geben wir Radiobuttons vor. Das Dokument könnte wie folgt aussehen (gespeichert in der Datei name.html):
<html>
<head>
<title>Erstes ASP-Beispiel</title>
</head>
<center><h1>Vorlesung MI</h1></center>
<center><h3>Edwin Schicker</h3></center>
Der Name ist in einem Eingabefeld und die Anrede mittels eines Radiobuttons
anzugeben. Durch Klicken des Submit-Buttons wird auf eine ASP-Seite
gewechselt, in der diese Daten ausgelesen und im Browser ausgegeben werden.
<p>Bitte geben Sie die entsprechenden Daten ein und klicken dann den
Weiter-Button. Der Rücksetzbutton erlaubt eine Neueingabe.</p>
<form action="name.asp" method=post> <!--Sprung nach name2.asp-->
<table cellpadding=10>
<tr>
<td align=right>Bitte geben Sie Ihren Namen ein:
</td>
<td> <!-- Eingabefeld: -->
<input size=30 maxlength=30 name=Name>
</td>
Multimedia Entwicklung (Teil2)
Edwin Schicker
10
</tr>
<tr>
<td align=right>Ihre Anrede:
</td>
<td> <!-- Radiobutton: -->
Herr<input type=radio name=Anrede value=1>
Frau<input type=radio name=Anrede value=2>
</td>
</tr>
<tr>
<td align=right> <input type="Submit" value="Weiter">
</td>
<td>
<input type="Reset" value="Rücksetzen">
</td>
</tr>
</table>
</form>
</body>
</html>
Dieses Beispiel enthält genau einen Formular-Tag, der wiederum ein Eingabefeld mit dem Namen
Name und einen Radiobutton mit dem Namen Anrede enthält. Diese Eingaben sind wieder mittels
einer Tabelle übersichtlich angeordnet. Durch Klick auf den Submit-Button wird in die Datei
name.asp, unsere erste ASP-Datei, verzweigt. Diese Datei kann nun mittels der Funktionen Request.Form("Name") und Request.Form("Anrede") auf die Inhalte der beiden Eingaben zugreifen. Sehen wir
uns also auch die Datei name.asp an:
<%@ LANGUAGE = "JScript" %>
<html>
<head>
<title>Erstes ASP-Beispiel, Ergebnis</title>
</head>
<center><h1>Vorlesung MI</h1></center>
<center><h3>Edwin Schicker</h3></center>
<!-- Die mit der Methode POST uebergebenenen Daten werden ausgelesen: -->
<%
// Javascript! Das Objekt REQUEST liefert mittels der Methode
// FORM die uebergebenen Daten!
name = Request.Form("Name");
geschlecht = Request.Form("Anrede");
if (geschlecht==1)
anrede = "Sehr geehrter Herr ";
else
anrede = "Sehr geehrte Frau ";
%>
<%=anrede%> <%=name%>! Geschafft! Die erste ASP-Seite wurde ausgeführt
und erfolgreich interpretiert. Es wird nicht der Code, sondern nur das
Ergebnis an den Client weitergereicht.
<p>
Das erste ASP-Beispielprogramm wäre damit bearbeitet. Mit dem folgenden
Link kehren Sie zur Anfangsseite zurück.
<p>
<center><a href="default.htm">Startseite</a></center>
</body>
</html>
Wie bereits erwähnt enthält die erste Zeile den Hinweis auf die verwendete Sprache, hier Javascript.
Der Code selbst ist geklammert in <% … %>. Im Wesentlichen haben wir nur die übergebenen Werte
ausgelesen und dann an den Browser weitergegeben. Die Ausgabe erfolgt am Einfachsten mittels der
Schreibweise <%= … %>, doch mehr im nächsten Abschnitt.
Multimedia Entwicklung (Teil2)
Edwin Schicker
11
3.3
Ein- und Ausgabe in Active Server Pages
Die Eingabe haben wir bereits im letzten Abschnitt kennengelernt. Sie erfolgt mittels Formularen. Wir
wollen hier aber etwas genauer die Möglichkeiten der Weiterverarbeitung dieser Eingaben betrachten.
Mittels des Form-Tags geben wir ein Zieldokument an. Im Zieldokument müssen wir die übergebenen
Daten auswerten. Dies erfolgt in ASP am Einfachsten mittels des Request-Objekts. Das Request-Objekt besitzt unter anderem die Methoden Form und Querystring.
Die Methode Form liest Werte ein, die mittels der Methode Post übergeben wurden, die Methode
Querystring liest die mittels Get übergebenen Werte. Die Syntax ist identisch, so dass wir nur die
Methode Form betrachten wollen:
Request.Form("Name")
Request.Form("Name").Count
Request.Form("Name") (i)
// Inhalt, der im Formular Name eingegeben wurde
// Anzahl der im Formular Name eingegebenen Werte
// Inhalt des i-ten Wertes aus dem Formular Name
Die erste Zeile haben wir bereits in einem Beispiel verwendet. Zu bemerken ist, dass eingegebene
Daten immer als Zeichenketten weitergegeben werden. Doch Javascript ist mit der Umwandlung in
andere Datentypen sehr großzügig.
Wurden bestimmte Formularfelder nicht ausgefüllt, so können wir dies leicht mit der Methode Count
überprüfen. Der Wert von Count ist 0, falls nichts eingegeben wurde, und 1 sonst. In Select-Boxen mit
Mehrfachauswahl kann dieser Zähler natürlich auch größere Werte annehmen. Jede einzelne Auswahl
kann dann mittels der dritten Schreibweise einzeln angesprochen werden, der Zählindex beginnt bei 0.
Die Ausgabe innerhalb eines Programmabschnitts ist ebenfalls einfach. Konstante Inhalte werden am
Einfachsten dadurch ausgegeben, dass der Programmabschnitt beendet und nach der Ausgabe der Zeichenkette wieder begonnen wird:
… %>
Dies ist eine konstante Zeichenkette
<% …
Es ist zu beachten, dass mit dem Beenden eines Programmabschnitts nicht auch automatisch Programmblöcke ( { … } ) beendet werden. Eine geöffnete geschweifte Klammer muss innerhalb eines
ASP-Programms auch wieder geschlossen werden! Ansonsten erhalten wir einen Interpreter-Fehler.
Aus Sicht des ASP-Programms werden also HTML-Texte außerhalb von Programmabschnitten wie
Kommentare, also als nicht existent betrachtet.
Für die Ausgabe von Variablen existiert zunächst eine bereits angewandte Möglichkeit:
<%= Variablenname %>
Diese Ausgabemöglichkeit ist aber oft nicht flexibel genug. Genaugenommen ist diese Schreibweise
nur eine Abkürzung für
<% Response.Write( Variablenname ); %>
Das in ASP definierte Ausgabeobjekt Response ist also das Gegenstück zum Eingabeobjekt Request.
Mittels der Methode Write können Variablen und konstante Texte ausgegeben werden. Write erwartet
genau einen Parameter, entweder eine Zeichenkette oder einen numerischen Ausdruck. Dank der impliziten Typumwandlung können aber auch Zeichenketten und numerische Ausdrücke mittels des
Konkatenierungsoperators (‚+’) verknüpft werden, etwa wie folgt:
Response.Write( "Variableninhalt: " + Variablenname);
Es sollte nicht übersehen werden, dass zwar das Zeichen ‚\n’ innerhalb einer Zeichenkette verwendet
werden darf, in HTML-Dokumenten bei der Ausgabe aber keinerlei Wirkung zeigt. Stattdessen ist
einer der beiden HTML-Tags ‚<br>’ oder ‚<p>’ zu benutzen.
Multimedia Entwicklung (Teil2)
Edwin Schicker
12
3.4
Javascript
An dieser Stelle soll Javascript nicht ausführlich vorgestellt werden. Gute Referenzen finden wir in
Selfhtml und in der Online Dokumentation des Option Packs von Microsoft. Ganz grob ist Javascript
ein extrem abgespecktes Java, so stark abgespeckt, dass kaum Unterschiede zu C++ (außer bei Strings)
feststellbar sind. Eine ganz grobe Zusammenfassung sei hier gegeben:
Kontrollstrukturen (Schleifen und Verzweigungen), Anweisungsblöcke ( { … } ), Zuweisungen und
Kommentare sind wie in Java und C++ definiert! Ebenso können Funktionen definiert werden, die
dann in der gesamten Datei sichtbar sind. Natürlich sind auch die meisten Operatoren implementiert,
auch die Bindungshierarchie ist wie in Java aufgebaut.
Wichtige Unterschiede gibt es allerdings in der Handhabung von Variablen. Insbesondere müssen in
Javascript Variablen nicht vordefiniert werden. Es gibt also keine Int- oder Float-Variablen im herkömmlichen Sinne. Stattdessen gibt es vordefinierte Objekte, z.B. number, date oder string. Javascript
entscheidet bei der ersten Verwendung einer Variable, welchem Objekttyp diese Variable zugeordnet
wird. Bei String-Variablen ist bei der Verwendung der Operatoren ‚==’ und ‚!=’ Vorsicht geboten. Es
wird nicht der Inhalt der Objekte verglichen, sondern die Objekte selbst! Der Vergleich der Inhalte
funktioniert nur bei den anderen Vergleichsoperatoren. Auch leistet die Konkatenierung (‚+’) häufig
große Dienste. Die folgenden Zeilen vergleichen zwei Strings, die dritte Zeile ist allerdings semantisch
falsch:
if (str1 >= str2 && str1 <= str2)
if (str1.toString() == str2.toString())
if (str1 == str2)
// Fehler, da Vergleich der Objekte!
Bevor wir es vergessen: In Javascript muss eine Anweisung am Ende einer Zeile nicht mit einem Semikolon beendet werden. Die Anweisungen break und continue arbeiten wie bekannt, return darf allerdings nur innerhalb einer Funktion benutzt werden. Das „ASP-Hauptprogramm“ kann also nicht
einfach mit Javascript-Mitteln abgebrochen werden.
3.5
Übungsaufgaben
1. Schreiben Sie eine HTML-Seite, die mehrere Formulareingaben anfordert (Eingabefeld,
Checkbuttons, Radiobuttons). Durch Klick auf den Submit-Button werden diese Daten tabellarisch ausgegeben. Verwenden Sie die Methode post.
2. Wie Aufgabe 1, nur dass die Methode get verwendet wird.
3. Schreiben Sie eine HTML-Seite, die mehrere Multiple-Choice-Fragen enthält. Der Anwender
soll diese Fragen beantworten und dann den Submit-Button drücken. Werten Sie die Antworten aus und geben das Ergebnis zurück.
4 ActiveX Data Objects
Im letzten Kapitel haben wir kennengelernt, im Internet zu programmieren. Es fehlt noch der Datenbankzugriff. Hier gibt es einige Begriffe wie ADO (ActiveX Data Objects), ODBC (Open Database
Connectivity), OLE-DB (Object Linking and Embedding for Data Bases), die vorab geklärt werden
müssen. Anschließend wollen wir dann mittels ADO auf Datenbanken zugreifen.
4.1
ODBC, OLE DB
Zum Zugriff auf Datenbanken benötigen wir vordefinierte und international normierte Schnittstellen.
Eine solche Schnittstelle, die darüberhinaus weit verbreitet ist, ist Open Database Connectivity
(ODBC). Diese Schnittstelle wurde von DEC, Lotus, Microsoft und Sybase unter Federführung von
Kyle Geigers entwickelt, wurde 1992 definiert und ist heute ein Weltstandard. Insbesondere in der
Microsoftwelt ist es die Standardschnittstelle. Praktisch alle CGI-Programme (CGI = Common Gateway Interface) setzen auf der ODBC-Schnittstelle auf.
Multimedia Entwicklung (Teil2)
Edwin Schicker
13
Ziel dieser Schnittstelle ist es, dem Programmentwickler nur den Namen einer Datenbank weiterzugeben. Der physische Ort der Datenbank und der Typ der Datenbank werden ihm verborgen. Damit
kann ein Programm die Datenbank wechseln, ohne dass auch nur eine Zeile Code neu geschrieben
werden müsste. Die Verwaltung übernimmt ODBC. Das Programm selbst kennt also nur den ODBCDatenbanknamen. ODBC kapselt also die Datenbank und verwaltet weitere Details selbst. Die ausschließliche Zugriffssprache ist SQL (Structured Query Language).
Zum Zugriff auf Datenbanken über ODBC benötigt der WWW-Server folglich einen ODBC-Treiber.
In Windows existiert dazu in der Systemsteuerung der Eintrag „ODBC-Datenquellen“. Hier werden in
der Regel im Ordner System-DSN die entsprechenden Daten eingetragen. Zumindest der Pfad zur
Datenbank sollte angegeben werden.
Auch bei OLE-DB (OLE = Object Linking and Embedding) handelt es sich um eine Schnittstelle zwischen Datenbanken und den Benutzerprogrammen. Diese Schnittstelle wurde von Microsoft entwickelt und wurde in den letzten Jahren erheblich erweitert und verbessert. Diese Schnittstelle wird direkt von ADO (ActiveX Data Objects) unterstützt und gilt als sehr performant. Im Unterschied zu
ODBC ist OLE-DB nicht allein auf Datenbanken fixiert. Damit ist auch nicht mehr die Sprache SQL
als Zugriffssprache vorgeschrieben. OLE-DB kann dabei direkt oder über ODBC auf Datenbanken
zugreifen. Wir werden beide Wege kennenlernen. Der Weg über ODBC schottet die Datenbank sauber
vom Programm ab, so dass Datenbank-Änderungen (andere Datenbank, neuer Pfad) keine Änderungen am Programm erfordern. Der direkte Weg ohne ODBC spart wiederum eine Schnittstelle und ist
daher performanter. Betrachten wir jetzt den schematischen Weg vom Browser zu den Daten:
Multimedia Entwicklung (Teil2)
Edwin Schicker
14
In unseren Programmen werden wir über ADO auf Datenbanken zugreifen. Die Wege OLE-DB und
ODBC leiten wir nur an Hand eines entsprechenden Befehls ein. Der Hauptaufwand zur Datenbankprogrammierung liegt also bei ADO.
4.2
ActiveX Data Objects (ADO)
ADO ist eine Programmschnittstelle zum Zugriff auf Datenbanken. ADO ist nahtlos in ASP eingebettet. Genaugenommen stellt ADO nur einige zusätzliche Objekte zur Verfügung. Diese Objekte unterstützen den Aufbau einer Verbindung zu einer Datenbank und deren Zugriff. Wir benötigen aus ASP
folgende Objekte:
•
•
•
Request-Objekt zum Lesen der übergebenen Daten
Response-Objekt zur Ausgabe von Daten
Server-Objekt zum Verwalten von Informationen und Strukturen
Wir benötigen von ADO die folgenden Objekte:
•
•
•
•
•
Connection-Objekt zum Verbindungsaufbau zur Datenbank
RecordSet-Objekt zum Auslesen der Daten aus der Datenbank
Command-Objekt zum Auslesen und Schreiben in die Datenbank
Field-Objekt zum Lesen einzelner Datenfelder (Attribute)
Error-Objekt zur Fehlerbehandlung
Grau ist jede Theorie. Wir wollen die einzelnen Möglichkeiten an Beispielen kennenlernen.
4.3
Erster Zugriff auf Datenbanken
Wir wollen eine Verbindung zur Beispieldatenbank Radl herstellen. Dazu setzen wir voraus, dass auf
dem WWW-Server die Datenbank Radl eingerichtet ist und eine ODBC-Verbindung zu dieser Datenbank hergestellt wurde.
Wir wollen nun aus der Relation Personal den Namen und den Wohnort des Mitarbeiters auslesen, der
die Personalnummer 2 besitzt. Der entsprechende SQL-Befehl ist einfach und lautet:
Select Name, Ort From Personal Where Persnr = 2;
Diesen Befehl müssen wir jetzt in unserem ASP-Programm unterbringen. Wir benötigen dazu folgende Schritte:
•
•
•
•
Verbindungsaufbau und Einloggen in die Datenbank
Senden des Select-Befehls
Empfang und Auswerten der Daten
Schließen der Datenbank
Diese vier Schritte werden mit Hilfe von ADO-Objekten realisiert. Die Umgebung bleibt weiterhin
ASP, die Programmiersprache Javascript. Betrachten wir gleich das vollständige Beispiel:
<%@ LANGUAGE = "JScript" %>
<html>
<head>
<title>Erster DB-Zugriff</title>
</head>
<body>
<center><h1>Vorlesung ME</h1></center>
<center><h3>Edwin Schicker</h3></center>
Multimedia Entwicklung (Teil2)
Edwin Schicker
15
Es erfolgt ein Einloggen in die Datenbank RADL mit dem ODBC-Namen "Radl".
Name und Ort des Mitarbeiters mit Persnr 2 wird ausgegeben, falls existent!
<p>
<%
Response.Write("Verbindung zur Datenbank herstellen.<br>");
conn = Server.CreateObject("ADODB.Connection");
// Verbindungs-Objekt
conn.Provider = "Microsoft.Jet.OLEDB.4.0"
// MS-Access-Treiber
conn.Open("F:\\user\\XXXXXXXX\\public_html\\Radl.mdb");
// Pfad
if (conn.Errors.Count==0)
// kein Fehler
{
Response.Write("Die Verbindung zur Datenbank wurde hergestellt.<p>");
// Die Datenbank ist geoeffnet, jetzt wird zugegriffen:
sqlstring = "Select Name, Ort From Personal Where Persnr = 2";
suchliste = conn.Execute(sqlstring);
// Select-Befehl ausfuehren
// Ausgeben der gelesenen Daten:
if (!suchliste.EOF) {
%>
<%
%>
<%
Mitarbeiter (Persnr 2):
<%= suchliste("Name")%>
aus <%= suchliste("Ort")%>
} else {
Der Mitarbeiter mit der angegebenen Nummer existiert nicht!
}
Response.Write("<p>Die Verbindung zur Datenbank wird geschlossen.");
conn.Close()
}
else
// Fehler beim Einloggen
{
Response.Write("Fehler beim Verbindungsaufbau: " + conn.Errors(0));
}
%>
</body>
</html>
Betrachten wir das kleine Programm Zeile für Zeile. Die Methode CreateObject des Server-Objekts
erzeugt ein neues Connection-Objekt, in dem die gesamten Verbindungsdaten aufgenommen werden.
Die Variable conn ist also ein Zeiger auf ein solches Connection-Objekt und wird im Folgenden für
alle Verbindungen zu unserer Datenbank benötigt. Die Methode Open des Connection-Objekts stellt
eine Verbindung zu einer Datenbank her und öffnet diese. Wir geben dazu vorher den MS-AccessTreiber an, um eine direkte OLE-DB-Verbindung zu erhalten. Als Open-Parameter ist die MS-AccessDatenbank anzugeben. Wurde diese Zeile erfolgreich abgearbeitet, so ist die Verbindung zur Datenbank hergestellt und aktiviert. Die Datenbankverbindung wird erst mit der Methode Close wieder
aufgegeben. Wird die Datenbank nicht explizit wieder geschlossen, so wird nach einer vordefinierten
Zeit (ca. 15 Minuten) die Verbindung automatisch abgebrochen. Diese Zeitspanne kann mittels ADO
auch geändert werden.
Möglicherweise gibt es Probleme beim Einloggen in die Datenbank. In diesem Falle werden Fehlermeldungen erzeugt, die mittels des Error-Objekts abgefragt werden können. Die Methode Count zählt
die Fehlermeldungen und die Indizierung erlaubt die Ausgabe der einzelnen Fehler. Im Fehlerfall
(Count > 1) wird an das Ende des Programms verzweigt, die erste Fehlermeldung wird ausgegeben.
Nach erfolgreichem Einloggen wird der Select-Befehl abgeschickt. Dies wurde im Programm in zwei
Schritten erledigt. Erst wird der Select-Befehl einer String-Variablen zugewiesen und dann wird die
Methode Execute des Connection-Objekts aufgerufen. Diese Methode führt die übergebene ZeichenMultimedia Entwicklung (Teil2)
Edwin Schicker
16
kette als Befehl aus, baut eine Liste auf, speichert die erhaltenen Daten dort ab und gibt einen Zeiger
auf diese Liste zurück.
Alle Listen besitzen die Methode Count. Wurden keine Daten zurückgeliefert, so ist die Liste leer und
der Zähler ist gleich Null. Andernfalls liegen Daten vor. Diese Daten werden mit dem Attributsnamen
angesprochen. Es ist zu beachten, dass also gegebenenfalls Aliasnamen im Select-Befehl verwendet
werden müssen, um erlaubte Bezeichner zu erhalten.
Wie bereits im vorigen Abschnitt erwähnt wurde, ist der Zugriff über ODBC etwas imperformant.
Dafür muss im Programm kein Pfad und kein Treiber angegeben werden (diese Angaben finden wir
direkt in ODBC), die Datenbank kann daher ohne Code-Änderung gewechselt werden (nur Eintragsänderung in ODBC). Die Anweisungen im Programm lauten jetzt einfach:
conn = Server.CreateObject("ADODB.Connection");
conn.Open("Radl");
// Angabe des ODBC-Namens
// internes Objekt
Die erste Zeile blieb unverändert. Der Open-Befehl enthält jetzt nur den eingetragenen ODBC-Namen.
Wird die Eigenschaft Provider nicht gesetzt, so wird standardmäßig der ODBC-Treiber gewählt. Der
Treiber für Access-Datenbanken lautet immer Microsoft.Jet.OLEDB.x, wobei x die aktuelle Version
angibt (zur Zeit 4.0). Um bei Änderung des Treibers und/oder der Datenbank nicht immer das Programm ändern zu müssen, gibt es auch die Möglichkeit, diese Daten aus einer Datei zu lesen, worauf
wir aber nicht näher eingehen.
Da auf dem Server nicht für jeden Benutzer ein ODBC-Eintrag existiert, müssen wir beim Zugriff auf
eine Datenbank im Rahmen der Vorlesung immer den Provider und den Pfad der Datenbank angeben!
4.4
Suche mehrerer Daten in Datenbanken
Im letzten Abschnitt haben wir nur eine ganz bestimmte Zeile ausgelesen. Wir wollen jetzt wesentlich
flexibler mit Datenbanken umgehen. Wir geben dazu einen Suchbegriff ein und erhalten kein, ein oder
mehrere Resultate. Das dazugehörige Handling wollen wir jetzt kennenlernen.
Bleiben wir dazu bei der Relation Personal. Wir geben einen String ein, und anschließend werden alle
Namen zusammen mit Personalnummer, Wohnort, Geburtsdatum und Gehalt ausgegeben, die diesen
String in ihrem Namen enthalten. Groß- und Kleinschreibung spiele dabei keine Rolle.
Wir schreiben dazu eine HTML-Seite, die ein entsprechendes Eingabefeld enthält. Beim Absenden
wird eine ASP-Seite aufgerufen, die die Eingabe liest, die Datenbank öffnet, die Daten abruft und
dann in Tabellenform ausgibt. Betrachten wir zunächst den wesentlichen Ausschnitt aus der Datei
mitarbeiter.html:
<form action="mitarbeiter.asp" method="post">
<table cellpadding=10>
<tr>
<td align=right>Bitte geben Sie die gesuchten Zeichen ein:
</td>
<td> <!-- Eingabefeld: -->
<input size=30 maxlength=30 name=Name>
</td>
</tr>
<tr>
<td>
</td>
<td align=right> <input type="Submit" value="Weiter"> <!-- Submit -->
</td>
</tr>
</table>
</form>
Wir erkennen eine Formular- und eine Tabellendefinition. Die Tabelle wurde nur wegen der besseren
Übersichtlichkeit gewählt. Das Formular ruft beim Absenden mit dem Submit-Button die Datei mitarMultimedia Entwicklung (Teil2)
Edwin Schicker
17
beiter.asp auf, die eingegebenen Daten im Eingabefeld namens „Name“ werden mit der Methode post
weitergereicht. Betrachten wir gleich die entsprechenden Daten in der Datei mitarbeiter.asp:
<% // Der eingelesene Teilstring wird ermittelt:
name = new String(Request.Form("Name"));
// eigenes Stringobjekt
name = name.replace(/\s*$/, "");
// entspricht einem RTrim!
if (name.length == 0)
{
%>
Es wurden im Formular keine Angaben gemacht.
<% }
else
{
%>
Die Datenbank Radl wird jetzt nach allen Mitarbeitern durchsucht,
die im Namen den Teilstring "<i><%= name%></i>" enthalten.
<p>
<%
// Aufbau einer DB-Verbindung:
conn = Server.CreateObject("ADODB.Connection");
// ADO-Verbindung
conn.Provider = "Microsoft.Jet.OLEDB.4.0"
// ohne ODBC
conn.Open("F:\\user\\XXXXXXXX\\public_html\\Radl.mdb "); // DB oeffnen
if (conn.Errors.Count==0)
// kein Fehler
{
// Die Datenbank ist geoeffnet, jetzt wird zugegriffen:
sqlstring = "Select Persnr, Name, Ort, GebDatum, Gehalt " +
"From Personal " +
"Where Ucase(Name) Like Ucase('%" + name + "%')";
suchliste = conn.Execute(sqlstring);
// SQL-Befehl ausfuehren
Unterbrechen wir das Programm an dieser Stelle. Wir finden zwar zum großen Teil Altbekanntes,
doch gleichzeitig auch eine Menge neuen Code. Gleich zu Beginn haben wir die übergebenen Daten
zwar wie bisher mit der Methode Request.Form ausgelesen, jedoch nicht direkt an die Variable name
weitergegeben. Stattdessen wurde ein neues Stringobjekt mit dem Operator new definiert. Dieser Operator erzeugt ein neues Stringobjekt und kopiert die Daten im angegebenen Parameter in dieses Objekt. Die Variable name verweist mittels der Zuweisung auf dieses Objekt. In unserem Beispiel ist
dieses Vorgehen notwendig, da wir auf das Stringobjekt die Methode Replace anwenden. Diese Methode kann nur auf ein Stringobjekt angewendet werden, Request.Form("Name") ist aber kein Stringobjekt!
Die hier verwendete Methode Replace entspricht einem Right Trim (Entfernen aller Whitespaces am
Ende eines Strings). Leider ist in Javascript kein Trim-Operator definiert und muss relativ komplex
nachgebildet werden. Der erste Parameter von Replace enthält einen Suchstring, der mittels Schrägstriche ('/') geklammert wird. Das Zeichen '\s' steht für ein Whitespace, zusammen mit dem folgenden
Zeichen '*' werden beliebig viele Whitespaces angesprochen. Das Zeichen '$' steht für das Stringende.
Der Suchstring ist also eine beliebige Folge von Whitespaces am Ende eines Strings. Der Ersetzstring
steht im zweiten Parameter und ist hier der Leerstring. Wir sehen, dass wir tatsächlich einen Right
Trim nachgebildet haben.
Der weitere Code ist einfacher. Wir überprüfen, ob das Eingabefeld tatsächlich Daten enthält. Wenn
nicht, so wird eine entsprechende Meldung ausgegeben und das Programm wird beendet. Ansonsten
wird eine Verbindung zur Datenbank aufgebaut. Wieder greifen wir direkt mit OLE-DB zu. Es ist zu
beachten, dass innerhalb eines Javastrings ein Rückstrich ('\') als Entwertungszeichen interpretiert
wird. Aus diesem Grund muss als Trenner von Verzeichnispfaden die Folge '\\' eingegeben werden.
Der Select-Befehl sollte keine Schwierigkeiten bereiten. Um nicht zwischen Groß- und Kleinschreibung zu unterscheiden, werden die zu vergleichenden Daten zunächst in Großbuchstaben umgewandelt. Die entsprechende Funktion in Access heißt Ucase.
Mit dem Execute-Befehl wurden alle gesuchten Daten aus der Datenbank in eine Liste eingelesen. Wir
müssen diese Daten jetzt in einer Schleife auf den Browser ausgeben. Wieder empfiehlt sich die Verwendung einer Tabelle. Betrachten wir dazu den Rest des Programms:
Multimedia Entwicklung (Teil2)
Edwin Schicker
18
// Ausgeben der gelesenen Daten:
if (suchliste.EOF) {
%>
Mitarbeiter mit dem Teilstring im Namen existiert nicht!
} else {
// Daten ausgeben:
<%
%>
Ergebnis:
<br>
<table border cellpadding=10>
<tr> <!-- Ueberschriftenzeile: -->
<th>Persnr </th>
<th>Name </th>
<th>Ort </th>
<th>GebDatum </th>
<th>Gehalt </th>
</tr>
<%
// In einer Schleife werden die Daten ausgelesen:
while (!suchliste.EOF) {
%>
<tr>
<!-- Die ausgelesenen Daten werden gleich in die Tabelle uebernommen: -->
<td> <%= suchliste("Persnr") %> </td>
<td> <%= suchliste("Name") %> </td>
<td> <%= suchliste("Ort") %> </td>
<td> <%= suchliste("GebDatum") %> </td>
<td> <%= suchliste("Gehalt") %> </td>
</tr>
<%
suchliste.MoveNext();
// naechsten Datensatz lesen
}
%>
</table>
<%
}
// Die Datenbank wird jetzt geschlossen:
conn.Close();
}
else
// Fehler beim Oeffnen der Datenbank
{
Response.Write("Fehler beim Verbindungsaufbau:" + conn.Errors(0));
}
}
%>
Wir überprüfen also zunächst, ob es Daten mit den gewünschten Eigenschaften überhaupt gibt. Wenn
ja, so bauen wir eine Tabelle auf. Wird in einer Tabelle statt der Spaltenangabe <td> die Angabe
<th> geschrieben, so interpretiert dies der Browser als Überschriftenzeile. Meist werden diese Spalten
dann fett gedruckt und zentriert ausgegeben.
In einer While-Schleife werden die Daten aus der Suchliste gelesen. Zum nächsten Datensatz in der
Suchliste gelangen wir mit der Methode MoveNext. Die Eigenschaft EOF teilt uns das Ende der Daten
mit.
4.5
Mehrfacher Zugriff auf Datenbank
Mit dem bisherigen Wissen kommen wir in den meisten Fällen aus. Wir wollen dieses Wissen jetzt
vertiefen, zusätzlich Auswahllisten generieren und weitere Zugriffsmöglichkeiten auf Datenbanken
mittels ADO kennenlernen. Schließlich sollen aus Performancegründen Datenbanken auch über mehrere ASP-Seiten hinweg geöffnet bleiben. Wir wollen diese neuen Möglichkeiten wieder an einem
Beispiel kennenlernen.
Multimedia Entwicklung (Teil2)
Edwin Schicker
19
Das Beispiel in diesem Kapitel liest einen Kunden- und einen Teilenamen ein. Anschließend werden
alle Auftragsdaten, die diesen Kunden und dieses Teil betreffen, ausgegeben. Bei der Eingabe eines
Kunden oder eines Teils können Fehler auftreten. Um dies zu vermeiden, werden in einer Auswahlliste alle existierenden Kunden und Teile angezeigt. Der Benutzer muss nur noch jeweils einen Eintrag
auswählen. Betrachten wir dazu die fertige HTML-Seite:
Wir erkennen zwei Drop-Down-Boxen. Diese enthalten alle Kundennamen und alle bestellbaren Teile.
Wir betrachten nicht den gesamten HTML/ASP/ADO-Code, da viele Teile bereits bekannt sind. Stattdessen picken wir die neuen interessanten Teile heraus. Wir loggen uns wieder direkt mittels OLE-DB
in die Datenbank ein. Neu ist jetzt, dass wir uns diese Verbindung in einer sogenannten Sessionvariable merken. Das in ASP definierte Session-Objekt kann beliebige Variablen über eine gesamte Sitzung
global speichern, insbesondere über mehrere ASP-Seiten hinweg. Dies geschieht wie folgt:
// Die Datenbank ist geoeffnet. Die Verbindungsdaten werden gemerkt:
Session("_conn") = conn;
// Sessionvariable _conn
Der Name der Sessionvariable ist im Rahmen eines erlaubten Javascript-Namens frei wählbar. Wir
haben uns hier für den Namen _conn entschieden. Auf diese Variable werden wir später zurückgreifen. Die Kunden- und Teiledaten werden wie folgt eingelesen:
// Jetzt werden Kunden und Teile gelesen:
sqlstring = "Select Nr, Name From Kunde;";
suchliste1 = conn.Execute(sqlstring);
// Kunden einlesen
sqlstring = "Select Teilnr, Bezeichnung From Teilestamm;";
suchliste2 = conn.Execute(sqlstring);
// Teiledaten einlesen
Zur Ausgabe im Browser haben wir eine Tabelle gewählt, die in der rechten Spalte je eine Auswahlliste enthält. Betrachten wir nur die erste der beiden Auswahllisten. Die zweite ist analog aufgebaut:
<td align=right>Bitte wählen Sie einen Kunden aus: </td>
<td><!-- Select Box: -->
<select name="Kundnr" size=1>
<!-- size=1: Drop Down Box -->
<%
// Auslesen der Daten fuer die Select-Box in einer Schleife:
while (!suchliste1.EOF) {
%>
<option value="<%=suchliste1("Nr")%>"><%=suchliste1("Name")%>
<%
suchliste1.MoveNext();
// naechsten Datensatz lesen
}
%>
Multimedia Entwicklung (Teil2)
Edwin Schicker
20
</select>
</td>
Die Auswahlliste erhalten wir mit dem Select-Tag. Der Parameter size=1 liefert eine Drop-Down-Box,
wie wir sie in obigem Bild erkennen können. In einer Schleife lesen wir nun die erhaltenen Daten aus
der Liste und geben diese gleich an die Auswahlliste weiter. Der Option-Tag besitzt den Parameter
value. Hier kann man einen Wert angeben, der statt der Auswahl weitergegeben wird. Es ist in der
Praxis meist nützlich, nicht den Kundennamen, sondern die Kundennummer weiterzureichen. Dies
haben wir hier auch angewendet. Im Browserfenster erscheint also der Kundenname, weitergereicht
wird jedoch die Kundennummer, genauer: der Wert, der im Value-Parameter angegeben wird.
Mit der Auflistung der Teile gehen wir analog vor. Wir zeigen die Teile an, reichen jedoch die Teilenummer weiter. Ein Submit-Button mit dem Namen Weiter rundet unsere Ausgabe ab. Beim Klick auf
diesen Button wird die Datei auswahlfeld2.asp aufgerufen. In dieser Datei werden die beiden übergebenen Parameter und die Sessionvariable ausgelesen. Es ist zu beachten, dass wir in der vorhergehenden Datei die Datenbank nicht geschlossen hatten. Wir brauchen diese daher nicht nochmals zu öffnen, sondern können sofort zugreifen:
<% // Die
Kundnr
Teilnr
// Die
conn =
Angaben in den Select Boxen werden ermittelt:
= Request.Form("Kundnr");
= Request.Form("Teilnr");
Datenbankverbindungsdaten werden aus der Sessionvariable geholt:
Session("_conn");
// Die Datenbank ist noch geoeffnet:
sqlstring = "Select A.Auftrnr As Auftrag, Datum, Persnr, " +
"Anzahl, Gesamtpreis " +
"From
Auftrag A, Auftragsposten AP " +
"Where A.Auftrnr = AP.Auftrnr " +
" And Kundnr = " + Kundnr +
" And Teilenr = " + Teilnr + ";"
// Wir verwenden jetzt einen Recordset zum Zugriff auf Datenbanken:
recSet = Server.CreateObject ("ADODB.Recordset")
// RecordSet
recSet.Open(sqlstring, conn)
Im Select-Befehl zum Auslesen der gewünschten Daten müssen wir beachten, dass wir Aliasnamen
verwenden müssen, wenn wir im Select-Teil Ausdrücke verwenden. Auch die Qualifizierung einer
Variable, hier A.Auftrnr, fällt darunter. Wir können nämlich aus der Recordliste nur Variablen auslesen, die der Syntax erlaubter Bezeichner genügen.
Weiter greifen wir jetzt nicht mehr direkt mit dem Connection-Objekt auf die Datenbank zu, sondern
erzeugen einen sogenannten Recordset. Das Öffnen dieses Recordsets mittels der Methode Open unter
Angabe der Verbindung conn als zweiten Parameter führt jetzt zum Zugriff auf die Datenbank und
entspricht der Execute-Methode des Connection-Objekts.
Der Zugriff mittels Recordsets ist dahingehend aufwendiger, dass zunächst ein Recordset-Objekt mittels der Servermethode CreateObject erzeugt werden muss. Der Vorteil eines Recordsets gegenüber
dem direkten Arbeiten mit dem Connection-Objekt liegt aber darin, dass wir den Cursor, der die Daten
in die Recordliste ausliest, entsprechend unseren Wünschen einstellen können. Wir wollen hier keinen
Gebrauch davon machen, einige Möglichkeiten aber aufzählen:
Methode Update: Erlaubt den Update an der aktuellen Cursorposition. Dies entspricht in SQL
dem Befehl Update … Where Current of …
Property Cachesize: Die Cachegröße beeinflusst die Performance erheblich. Angegeben wird
die Anzahl der Records, die im Cache gehalten werden sollen. Diese Zahl muss größer als
Null sein.
Property CursorLocation: Der Cursor kann auf dem Server (adUseServer) oder auf dem Client
(adUseClient) gehalten werden. Ein Cursor auf dem Client erfordert, dass zunächst alle Daten
vom Server auf den Client übertragen werden müssen. Beispielsweise liefert die Property
Multimedia Entwicklung (Teil2)
Edwin Schicker
21
RecordCount nur im Falle eines Client-Cursors die Anzahl der Records zurück (ein ServerCursor liefert hier den Wert –1).
Property CursorType: Hier kann angegeben werden, wie sich der Cursor durch die Recordliste
bewegen kann. Beispielsweise erlaubt der Typ adOpenForwardOnly nur ein Vorwärtsbewegen durch die Liste. Dies ist auch die Standardeinstellung.
Property LockType: Beim Durchsuchen und eventuellem Update sind Lockmechanismen
erforderlich, um einen korrekten Parallelbetrieb zu ermöglichen. Standardmäßig ist der Wert
adLockReadOnly eingestellt. Es darf nur gelesen werden.
Diese Beispiele sollten hinreichend erklären, warum Recordlisten den einfachen Connectionlisten
vorzuziehen sind. Das Objekt Connect erlaubt aus der obigen Aufzählung nur die Property CursorLocation. Um obige Properties zu setzen, muss die entsprechende Zuweisung vor der Open-Methode
erfolgen!
Das Auslesen der Recordlisten entspricht in unseren Fällen dem Auslesen der Connectionlisten. Doch
sehen wir selbst:
// Ausgeben der gelesenen Daten:
if (recSet.EOF) {
%>
Der Kunde <%=Kundnr%> hat das Teil <%=Teilnr%> noch nicht bestellt.
<p>
} else {
<%
%>
Der Kunde <%=Kundnr%> hat Teil <%=Teilnr%> wie folgt bestellt:
<p>
<table border cellpadding=10>
<tr>
<!-- Kopfzeile definieren (mit <th> statt <td>: -->
<th>Auftragsnr </th>
<th>Auftragsdatum </th>
<th>Verkäufernr </th>
<th>Anzahl </th>
<th>Gesamtpreist </th>
</tr>
<%
while (!recSet.EOF) {
// Auslesen der Daten:
%>
<tr>
<!-- Die ausgelesenen Daten kommen gleich in die Tabelle: -->
<td> <%= recSet("Auftrag") %> </td>
<td> <%= recSet("Datum") %> </td>
<td> <%= recSet("Persnr") %> </td>
<td> <%= recSet("Anzahl") %> </td>
<td> <%= recSet("Gesamtpreis") %> </td>
</tr>
<%
recSet.MoveNext();
// naechsten Datensatz lesen
}
%>
</table>
<%
}
// Die Datenbank wird jetzt geschlossen:
Session("_conn") = null;
// Schliessen der Sessionvariable
conn.Close();
}
%>
Multimedia Entwicklung (Teil2)
Edwin Schicker
22
Aus programmtechnischen Gründen sollte mit dem Schließen der Datenbank das entsprechende Session-Objekt _conn auf Null gesetzt werden. Somit wird nicht versehentlich versucht, auf eine geschlossene Datenbank zuzugreifen.
4.6
Transaktionen
Bisher haben wir nur lesend auf die Radl-Datenbank zugegriffen. Das Schreiben in eine Datenbank ist
aber genauso einfach. Wir müssen dazu lediglich im SQL-String einen Schreibbefehl einfügen. In der
Regel erfordert aber ein Arbeitsvorgang, etwa eine Buchung, mehrere Schreibzugriffe. Es muss hier
sichergestellt werden, dass alle diese Schreibzugriffe auch vollständig ausgeführt werden. Sollte ein
Schreibzugriff misslingen, so ist der gesamte Arbeitsvorgang zurückzusetzen.
Einen solchen Arbeitsvorgang nennt man eine Transaktion. In einer Datenbank wird sichergestellt,
dass Transaktionen immer vollständig ausgeführt werden. Im Fehlerfall werden alle bereits ausgeführten Änderungen wieder zurückgenommen. Gerade im ECommerce-Bereich und im Internet-Banking-Bereich ist dieser Transaktionsmechanismus zwingend erforderlich. Auch unser Zugriff auf Datenbanken über das Internet muss also Transaktionen voll unterstützen.
Hier scheidet sich jetzt das Spreu vom Weizen. Einfache CGI-Programme können Transaktionen vom
Prinzip her nicht unterstützen, da jede Aktion von der anderen unabhängig erfolgt. Nur durch komplexe Programmierung können hier einfache Transaktionen nachgebildet werden. Aus Sicherheitsgründen sollten wir aber keine Risiken eingehen und nur mit WWW-Servern arbeiten, die Datenbanktransaktionen mit eigenen Mechanismen zusätzlich unterstützen.
Zusätzlich zu ASP und ADO bietet hier Microsoft den Microsoft Transaction Server (MTS) an. Die
Möglichkeiten sind enorm. Wir wollen hier nur den Grundmechanismus im Zusammenspiel mit ASP
und ADO kennenlernen.
Wir benötigen genaugenommen zwei Transaktionsmechanismen, die Datenbanktransaktion und die
Programmtransaktion. Beide müssen korrekt zusammenarbeiten. Datenbanktransaktionen unterstützt
ADO, die entsprechenden Methoden des Connection-Objekts lauten:
BeginTrans( )
CommitTrans( )
RollbackTrans( )
Die Methode BeginTrans ist nur in Datenbanken erforderlich, die nicht automatisch nach einem
Commit die nächste Transaktion starten, wie etwa in MS-Access. Die Methode CommitTrans beendet
eine Transaktion, die Methode RollbackTrans setzt die gesamte Transaktion zurück.
Insbesondere bei einem auftretenden Fehler beim Datenbankzugriff oder im Programm muss die Methode RollbackTrans aufgerufen werden. Dies muss aber jetzt programmtechnisch gelöst werden. Hier
kommt MTS ins Spiel. Wir müssen dazu nur die erste Zeile unseres ASP-Programms erweitern:
<%@ TRANSACTION=Required LANGUAGE = "JScript" %>
Zusätzlich zu unserer Sprachangabe schalten wir auch den Transaktionsmechanismus ein. Im ASPProgramm ändert sich erfreulicherweise sehr wenig. Zum Einen benutzen wir jetzt unsere obigen
Transaktionsbefehle beim Zugriff auf die Datenbank. Zum Anderen ruft MTS nach dem Ablauf des
ASP-Programms eine der folgenden Funktionen auf (falls definiert):
OnTransactionCommit()
OnTransactionAbort()
// Erfolgreiches Beenden des ASP-Programms
// Fehlerhaftes Beenden des ASP-Programms
Wurde das ASP-Programm korrekt ausgeführt, so wird am Ende des Programms automatisch die
Funktion OnTransactionCommit aufgerufen. Wir definieren daher diese Funktion und schreiben hier
auch den Datenbank-Commit-Befehl.
Stößt das ASP-Programm während des Arbeitens auf einen Fehler, so wird das Programm verlassen
und die Funktion OnTransactionAbort aufgerufen. Hier ist jetzt der ideale Platz, um den DatenbankRollback-Befehl auszuführen.
Multimedia Entwicklung (Teil2)
Edwin Schicker
23
Es sei dringend darauf hingewiesen, dass MTS genau darauf achtet, dass sich der Programmierer an
diesen Mechanismus hält. Aus diesem Grund sind in MTS die Methoden CommitTrans und RollbackTrans im normalen Programmcode nicht erlaubt. Sie dürfen nur innerhalb der beiden oben erwähnten Funktionen geschrieben werden!
Wieder wollen wir an Hand eines Beispieles diesen Mechanismus verstehen lernen. Wir wollen dazu
einen neuen Auftrag in die Radl-Datenbank aufnehmen. Einfachheitshalber gehen wir davon aus, dass
höchstens zwei Auftragsposten je Auftrag existieren. Im Programm transaktion1.asp sind die notwendigen Daten einzugeben. Eine neue Auftragsnummer und das aktuelle Datum werden automatisch
vorgegeben. Die Namen der Kunden und Mitarbeiter werden in einer Drop-Down-Box angeboten. Bei
den beiden Auftragsposten wird die Positionsnummer ebenfalls vorgegeben, ebenso die Teilenamen in
einer Drop-Down-Box. Betrachten wir die Oberfläche:
Diese Oberfläche enthält fast keine neuen Elemente. Wir haben Drop-Down-Boxen und Eingabefelder
bereits kennengelernt. Die neue Auftragsnummer wird ermittelt, indem die bisherige maximale Auftragsnummer aus der Datenbank gelesen und um eins erhöht wird. Neu ist das Ermitteln des aktuellen
Datums und das Weiterreichen der Auftragsnummer und des Datums an die nächste ASP-Seite.
Das aktuelle Datum wird in ASP direkt mit der Methode new geliefert. Ein Problem ist, dass dieses
Datum auch die Uhrzeit enthält. Das Datum kann nicht direkt von der Uhrzeit getrennt werden. Wir
müssen stattdessen mit den entsprechenden Methoden den Tag, das Monat und das Jahr auslesen. Leider wird das Monat von 0 bis 11 gezählt. Sind diese Fallen aber alle bekannt, so löst folgender Code
unsere Probleme:
<%
// Heutiges Datum ermitteln:
datum = new Date();
Tag
= datum.getDate();
Monat = datum.getMonth() + 1;
Jahr = datum.getYear();
datum = Tag + "." + Monat + "."
// enthaelt auch die Uhrzeit!
// aktueller Tag
// Monatsangabe beginnt bei 0!
// aktuelles Jahr
+ Jahr;
%>
Multimedia Entwicklung (Teil2)
Edwin Schicker
24
Wir haben nun das Datum und mit einem Datenbankzugriff auch die neue Auftragsnummer ermittelt
und ausgegeben. Da diese Daten in keinem Formularfeld stehen, werden diese jedoch nicht an die
nächste Seite weitergereicht. Um dort diese Daten nicht noch einmal berechnen zu müssen, wurden
sogenannte versteckte Eingabefelder verwendet:
<td><%=suchliste3("Nr")%>
<!-- enthaelt neue Auftragsnummer -->
<!-- Die Auftragsnummer muss weitergegeben werden. Daher
wird ein verstecktes Eingabefeld verwendet! -->
<input type="hidden" NAME="AuftrNr" VALUE="<%= suchliste3("Nr") %>" >
</td>
Wir wenden uns jetzt der Datei transaktion2.asp zu, die vom obigen Programm aufgerufen wird. In
der ersten Zeile ist der Transaktionsbetrieb vermerkt. Weiter wird eine Variable ta eingeführt, die sich
merkt, ob eine Datenbanktransaktion gestartet wurde. Betrachten wir den Beginn des Programms, wo
alle notwendigen Daten eingelesen werden, die Datenbankverbindung überprüft und die Transaktion
begonnen wird.
<%
ta = 0;
// Transaktions-Variable
// Die übergebenen Angaben werden ermittelt:
Auftrnr = Request.Form("AuftrNr");
Datum
= Request.Form("Datum");
Kundnr = Request.Form("Kundnr");
Persnr = Request.Form("Persnr");
Teilnr1 = Request.Form("Teilnr1");
Anz1
= Request.Form("Anzahl1");
Teilnr2 = Request.Form("Teilnr2");
Anz2
= Request.Form("Anzahl2");
// Die Datenbankverbindung wird ueberprueft:
if (Session ("_conn") == null || (Anz1==0 && Anz2==0))
{
%>
Fehler! Die DB-Verbindung wurde unterbrochen oder die Variable Anzahl
wurde nicht gesetzt. Bitte geben Sie die Daten nochmals ein.
<p><center><a href="transaktion1.asp">Zurück</a></center></p>
<%
} else {
conn = Session("_conn");
// Die Datenbank ist noch geoeffnet.
//In Access muss der TA-Beginn explizit gesetzt werden:
conn.BeginTrans();
ta = 1;
// zeigt an, dass Transaktion gestartet wurde
// Neuen Auftrag einfuegen:
sqlstring = "Insert Into Auftrag(Auftrnr, Datum, Kundnr, Persnr) " +
"Values(" + Auftrnr + ",'" + Datum +"'," + Kundnr + "," +
Persnr + ");";
conn.Execute(sqlstring);
// Befehl ausführen
Wir erkennen, dass wieder die Sessionvariable _conn überprüft wird, die natürlich in transaktion1.asp
gesetzt wurde. Die Transaktion wird gestartet, die Variable ta wird auf den Wert 1 gesetzt. In die Variable sqlstring schreiben wir den Insert-Befehl und führen ihn mit der Execute-Methode aus. Die
anderen Schreibbefehle in die Relation Auftragsposten sind analog. Allerdings taucht dort eine kleine
Falle auf. Die Positionsnummer setzt sich nämlich zusammen aus der Auftragsnummer plus einem
fortlaufenden Zähler. Wollen wir mehr als 10 Auftragsposten pro Auftrag unterstützen, so wäre folgender Code innerhalb des Insert-Befehls für den ersten Auftragsposten denkbar:
"Values(" + Auftrnr + "," + (100*Auftrnr+1) +"," + Teilnr1 + ...
Multimedia Entwicklung (Teil2)
Edwin Schicker
25
Wir multiplizieren also die Auftragsnummer mit dem Wert 100 und addieren dazu die Zahl 1. Die
Falle besteht jetzt darin, dass die Klammern zwingend erforderlich sind, da Javascript den Plus-Operator sonst als Konkatenierungsoperator interpretiert!
Wurden die Schreibbefehle nun alle korrekt ausgeführt, so wird am Ende des Programms die Funktion
OnTransactionCommit aufgerufen. Diese Funktion haben wir am Ende des Programms (nach dem Tag
</html>) hinzugefügt:
<%
function OnTransactionCommit()
// MTS-Transaktion war erfolgreich
{
if (ta == 1)
// Transaktion war gestartet, also beenden:
{
conn.CommitTrans();
// Daten werden endgueltig gespeichert
Response.Write ("<p>Die Bestelldaten wurden aufgenommen.");
}
conn.Close();
// Verbindung schliessen
Session("_conn") = null;
%>
<p><center><a href="default.htm">Zurück zur Startseite</a></center></p>
<%
}
Im Wesentlichen haben wir in dieser Funktion nur die Methode CommitTrans aufgerufen und damit
die Transaktion beendet. Da wir nicht mehr auf die Datenbank zugreifen müssen, haben wir auch die
Verbindung geschlossen.
Sollte im Programm bei einem der Schreibbefehle ein Fehler aufgetreten sein, so wird MTS das Programm sofort beenden und die Funktion OnTransactionAbort aufrufen. Natürlich haben wir am Programmende deshalb auch diese Funktion definiert:
function OnTransactionAbort()
// MTS-Transaktion endet mit Fehler
{
if (ta == 1)
// Transaktion war gestartet:
{
conn.RollbackTrans()
// Daten werden zurueckgesetzt
Response.Write ("<p>Die Bestelldaten wurden nicht gespeichert.");
}
conn.Close();
// Verbindung schliessen
Session("_conn") = null;
%>
<p>
<p><center><a href="default.htm">Zurück zur Startseite</a></center></p>
<%
}
Diese Funktion unterscheidet sich von der vorherigen nur dadurch, dass die Methode RollbackTrans
aufgerufen wird. Eine begonnene Transaktion wird damit vollständig zurückgesetzt.
4.7
Weitere Möglichkeiten
Wir können mit dem bisherigen Wissen bereits sehr komplexe Datenbankzugriffe durchführen. Mit
der Zeit werden wir aber bemerken, dass einige Zusatzmöglichkeiten die Programmierung noch effizienter, die Performance noch besser werden lässt. Hier sei nur stichpunktartig auf einige Möglichkeiten verwiesen:
Command-Objekt: Das Command-Objekt ist ein ADO-Objekt und ermöglicht noch mehr Möglichkeiten als das Recordset-Objekt. Insbesondere bei mehreren sehr ähnlichen Datenbankzugriffen zeigen
Command-Objekte Vorteile, da hier mit Variablen gearbeitet werden kann, die vor jedem Befehl entsprechend gesetzt werden können. Diese Command-Objekte sollen bei komplexen Zugriffen performanter sein als Recordsets.
Multimedia Entwicklung (Teil2)
Edwin Schicker
26
MTS: Microsoft Transaction Server ermöglichen ein fast beliebiges Transaktionshandling. Natürlich
können Transaktionen auch über mehrere ASP-Seiten hinweg erfolgen. Hier empfiehlt sich das Lesen
der entsprechenden Online-Hilfe.
Debugging: Werden die Programme komplexer, so werden wir ohne entsprechende Debug-Unterstützung kaum mehr auskommen. Auch diese Unterstützung wird in ASP geboten.
4.8
Übungsaufgaben
1. Geben Sie alle Teile der Relation Teilestamm aus, insbesondere Teilnr, Bezeichnung, Preis,
Maß und Einheit.
2. Lesen Sie eine Zahl ein. Geben Sie dann alle Teile aus, deren Bestand unter diese Zahl gesunken ist. Geben Sie mindestens Teilenr, Bezeichnung und Bestand aus.
3. In einer Drop-Down-Box werden alle Teile angezeigt. Wählen Sie ein Teil aus. Alle Daten zu
diesem Teil werden angezeigt (aus Relation Teilestamm und Lager).
4. Fügen Sie ein neues Teil in die Datenbank hinzu. Aktualisieren Sie die Relationen Teilestamm
und Lager!
5 Überblick über weitere Möglichkeiten
An dieser Stelle sollen einige weiteren Möglichkeiten in ADO/ASP aufgezeigt werden. Zum Einen
wird das Application-Objekt vorgestellt, sozusagen ein Gegenstück zum Session-Objekt. Weiter wird
kurz auf die Datei Global.asa eingegangen. Hier können einige zentrale Daten und Ereignisse abgelegt
bzw. ausgeführt werden. Zuletzt seien noch einige weitere Möglichkeiten zum Zugriff auf Datenbanken aufgezeigt, etwa der Zugriff mittels des Command-Objekts.
5.1
Das Application-Objekt
Wir haben bereits das Session-Objekt kennengelernt. Dieses ermöglicht das Anlegen von Daten über
die gesamte Sitzung. Die Daten werden benutzerspezifisch verwaltet, so dass nur der augenblicklich
mit dem WWW-Server verbundene eindeutige Benutzer auf diese Daten zugreifen kann. Wir haben
mit dem Befehl
Session("_conn") = conn;
die aktuell hergestellte Verbindung in der Session-Variable _conn hinterlegt. Analog können wir auch
definieren:
Application("zaehler") = 0;
Diese Variable zaehler ist aber jetzt nicht für einen Benutzer sichtbar, sondern für alle Benutzer, die
auf diese Seite zugreifen. Eine Application-Variable ist also so lange gültig, so lange eine Seite vom
WWW-Server angeboten wird und dieser Server aktiv ist. Diese Variable ist für jeden zugreifenden
Benutzer sichtbar.
Wollen wir also wissen, wie oft auf eine Seite zugegriffen wurde, so können wir eine entsprechende
Variable definieren und diese bei jedem Seitenzugriff um den Wert 1 erhöhen. Das Problem ist jetzt
allerdings, dass womöglich zwei Benutzer gleichzeitig die Seite starten. Um Synchronisationsprobleme lösen zu können, besitzt das Application-Objekt die Methoden Lock( ) und Unlock( ).
Betrachten wir ein Beispiel: Wir wollen wissen, wie viele Benutzer die aktuelle Seite lesen, und wir
wollen wissen, wie viele Datenbankzugriffe insgesamt von dieser Seite aus erfolgen. Wir definieren
daher die beiden Application-Variablen zaehler und db_zaehler. Das Setzen auf den Wert 0 zu Beginn
erfolgt dabei beispielsweise wie folgt:
<%
if (Application("zaehler") == null)
Application("zaehler") = 0;
Multimedia Entwicklung (Teil2)
Edwin Schicker
27
if (Application("db_zaehler") == null)
Application("db_zaehler") = 0;
%>
Wir überprüfen also zunächst, ob die beiden Variablen bereits existieren, wenn nicht so werden sie auf
den Wert 0 gesetzt. Dies geschieht daher in einer Anwendung nur ein einziges Mal.
An der gewünschten Stelle im Programm können wir jetzt einen der Zähler erhöhen. Betrachten wir
dies am Beispiel der Variablen zaehler.
<%
Application.Lock();
Application("zaehler") = Application("zaehler") + 1;
Application.Unlock();
%>
Wir erkennen, dass wir das Manipulieren des Zählers in einem durch einen zentralen Lock geschützten
Bereich durchführen. Dadurch wird sichergestellt, dass die Erhöhung des Zählers immer korrekt erfolgt, unabhängig von etwaigen anderen parallel zugreifenden Benutzern.
Die Ausgabe eines solchen Zählers könnte wie folgt aussehen:
Auf diese Seite wurde bisher <% =Application("zaehler") %>-mal zugegriffen.
Diese Vorgehensweise ist so möglich, hat aber den Nachteil, dass dadurch der Code unnötigerweise
vergrößert wird. In der Praxis steht sowieso meist zu viel Code in einer Seite. Weiter wird bei jedem
Zugriff überprüft, ob die Application-Variablen bereits existieren. Hier kann die Datei Global.asa eine
große Hilfe sein.
5.2
Die Datei Global.asa
Eine komplette ADO/ASP-Anwendung kann aus vielen HTML- und ASP-Seiten bestehen, eventuell
noch über mehrere Unterverzeichnisse verteilt. Jede solche Anwendung darf im Hauptverzeichnis
genau eine Datei Global.asa enthalten. Diese Datei Global.asa kann globale Informationen aufnehmen, etwa wie die Anwendung beim Hochfahren und Herunterfahren des WWW-Servers reagieren
soll. Weiter können hier globale Objekte und Typen definiert werden.
Mit Hilfe dieser Datei können wir das im letzten Abschnitt behandelte Zählen der Benutzer aus der
ASP-Datei auslagern. Betrachten wir eine komplette Datei Global.asa:
<SCRIPT LANGUAGE="Jscript" RUNAT="Server">
function Application_OnStart()
{ Application("zaehler")
= 0;
Application("db_zaehler") = 0;
}
function Application_OnEnd() { }
function Session_OnStart()
{ Application.Lock();
Application("zaehler") = Application("zaehler") + 1;
Application.Unlock();
}
function Session_OnEnd() { }
</SCRIPT>
Hier wurden 4 Funktionen definiert. Die ersten Beiden werden beim Hochfahren und Herunterfahren
des Servers aufgerufen, die letzten beiden beim Zugriff eines neuen Benutzers und beim Beenden des
Benutzers (meist nach einer abgelaufenen Zeitspanne von 20 Minuten nach dem letzten Zugriff; diese
Zeitspanne ist einstellbar: Session.Timeout( ) ).
Multimedia Entwicklung (Teil2)
Edwin Schicker
28
Wir haben hier beim Hochfahren des Servers unsere Variablen initiiert und beim Start eines neuen
Benutzers wird der Zähler um den Wert 1 erhöht. Dieses Hochsetzen erfolgt immer dann, wenn ein
neuer Benutzer auf die Anwendung zugreift. Es ist dabei nicht notwendig, dass der Benutzer die Startseite öffnet, der Zugriff auf eine beliebige Seite der Anwendung genügt. Ein mehrmaliger Zugriff auf
eine der Seiten der Anwendung innerhalb einer Session führt dabei nicht nochmals zum Fortschalten
des Zählers!
5.3
Das Command-Objekt in ADO
Es gibt zahlreiche Anwendungen, wo mehrere ähnliche SQL-Anforderungen nacheinander an den DBServer geschickt werden. Unterscheiden sich diese SQL-Befehle nur durch ein, zwei oder drei Angaben, so können wir sehr geschickt das Command-Objekt einsetzen. Betrachten wir dazu ein Beispiel:
Wir wollen das Gehalt der Mitarbeiter erhöhen. Wir geben dazu die Namen der Mitarbeiter in einer
Select-Box aus. Die gewünschten Mitarbeiter können nun ausgewählt werden. Bei allen angegebenen
Mitarbeitern wird dann das Gehalt um 2% erhöht.
Wir benötigen für diese Aufgabe zwei ASP-Dateien. In der ersten Datei namens command1.asp wird
die Datenbank geöffnet und die Mitarbeiterdaten werden in einer Select-Box ausgegeben. Beim Klick
auf den Button für die Gehaltserhöhung wird die zweite Datei namens command2.asp aufgerufen. Die
erste Datei bereitet keine Probleme, der Stoff wurde bereits weiter oben behandelt. Als kleine Wiederholung wird der Aufbau der Select-Box trotzdem wiedergegeben:
<form action="command2.asp" method="post">
<!-- Select Box: -->
<select name="Persnr" size=6 multiple> <!-- 6er-Box, Mehrfachauswahl -->
<%
// In einer Schleife die Daten fuer die Select Box auslesen:
while (!suchliste.EOF) {
%>
<option value="<%=suchliste("Persnr")%>"><%=suchliste("Name")%>
<%
suchliste.MoveNext();
// naechsten Datensatz lesen
}
%>
</select>
<p> <input type="Submit" value="Gehaltserhöhung!">
</form>
Wir erkennen hier eine Select-Box mit Mehrfachauswahl, in der die Mitarbeiternamen ausgegeben,
deren Personalnummern aber an die Datei command2.asp weitergereicht werden.
Die Datei command.asp muss nun die übergebenen Daten verarbeiten. Optimal wäre das Abschicken
eines einzigen Update-Befehls. Dies ist allerdings ohne dynamisches SQL kaum möglich, da ja von
vorneherein nicht bekannt ist, welche und wie viele Mitarbeiter eine Gehaltserhöhung erhalten. Wir
behelfen uns daher damit, je ausgewähltem Mitarbeiter einen Update-Befehl zu schreiben. Hier hilft
uns jetzt das Command-Objekt weiter, da sich die einzelnen Befehle nur durch unterschiedliche Personalnummern unterscheiden. Betrachten wir den Aufbau dieses Update-Befehls mittels des CommandObjekts:
comm = Server.CreateObject ("ADODB.Command")
comm.ActiveConnection = conn
// Command-Objekt erzeugen
// Verbinden mit Connection
// SQL-Text, Fragezeichen ist Platzhalter:
comm.CommandText = "Update Personal Set Gehalt = Gehalt *1.02 " +
"Where Persnr = ?;"
// Platzhalter wird definiert:
comm.Parameters.Append( comm.CreateParameter("Pnr", 3) )
// 3 = 4 Byte-Integer, Konstanten sind in adojavas.inc definiert
Multimedia Entwicklung (Teil2)
Edwin Schicker
29
// ausgewaehlten Mitarbeiter als Parameter uebernehmen:
for (i=1; i <= Request.Form("Persnr").Count; i++)
{
comm("PNr") = Request.Form("Persnr")(i)
// Wert -> Platzhalter
comm.Execute()
// Update ausfuehren
}
Wir definierten hier zunächst ein neues Command-Objekt und ordnen dieses der aktuellen DB-Verbindung zu, also der Connection-Variable conn. Wir schreiben den Update-Befehl und setzen statt
einer Personalnummer ein Fragezeichen. Je Fragezeichen müssen wir jetzt einen Parameter erzeugen
(mittels CreateParameter) und diesen der Parameterliste mittels der Methode Append hinzufügen.
Jeder Parameter wird durch einen Namen identifiziert und besitzt einen Datentyp. Die Datentypen sind
in der Datei adojavas.inc definiert. Einige Beispielwerte:
Datentyp
adInteger
adChar
adDate
adSmallint
adSingle
adDouble
Wert
3
129
7
2
4
5
Info
32Bit-Integerwert
Zeichenkette
Datum
16Bit-Integerwert
32Bit-Gleitpunktzahl
64Bit-Gleitpunktzahl
Soll der Datentyp verwendet werden, so muss die Datei adojavas.inc inkludiert werden:
<!--#include File="adojavas.inc"-->
Im Falle von Zeichenketten muss in der Methode CreateParameter zusätzlich die Zeichenkettenlänge
mit übergeben werden, etwa
comm.CreateParameter ("Ort", 129, 1, 30);
Hier wird ein Zeichenkettenparameter mit Namen Ort als Zeichenkette mit der Länge 30 definiert,
oder ausführlich:
comm.CreateParameter ("Ort", adChar, adParamInput, 30);
adParamInput heißt, dass der Wert des Parameters eingegeben wird, besitzt den Wert 1 und ist die
Standardvorgabe.
In unserem obigen Beispiel wird jetzt in einer Schleife jeder Mitarbeiter ausgelesen, dem CommandParameter zugewiesen und der Update-Befehl ausgeführt.
5.4
Die Methode Redirect des Session-Objekts
Arbeiten wir mit MTS, so wird am Ende einer HTML-Seite immer noch Code abgearbeitet, entweder
der Code in der Funktion OnTransactionCommit oder in OnTransactionAbort. Hier können noch Aufräumungsarbeiten geleistet werden, etwa das Schließen der noch geöffneten Datenbank.
In der Datei command1.asp wird ebenfalls die Datenbank geöffnet. In der Regel wird durch das Drücken des Submit-Buttons zur Datei command2.asp gewechselt, die eine geöffnete Datenbank erwartet.
Es wäre also unklug, die Datenbank vorher zu schließen. Andererseits können wir aber mit einem
Hyperlink auf die Startseite zurückspringen. In diesem Fall wäre aber die Datenbank noch offen, das
Ausführen der Datenbankbeispiele würde dann aber scheitern, da jeweils eine bereits geschlossene
Datenbank erwartet wird.
Wir können uns damit behelfen, dass wir nicht direkt zu der Startseite zurückspringen, sondern eine
Hilfsseite aufrufen, die die Datenbank schließt und dann von sich aus zur Startseite wechselt. Soll dies
Multimedia Entwicklung (Teil2)
Edwin Schicker
30
automatisch funktionieren, also ohne erneuten Klick auf einen Button oder einen Link, so ist es
zweckmäßig, die Methode Redirect des Response-Objekts einzusetzen.
Betrachten wir dies wieder am Beispiel. Statt zur Startseite zurückzuspringen, rufen wir die Seite
ende.asp aus. Erst hier wird zur Startseite gewechselt. Betrachten wir den dazugehörigen Code:
if (Session ("_conn") != null ) {
conn = Session("_conn")
Session("_conn") = null
conn.Close()
Session.Abandon ()
}
Response.Redirect("default.htm")
// Verbindung existiert noch
// Explizites Schließen der DB
// Sessionobjekte freigeben
// Umlenken auf die Startseite
Dieses Beispiel besitzt eine kleine Falle. Die Methode Redirect funktioniert nur dann einwandfrei,
wenn noch keine Daten der aktuellen Seite zum Benutzer gesendet wurden, da sonst meist der HTMLAufbau gestört wird. Versuchen wir dies zu verstehen.
Die hier angegebene Datei ende.asp enthält auch normalen HTML-Code, also Html- und Body-Tags.
Sind diese bereits beim Browser des Benutzers und erfolgt jetzt ein Redirect-Aufruf, so werden die
bisherigen Daten nicht gelöscht, vielmehr werden jetzt die Daten der angegebenen Seite noch zusätzlich übertragen. Da ja der Tag </body> von dieser Seite noch nicht übertragen wurde, kommt dann
meist der Browser erheblich durcheinander, auch weil nochmals ein Html-Header übertragen wird.
Für einen störungsfreien Betrieb sei daher dringend empfohlen, die Datenpufferung einzuschalten. In
diesem Fall werden vom Server Daten erst dann an den Benutzer übertragen, wenn die Flush- oder
End-Methode des Response-Objekts aufgerufen wurde. Wir schreiben daher am Anfang unserer Datei
noch vor den Html-Tag:
Response.Buffer = True
Jetzt ist sichergestellt, dass die Daten dieser Seite nicht zum Benutzer gelangen. Erst durch die Methode Redirect werden dann die Daten der Datei default.htm an den Benutzer geschickt, da in dieser
Datei die Pufferung nicht gesetzt ist (standardmäßig ist die Pufferung ausgeschaltet).
5.5
Providerangaben
Bisher haben wir ausschließlich auf Microsoft Access-Datenbanken zugegriffen. Natürlich können wir
mittels ADO und OLE-DB auch auf andere Datenbanken zugreifen, insbesondere auf SQL-Server
oder Oracle. Wir können zum Einen ODBC verwenden und dort die entsprechenden Datenbanken
einschließlich Treiber auswählen. Es geht aber auch ohne ODBC. Bisher haben wir folgende Providerangabe gesetzt:
conn.Provider = "Microsoft.Jet.OLEDB.4.0"
// Access-Treiber
Wir könnten aber auch schreiben:
conn.Provider = "MSDASQL"
conn.Provider = "SQLOLEDB"
conn.Provider = "MSDAORA"
Multimedia Entwicklung (Teil2)
// Verbindung über ODBC, Standardvorgabe
// Verbindung zu SQL-Server
// Verbindung zu Oracle
Edwin Schicker
Herunterladen