Einleitung
Systemvoraussetzungen
Einrichten der Datenquelle
Einrichten DSN mit PERL
Installation des Win32::ODBC-Moduls
Erste Schritte
Win32::ODBC-Objekterstellung
SQL-Statements
HTML-Page und Script zu MS-Access-Nordwind.MDB
Einleitung
Wer damit anfängt, mit PERL Zugriffe auf Datenbanken zu schreiben ist gut beraten, seine Scripte zunächst im "Stillen Kämmerlein" zu testen bevor er einen SQL-Server mit wilden Transaktionen lahmlegt. Um SQL auf dem lokalen PC zu testen eignet sich bereits die mit MS-Access mitgelieferte Beispieldatenbank "nordwind.mdb". In dieser Beispieldatenbank, die auf einem relationalen Modell basiert, gibt es mehrere Tabellen und vorgefertigte Querys in SQL. SQL heißt "Structured Query Language" und stellt praktisch einen internationalen Standard der Kommunikation mit Relationalen Datenbanksystemen dar. Dieser Beitrag beschreibt den Weg dahin wie SQL-Statements über den Browser auf diese Beispieldatenbank ausgeführt werden können.
Eine solche Testumgebung lokal eingerichtet ermöglicht das Vertrautmachen mit der Problematik "SQL mit PERL/CGI" und erleichtert somit die nächsten Schritte, etwa die Anbindung eines MS-SQL-Servers an das Intranet.
Eine komplette Einführung mit einer umfangreichen Dokumentation und FAQ zum Modul Win32::ODBC gibt natürlich der Autor Dave Roth selbst auf seiner ODBC-Page. Auf dieser Site stellt Dave Roth u.a. eine hervorragend gemachte PowerPoint-Presentation über ODBC zur Verfügung die auch downgeloadet werden kann.
Systemvoraussetzungen
Voraussetzung für das Nachvollziehen der in diesem Beitrag aufgeführten Schritte ist ein lokal installierter Webserver (OmniHttpd, Apache o.ä.), ein installierter PERL-Interpreter für eine Win32-Umgebung sowie MS Access.
Als Grundlage für diesen Beitrag diente:
- Eine WinNT-Workstation 4.0
- MS-Access97
- Active PERL " version 5.005_02 built for MSWin32-x86-object"
- Das Modul "Win32-ODBC" VERSION="0,03,0,0"
- HTTPd "Apache/Win32, 1.3.9."
Einrichten der Datenquelle
Bevor mit dem Win32::ODBC-Modul auf eine Datenquelle zugegriffen werden kann, muss diese als System-DSN (Data Source Name) erstellt werden.
ODBC: Open Data Base Connectivity - ist eine spezielle Schnittstelle über die von verschiedenen Anwendungen aus (z.B.: PERL) auf Datenquellen zugegriffen werden kann.
Die Datenquelle kann entweder über die Systemsteuerung ODBC oder über ein Script erstellt werden.
Warum muss es ein System-DSN sein? Nun, der Webserver (auch httpd: HTTP-Dämon genannt) läuft als Systemdienst. Ein Systemdienst kann mit einer Benutzer-DSN nichts anfangen. Ein SQL-Statement in einem PERL/CGI-Script eingebettet, würde in einem solchen Fall fehlschlagen.
Über ODBC-Setup in der Systemsteuerung
Zum Einrichten der Datenquelle in der Systemsteuerung auf das Icon "ODBC" klicken:

Wichtig ist dann die Auswahl des Registers "System-DSN":
... und dann die Schaltfläche "Hinzufügen" klicken. Es erscheint nun eine Auswahl der zur Verfügung stehenden ODBC-Treiber:
Den Treiber für MS-Access auswählen und weiter gehts mit der Auswahl der Datenbankdatei...
Mit der Auswahl der MS-Access-Datenbankdatei "nordwind.mdb" ist das ODBC-Setup abgeschlossen und die Datenquelle "nordwind" erstellt:
Mit PERL
Die Datenquelle kann genausogut mit einem Script erstellt werden, das Modul "Win32::ODBC" bietet hierfür auch Methoden an. Als Erstes soll ein einfaches Script vorgestellt werden, welches alle zur Verfügung stehenden ODBC-Treiber mittels der Methode "Drivers()" auflistet:
use Win32::ODBC;
%drivers = Win32::ODBC::Drivers();
foreach $driver (sort keys %drivers){
print "Driver = $driver\n";
}
Dieses kleine Script liefert also eine Liste der zur Verfügung stehenden ODBC-Treiber und zeigt auch deren richtige Schreibweise. Die richtige Schreibweise ist in dem folgendem zweiten Script wichtig, mit welchem die Datenquelle eingerichtet wird:
# Eine ODBC Datenquelle erstellen
# Dieses Scrip als CGI über den Webserver starten
# Wenn der Server als System-Dienst läuft,
# wird somit ein System-DSN erstellt
use Win32::ODBC;
$DriverType = "Microsoft Access-Treiber (*.mdb)";
$DSN = "nordwind";
$Description = "Test Datenbank";
$DataBase = "Nordwind.mdb";
$dir="c:\\programme\\Microsoft Office\\Office\\Beispiel";
if(Win32::ODBC::ConfigDSN(ODBC_ADD_DSN,
$DriverType,
("DSN=$DSN",
$Description,
"DBQ=$dir\\$DataBase",
"DEFAULTDIR=$dir",
"UID=", "PWD="))){
print "content-type:text/html\n\n";
print "Konfiguration des DSN: $DSN erfolgreich!\n";
}
else{
print "content-type:text/html\n\n";
print "Fehler beim Erstellen der Datenquelle $DSN\n";
Win32::ODBC::DumpError();
die;
}
Installation des Win32::ODBC-Moduls
Der Autor des Modul' s Win32::ODBC Dave Roth beschreibt in seiner PowerPoint-Presentation die Installation des Moduls wie folgt:
- Create the directory c:\perl\lib\auto\win32\odbc
- Copy ODBC.PLL into the new directory
- Copy ODBC.PM into c:\perl\lib\win32
Es gibt verschiedene Versionen dieses Moduls, die aktuelle Version ist "970208". Die Datei "ODBC.PLL" gibt es außerdem für verschiedene Perlversionen also aufgepasst.
Andererseits ist mit dem Perl Package Manager "PPM" die Installation des Win32::ODBC-Moduls ganz leicht. Nachdem das ZIP-File von ActiveState/Packages/zips
downgeloadet wurde, wird dieses mit einem geeignetem Packer (WinZip, PowerZip oder WinCommander) in ein beliebiges Verzeichnis entpackt. In diesem Verzeichnis finden sich sodann die folgenden Dateien bzw. das Verzeichnis:
- [x86] (Verzeichnis)
- Win32-ODBC.ppd (Datei)
- Readme (Datei)
Zum Installieren eine "CMD" in diesem Verzeichnis starten und die folgende Kommandozeile eintippen: "ppm install Win32-ODBC.ppd" (Die ganz Tippfaulen kopieren diese Zeile aus der "Readme" in die "CMD"...).
Erste Schritte
In den folgenden Abschnitten werden verschiedene Methoden des Moduls "Win32::ODBC" beschrieben mit welchen der Benutzer auf die Daten zugreifen kann.
Win32::ODBC-Objekterstellung
Typische Zeilen:
use Win32::ODBC; # Modul einbinden
$db = new Win32::ODBC("DSN=nordwind"); # Erstellung eines Objekts
Sofern für die Datenquelle ein Benutzername und ein Passwort erforderlich sind, kann der folgende Syntax Verwendung finden:
$db = new Win32::ODBC("DSN=XBASE;UID=interaktiv;PWD=interaktiv;")
Das Erstellen der Verbindung zur Datenquelle kann auch in eine Fehlerbehandlung eingeschlossen werden, indem der Rückgabewert wie folgt ausgewertet wird:
if(!($db = new Win32::ODBC("DSN=XBASE;UID=interaktiv;PWD=interaktiv;"))){
print "Fehler beim Verbinden mit $DSN\n";
print "Fehler: " . Win32::ODBC::Error() . "\n";
exit;
}
Anmerkung: Die Rückgabe ist "undef" wenn ein Fehler bei der Objekterstellung auftritt.
Sql-Statements
SQL stellt dem Benutzer einen Sprachschatz zur Verfügung mit dessen Vokabeln er alle erdenklichen Abfragen und Manipulationen an Datenbanken vornehmen kann:
Abfragen (Querys) auf einzelne oder mehrere Tabellen
"SELECT Anrede, Vorname, Nachname FROM Personal
WHERE Geburtsdatum > #01/01/1960#"
Zeigt aus der Tabelle Personal Anrede, Vorname und Nachname von Personen mit dem Geburtsdatum jünger als 01.01.1960.
Updates, Löschen und Einfügen von Datensätzen
"INSERT INTO Artikel
VALUES (9999, 'Puffbohnen', 29, 5, 'Sack', '10', 10000, 1, 10000, 0)"
Fügt einen Datensatz in die Tabelle Artikel ein. Die referentielle Integrität des Lieferanten ist gewährleistet man versuche, in dieser Anweisung einen Lieferanten zu benennen, den es nicht in der Tabelle Lieferanten gibt: Der ODBC-Treiber wird einen Fehler melden.
"DELETE FROM Artikel WHERE [Artikel-Nr] = 9999"
Löscht den Datensatz mit der Artikelnummer 9999.
Ändern, Löschen und Erstellen von Tabellen
"DROP TABLE Kunden"
Löscht die gesamte Tabelle Kunden.
Und vieles Andere mehr kann mit SQL in relationalen Datenbanken gemacht werden. Die hier vorgestellte Testumgebung ermöglicht das Kennenlernen der "Structured Query Language" anhand der Beispieldatenbank "nordwind".
Das folgende Bild gibt eine Übersicht über die Tabellen in der Beispieldatenbank und deren Beziehungen untereinander:
Der Vollständigkeit halber sei hier noch ein Beispiel eines Joins aufgeführt, ein Join ist eine Abfrage auf mehrere Tabellen:
SELECT artikel.Artikelname, lieferanten.Firma
FROM artikel, lieferanten
WHERE artikel.[Lieferanten-Nr] = lieferanten.[Lieferanten-Nr]
ORDER BY 2
Diese Abfrage ergibt als Ergebnis in der linken Spalte alle Artikel welche vom in der rechten Spalte zugehörigen Lieferanten (nach dieser Spalte ist sortiert) verfügbar sind.
An dieser Stelle muss auf die Fachliteratur verwiesen werden.
Mittels der Sql() - Methode wird die SQL-Anweisung auf die Datenbank ausgeführt, Syntax:
# $db ist das weiter oben erstellte Objekt der Datenquelle
$sql_string = ("SELECT * FROM Lieferanten");
$db->Sql($sql_string);
Anmerkung: Die Methode Sql() gibt "undef" zurück bei einer erfolgreichen Ausführung des SQL-Statements.
Nach dem Anwenden der Sql()-Methode können im Script weitere Methoden angewandt werden, wie z.B.:
FieldNames() # Spaltenüberschriften ermitteln
FetchRow() # Nächster Datensatz...
DataHash() # liefert den Record als Hash: ('FeldName','Wert',...)
Error() # Fehlerausgabe
Close() # Datenbank schließen
welche auch in "nordwind.pl" gebraucht wurden. Eine vollständige Liste aller in Win32::ODBC zur Verfügung stehenden Methoden findet sich auf den Seiten von Dave Roth.
HTML-Page und Script zu MS-Access-Nordwind.MDB
Die nun folgenden beiden Abschnitte beschreiben eine HTML-Seite mit dem zugehörigen Script. Die HTML-Seite enthält 3 vorgefertigte Abfragen auf "nordwind.mdb" sowie ein mehrzeiliges Texteingabefeld. In dieses Texteingabefeld können nun die SQL-Statements eingetippt werden und der Benutzer kann das Ergebnis der Abfrage im Browser sehen. Außer SELECT-Anweisungen können auch alle anderen SQL-Anweisungen getestet werden, wie das Updaten von Datensätzen, die Erstellung von Views, das Löschen von Tabellen u.s.w.
Der Quellcode für Nordwind.htm
<HTML>
<HEAD>
<TITLE>SQL auf Nordwind</TITLE>
</HEAD>
<BODY>
<H2>SQL auf MS Access "Nordwind.MDB"</H2>
<FORM ACTION="/cgi-bin/nordwind.pl" METHOD="post">
<pre>
Alle Artikel zeigen:
<INPUT TYPE="Radio" NAME="default" VALUE="Artikel">
Alle Kunden zeigen:
<INPUT TYPE="Radio" NAME="default" VALUE="Kunden">
Alle Lieferanten zeigen:
<INPUT TYPE="Radio" NAME="default" VALUE="Lieferanten">
</pre>
SQL Statement eingeben:
<p>
<TEXTAREA NAME="sql_eingabe" COLS="100" ROWS="12"></TEXTAREA>
<p>
Max Zeilen:
<SELECT NAME="max_rows">
<OPTION VALUE="10">10
<OPTION VALUE="50">50
<OPTION VALUE="100">100
<OPTION VALUE="200">200
</SELECT>
<INPUT TYPE="Submit"><INPUT TYPE="reset">
</FORM>
</BODY>
</HTML>
Das Script nordwind.pl
#!perl
use CGI; # CGI-Modul einbinden
$cgi = new CGI;
use Win32::ODBC; # ODBC-Modul einbinden
$db = new Win32::ODBC("DSN=nordwind"); # Objekt erstellen
$max_rows = 2; # Max Zeilen die später ausgegeben werden
$rows = 0;
# Parameter auslesen
$max_rows = $cgi->param('max_rows');
$vordef = $cgi->param('default');
if($vordef){
$sql_string = ("select * from $vordef");
}
else{
$sql_string = $cgi->param('sql_eingabe');
}
if(! $db->Sql($sql_string)){
@FelderNamen = $db->FieldNames(); # Feldnamen
$spalten = @FelderNamen; # Spaltenanzahl ermitteln
#Ausgabe der Daten in den Browser (Tabelle)
print $cgi->header,
$cgi->start_html('Ergebnis der SQL - Abfrage'),
$cgi->h2('Ergebnis der SQL - Abfrage'),
$cgi->h5($sql_string),
"Maximal angezeigte Zeilen: ", $max_rows;
print "<table border cellspacing=0>\n";
# Die Überschriften nicht vergessen
print "<tr>\n";
for (@FelderNamen){
print "<th>", $_, "</th>\n";
}
print "</tr>\n";
# Und nun den Rest der Tabelle
# FetchRow() gibt 0, wenn keine weiteren Daten anliegen
while ($db->FetchRow() and $rows < $max_rows){
print "<tr>\n";
undef %Daten ;
%Daten = $db->DataHash();
$rows++;
for ($i = 0; $i < $spalten; $i++){
if ($Daten{$FelderNamen[$i]} gt ''){
print "<td>", $Daten{$FelderNamen[$i]}, "</td>\n";
}
else{
print "<td>Nicht Angegeben</td>\n";
}
}
print "</tr>\n";
}
print "</table>\n",
$cgi->end_html;
$db->Close() ;
}
else{
print $cgi->header,
$cgi->start_html('Fehler im SQL Statement'),
$cgi->h2('Fehler im SQL Statement'),
$cgi->p,
$db->Error();
}
|