Beispiel Datenbankabfrage mit Informix
Für dieses Beispiel wird wie bereits im vorangegangenen Gästebuch eine Eingabeform in einem HTML-Dokument verwendet.
Hierdurch soll der Anwender die Möglichkeit erhalten, SQL-Befehle auf eine voreingestellte Datenbank abzusetzen. Das Ergebnis wird in Tabellenform angezeigt. Diese Tabelle wird dynamisch formatiert, weil vor der Anfrage nicht feststeht, wieviel Spalten diese hat.
In der Praxis ist dieses Beispiel nicht unbedingt ein Vorzeigeprojekt zum Thema ?Sicherheit", da der Webbesucher alles lesen darf.
Es besteht jedoch nicht die Möglichkeit, daß ein Datensatz eingefügt oder gelöscht wird, weil die eigentliche Datengewinnung mit dem ?unload" - Befehl beginnt. Würde der Anwender z.B. ?insert into ..." eingeben führt dies zu einem Syntaxerror.
?unload to <Datei> insert into <Tabelle> macht keinen Sinn.
Ebenso empfiehlt sich, die Zugriffsrechte des Webbesuchers ausschließlich auf die notwendigen Tabellen und hierbei nur auf select-Rechte zu beschränken. (SQL-Befehl ?grant...").
Trotz dieser Sicherheitseinschränkungen ist es ein brauchbares Beispiel, weil der Benutzer die Menge und die Sortierung der Daten selbst gestalten kann, sowie durch die Quellcodeansicht des Browsers auch eine Art Exportfunktion hat.
In der Praxis wird man aber dem Benutzer der kein SQL beherrscht lieber eine Auswahlliste der zu suchenden Daten anbieten oder nur ein Textsuche, bei der der eigentliche SQL-Befehl im Script erzeugt wird.
<HTML> <HEAD><TITLE>Lokale Abfrage in Datenbank Informix</TITLE></HEAD> <BODY> <FORM NAME="ABFRAGE" ACTION="/cgi-keipke/db_local.sh"> SQL-Befehl: <INPUT TYPE="text" NAME=SQLBEFEHL SIZE=100 MAXLENGTH="100"><BR> <INPUT TYPE="submit" VALUE="Abfrage starten"> <INPUT TYPE="reset" VALUE="Eingabeform löschen"> </FORM> </BODY> </HTML>
Bild 13: Inhalt der Datei db_local.htm, welche die Eingabemaske darstellt.
Bild 14: Darstellung der Datei db_local.htm
Der eigentliche Datenbankzugriff wird über das ?ACTION"-Script db_local.sh erledigt.
#!/bin/sh # disable filename globbing set -f echo Content-type: text/html echo echo "<HTML><TITLE>Ergebnis der Datenbankanfrage</TITLE><BODY>" # Umgebungsvariablen setzen INFORMIXDIR=/opt/INF7.24 DBPATH=/ihr/pfad DBSERVER=demo_se DBNAME=kunden_db DBDELIMITER='|' INFORMIXSERVER=demo_se PATH=$INFORMIXDIR/bin:$PATH export DBSERVER DBPATH INFORMIXDIR PATH INFORMIXSERVER DBDELIMITER DBNAME if [ -z "$QUERY_STRING" ] then echo "Die Datenbankanfrage konnte nicht gestartet werden," echo "da kein Suchargument angegeben wurde." else #Parameter auswerten SQLBEFEHL=`echo $QUERY_STRING|cut -d'&' -f1|cut -c 11-` #Bestimmte Sonderzeichen des Browsers ersetzen SQLBEFEHL=`echo $SQLBEFEHL|sed -e 's/+/ /g'` SQLBEFEHL=`echo $SQLBEFEHL|sed -e 's/%28/(/g'` SQLBEFEHL=`echo $SQLBEFEHL|sed -e 's/%29/)/g'` SQLBEFEHL=`echo $SQLBEFEHL|sed -e 's/%2C/,/g'` SQLBEFEHL=`echo $SQLBEFEHL|sed -e 's/%3C/</g'` SQLBEFEHL=`echo $SQLBEFEHL|sed -e 's/%3D/=/g'` SQLBEFEHL=`echo $SQLBEFEHL|sed -e 's/%3E/>/g'` SQLBEFEHL=`echo $SQLBEFEHL|sed -e 's/%22/\"/g'` #Tabelle für Ausgabe vorbereiten echo '<TABLE BORDER="1">' echo '<TR>' echo '<TD>Datenbankname</TD><TD>' $DBNAME '</TD>' echo '</TR>' echo '<TR>' echo '<TD>SQL-Befehl</TD><TD>' "$SQLBEFEHL" '</TD>' echo '</TR>' echo '<TR>' echo '<TD>Start:</TD><TD>' date echo '</TD>' echo '</TR>' echo '</TABLE>' echo '<a href="/db_local.htm">Zurück zur Eingabemaske</a><BR>' #Die temporären Dateien für das Ergebnis und ggf. Fehlermeldungen Informix UNL_FILE=/tmp/db_anfrage.local.$$ ERR_FILE=/tmp/db_anfrage.local.ERR.$$ #Die eigentliche Datenbankabfrage als Here-Script, #muss immer am Zeilenanfang stehen $INFORMIXDIR/bin/dbaccess - - 2>$ERR_FILE <<! database $DBNAME; unload to $UNL_FILE $SQLBEFEHL; ! echo '<BR>Ergebnis der Anfrage: ' #Wenn ein Errorfile existiert, wird es angezeigt [ -f $ERR_FILE ] && cat $ERR_FILE echo '<BR><BR>' echo '<TABLE BORDER="1">' #Durch den sed-Befehl wird das Datenbankergebnis formatiert #Das Pipezeichen wird durch den TR TD Tag ersetzt. #Der awk setzt jeweils am Zeilenanfang und -ende ebenfalls TR TD #Hierdurch ist die Ausgabe unabhängig von der Anzahl der Spalten #und es erscheint immer eine ordentliche Tabelle [ -f $UNL_FILE ] && sed -e 's/|/<\/TD><TD>/g' $UNL_FILE|awk -F'|' '{ print "<TR><TD>" $0 "</TD></TR>" }' echo '</TABLE>' #temporäre Dateien löschen rm -f $UNL_FILE $ERR_FILE fi echo "</BODY></HTML>"
Bild 15: Inhalt der Datei /cgi-bin/db_local.sh
Realisierung in ?Perl"
Perl ist eine Scriptsprache, ähnlich UNIX-Shellscript. Sie erfreut sich aber größerer Beliebtheit, insbesondere unter der großen Gemeinde der C-Programmierer, weil die Syntax ähnlich der C-Syntax ist. Zusätzlich ist die Vereinbarung von Variablen sehr einfach, weil unnötig wie in allen Interpreter - Sprachen.
Eine sehr gute Sprachbeschreibung von Perl finden Sie unter: http://de.selfhtml.org/perl/index.htm
Als ?praktisches Anschauungsstück" soll hier das Beispiel des Counters dienen. Hierbei werden die wichtigsten Kenntnisse vermittelt.
Der Pfad zum Perl-Interpreter wird in der ersten Zeile des Scripts angegeben.
#!/usr/bin/perl #Kommentare beginnen immer mit Rautezeichen print "Content-type: text/html\n\n"; print "<HTML><HEAD><TITLE>CGI-Counter in Perl</TITLE></HEAD>\n"; print "<BODY><CENTER>"; $COUNT_FILE_IN="</www/htdocs/keipke/count/.count"; $COUNT_FILE_OUT=">/www/htdocs/keipke/count/.count"; if(!open(COUNTFILE, $COUNT_FILE_IN)) { #Die Datei ist nicht lesbar oder nicht vorhanden if(!open(COUNTFILE, $COUNT_FILE_OUT)) { #Keine Schreibrechte auf Datei oder Verzeichnis print "Die Counterdatei kann nicht erzeugt werden\n"; print "Sie besitzen nicht das Schreibrecht\n"; print "</BODY>"; exit; } else { #Datei mit Wert 1 initialisieren print COUNTFILE "1"; close (COUNTFILE); $LAST_COUNT="1"; } } else { while (<COUNTFILE>) { #liest alle Zeilen nacheinander in die vorbestimmte Variable $_ #in diesem Fall nur eine Zeile $LAST_COUNT = $_; } close(COUNTFILE); #Zählerstand erhöhen ++$LAST_COUNT; #Und wieder zurückschreiben open(COUNTFILE,$COUNT_FILE_OUT); print COUNTFILE $LAST_COUNT; close(COUNTFILE); } #Datei ist eingelesen und hochgezählt. Der Wert steht nun in der Variablen #LAST_COUNT print "<TABLE BORDER=0><TR><TD>\n"; for ( $i = 100000 ; $i >= 1 ; $i = $i / 10 ) { $FILENAME=int($LAST_COUNT / $i); while ( $FILENAME > 9 ) { $FILENAME=$FILENAME % 10; } print "<img src=/graphics/"; print $FILENAME ; print ".gif>\n"; } print "</TD></TR></TABLE>\n"; print "</CENTER>\n"; print "</BODY></HTML>\n";
Bild 17: Inhalt der Datei ?/cgi-bin/counter.pl"