Anfrageneditor - Hilmar Falkenberg

Werbung
Institut für Informatik und Praktische Mathematik der
Christ ia n- Alb rec hts- Uni ve rsität zu Kiel
Gra phi sc he Sc hni tts te ll e zur G e ner ier ung v on
SQ L-A nf ra ge n a n die Studiere nde nda te nba nk
– A nf ra ge ne di tor –
Bachelorarbeit von
Hilmar Falkenberg
Kiel, im Oktober 2004
Institut für Informatik und Praktische Mathematik der
Christ ia n- Alb rec hts- Uni ve rsität zu Kiel
Gra phi sc he Sc hni tts te ll e zur G e ner ier ung v on
SQ L-A nf ra ge n a n die Studiere nde nda te nba nk
– A nf ra ge ne di tor –
Bachelorarbeit von
Hilmar Falkenberg
Betreuer:
Prof. Dr. Hans-Joachim Klein
Kiel, im Oktober 2004
1
Vorwort
5
1.1
Projektaufteilung
6
1.2
Anmerkung
6
2
Einleitung
7
2.1
Themenstellung
7
2.2
Inhalt der Arbeit
8
Problemanalyse
9
3
3.1
Allgemeine Anforderungen
9
3.2
Anforderungen vom Prüfungsamt
9
3.3
Anforderungen an die Statistikerstellung
11
3.3.1
Umsetzung
11
3.3.2
Flexibilität
12
4
Graphische Anfragesprachen für Datenbanken
13
4.1
QBE – Query-By-Example
13
4.2
NQS – Network-Query-System
15
4.3
Ansatz dieser Arbeit
15
4.3.1
Konzept
16
4.3.2
Join
17
4.3.3
Bedingungen
17
4.3.4
Aggregatfunktionen
18
4.3.5
Bedingungen für Aggregatfunktionen
18
4.3.6
SQL-Kontrollanzeige für den Administrator
18
5
Umsetzung der Statistikerstellung
19
5.1
HTML-Seite
19
5.2
Javascriptdateien
22
5.3
Erzeugung der SQL-Anweisung
23
5.4
Gespeicherte Datenbankanfragen
23
5.4.1
Anmerkung zu Cookies
24
-1-
6
Umsetzung der Grundlagen
25
Basisklassen (package base)
25
6.1
6.1.1
class SDBDocument
25
6.1.2
class SDBElementList
25
6.1.3
class SDBGroup
25
6.1.4
class SDBGroupElement
26
6.1.5
interface SDBResults
26
6.1.6
class SDBResultset
26
6.1.7
class SDBResultsImpl
27
6.1.8
class SDBRow
27
6.1.9
abstract class SDBServlet
27
6.2
Servlets (package servlet)
28
6.2.1
Parameterliste zur Steuerung der Servlets
28
6.2.2
class SDBSelect
30
6.2.3
class SDBExecute
30
6.2.4
class SDBStatistik
31
7
Analyse der Umsetzung
33
7.1
Tests
33
7.2
Gelöste Probleme
33
7.3
Beschränkungen
34
8
Zusammenfassung
8.1
35
Ausblick
35
8.1.1
Datenbankschema
35
8.1.2
Subqueries
36
8.1.3
Maximale Anzahl von zehn Spalten
36
8.1.4
„Durchblättern“ von Daten
36
9
9.1
Literaturverzeichnis
37
Verwendete Entwicklungsumgebung & Tools
10 Erklärung
39
40
-2-
11 Anhang
Datenbankschema
1
Anfrageneditor
HTML-Quellcode (statistik.html)
1
Javascripte
check.js
11
cookie.js
13
stat_cookies.js
13
stat_erstellen.js
14
stat_events.js
19
stat_globals.js
25
stat_schema.js
26
Cascaded Style Sheet (statistik.css)
29
Hilfedateien für den Anfrageneditor
alias.html
29
anzeigen.html
30
Bedingung.html
30
Felder.html
31
Frage.html
32
Funktionen.html
32
GBedingung.html
33
index.html
34
join.html
35
sortieren.html
35
SQL.html
36
Tabelle.html
36
tauschen.html
37
Anfragenverwaltung
Javascript (stat_verwalten.js)
37
XSL-Stylesheet (stat_gespeicherte.xsl)
38
XSL-Stylesheets
logo.xsl für die Navigationsleiste, Fehlermeldungen und das Logo
39
stat_antwort.xsl für die Ergebnislisten einer Anfrage
40
Administratorenschnittstelle (administrator.html)
41
Sonstiges für den Anfrageneditor
general_layout.css
42
-3-
javascript.sql
43
stat_statistiken.sql
43
sdbdocument.dtd
44
Javaklassen (package base)
class SDBDocument
44
class SDBElementList
49
class SDBGroup
50
class SDBGroupElement
52
interface SDBResults
53
class SDBResultset
54
class SDBResultsImpl
57
class SDBRow
59
abstract class SDBServlet
60
Javaklassen (package servlet)
class SDBSelect
62
class SDBExecute
66
class SDBStatistik
67
-4-
1 Vorwort
Am Institut für Informatik und Praktische Mathematik der Christian-Albrechts-Universität zu Kiel werden seit einigen Jahren die Daten der Studierenden in einer
institutseigenen Datenbank verwaltet.
Da die Lizenz für das verwendete Datenbanksystem Ingres in Kürze ausläuft und
inzwischen erweiterte Anforderungen an die Datenbankanwendung gestellt werden,
ist es notwendig, eine neue Lösung zu erarbeiten. Hierfür wurde am Lehrstuhl „Technologie der Informationssysteme“ das Projekt „Studierendendatenbank“ (SDB) mit
der Zielsetzung gegründet, von einer proprietären zu einer datenbanksystemunabhängigen Lösung zu kommen, die auch wesentlich mehr Funktionalität bieten soll. So
sollen z.B. auch der Übungsbetrieb mit erfasst werden und Schnittstellen zum
UnivIS1 [26] und zum zentralen Studierendensekretariat integriert werden. Für
Studenten soll ein Webinterface mit ihren persönlichen Daten zur Verfügung gestellt
werden.
Während der Diskussion um die Inhalte des Projektes hatte sich Computer
Associates dazu entschieden, Ingres freizugeben [35], so dass auf diesem Datenbanksystem die neue Anwendung weiter entwickelt werden kann, ohne dass
Lizenzgebühren fällig werden.
Um aber trotzdem möglichst datenbanksystemunabhängig zu werden und weil das
bisherige System (noch mit 4GL als graphischer Schnittstelle) ersetzt werden soll,
wurde festgelegt, dass die neue Studierendendatenbank als three-tier-architecture
mit einem Internet-Browser (überwiegend Mozilla 1.6 [36]) auf der Clientseite und
Java-Servlet-Technologie [10] (Tomcat [37] als Webserver) und Ingres als
Datenbanksystem aufgebaut wird.
1
Das System erlaubt die Erfassung von Informationen aus Forschung und Lehre (Vorlesungen, Personen, Veranstaltungen,
Forschungsprojekte, Publikationen, ...). Die einmal erfassten Informationen können in einer Vielzahl von Verzeichnisarten
(z.B. individuelle Stundenpläne, Raumbelegungspläne, Veranstaltungskalender, Forschungsberichte, Publikationsverzeichnisse) mit flexiblen Abfragemöglichkeiten (z.B. Telefon- und E-Mail-Verzeichnis, kommentiertes Vorlesungsverzeichnis)
abgerufen werden. Erfassung und Abruf der Informationen erfolgt vollständig über das WWW.
-5-
Folgende Abbildung verdeutlicht die geplante neue Struktur:
Web Server
Java Servlet
Teil dieser Arbeit
SDBServlet
XML
Prozes sor
HTML
(DOM/SA X)
Clients
SDBDocument
SDBResultSet
XSL
XSL
stylesheet
(Tomcat)
java.sql.ResultSet
(Studenten, Sekreteriat,
Prüfungsamt, Lehrpersonal)
JDBC
DB
(Ingres)
Geplante three-tier-architecture
1.1
Projektaufteilung
Das Projekt Studierendendatenbank ist gegliedert in:
Benutzergruppen
Bereiche
1. Sicherheit
-
I. Sekretariate
Verschlüsselung
Passwörter
Rollen (Benutzergruppen)
Zertifizierung / Behördenaudit
-
II. Prüfungsamt
2. Skalierbarkeit / Performance / Verfügbarkeit
-
Session-Verwaltung
Leistung (Antwortzeiten)
einfache, flexible Erstellung
automatische Generierung von SQL-Anfragen
4. XML
-
-
Statistik
Zeugnisse
III. Studierende
3. Statistik
-
Scheine
Pflege
Dokumentenerstellung / -verwaltung
Textbausteine
-
Web-Interface
Abfragen
IV. Übungsleiter
-
Teilnehmerliste
Mailliste
Rechnerbetriebsgruppe
-
Accountkontrolle
Diese Arbeit beschränkt sich auf die Teile 3. Statistik und II. Prüfungsamt (mit der
Statistik und grundlegenden Funktionen).
1.2
Anmerkung
In dieser Arbeit wird davon ausgegangen, dass der Leser mit den verschiedenen
Prinzipien und Funktionsweisen von XML [28], XSL [29], Java [07][16], Java Servlet
[10][11][17], Javascript [06][18], HTML [13], SQL [21][23] in Verbindung mit Java [22]
(SQLJ, JDBC) und relationalen Datenbanken [02][05][12] vertraut ist. Daher erfolgt
hier keine nähere Beschreibung dazu.
-6-
2
Einleitung
2.1
Themenstellung
Um die Anfragen von Professoren oder von der Universitätsleitung an das
Prüfungsamt nach statistischen Größen, wie z.B. Prüfungsergebnisse bestimmter
Jahrgänge, zu bearbeiten, war es bisher notwendig, dass vom Prüfungsamt diese
Anfragen an einen Administrator der Studierendendatenbank (meistens ein
Mitarbeiter des Lehrstuhls „Technologie der Informationssysteme“) weitergeleitet
wurden. Der Administrator musste dann die entsprechenden SQL-Anweisungen
formulieren und die Ergebnisse an das Prüfungsamt weiterleiten.
Das Ziel des Teilprojektes „Statistiken“ und damit Thema dieser Arbeit ist es, diesen
Ablauf wesentlich zu verkürzen und damit so zu vereinfachen, dass die MitarbeiterInnen des Prüfungsamtes diese Daten schnell und problemlos selbst ermitteln
können.
Da sich die bisherigen Fragen häufig ähnelten und nur in bestimmten SelektionsKriterien unterschieden, erscheint es sinnvoll, eine Anzahl vorgefertigter Datenbankanfragen zu haben, in denen die MitarbeiterInnen des Prüfungsamtes selbst die
Bedingungen ändern können (wie z.B. das Datum für einen Jahrgang), um dann die
entsprechende Statistik zu erstellen.
Eine typische Frage ist z.B.:
„Welche Studenten (MatrikelNr, Name, Hauptfach, Nebenfächer, Studienbeginn,
Studienfachbezeichnung) haben als erstes oder zweites Nebenfach Nummer 11 oder 25 und
haben ihr Studium zwischen dem 01.10.2000 und 01.10.2001 begonnen?“
Diese Frage kann als SQL-Anweisung wie folgt formuliert werden:
select
s.matrikel_nr, name, s.hauptfach_nr_i, s.nebenfach_nr_1_i,
s.nebenfach_nr_2_i, s.studienbeginn, f.bezeichnung
from studierende s, studienfaecher f
where
f.studienfach_nr_i = s.nebenfach_nr_1_i
AND (s.nebenfach_nr_1_i = 25 OR s.nebenfach_nr_1_i = 11
OR s.nebenfach_nr_2_i = 25 OR s.nebenfach_nr_2_i = 11)
AND s.studienbeginn >= '1.10.2000'
AND s.studienbeginn < '1.10.2001'
Eine derartige Frage kehrt in etwas anderer Form immer wieder, dann evtl. mit
anderen Nebenfachnummern oder für einen anderen Studienbeginn. Daher ist es
wünschenswert, eine solche Beispielfrage speichern zu können, um sie zu einem
späteren Zeitpunkt an die aktuellen Bedürfnisse anpassen und ausführen zu können.
-7-
2.2
Inhalt der Arbeit
Im Wesentlichen geht es in dieser Arbeit um den Entwurf und die Realisierung einer
neuen einfachen Benutzerschnittstelle für die Erstellung, Veränderung, Ausführung
und Verwaltung von Datenbankanfragen. Hinzu kommen noch einige Servlets, die
grundlegende Funktionen für die Dateneingabemasken des Prüfungsamtes und die
Dokumentenerstellung (s. 4. bei der Projektaufteilung) zur Verfügung stellen.
-8-
3
Problemanalyse
3.1
Allgemeine Anforderungen
Die zu realisierenden Benutzerschnittstellen sollten weitgehend datenbanksystemund browserunabhängig sein. Alle Schnittstellen (im Wesentlichen die Dateneingabemasken) sollten intuitiv und ohne lange Einarbeitungszeiten bedienbar sein.
Es ist dabei zu berücksichtigen, dass nicht alle Datenbankhersteller immer die
gesamten java.sql-Spezifikationen in ihren JDBC-Treibern umsetzen. Auch kann die
Darstellung in unterschiedlichen Browsern etwas variieren, so dass ein einheitliches
Bild einer Bildschirmmaske an allen Arbeitsplätzen unmöglich ist. Zum Entwickeln
und Optimieren haben wir uns deshalb auf Ingres mit dem JDBC-Treiber vom
09.10.2002 und auf den Mozilla Browser 1.6 geeinigt.
3.2
Anforderungen vom Prüfungsamt
Von der bisherigen Studierendendatenbank sollten alle Funktionen neu implementiert
bzw. übernommen werden. Zudem soll z.B. die gesamte Menüstruktur sehr stark an
das benutzergewohnte alte System angelehnt werden.
Speziell für das Prüfungsamt sind daher folgende Menüpunkte auf jeden Fall
umzusetzen:
-
Studienarbeiten
Industriepraktika
Liste ausgewählter Klausuren
Immatrikulierte Studierende
Abgeschlossene Vordiplomprüfungen
Abgeschlossene Diplomprüfungen
Zertifikatszeugnisse
Bewertungsbogen Vordiplom
Bewertungsbogen Diplom
Erhebung der Prüfungsdaten
Anmeldung Diplomarbeiten
Außerdem sind noch die Funktionen aus einem Pascal-Programm zu integrieren, das
zur Unterstützung bei der Durchführung von Prüfungen erstellt worden war und
dessen Wartung zu Problemen führt.
Die Arbeit gliedert sich in zwei Teile. So ist zum einen die Implementierung der
Javaklassen notwendig (Bestandteil dieser Arbeit: 6. Umsetzung der Grundlagen),
-9-
zum anderen muss für jeden einzelnen Menüpunkt ein Stylesheet erstellt werden.
Die Erstellung der Stylesheets ist Gegenstand einer anderen Bachelorarbeit (Thema:
Dokumentenerstellung, siehe Projektaufteilung: 4. XML). Die Java-Klassen bzw.
Servlets sollen die entsprechenden Daten aus der Datenbank in ein einheitliches
XML-Format bringen, welches, mit dem richtigen Stylesheet kombiniert, eine Eingabemaske aus dem alten System repräsentieren soll.
In manchen dieser Eingabemasken (z.B. bei Studienarbeiten) wird unter
anderem eine sogenannte Navigationsleiste benötigt, die es dem Benutzer
ermöglichen soll, von einem Datensatz zum nächsten zu blättern, um sich so durch
alle Daten zu bewegen. Da Ingres in der JDBC-Treiberumsetzung die Methode
previous() bei java.sql.ResultSet nicht unterstützt, kann das ‚Durchblättern’
nicht mit den ResultSet-eigenen Methoden next() und previous() erledigt
werden. Es muss daher eine Lösung geschaffen werden, die es ermöglicht, sowohl
alle Datensätze einer bestimmten Abfrage zu repräsentieren als auch immer nur
einen (den gerade aktuellen) aus einer Liste anzuzeigen. Das bedeutet, der
ResultSet muss auf irgendeine Art zwischengespeichert werden, anderenfalls
müsste für jeden ‚Blättervorgang’ eine erneute Datenbankanfrage ausgeführt
werden. Da aber die Datensätze nicht immer in der gleichen Reihenfolge geliefert
werden, es sei denn, es wird grundsätzlich eine ORDER BY-Klausel verwendet, ist es
schwierig, im allgemeinen Fall (ohne jeweils den entsprechenden UNIQUE KEY zu
haben) den nächsten oder vorhergehenden Datensatz zu bestimmen.
Beispiel der Navigationsleiste
Die Bedienung der Browseroberfläche sollte benutzer- und sessionorientiert sein,
d.h. ein Benutzer muss sich zuerst am System anmelden und authentifizieren, bevor
er Daten ansehen oder verändern darf. Dazu wird in den Servlets immer eine
sogenannte SessionID benötigt; dementsprechend ist es notwendig, ein XMLElement <sessionid> vorzusehen. Auch für die Navigationsleiste ist eine
SessionID unablässig: Es muss feststellbar sein, welcher Datensatz für den Benutzer
der aktuelle ist. Der aktuelle Datensatz soll in einem javax.servlet.http.httpSession-Objekt gespeichert werden, so dass sich daraus ermitteln lässt, welchen
Datensatz der Benutzer als nächstes sehen möchte.
- 10 -
Für manche Bereiche ist es notwendig, dass zwei ResultSets angezeigt werden.
Wenn z.B. zu einem Studenten alle erworben Scheine angezeigt werden sollen,
dann stellt dieser Student (mit Matrikelnummer, Name, Vorname, etc.) sozusagen
den Masterdatensatz dar und die Liste seiner Scheine wäre der Slave-ResultSet. Im
relationalen Datenbankmodell entspricht das einer „1 zu n-Beziehung“, diese muss
sich in dem XML-Format widerspiegeln.
Weiterhin ist es unbedingt notwendig, gespeicherte Daten verändern zu können.
Dementsprechend sind die Operationen INSERT, UPDATE und DELETE einzuplanen.
Um dem Benutzer wiedergeben zu können, dass bei diesen Operationen keine
Fehler aufgetreten sind, und um ggf. anzuzeigen, wie viele Datensätze z.B. bei einer
Änderung betroffen sind, müssen entsprechende XML-Tags vorgesehen werden. Für
die Dokumentenerstellung ist es auch nötig, temporäre Tabellen oder Views
anzulegen und sie später wieder zu löschen.
Für den Fall, dass eine Datenbankoperation nicht erfolgreich durchgeführt werden
konnte, müssen lesbare verständliche Fehlermeldungen erzeugt werden, die es
ermöglichen, die Ursache zu erkennen, um diese ggf. beheben zu können.
3.3
Anforderungen an die Statistikerstellung
3.3.1 Umsetzung
Es muss eine leicht zu bedienende übersichtliche HTML-Seite erzeugt werden, die
es ermöglicht, neue Anfragen zu erstellen, bereits vorhandene zu bearbeiten und die
aktuelle auszuführen und somit eine Statistik zu erzeugen. Damit nicht unnötig viele
Daten über das Netz geschickt werden und dadurch der Server unnötig belastet wird,
wird hierbei zugunsten von Javascript (also dynamisches-HMTL) auf einen verstärkten Einsatz von Java-Servlets verzichtet. Die Servlets gestatten zwar, die Seiten
dynamisch aufzubauen und so z.B. das Datenbankschema immer aus der Datenbank selbst herauszulesen, jedoch müsste bei jeder Auswahl (z.B. Wahl einer
anderen Tabelle), die der Benutzer vornimmt, wieder eine Kommunikation zwischen
Client und Server stattfinden. Dies ist speziell in der Erstellungsphase einer neuen
Datenbankanfrage unpraktisch.
Außerdem ist die Interaktion mit dem Benutzer über den Javascript-Eventhandler
wesentlich einfacher. So können z.B. nicht benötigte Teile der Schnittstelle einfach
- 11 -
ausgeblendet werden, wenn der Benutzer Einstellungen vornimmt, die die
Anwendung bestimmter Funktionen gar nicht zulassen.
3.3.2 Flexibilität
Der Benutzer sollte möglichst nicht in der Mächtigkeit von SQL-Select-Anweisungen
eingeschränkt werden, aber dennoch sollte die Schnittstelle datenbanksystemunabhängig und einfach zu bedienen sein. Daher wird auf den Einsatz von nichtstandardisierten SQL-Funktionen und Outer-Joins verzichtet. Da die Anwendung von
Unteranfragen (Subqueries) eine schnelle und einfache Möglichkeit darstellt (die
vielen Benutzern logischer erscheint), Ergebnislisten einzuschränken, sollten diese
zugelassen werden, auch wenn sie z.Z. nicht von allen Datenbanksystemen
unterstützt werden. Dadurch erhalten Anfragen eine höhere Komplexität, so dass auf
eine Überprüfung der Unteranfragen auf deren Korrektheit zunächst verzichtet wird
(vgl. 8.1).
- 12 -
4
Graphische Anfragesprachen für Datenbanken
In den letzten Jahren wurden einige graphische Sprachen bzw. Hilfsmittel zur
Formulierung von Anfragen an Datenbanken vorgestellt. Diese sollen dem Benutzer
ermöglichen, auf einfache Art und Weise Anfragen an eine Datenbank zu stellen.
Einen einheitlichen Standard wie SQL für die textbasierte Formulierung von Anfragen
gibt es für graphische Anfrageverfahren nicht. SQL selbst kommt aber in diesem
speziellen Anwendungsfall als Anfragesprache nicht in Frage, da es nicht zumutbar
wäre, dass alle MitarbeiterInnen des Prüfungsamtes SQL lernen, um damit gelegentlich Anfragen nach statistischen Größen formulieren und bearbeiten zu können.
4.1
QBE – Query-By-Example
Query-By-Example war die erste graphische Anfragesprache für relationale Datenbanken und wurde 1975 von M.M. Zloof [30][31] vorgestellt. Schon kurze Zeit später
wurde in einer Studie [08] die Benutzerfreundlichkeit von QBE belegt. Eine
graphische Anfrage an die Studierendendatenbank in Form von QBE würde auf
einem alphanumerischen Terminal etwa so aussehen:
Beispiel: Drucke (P.) matrikel_nr, name, abschlussnote aus Tabelle s.studierende, mit einer abschlussnote <=2
Seit etwa zehn Jahren stagniert jedoch die Weiterentwicklung von QBE. Bis auf
wenige Ausnahmen ist QBE in seiner ursprünglichen Form [14] vom Markt verschwunden, aber die Idee, Anfragen durch das Eintragen von Beispielelementen in
Tabellenstrukturen zu erstellen, ist auch heute noch Teil von vielen relationalen
Datenbankoberflächen. So stellt z.B. IBM zu der Datenbank DB2 eine auf vereinfachtem QBE basierende Anfrageschnittstelle zur Verfügung [15].
In der Microsoft-Datenbank Access ist ein QBE-ähnlicher Teil integriert, der auch die
Bildung von Joins unterstützt. Die obige Anfrage würde in MS Access 2000 folgendermaßen aussehen:
- 13 -
Darstellung einer vergleichbaren Auswahlabfrage in MS Access 2000
Die gute Verständlichkeit und damit die leichte Erlernbarkeit von QBE, wie sie sich
auch in Vorlesungen und vielen Lehrbüchern (z.B. [05][24]) zeigt, ist der Grund,
weshalb in dieser Arbeit eine Benutzerschnittstelle entworfen wird, die QBE-ähnlich
gestaltet ist. Dabei sollen wesentliche Punkte, insbesondere die Ausdrucksfähigkeit
und die flexible Formulierung und Umgestaltung von Anfragen berücksichtigt werden.
Parametrisierbare Unteranfragen sind ein wichtiges Konstruktionsprinzip zur Erstellung von Abfragen. Sie wurden bisher jedoch in relationalen Datenbanken kaum
berücksichtigt, obwohl sie für viele Arten von Anfragen ein wünschenswertes
Strukturierungsmittel sind.
Nach der Studie, die die Benutzerfreundlichkeit von QBE untersucht hat [08], waren
die Probanden der Studie bereits nach einer kurzen Einarbeitungszeit in der Lage,
selbstständig QBE-Anfragen zu formulieren. Dabei erleichterte die QBE-Darstellung
der Relationen als Tabellen den Benutzern das Verständnis und die Eingabe der
Anfragen.
Hauptfehlerquellen der Probanden bei der Formulierung von Anfragen waren die
Aggregatfunktionen mit Gruppierungen und die Verwendung der Negation. Ein Grund
dafür lag sicher darin, dass die Semantik im Wesentlichen selbst durch Beispiele
eingeführt war, die für sich einleuchtend waren, die aber vor allem bei den
Konstrukten mehrdeutige Fortsetzungen auf kompliziertere Anfragen zuließen. Für
den auf dem Bereichskalkül basierenden „Kern" von QBE ohne Aggregationen kann
in der Arbeit von A. Heuer und G. Saake [12] eine formale Semantik nachgelesen
werden.
- 14 -
4.2
NQS – Network-Query-System
NQS [20] verfolgt einen etwas anderen Ansatz als QBE. Bei NQS sieht der Benutzer
die Datenbank als ein Schema-Diagramm. Die Tabellen sind dabei wie bei dem
Entity-Relationship-Datenmodell [01] über Relationen und Rollen zu einem Graphen
verbunden. Für eine Anfrage an die Datenbank wählt der Benutzer einfach mit der
Maus die Tabellen aus, die die Attribute beinhalten, die er benötigt. Das System
bildet dann den Pfad zwischen den ausgewählten Tabellen als Teilgraphen ab. Der
Graph muss rekursionsfrei sein, d.h. der Benutzer muss ggf. vorhandene
Rekursionen auflösen, indem er die unerwünschten Zweige entfernt. Falls bestimmte
Bedingungen für Attribute zutreffen sollen, kann der Benutzer diese einfach durch
Anklicken des entsprechenden Attributs in eine sich öffnenden Textbox eingeben.
Zum Ausführen einer solchen graphischen Anfrage wird der dargestellte Teilgraph
erst in NQL (Network-Query-Language [19]) umgewandelt und dann die NQLAnweisung gestartet, ähnlich wie bei MS Access auch die Visualisierung einer
Abfrage intern immer in eine SQL-Anweisung übersetzt wird.
4.3
Ansatz dieser Arbeit
In dieser Arbeit wird der Ansatz von NQS nicht verfolgt, weil eine dynamische
Darstellung von Graphen in einem Browser den zeitlichen Rahmen sprengen würde
und z.Z. auch nur mit Hilfe von Java Applets oder Ähnlichem realisiert werden
könnte.
Die Anwendung von QBE in seiner ursprünglichen Form scheint für die Statistikerstellung im Prüfungsamt nicht angebracht. Zum einen ist es für die MitarbeiterInnen
des Prüfungsamtes nicht unbedingt erforderlich neue Anfragen zu formulieren, da in
erster Linie lediglich die von dem Administrator vorgefertigten und gespeicherten
Anfragen von ihnen verändert werden müssen.
Zum anderen ist ein strenges QBE-Konzept in einem Browser nicht so ohne weiteres
umsetzbar. Zwar könnte mit einem Textfeld auf einer HTML-Seite ein alphanumerisches Terminal simuliert werden, aber das wäre nicht besonders benutzerfreundlich. Die verschiedenen Steuerelemente von HTML-Formularen bieten weitaus
bequemere Möglichkeiten. Es werden daher lediglich die Namen der Tabellen zur
Auswahl vorhanden sein, anstatt die Tabellen und ihre Attribute komplett
- 15 -
darzustellen. Dafür jedoch werden die einzelnen Attribute in der Schnittstelle, die der
Benutzer auswählen kann, in tabellarischer Form angeordnet sein.
Grundsätzlich soll keine neue graphische Anfragesprache erfunden werden. Es soll
vielmehr eine HTML-Seite entwickelt werden, die den Benutzer dabei unterstützt
SQL-Anweisungen zu erzeugen, die dann an die Datenbank gesendet und dort
ausgeführt werden.
4.3.1 Konzept
Zur Umsetzung dieser Ziele wurde folgendes Konzept gewählt. Als erstes muss der
Benutzer eine oder mehrere Tabellen aus einer Liste aller Tabellen auswählen, die in
der Datenbank für die Statistiken in Frage kommen. Dann können einzelne Attribute
aus den Tabellen in sogenannten Dropdown-Listen ausgewählt werden. Die
Dropdown-Listen sind in tabellarischer Form nebeneinander angeordnet, so dass der
Eindruck entsteht, dass es sich um eine neue Tabelle handelt. Dies ist besonders
intuitiv, da die bisher angeforderten Statistiken immer eine tabellarische Form hatten.
Diese Form ergibt sich durch die Ergebnisse einer SQL-Select-Anweisung, die immer
eine Tabelle bzw. eine Sicht (View) darstellen.
In den Zeilen unter den ausgewählten Attributen hat der Benutzer verschiedene
Möglichkeiten, die Ergebnisliste zu manipulieren. So kann z.B. mit einer Checkbox
für jede Spalte bestimmt werden, ob die Spalte im Ergebnis angezeigt werden soll.
Außerdem kann ausgewählt werden, ob nach einem Attribut auf- oder absteigend
oder gar nicht sortiert werden soll.
In der ersten Spalte befinden sich die Zeilenerklärungen, die mit einem Hyperlink zu
entsprechenden Hilfetexten führen. Die ersten drei Zeilen werden immer angezeigt,
bei den weiteren kann der Benutzer die Zeile und die damit verbundene
Funktionalität (s.u.) an- oder ausschalten. Dies dient der Übersichtlichkeit, damit der
Benutzer nicht durch die Auflistung aller Eingabemöglichkeiten überfordert wird. Um
die Schnittstelle möglichst einfach und noch übersichtlicher zu gestalten, wird immer
nur eine zusätzliche Spalte zu den vom Benutzer ausgewählten Spalten angezeigt
(bis zu maximal zehn Spalten).
Zusätzlich wird der Benutzer durch farbliche Markierungen in der Tabelle auf die für
die Ausgabe relevanten Zellen hingewiesen.
- 16 -
4.3.2 Join
Da es sich um eine relationale Datenbank handelt, müssen, falls der Benutzer
mehrere Tabellen ausgewählt hat, diese noch miteinander in Beziehung gesetzt
werden, anderenfalls würde das Kreuzprodukt der Tabellen gebildet. Dafür ist eine
Extrazeile „verknüpfen mit“ vorgesehen, in der der Benutzer ein Attribut einer
anderen Tabelle auswählt, mit dem er diese Spalte, d.h. das zuvor ausgewählte
Attribut, verknüpfen möchte. Für z.B. die „Liste der Studenten und deren erworbene
Scheine zu einer Veranstaltung“ müssen die Tabellen Studierende und Scheine
ausgewählt werden und die Tabellen über das gemeinsame Attribut MatrikelNr
verknüpft werden.
4.3.3 Bedingungen
Um Bedingungen wie z.B. Veranstaltungsnummer = 42 (s. Beispiel unten) zu
realisieren, gibt es insgesamt drei zusätzliche Zeilen. Schreibt der Benutzer seine
exemplarischen Daten z.B. „42“, „23“ (vgl. QBE) untereinander in eine Spalte, so
werden diese maximal drei Werte mit dem logischen ODER verknüpft, so dass
folgende WHERE-Klausel erzeugt würde: „where veranstaltung = 42 or
veranstaltung = 23“. Werden die Bedingungsdaten nebeneinander, d.h. in
einer Zeile aber in verschiedenen Spalten eingetragen, so werden die Bedingungen
auf dieser Ebene mit dem logischen UND verknüpft.
Eine Beispielanfrage im Vergleich: QBE vs. SDB-Anfrageneditor
QBE: Verknüpfungen werden mit Beispieldaten in Klammern, Bedingungen werden mit vorangestellten Vergleichsoperatoren realisiert.
- 17 -
Erstellter Studierendendatenbank-Anfrageneditor
4.3.4 Aggregatfunktionen
Die Aggregatfunktionen müssen ebenso wie die Bedingungen und die Verknüpfungen (Join) zuerst mit der Checkbox in der ersten Spalte eingeschaltet werden. Der
Benutzer kann aus den für Statistiken am häufigsten benötigten folgenden Aggregatfunktionen wählen: Durchschnitt, Minimum, Maximum, Summe, Anzahl und Gruppierung. Als Standard ist die Gruppierung nach einem Attribut eingestellt.
4.3.5 Bedingungen für Aggregatfunktionen
In SQL werden Bedingungen für Aggregatfunktionen als HAVING-Klausel formuliert.
Hierbei wird der Benutzer wiederum mit maximal drei Zeilen (vgl. 4.3.3) unter den
Aggregatfunktionen bei der Erstellung einer solchen Klausel unterstützt. Um es dem
Benutzer so übersichtlich wie möglich zu gestalten, werden diese Zeilen aber nur
angezeigt, wenn auch zuvor die Aggregatfunktionen eingeschaltet wurden.
4.3.6 SQL-Kontrollanzeige für den Administrator
Der Datenbankadministrator hat zur Kontrolle in der letzten Zeile ein Textfeld, in das
die automatisch erzeugte SQL-Anweisung geschrieben wird. So kann auf einfache
Weise verglichen werden, ob die mit dem Anfrageneditor erstellte Anweisung der
ursprünglichen Fragestellung entspricht. Das allgemein auftretende Problem, dass
umgangssprachliche Fragen nicht immer eindeutig sind und daher unterschiedlich in
SQL formuliert werden können, bleibt aber bestehen. Dies ist jedoch im
Wesentlichen
ein
Kommunikationsproblem
zwischen
dem
Fragenden
demjenigen, der die Frage mit Hilfe der Datenbank beantworten soll.
- 18 -
und
5
Umsetzung der Statistikerstellung
Vergleichbare Arbeiten (siehe www.google.de „qbe, browser, web“) bestehen oft aus
einem Programm, welches nicht in einen Internet-Browser integriert ist, sondern nur
die Funktion bietet, Daten aus der Datenbank mit einem Daten-Browser im Internet
zu publizieren. Ein Projekt der Université Mons-Hainaut (Belgien) hat zwar das Ziel
ein Webinterface auf QBE-Basis für bestehende relationale Datenbanken zu
entwickeln, aber es wird dabei auf die Technologie von PHP, Perl und CGI-Scripte
zurückgegriffen und nicht die flexible Datenverarbeitung von XML-Dokumenten
angestrebt. Da uns bis zum jetzigen Zeitpunkt eine „QBE-Internet-Browser-Lösung“,
die für unsere Bedürfnisse ausreichend wäre, nicht bekannt ist, wurde folgende neue
Lösung entwickelt.
5.1
HTML-Seite
Die komplette Seite besteht aus einer Tabelle mit 15 Zeilen und 11 Spalten. Wie
schon im Konzept erwähnt, steht in der ersten Spalte immer die Bedeutung für eine
Zeile. Es gibt zusätzlich maximal zehn weitere Spalten, die sich dynamisch ein- und
ausblenden.
Die Zeilen 1, 2, 14 und 15 erstrecken sich über die gesamte Tabellenbreite, die
anderen sind abhängig von der Anzahl der ausgewählten Attribute. Nachfolgend
werden die Funktionen der einzelnen Zeilen erläutert.
1. Zeile „Frage“:
Hier ist ein maximal 100 Zeichen langes Textfeld vorhanden. In dieses soll eine
Frage, eine Beschreibung oder ein Name für die Anfrage eingegeben werden.
Die gespeicherte Anfrage ist dann später unter dem eingegebenen Text
wiederzufinden.
2. Zeile „Tabellenauswahl“:
Hier befindet sich eine Auswahlliste mit den Tabellennamen, die für die
Statistiken relevant sind. Diese Liste wurde halbautomatisch mit einem Datenbankscript erzeugt (siehe Anhang javascript.sql). Falls das Datenbankschema
geändert wird und Tabellen hinzukommen oder wegfallen, muss diese Liste
manuell dem neuen Schema angepasst werden.
Ein Eintrag in der Liste hat folgende Form:
<option value="studierende s" label="Studierende" > Studierende </option>
- 19 -
Wichtig dabei ist der Alias für die Tabelle in dem Attribut value (in diesem
Beispiel „s“ für studierende), damit die erzeugte SQL-Anweisung nicht zu lang
und dadurch unübersichtlich wird. Derselbe Alias muss auch in der Javascriptdatei stat_schema.js (siehe Anhang) verwendet werden.
3. Zeile „Spalten tauschen“:
In dieser Zeile werden Buttons mit Pfeilen angezeigt, wenn der Benutzer mehr
als ein Attribut ausgewählt hat. Mit einem Mausklick auf einen derartigen Button
werden zwei nebeneinanderliegende Spalten miteinander vertauscht. Damit hat
der Benutzer die Möglichkeit, schnell und bequem die Reihenfolge der Attribute
in den Spalten zu verändern.
4. Zeile „Feld / aus Tabelle“:
Hier kann der Benutzer die Felder / Attribute der von ihm zuvor ausgewählten
Tabellen in Dropdown-Listen anwählen. Die Attribute sind dabei nach den
Tabellen gruppiert und dann alphabetisch sortiert. Damit der Benutzer immer
leicht erkennen kann, aus welcher Tabelle er ein bestimmtes Attribut ausgewählt hat, ist unter jeder Dropdown-Liste ein Textfeld angeordnet, in dem der
jeweilige Tabellenname angezeigt wird. Damit die Listen übersichtlich bleiben
und nur die Attribute der ausgewählten Tabellen angezeigt werden, werden
diese Dropdown-Listen dynamisch mit einem Javascript gefüllt.
5. Zeile „anzeigen / sortieren / Spaltenüberschrift“:
Mit einer Checkbox kann der Benutzer entscheiden, ob das Attribut dieser
Spalte auch in der Ergebnisliste ausgegeben werden soll (SELECT), oder ob es
nur ausgewählt wurde, um eine Bedingung (WHERE) zu formulieren. Mit einer
Dropdown-Liste kann die Sortierung (ORDER BY) für dieses Attribut eingestellt
werden. Ein zusätzliches Textfeld erlaubt die Eingabe einer anderen Spaltenüberschrift (AS). Dies ist besonders bei der Verwendung von Aggregatfunktionen von Vorteil, da sonst von der Datenbank nichts-aussagende Spaltenüberschriften (bei Ingres z.B. „col1“) automatisch erzeugt werden.
6. Zeile „verknüpfen mit / aus Tabelle“:
Dies ist die erste Zeile, die mit der Checkbox in der ersten Spalte komplett einoder ausgeblendet werden kann, wenn eine Verknüpfung von zwei oder mehr
Tabellen nicht erforderlich ist. Ansonsten ist diese Zeile genauso aufgebaut wie
Zeile 4. Zusätzlich gibt es noch eine Dropdown-Liste mit Vergleichsoperatoren,
- 20 -
so dass auch Verknüpfungen zwischen Tabellen möglich sind, in denen ein
Attributwert kleiner oder größer als der zu vergleichende ist. Diese Art der
Verknüpfung bietet mehr Möglichkeiten als die übliche JOIN-Operation.
7. – 9. Zeile „Bedingung“, „oder“, „oder“:
Diese Zeilen haben den stärksten QBE-Charakter. Wie schon im Abschnitt
Bedingungen 4.3.3 beschrieben, kann hier der Benutzer einfach die Kriterien
bzw. Werte eintragen, die ein Attribut enthalten soll. Dazu stehen ihm wieder in
einer Dropdown-Liste eine Anzahl von Vergleichsoperatoren zur Verfügung.
Neben den aus der Mathematik bekannten Vergleichsoperatoren (<, ≤, =, ≥, >,
≠) sind die datenbanktypischen: IS NULL, IS NOT NULL, LIKE, IN, NOT IN
ebenfalls implementiert. Eine Besonderheit stellt der zusätzliche letzte Punkt
(„SUBQUERY“) in der Vergleichsoperatorenliste dar. Wenn „SUBQUERY“ als
Operator ausgewählt wird, kann in dem Textfeld, in das sonst die Vergleichswerte eingetragen werden, eine SQL-Unterabfrage geschrieben werden. Da
diese Unterabfrage auf keinerlei Korrektheit geprüft wird, muss es sich nicht
unbedingt um eine Unterabfrage handeln. So kann der Benutzer jede
Bedingung formulieren, die vom jeweiligen Datenbanksystem unterstützt wird.
10. Zeile „Funktion“:
In dieser Zeile können die Aggregatfunktionen (vgl. 4.3.4) ein- bzw. ausgeschaltet werden. Eine Javascriptfunktion sorgt dafür, dass nur eine korrekte
Auswahl getroffen werden kann. Beispielsweise ist in SQL eine COUNT(*)Anweisung erlaubt, nicht aber eine SUM(*)-Anweisung.
11. – 13. Zeile „Bedingung für Gruppe“, „oder“, „oder“:
Die HAVING-Klausel kann mit diesen drei Zeilen erstellt werden (vgl. 4.3.5). Die
Funktionsweise entspricht den Zeilen 7 – 9 und wird daher hier nicht weiter
beschrieben.
14. Zeile „Aktionsmöglichkeiten“:
Der Benutzer hat verschiedene Aktionsmöglichkeiten, zwischen denen er
auswählen kann, wie z.B. Speichern, Ausführen oder Rücksetzen einer
formulierten Anfrage. Diese Aktionen können jeweils mit einem Mausklick auf
den entsprechenden Button ausgeführt werden. Zusätzlich gibt es in dieser
Zeile noch einen Link zu der Liste mit den gespeicherten Anfragen.
- 21 -
15. Zeile „erzeugter SQL“:
Hier ist ein nicht veränderbares Textfeld vorhanden, in das zur Kontrolle der
erzeugte SQL-Ausdruck geschrieben wird. Dieser kann ggf. auch markiert und
kopiert werden, so dass die Anfrage auch in ein Datenbankscript o.ä.
geschrieben werden kann.
5.2
Javascriptdateien
In dem HTML-Tag <head> werden folgende Javascripte geladen:
check.js stellt verschiedene Funktionen zum Überprüfen von Textfeldern auf
bestimmte Datentypen zur Verfügung. Diese Datei wird unter anderem auch bei
der Navigationsleiste benötigt, um zu testen, ob eine Datensatznummer gültig
ist.
cookie.js stellt die Basisfunktionen zum Setzen und Löschen von Cookies zur
Verfügung. Diese Datei wird z.Z. in keiner anderen Maske benötigt, ist aber so
allgemein gehalten, dass sie nicht nur für die Datenbankanfragenerstellung
geeignet ist.
stat_globals.js deklariert alle globalen Variablen.
stat_schema.js erstellt das zweidimensionale Array felder[i][j]. Dabei ist unter
dem i-ten Eintrag das Array mit den Attributen der i-ten Tabelle (vgl. 2. Zeile
„Tabellenauswahl“ in 5.1) zu finden. Der j-te Eintrag enthält dann das j-te
Attribut der i-ten Tabelle. Ein solches Attribut ist durch den angezeigten Namen,
einem Alias und den Datentyp charakterisiert. Wenn das Datenbankschema
verändert wird, müssen in dieser Datei ebenfalls die hinzugefügten Attribute
ergänzt oder die gelöschten herausgenommen werden, damit keine fehlerhaften SQL-Anweisungen mit dem Anfrageneditor erzeugt werden.
stat_cookies.js fasst die Funktionen zum Speichern und Wiederherstellen der
Cookies zusammen, die für den Anfrageneditor wichtig sind.
stat_erstellen.js implementiert die wichtigsten Funktionen zum Erzeugen der SQLAnweisung (setSelect()) und zum dynamischen Füllen der AttributDropdown-Listen (fill_feld()). Hinzu kommen noch einige Funktionen, mit
- 22 -
denen das Erscheinungsbild der HTML-Seite dynamisch verändert werden
kann, z.B. durch das Setzen von einer Hintergrundfarbe für besondere Zellen.
stat_events.js fasst alle Funktionen zusammen, die durch bestimmte Ereignisse
(Benutzeraktionen) hervorgerufene Javascript-Events behandeln. Dabei wurde
besonderen Wert auf die Namensgebung der Funktionen gelegt, so dass leicht
erkennbar ist, bei welchem Event eine Funktion aufgerufen wird.
5.3
Erzeugung der SQL-Anweisung
Die SQL-Anweisung wird on-the-fly, d.h. sobald mindestens ein Attribut ausgewählt
und zur Anzeige markiert wurde, in der Funktion setSelect() erzeugt. Je nachdem welche Einstellungen der Benutzer vornimmt, wird die SQL-Anweisung dann
erweitert oder auch wieder gelöscht, wenn z.B. kein Attribut zur Anzeige markiert ist
(vgl. 5. Zeile in 5.1).
Die Erzeugung der SQL-Anweisung orientiert sich stark an der Grammatik für SQL.
So wird zunächst für jede Klausel ein String erzeugt, in dem die entsprechenden
SQL-Keywords gespeichert sind. Dann werden der Reihe nach die einzelnen Spalten
durchgegangen und dabei z.B. der SELECT-String um die ausgewählten Attribute
erweitert. Zum Schluss, wenn alle Klauseln vollständig zusammengesetzt wurden,
wird durch die Konkatenation d.h. durch das hintereinander Schreiben der Klauseln
die SQL-Anweisung erzeugt.
Neben der Erzeugung der SQL-Anweisung werden alle vorgenommenen Einstellungen in den Cookies gespeichert. Zur besseren Übersichtlichkeit werden zusätzlich
die für die SQL-Anweisung relevanten Zellen farblich markiert.
5.4
Gespeicherte Datenbankanfragen
Die Datenbankanfragen werden mit einem Mausklick auf den Button „Abfrage
speichern“ in der Tabelle pra03.stat_statistiken gespeichert. Diese hat
folgenden Aufbau (vgl. Create-Script stat_statistiken.sql im Anhang):
Ein integer-Feld „lfd_nr“ stellt den Primärschlüssel dar. Daher muss eine
fortlaufende Nummer immer angegeben werden.
Im „datum“-Feld soll das Datum der letzten Änderung dieser Datenbankanfrage
festgehalten werden.
- 23 -
Das varchar-Feld „frage“ bietet Platz für 100 Zeichen und soll es ermöglichen,
einer Datenbankanfrage einen aussagekräftigen Namen zuzuordnen oder die ursprüngliche Fragestellung einzutragen.
In dem „query“-Feld werden die fertigen und korrekten SQL-Anweisungen mit einer
maximalen Länge von 1000 Zeichen gespeichert. Dieses Feld darf nicht leer sein.
Wenn eine Datenbankanfrage direkt, d.h. von der Liste der gespeicherten Datenbankanfragen aufgerufen wird, wird dieses Feld ausgelesen und die darin enthaltene
SQL-Anweisung ausgeführt. Die Längenbeschränkung auf maximal 1000 Zeichen
sollte keine Probleme bereiten, da die bisherigen SQL-Anweisungen eine durchschnittliche Länge von ca. 450 Zeichen hatten. Dennoch ist es theoretisch möglich,
dass bei sehr großen UNTERANFRAGEN dieses Limit überschritten wird.
Für die Speicherung der Cookies wurde ein long-varchar-Feld „cookie“ angelegt.
Damit ist es relativ leicht möglich, eine gespeicherte Datenbankanfrage so wiederherzustellen, dass sie in der dafür vorgesehenen HTML-Seite bearbeitet und
verändert werden kann. Dieses Feld kann auch leer (NULL) gelassen werden. Das
hat aber zur Folge, dass diese Datenbankanfrage nicht verändert werden kann. In
diesem Fall erscheint in der Liste der gespeicherten Datenbankanfragen der Button
„bearbeiten“ nicht. Diese Funktionsweise gestattet es einem Administrator eine
Datenbankanfrage direkt in der Datenbank abzulegen, ohne diese mit der „EditorSeite“ erstellt zu haben. So können immer wiederkehrende Fragen, die keiner
Änderung bedürfen, auch davor geschützt werden. Außerdem können so Datenbankanfragen, die datenbanksystemspezifische Funktionen enthalten, die z.Z. nicht von
dem Editor unterstützt werden, trotzdem an dieser Stelle allen Benutzern auf
einfache Art und Weise zugänglich gemacht werden.
5.4.1 Anmerkung zu Cookies
Maximal können pro Website 20 Cookies erstellt werden. Jeder Cookie kann
maximal bis zu 20KB groß sein. Da jedoch die Werte der Cookies mit der
JavaScriptfunktion escape() noch entsprechend maskiert werden, können ggf.
auch mehr als 400KB an Daten entstehen, daher wird zum Abspeichern der Cookies
in der Datenbank ein long-varchar-Feld verwendet. Allerdings ist es zweifelhaft, ob
wirklich so komplexe Datenbankanfragen erstellt werden müssen. In der Vergangenheit waren die Datenbankanfragen nicht so umfangreich.
- 24 -
6
Umsetzung der Grundlagen
In diesem Abschnitt werden die Umsetzung der einzelnen Java-Klassen und deren
Aufgaben beschrieben. Die Klassen sind in zwei Pakete aufgeteilt.
6.1
Basisklassen (package
base)
6.1.1 class SDBDocument
In der Klasse SDBDocument werden alle Daten für eine Ein- bzw. Ausgabemaske im
XML-Format zusammengefasst. In dem Konstruktor der Klasse wird zuerst ein
org.w3c.dom.Document instanziert. Anschließend werden die verschiedenen
XML-Tags je nach Servlet und Anforderung erzeugt. In der toString()-Methode
wird dann aus dem org.w3c.dom.Document mit Hilfe von einem org.apache.
xml.serialize.XMLSerializer ein String erzeugt. Eine Doc-Type-Definition
für diesen XML-String ist in der Datei sdbdocument.dtd (siehe Anhang) zu finden.
Diese kann aber nie vollständig sein, da in dem Tag <formdata> alle Parameter
aufgelistet werden, die dem Servlet zugesandt worden sind. Für diesen Tag gibt es
daher keine vollständige Beschreibung, da nicht abzusehen ist, welche Parameter an
ein Servlet übergeben werden. Eine Liste der typischen Parameter zur Steuerung der
Servlets wird unter 6.2.1 Parameterliste beschrieben.
6.1.2 class SDBElementList
SDBElementList stellt die Basisklasse für SDBResultsImpl und SDBGroup dar.
Es handelt sich dabei um eine dynamische Liste, die je nach Anforderungen ihre
Kapazität verdoppelt oder halbiert. Gespeichert werden die org.w3c.dom.
Element-Objekte in einem Array.
6.1.3 class SDBGroup
Die Klasse SDBGroup soll alle Arten von Optionsgruppen aus dem HTML-Standard
realisieren.
Dabei
ist
ein
einheitliches
XML-Format
für
Dropdown-Listen,
Radiobuttons und Checkboxen vorgesehen. Mit dem richtigen Stylesheet kombiniert
ergibt sich dann der entsprechende HTML-Tag. Gerade an den Stellen, an denen
eine gewisse referentielle Integrität gefordert wird, z.B. bei Diplomarbeiten, bei denen
als Betreuer eine Lehrpersonalnummer eingetragen werden muss, sollte der
Benutzer durch eine dynamisch gefüllte Dropdown-Liste mit dem gesamten
- 25 -
Lehrpersonal (Name und Nummer) bei seiner Eingabe unterstützt werden. Für
dieses häufig wiederkehrende Key-Value-Prinzip wurde diese Klasse erstellt.
6.1.4 class SDBGroupElement
Ein SDBGroupElement stellt eine einzelne Option für die SDBGroup zur Verfügung
und besteht aus einem Key und einem Value,.
6.1.5 interface SDBResults
Das Interface SDBResults soll eine einfache Schnittstelle bieten, falls in Zukunft
einmal das benutzte Datenbanksystem die volle JDBC-API unterstützt und so auf die
Funktionalität des ResultSets zurückgegriffen werden kann. Anstatt den ResultSet
aus der Datenbank komplett auszulesen und in einer Klasse SDBResultset
zwischenzuspeichern, um das Vorwärts- und Rückwärtsblättern zu ermöglichen,
könnten
dann
die
Methoden
des
java.sql.ResultSet
next()
und
previous() direkt verwendet werden.
6.1.6 class SDBResultset
Die Klasse SDBResultset baut das XML-Element <Resultset> auf. Dazu wird
dem Konstruktor ein java.sql.ResultSet, ein org.w3c.dom.Document und
ggf. ein String mit der erzeugenden SQL-Select-Anweisung übergeben. Mit der
createElement()-Methode der Klasse Document, wird, falls ein String-Objekt
mit übergeben wurde, ein <statement>-Element erzeugt, das die SQL-Anweisung
beinhaltet, anderenfalls fehlt das <statement>-Element. Aus den Informationen des
java.sql.ResultSetMetaData-Objekts
wird
anschließend
das
<table>-
Element mit den dazugehörigen <column>-Elementen erzeugt. Entsprechend dem
Konzept der java.sql-API wird so die Datenbeschreibung strikt von den Daten
getrennt gespeichert.
Die Daten werden in einem SDBResultsImpl-Objekt zwischengespeichert, d.h. in
der Methode initResults() wird der übergebene ResultSet einmal komplett
durchlaufen, alle Daten ausgelesen und für jeden Datensatz ein SDBRow-Objekt
instanziert. Dieses SDBRow-Objekt wird dann in dem SDBResultsImpl-Objekt
gespeichert.
Anschließend
werden
der
übergebene
ResultSet
und
sein
erzeugendes Statement geschlossen und damit die verknüpften Datenbankres-
- 26 -
sourcen freigegeben. Um die Funktionalität einer Navigationsleiste zu implementieren, wird das <results>-Element (siehe 6.1.7 class SDBResultsImpl) je nach
angefordertem Datensatz ersetzt.
6.1.7 class SDBResultsImpl
Diese Klasse stellt eine Erweiterung der SDBElementList dar und implementiert
das Interface SDBResults. In einem SDBResultsImpl-Objekt werden die Daten
eines ResultSets in Form von SDBRow-Objekten in einem Array zwischengespeichert. Die hier implementierten Methoden des Interfaces geben jeweils ein
<results>-Element mit entweder einem Datensatz (ein <row>-Element) oder allen
Datensätzen (0 bis n <row>-Elemente) zurück.
6.1.8 class SDBRow
Jedes SDBRow-Objekt stellt einen Datensatz dar. Die Klasse erzeugt dazu ein
<row>-Element mit so vielen <col>-Elementen, wie in der SQL-Anweisung
selektiert wurden bzw. in den ursprünglichen java.sql.ResultSet-Columns
vorhanden sind. Bei sehr großen Datenmengen sollten an dieser Stelle evtl. noch
kürzere XML-Elementnamen, z.B. <r> und <c> gewählt werden, um die Performance nicht zu gefährden.
6.1.9 abstract class SDBServlet
Diese abstrakte Klasse stellt grundlegende Funktionen zur Verfügung, die in jedem
Servlet gebraucht werden. In der init()-Methode, die automatisch vom Webserver
beim Start eines Servlets aufgerufen wird, wird der JDBC-Datenbanktreiber
instanziert. In der destroy()-Methode, die beim Beenden aufgerufen wird, werden
noch
nicht
geschlossene
Datenbankverbindungen
getrennt.
Die
Methode
process() transformiert eine XML- und eine XSL-javax.xml.transform.
Source mit Hilfe eines javax.xml.transform.Transformer in einen Datenausgabestrom.
Die
wesentlichen
Funktionen
für
den
Zugriff
auf
das
sessiongebundene
SDBDocument, wie z.B. newDocument() zum Anlegen eines neuen Dokumentes in
der aktuellen Session sind ebenfalls in dieser Klasse implementiert. Da in allen
Servlets keine Unterscheidung zwischen den verschiedenen Kommunikationsformen
- 27 -
post bzw. get vorgenommen werden muss, ist auch die Methode doPost() schon
implementiert. Diese leitet nur die HttpServletRequest- und HttpServletResponse-Objekte an die abstrakte Methode doGet() weiter. Damit genügt es, in
von dieser Klasse abgeleiteten Servlets die Methode doGet() zu implementieren. In
den HTML-Formularen ist es dann egal, ob <form method="get"> oder <form
method="post"> verwendet wird, da sich das Servlet in beiden Fällen gleich
verhält. Es ist dabei nur zu bedenken, dass bei „get“ die Menge der zu
versendenden Daten vom Client an den Server durch die maximale Länge der
übertragenen URI / URL begrenzt ist [08].
6.2
Servlets (package
servlet)
Im Rahmen dieser Arbeit wurden drei Servlets (siehe 6.2.2 class SDBSelect, 6.2.3
class SDBExecute, 6.2.4 class SDBStatistik) entwickelt. Alle drei lassen sich mit
folgenden Parametern steuern.
6.2.1 Parameterliste zur Steuerung der Servlets
6.2.1.1 Parameter: requery
Wird der Parameter „requery“ an ein Servlet gesendet, wird ein neues
SDBDocument angelegt. Diese Funktionalität ist notwendig, weil sonst im Laufe einer
Session immer mehr <resultset>- Elemente in dem SDBDocument gespeichert
werden würden und daher in den Stylesheets nicht ermittelt werden könnte, welcher
Resultset wo angezeigt werden soll. Aus diesem Grund sollte bei einem Wechsel
zwischen zwei verschiedenen Eingabemasken immer auch ein requery an das
Servlet gesendet werden, es sei denn, es werden zwei <resultset>-Elemente
gewünscht (vgl. Anforderungen 3.2). So kann z.B. in einer ersten Eingabemaske ein
Student ausgewählt und in einer folgenden seine erworbenen Scheine zusätzlich
aufgelistet werden. Der Wert des Parameters ist ohne Bedeutung, da nur überprüft
wird, ob er vorhanden ist. Ist das der Fall, wird ein neues SDBDocument angelegt. Ist
er nicht an das Servlet gesendet worden, wird das SDBDocument von der aktuellen
Session weiterverwendet.
6.2.1.2 Parameter: query
An ein Servlet können ein oder mehrere „queries“ geschickt werden. Jeder String,
- 28 -
der als query an ein Servlet geschickt wird, wird darauf getestet, ob er mit SELECT
anfängt (vgl. servlet.SDBSelect.setQuerys()). In diesem Fall wird versucht,
eine Datenbankverbindung herzustellen und die Select-Anweisung auszuführen (vgl.
base.SDBServlet.setResultSet()).
Wenn
dies
gelingt,
wird
ein
<resultset>-Element in das aktuelle SDBDocument eingefügt, anderenfalls
werden entsprechende Fehlermeldungen erzeugt.
6.2.1.3 Parameter: nav_[1-7]
Alle Parameter, die mit nav_ beginnen, werden dahingehend überprüft, ob hinter
dem Unterstrich eine Ziffer folgt. Die Ziffern haben dabei folgende Bedeutungen:
1: Der erste Datensatz wird angezeigt.
2: Ausgehend von der aktuellen Position wird um zehn Datensätze zurückgerückt.
3: Ausgehend von der aktuellen Position wird um einen Datensatz zurückgerückt.
4: Ist zusätzlich der Parameter row vorhanden und eine Zahl zwischen 1 und der Anzahl der
Datensätze eingetragen, wird zu dem Datensatz mit dieser Nummer gesprungen.
5: Ausgehend von der aktuellen Position wird um zehn Datensätze vorgerückt.
6: Ausgehend von der aktuellen Position wird um einen Datensatz vorgerückt.
7: Der letzte Datensatz wird angezeigt
Falls keine Ziffer zwischen 1 und 7 hinter dem Unterstrich steht, werden alle Datensätze angezeigt.
6.2.1.4 Parameter: stylesheet
Mit dem Parameter stylesheet wird dem Servlet mitgeteilt, welchen Stylesheet es
verwenden soll, um aus den XML-Daten des SDBDocuments eine HMTL-Seite zu
erzeugen.
6.2.1.5 Parameter: form
Dieser Parameter soll die Einstellung verschiedener Ausgabeformate ermöglichen.
Zur Zeit werden aber nur zwei Formate unterstützt. Das Standardformat ist HTML
und wird immer verwendet, auch wenn dieser Parameter nicht gesetzt wird. Wenn
form=xml an das Servlet gesendet wird, wird der XML-String eines SDBDocuments
unverändert gelassen.
In den doGet()-Methoden der Servlets läßt sich vor der Datenausgabe (siehe
process()) leicht jedes andere Format einstellen. Da die javax.servlet.http-Technologie es nicht zulässt, allein durch Angabe eines anderen Stylesheets das
- 29 -
Ausgabeformat einzustellen, muss dieses zusätzlich immer mit der Methode
HttpServletResponse.setContentType() gesetzt werden.
6.2.1.6 Parameter: xmlparam
Dieser Parameter gestattet es, an einen Stylesheet selbst wiederum Parameter
weiterzugeben. Diese Technik wird zum Beispiel bei den Statistiken verwendet, um
ein schnelles einfaches Umsortieren der Ergebnislisten zu ermöglichen. Dazu wird
xmlparam=order_by_column:1 an das Servlet gesendet, dieses setzt anschließend in der SDBServlet.process()-Methode mit javax.xml.transform.Transformer.setParameter(order_by_column,
1) den entsprech-
enden XSL-Parameter. In dem Stylesheet (siehe Anhang stat_antwort.xsl) kann dann
auf den Wert zugegriffen werden und wie in diesem Beispiel nach der 1. Spalte
sortiert werden.
6.2.2 class SDBSelect
Dieses Servlet unterstützt alle unter 6.2.1 angegebenen Parameter. Damit eignet es
sich lediglich zur Anzeige jedoch nicht zum Ändern von Daten. Entsprechend den
Anforderungen für Navigationsleisten bietet es die Möglichkeit, immer nur einen
Datensatz oder aber alle anzuzeigen.
6.2.3 class SDBExecute
Aus Sicherheitsgründen sind die Möglichkeiten zur Datenmanipulation (insert,
update, delete, etc.) durch das Servlet SDBExecute von der Selektion getrennt.
Es stellt eine Erweiterung von SDBSelect dar und verarbeitet zusätzlich den
folgenden Parameter sql.
6.2.3.1 Spezialparameter: sql
Mit Hilfe des sql-Parameters können alle Arten von SQL-Anweisungen an das
Servlet geschickt werden. Ähnlich wie bei dem Parameter query werden diese der
Reihe nach, d.h. in der Reihenfolge ausgeführt, wie sie in der URL vorkommen bzw.
an das Servlet gesendet werden. Es wird dabei keinerlei Überprüfung vorgenommen,
ob das Statement korrekt ist oder ob es überhaupt ausgeführt werden darf. So ist es
auch möglich, create table-Anweisungen wie auch drop table-Anweisungen
auszuführen. Damit ist eine weitere Anforderung (vgl. 3.2 Anforderungen vom
- 30 -
Prüfungsamt) umgesetzt, denn in bestimmten Masken ist es notwendig temporäre
Tabellen anzulegen.
Alle SQL-Anweisungen werden in einer Transaktion zusammengefasst und nur mit
commit beendet, wenn es keine Fehler gibt. Falls noch weitere Parameter, wie z.B.
query an das Servlet geschickt werden, werden diese erst danach behandelt.
6.2.4 class SDBStatistik
Das Servlet SDBStatistik erbt zwar genau wie SDBExecute auch von
SDBSelect, hat aber eine grundlegend andere doGet()-Methode und damit auch
eine andere Verarbeitung. Entsprechend der Implementierung wird davon ausgegangen, dass es ausschließlich von der Anfrageneditor-HTML-Seite oder von der
Seite mit den gespeicherten Datenbankanfragen aufgerufen wird.
Je nachdem welchen Wert der folgende Parameter doWhat hat, wird eine andere
Methode ausgeführt. Damit sind alle Aufgaben für die Verwaltung der Datenbankanfragen für die Statistikerstellung in einem Servlet zusammengefasst. Falls der
Parameter nicht an das Servlet übergeben wird, wird immer die Liste der gespeicherten Statistiken erzeugt.
6.2.4.1 Spezialparameter: doWhat
In Abhängigkeit von dem Wert des Parameters steuert dieser das Servlet. Als Werte
sind zulässig: speichern/save, bearbeiten/edit, ausführen/execute,
löschen/delete, es kann jeweils der deutsche wie auch der englische Begriff
verwendet werden. So kann direkt auf einen Button (vgl. HTML: <input
type=“button“ name=“doWhat“ value=“speichern“>) das deutsche Wort
geschrieben werden, denn der Wert des Buttons wird durch den angezeigten Text
bestimmt. Um evtl. auftretende Probleme mit den deutschen Umlauten zu vermeiden,
wurden zusätzlich die englischen Bezeichnungen mit aufgenommen.
speichern/save
Mit diesem Wert wird das Servlet dazu veranlasst, die
Cookies auszulesen (vgl. 6.2.4.2). Je nachdem, ob eine STATID als
Parameter mit übergeben wurde, wird ein insert (keine STATID) oder ein
update
(mit
entsprechender
STATID)
auf
der
Tabelle
pra03.
stat_statistiken vorgenommen. Anschließend wird die Liste der
- 31 -
gespeicherten Anfragen mit einem Hinweis dargestellt, ob das Speichern
erfolgreich war.
bearbeiten/edit
Wird einer dieser beiden Werte an das Servlet ge-
sendet, ist ein zusätzlicher Parameter STATID unablässig. Es wird dann der
Datensatz mit der entsprechenden lfd_nr aus der Tabelle pra03.
stat_statistiken gelesen und die Cookies aus dem long-varchar-Feld
werden wieder hergestellt (vgl. 6.2.4.2), so dass nach einem HttpServletResponse.sendRedirect("statistik.html") eine Bearbeitung in dem
Anfrageneditor vorgenommen werden kann.
ausführen/execute Diese Werte steuern das Servlet so, dass entweder die
aktuelle Anfrage gemäß der Eingabe in dem Anfrageneditor ausgeführt wird
oder eine aus der Liste der gespeicherten Datenbankanfragen ausgewählte
Anfrage. Dazu wird diese aus der Tabelle pra03.stat_statistiken
zuerst ausgelesen und dann ausgeführt.
löschen/delete
Der Aufruf des Servlets mit diesen Werten wird nur von
der Seite mit den gespeicherten Datenbankanfragen vorgenommen und führt
dazu, dass die Datenbankanfrage mit der lfd_nr (entspricht mitgesendeter
STATID) gelöscht wird. Anschließend wird wieder die Liste mit den
gespeicherten Anfragen mit einem Hinweis dargestellt, ob das Löschen
erfolgreich war.
6.2.4.2 private class StatCookie
Diese Klasse übernimmt die Umwandlung der Cookies in einen langen zusammenhängenden String und auch wieder zurück. Wird eine Statistik gespeichert, werden
die Cookies von dem Client gelesen und hintereinander in einen String mit den
Trennsymbolen (:::: und ####) geschrieben. Dieser String wird in dem longvarchar-Feld der Tabelle pra03.stat_statistiken gespeichert (vgl. 5.4
Gespeicherte Datenbankanfragen). Soll stattdessen eine Anfrage bearbeitet werden,
wird der String aus dem long-varchar-Feld ausgelesen und wieder in die einzelnen
Cookies zerlegt, die anschließend bei dem Client wieder gesetzt werden. Der Anfrageneditor kann die Werte mit einem Javascript auslesen und die entsprechenden
Einstellungen in den Textfeldern, Dropdown-Listen und Checkboxen vornehmen, so
dass die Anfrage bearbeitet werden kann.
- 32 -
7
Analyse der Umsetzung
7.1
Tests
Die Servlets (SDBSelect, SDBExecute) wurden schon in der Erstellungsphase der
Stylesheets im Rahmen der Bachelorarbeit für den Bereich 4. XML (Dokumentenerstellung) ausgiebig getestet. Zum Teil stellten sich erst beim Entwickeln der Stylesheets weitere Anforderungen an die Servlets heraus. Da sie noch in der
Anfangsphase der Codierung festgestellt wurden, wurden diese auch gleich
umgesetzt, so dass z.Z. keine weiteren Veränderungen an den Servlets anstehen.
Bei den ersten Versionen des Anfrageneditors fühlten sich die Testpersonen, die
evtl. später neue Datenbankanfragen erzeugen sollen, etwas „erschlagen“ von den
vielen Eingabefeldern. Die Unübersichtlichkeit der Eingabemaske wurde ebenfalls
bemängelt. In den folgenden Versionen wurde daher dynamisches-HTML eingeführt,
damit nicht benötigte Eingabefelder ausgeblendet werden können und besonders
wichtige Zellen in der Tabellestruktur des Editors farblich hervorgehoben werden. Mit
dieser Lösung waren auch die MitarbeiterInnen des Prüfungsamtes sehr zufrieden.
Gerade diesen Anwendern kommt es auf eine sehr einfache und übersichtliche
Bedienung an, da sie über keine SQL-Kenntnisse verfügen und somit nicht in der
Lage sind, die Fragestellung mit der erzeugten SQL-Anweisung abzugleichen.
Bisher wurden einige der früheren Fragen als Datenbankanfragen mit dem
Anfrageneditor neu erstellt, bearbeitet, ausgeführt, als XML exportiert, gespeichert
und wieder gelöscht. Es wurden dabei keinerlei Probleme erkannt.
7.2
Gelöste Probleme
Große Probleme bereitete anfangs die Tatsache, dass die ResultSets sich nur einmal „forwardonly“ lesen ließen. Die Frage, an welcher Stelle und in welchem
Format die Daten am besten zwischengespeichert werden und ob sie überhaupt in
einem Puffer gehalten werden sollten, löste einige Diskussionen unter den Projektbeteiligten aus. Die gefundene Lösung mit dem Speichern der Daten als ElementObjekte in einem Array erscheint nach den bisherigen Tests als praktikabel.
Keine leichte Aufgabe bei der Codierung ist es Datenbankanfragen so zu speichern,
dass sie später wieder in einen Editor zum Bearbeiten geladen werden können. Wird
z.B. nur die erzeugte SQL-Anweisung gespeichert, muss das Erscheinungsbild einer
- 33 -
gespeicherten und wieder geladenen Anfrage in dem Anfrageneditor nicht unbedingt
dem Erscheinungsbild vor dem „speichern/laden-Prozess“ gleichen. Das liegt daran,
dass beim Wiederherstellen aus dem SQL-Text nicht festgestellt werden kann, in
welcher Reihenfolge der Benutzer die Attribute in dem Anfrageneditor dargestellt
hatte. Er könnte zuerst alle Attribute ausgewählt haben, die selektiert werden sollten
und dann die für die Bedingungen oder in umgekehrter bzw. gemischter Reihenfolge.
Daher wurde die Lösung mit den Cookies gewählt. Nur hiermit kann wirklich
sichergestellt werden, dass eine Anfrage so wiederhergestellt wird, wie sie auch
gespeichert wurde.
Mangelnde Kenntnisse in der Webprogrammierung haben viel Zeit gekostet herauszufinden, dass es nicht möglich ist, mehr als 20 Cookies zu verwenden und dass die
Datenmengen beim Versenden von HTML-Formulardaten bei der Verwendung von
„get“, browser- und webserverabhängig begrenzt sind.
7.3
Beschränkungen
Bisher ist es bei der Anfragenerstellung nicht möglich, Outer-Joins zu verwenden.
Eine Tabelle kann auch nicht mehrfach ausgewählt werden, so dass ebenfalls keine
Self-Referential-Joins genutzt werden können. Für die bisher gestellten Fragen war
dies nicht notwendig. Sollte es wiedererwartend doch notwendig sein, wäre es evtl.
sinnvoll, ähnlich wie bei den Unteranfragen eine frei veränderbare FROM-Klausel
einzuführen. Gegebenenfalls müssten weitere Möglichkeiten überlegt und erprobt
werden.
Der Anfrageneditor ist z.Z. auf maximal zehn Spalten für Attribute begrenzt. Bei der
Programmierung der Javascripte wurde allerdings darauf geachtet, relativ einfach die
Anzahl der Spalten erhöhen zu können. Nach den bisherigen Tests und den früheren
Anfragen scheint dies jedoch nicht notwendig zu sein.
- 34 -
8
Zusammenfassung
Für einen Datenbankadministrator oder für versierte Datenbankbenutzer mit SQLErfahrungen ist nur eine sehr kurze Einarbeitungszeit nötig, um neue Datenbankanfragen mit der neuen Schnittstelle (dem Anfrageneditor) zu entwerfen. Inwieweit die
MitarbeiterInnen des Prüfungsamtes in der Lage sein werden, selbst neue Anfragen
zu erstellen, bleibt abzuwarten. Bei der durchgeführten Vorstellung des Anfrageneditors im Prüfungsamt waren die MitarbeiterInnen diesem System gegenüber sehr
aufgeschlossen und daran interessiert, es auf seine Möglichkeiten zu testen. Schon
nach ca. einer halbstündigen Einführung waren sie in der Lage, eine vorgefertigte
Anfrage in den Editor zu laden und die Bedingungen nach ihren Bedürfnisse
anzupassen. Damit ist eine wesentliche Anforderung erfüllt.
Eine noch stärker an QBE oder NQS angelehnte Schnittstelle wäre ebenfalls
realisierbar gewesen, allerdings nur mit dem Einsatz von z.B. Java-Applets oder in
einer Nicht-Browser-Lösung, auf die ausdrücklich verzichtet werden sollte.
Das vorgestellte System eignet sich nicht nur für Datenbankanfragen, um daraus
Statistiken zu erstellen, mit ihm kann sich auch ein Datenbankadministrator Anfragen
für seine tägliche Datenüberwachung und -pflege erzeugen. So wurden schon bei
den ersten Tests Anfragen erzeugt, die doppelte Einträge in der Lehrpersonaltabelle
aufdeckten. Mit Hilfe des Servlets SDBExecute können solche doppelten Einträge in
einer Administratorschnittstelle schnell korrigiert oder gelöscht werden.
8.1
Ausblick
In diesem Abschnitt soll aufgezeigt werden, welche Veränderungen (Verbesserungen, Erweiterungen) nach einer angemessenen Erprobungsphase evtl. sinnvoll
wären.
8.1.1 Datenbankschema
Das Datenbankschema ist z.Z. in die HTML-Seite der Statistik bzw. in die
dazugehörigen Javascripte fest eincodiert. Es wäre ebenfalls möglich diese von
einem Servlet dynamisch zu erzeugen.
- 35 -
8.1.2 Subqueries
Bisher werden Subqueries bei den Bedingungen nicht weiter überprüft. Es könnte an
dieser Stelle das Öffnen eines weiteren Eingabefensters vorgesehen werden, das
den Benutzer unterstützt, eine Unterabfrage zu erzeugen, genauso wie es bereits bei
der Erstellung der eigentlichen Anfrage realisiert wurde.
8.1.3 Maximale Anzahl von zehn Spalten
Die Anzahl der zur Verfügung stehenden Spalten für die Attribute könnte evtl.
erweitert werden. Jedoch sollten für die bisherigen Anforderungen zehn Spalten
vorerst genügen.
8.1.4 „Durchblättern“ von Daten
Falls zukünftig auf ein anderes Datenbanksystem umgestiegen wird, das die volle
JDBC API ohne Einschränkungen unterstützt, sollte überprüft werden, inwiefern es
besser wäre, die Daten nicht in den Servlets zwischenzuspeichern, sondern direkt
auf den ResultSets zu operieren. Dann könnten ggf. die Klassen SDBElementList,
SDBResultsImpl, SDBResultset und SDBRow entfallen.
- 36 -
9
Literaturverzeichnis
[01] P.P. Chen (1976): "The entity-relationship model toward a unified view of data", ACM Trans. on Database
Systems 1 (1), S. 9-36
[02] E.F. Codd (1970): "A Relational Model of Data for
Large Shared Data Banks“, Communications of the ACM,
13 (6), S. 377-387 http://www.acm.org/classics/nov95/
(12.09.2004)
[03] CSS Cascading Style Sheets
http://www.w3c.org/Style/CSS/ (12.09.2004)
[04] DOM Document Object Model http://www.w3c.org/DOM/
(12.09.2004)
[05] R. Elmasri, S. B. Navathe (1994): "Fundamentals of
Database Systems“, 2nd Ed., Addison-Wesley, Amsterdam
[06] D. Flanagan (1997): "JavaScript - Das umfassende
Referenzwerk“, O'Reilly
[07] D. Flanagan (1999): "JAVA in a Nutshell“, O'Reilly
[08] Form submission method im HTML 4 Standard
http://www.w3.org/TR/html4/interact/forms.html#submitformat (03.10.2004)
[09] J.D. Gould, J.C. Thomas (1975): "A psychological study
of query by example“, Proc. 10th CompCon, IEEE CS
Press, S. 439-445
[10] M. Hall, L. Brown (2003): "Core Servlets and
JavaServer Pages“, 2nd Ed., Prentice Hall
[11] P. Hanna (2000): "Instant Java Servlets“, McGraw Hill
[12] A. Heuer, G. Saake (1995): "Datenbanken - Konzepte und
Sprachen“, Thomson Publishing, Bonn
[13] HTML HyperText Markup Language
http://www.w3.org/MarkUp/ (12.09.2004)
[14] IBM (1983): "Query-By-Example - Terminal User's
Guide“, 4th Ed.
[15] IBM-DB2 QMF / QBE
http://publib.boulder.ibm.com/infocenter/dzichelp/inde
x.jsp?topic=/com.ibm.qmf.doc.using_8.1.0/dsqk2mst338.h
tm (24.09.2004)
- 37 -
[16] Java http://java.sun.com/ (12.09.2004)
http://www.java.net/ (12.09.2004)
[17] Java Servlets http://java.sun.com/products/servlet/
(12.09.2004)
[18] Javascript http://de.selfhtml.org/javascript/index.htm
(12.09.2004)
[19] H.-J. Klein (1989): "Pragmatics and Semantics of NQL,
a Descriptive Query Language for Network Databases“,
Information Systems, 14 (1), S. 29-45
[20] H.-J. Klein, D. Krämer (1995): "NQS a graphical query
system for data models with binary relationship
types“, Proc. Visual Database Systems 3, Chapman &
Hall, S. 394-409
[21] J. Melton (2003): "Advanced SQL:1999. Understanding
Object-Relational and Other Advanced Features“, Morgan
Kaufmann
[22] J. Melton, A. Eisenberg (2000): "Understanding SQL and
Java Together. A Guide to SQLJ, JDBC, and Related
Technologies“, Morgan Kaufmann
[23] J. Melton, A.R. Simon (2002): "SQL:1999. Understanding
Relational Language Concepts“, Morgan Kaufmann
[24] Query By Example (QBE) Web interface to an existing
RDBMS, http://ssi.umh.ac.be/tpfbd2002-03.shtml
(06.10.2004), Université Mons-Hainaut (U.M.H.)
[25] J.D. Ullman (1988): "Principles of Database and
Knowledge Base Systems Vol. I“, 3rd Ed., Computer
Science Press, Rockville, MD
[26] UnivIS http://www.univis.de/ (06.10.2004)
[27] URI/URL http://www.w3c.org/Addressing/ (12.09.2004)
[28] XML Extensible Markup Language http://www.w3.org/XML/
(12.09.2004)
[29] XSL Extensible Stylesheet Language
http://www.w3.org/Style/XSL/ (12.09.2004)
[30] M.M. Zloof (1975): "Query-by-example“, AFIPS
Conference Proceedings National Computer Conference
44, S. 431-438
[31] M.M. Zloof (1977): "Query by Example: a data base
language“, IBM Systems Journal 16 (4) S. 324-343
- 38 -
9.1
Verwendete Entwicklungsumgebung & Tools
[32] CSS Validator http://jigsaw.w3.org/css-validator/
(12.09.2004)
[33] Eclipse http://www.eclipse.org/ (12.09.2004)
[34] HTML Validator http://validator.w3.org/ (12.09.2004)
[35] Ingres http://opensource.ca.com/projects/ingres/
(12.09.2004)
[36] Mozilla 1.6
http://www.mozilla.org/releases/mozilla1.6/
(27.09.2004)
[37] Tomcat http://jakarta.apache.org/tomcat/ (12.09.2004)
- 39 -
10
Erklärung
Hiermit versichere ich, dass ich diese Arbeit selbstständig verfasst und keine
anderen als die angegebenen Hilfsmittel benutzt habe. Diese Arbeit ist bisher noch
nicht anderweitig als Bachelorarbeit eingereicht oder veröffentlicht worden.
Kiel, 07.10.2004
Hilmar Falkenberg
- 40 -
DIPLOMARBEITEN
INDUSTRIEPRAKTIKA
1
1
(0,1)
STUDIERENDE
1 -----------------------------------
1
1
(0,1)
DIPLOM_PRUEFUNGEN
ANERKENNUNGEN
-------------------------------Matrikel_nr
Lehrpersonal_nr_1
Lehrpersonal_nr_2 N
Datum N
Note N
(0,n) Fach_nr
Wiederholung_ja_nein
Kommentar N
(0,n)
(0,n)
----------------------Matrikel_nr
Leistung
(0,n)
Leistpunkte N
Note N
UNTERBRECHUNGEN
Datum
------------------------Verantwortlich
(0,n)
Matrikel_nr
Kommentar N
Beginn
Ende N
Grund N
DIPLOM
--------------------------------------Matrikel_nr
Datum_letzte_pruefung N
Datum_erstellung_zeugnis N
Gesamtnote N
Bemerkung N
Nbestanden_ja_nein
Anmeldedatum
Kommentar N
VORDIPLOM
------------------------------------Matrikel_nr
Datum_letzte_pruefung N
Gesamtnote N
Bemerkung N
Nbestanden_ja_nein
Anmeldedatum
Kommentar N
Fach_nr
Bezeichnung
Kommentar N
1 -------------------------- 1
PRUEFUNGSFAECHER
1
Matrikel_nr
Name
Vorname
Geschlecht
---------------------------1
Geburtsdatum
Matrikel_nr
Datum
1 Strasse N
Name_des_betriebes (0,n) Plz N
(0,n)
(0,m)
Ort N
Dauer N
Telefon_1 N
ANGESTR_ABSCHLUSS
Anerkannt_ja_nein
(0,n)
(0,1) ------------------------------Telefon_2 N
Kommentar N
Email_institut N
Angestr_abschluss_nr
Email_privat N
Bezeichnung
STUDIENFAECHER
Hauptfach_nr N
INDUSTRIEPRAKTIKA_ING
------------------------(0,m)
Nebenfach_nr_1 N
-----------------------------(0,n) Studienfach_nr
(1,n)
Nebenfach_nr_2 N
Matrikel_nr
Bezeichnung
STUDIENFORM
1
LEHRSTUHL
Angestr_abschluss_nr N (0,n)
Datum_erstellt
(0,1) ---------------------(0,n)
------------------Fachsemester N
Dauer_mech_gp N
Studienform_nr
Lehrstuhl_nr
Studienbeginn N
Dauer_elek_gp N
Bezeichnung
Bezeichnung
Studienabschluss N
Dauer_fachpraxis N
1
(0,n)
Exmatrikuliert_ja_nein
Geprueft_ja_nein
SCHEINE
Kommentar N
1 (0,1)
---------------------------------STUDIENARBEITEN (0,n) 1 Zuletzt_bearbeitet N
Scheintyp_nr
Abschlussnote N
----------------------Veranstaltung_nr
Studienform_nr N
Matrikel_nr
Semester
1
Datum
Matrikel_nr
(0,1)
Lehrpersonal_nr
Datum
Thema
ZERTIFIKAT_PRUEFUNGEN
Text_zeile_1 N
1
(0,1)
Beurteilung N
-------------------------------- (0,1)
1
(0,n)
(4,n) Text_zeile_2 N
Kommentar
N
Matrikel_nr
LEHRPERSONAL 1
Kommentar N
Datum_zeugnis
-------------------------Note_ja_nein
Pruefungsfach_1
Lehrpersonal_nr
Note N
Pruefungsfach_2
Titel N
Thema N
Name
Stundenzahl N
1
Vorname
Wiederholung
1
1 (0,n) Zurueckgetreten_ja_nein
VERANSTALTUNGEN
Fakultaet
WIRD_GEHALTEN_VON
-----------------------------------------------------------------Institut_ja_nein
Zuordnung
1
(1,n)
Veranstaltung_nr
Veranstaltung_nr
Lehrstuhl_nr N
(0,n)
1
1
(0,n) Semester
Semester
Bezeichnung
Lehrpersonal_nr
SCHEINTYPEN
Teilnehmerzahl_beginn N
-------------------Teilnehmerzahl_ende N
Scheintyp_nr
Vtyp_nr
Bezeichnung
Stundenzahl
GRUPPEN
VERANSTALTUNGEN_FACHGEBIET
Ects_univis
FACHGEBIET
-----------------------1
------------------------------------------ (0,n)
Ects_schein
------------------- 1
Semester
Veranstaltung_nr
1 Kommentar N
Fachgebiet_nr (0,n)
(0,n)
(0,n) (0,n) Veranstaltung_nr
Semester
(0,n)
Bezeichnung
VERANST_TEILNEHMER 1 Gruppe_nr
Lfd_nr
1
Zeit N
----------------------------Fachgebiet_nr
Leiter N
Semester
VERANSTALTUNGSTYPEN
Anzahl_max N
Veranstaltung_nr
----------------------------------Anzahl_akt N
Matrikel_nr
Vtyp_nr
Bemerkung N
Gruppe_nr
Veranstaltungstyp
---------------------------------Matrikel_nr
Anmeldedatum
Note N
Thema
(0,n)
Betreuer N
Gutachter_1
Gutachter_2 N
Abgabedatum N
Lehrstuhl_nr N
Zurueckgegeben_ja_nein
Kommentar N
(0,n)
--------------------------------Matrikel_nr
Lehrpersonal_nr_1
Lehrpersonal_nr_2 N
Datum N
Note N
Fach_nr
Wiederholung_ja_nein (0,n)
Klausur_ja_nein
Kommentar N
VORDIPLOM_PRUEFUNGEN (0,n)
Schema Studierendendatenbank : Stand 27. Sep. 2004
Anhang
1 von 71
Gutachter 1
Gutachter 2
Seite: 1 von 20
Seite: 1 von 20
<!-- 2. Zeile: Tabellenauswahl, hier ist die Liste mit den Tabellen, die für
die Anfragen zur Verfügung stehen. Wenn sich das Datenbankschema
ändert, müssen hier ggf. Tabellen ergänzt werden. Pro Tabelle
eine Option.
<td id="R0C2" colspan="10"><input maxlength="255" size="150"
type="text" name="frage"
onchange="onChangeFrage(this.value)" /></td>
</tr>
<!-- Die ganze Tabelle ist in ein Formular eingebettet -->
<form action="Statistiken" method="post" name="StatistikFormular">
<table border="1" align="center"
summary="Tabelle dient nur fürs Layout">
<!-- 1. Zeile: Frage, 100 Zeichenlanges Textfeld für einen Namen der Anfrage
-->
<tr id="ROW0">
<td id="R0C1" class="disabled" align="right"><a
href="javascript:popUp('help/Frage.html')">Frage</a>
</td>
<!-- Body-Events: onload="onLoadStatBody()" -->
<body onload="onLoadStatBody()">
<h3>Anfrageneditor für die Studierendendatenbank</h3>
<title>Anfrageneditor für die Studierendendatenbank</title>
<!-- Liste der zu importierdenden Javascripte und Stylesheets -->
<script language="javascript" src="scripts/check.js" type="text/javascript">
</script>
<script language="javascript" src="scripts/cookie.js" type="text/javascript">
</script>
<script language="javascript" src="scripts/stat_globals.js"
type="text/javascript">
</script>
<script language="javascript" src="scripts/stat_schema.js"
type="text/javascript">
</script>
<script language="javascript" src="scripts/stat_cookies.js"
type="text/javascript">
</script>
<script language="javascript" src="scripts/stat_erstellen.js"
type="text/javascript">
</script>
<script language="javascript" src="scripts/stat_events.js"
type="text/javascript">
</script>
<link rel="stylesheet" type="text/css" href="styles/statistik.css" />
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: statistik.html
Version: $Revision: 1.10 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/06 17:33:12 $
==
== Beschreibung: Der Anfrageneditor - die BASIS-Seite zum erstellen neuer
== Datenbankanfragen und zum bearbeiten von gespeicherten Anfragen.
== Aufruf mit 'statistik.html?neu' öffnet den Editor, ohne alte Werte aus
== den Cookies wiederherzustellen. Wird die Seite nur mit 'statistik.html'
== aufgerufen, wird nach den Cookies gesucht und die zuletzt bearbeitete
== Anfrage in den Editor geladen.
========================================================================== -->
Datei: statistik.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: statistik.html
2 von 71
Seite: 2 von 20
Seite: 2 von 20
<option value="studienarbeiten sa" label="Studienarbeiten">
Studienarbeiten
</option>
<option value="scheintypen scht" label="Scheintypen">
Scheintypen
</option>
<option value="scheine sch" label="Scheine">
Scheine
</option>
<option value="pruefungsfaecher pf" label="Prüfungsfächer">
Prüfungsfächer
</option>
<option value="lehrstuhl ls" label="Lehrstuhl">
Lehrstuhl
</option>
<option value="lehrpersonal lp" label="Lehrpersonal">
Lehrpersonal
</option>
<option value="industriepraktika_ing ii"
label="Industriepraktika (Ing)">
Industriepraktika (Ing)
</option>
<option value="industriepraktika i"
label="Industriepraktika">
Industriepraktika
</option>
<option value="gruppen g" label="Gruppen">
Gruppen
</option>
<option value="fachgebiet f" label="Fachgebiet">
Fachgebiet
</option>
<option value="diplomarbeiten da" label="Diplomarbeiten">
Diplomarbeiten
</option>
<option value="diplom_pruefungen dp"
label="Diplom-Prüfungen">
Diplom-Prüfungen
</option>
<option value="diplom d" label="Diplom">
Diplom
</option>
<option value="angestr_abschluss aa"
label="Angestr-Abschluss">
Angestr-Abschluss
</option>
<tr id="ROW1">
<td id="R1C1" colspan="1"><select name="Tabellen" size="5"
onchange="onChangeTabellen();" multiple="multiple">
<option value="anerkennungen a" label="Anerkennungen">
Anerkennungen
</option>
Events: onchange="onChangeTabellen();"
Datei: statistik.html
69
70 -->
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Datei: statistik.html
Anhang
<option value="zertifikat_pruefungen z"
label="Zertifikat-Prüfungen">
Zertifikat-Prüfungen
</option>
</select> </td>
<option value="wird_gehalten_von w"
label="Wird gehalten von">
Wird gehalten von
</option>
<option value="vordiplom_pruefungen vdp"
label="Vordiplom-Prüfungen">
Vordiplom-Prüfungen
</option>
<option value="vordiplom vd" label="Vordiplom">
Vordiplom
</option>
<option value="veranstaltungstypen vtyp"
label="Veranstaltungstypen">
Veranstaltungstypen
</option>
<option value="veranstaltungen_fachgebiet vf"
label="Veranstaltungen-Fachgebiet">
Veranstaltungen-Fachgebiet
</option>
<option value="veranstaltungen v" label="Veranstaltungen">
Veranstaltungen
</option>
<option value="veranst_teilnehmer vt"
label="Veranst-Teilnehmer">
Veranst-Teilnehmer
</option>
<option value="unterbrechungen u" label="Unterbrechungen">
Unterbrechungen
</option>
<option value="studierende s" label="Studierende">
Studierende
</option>
<option value="studienform sfo" label="studienform">
Studienform
</option>
<option value="studienfaecher sf" label="Studienfächer">
Studienfächer
</option>
Seite: 3 von 20
Seite: 3 von 20
<td id="R1C2" colspan="10" class="disabled">
<p>Wählen Sie (links) die Tabellen aus, die Sie in die
Abfrage mit einbeziehen möchten.<br />
<em>Tipp: Sie können auch mehrere Tabellen markieren, wenn
Sie die Steuerungstaste ('Strg' bzw.
'Ctrl') gedrückt halten.</em><br />
Wählen Sie dann die Felder aus, die angezeigt werden
sollen.<br />
<a target="new" href="help/studi_schema_neu.pdf">Datenbankschema<
</td>
</tr>
Datei: statistik.html
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
Datei: statistik.html
Seite: 4 von 20
3 von 71
Datei: statistik.html
Seite: 4 von 20
205 <!-- 3. Zeile: Spalten tauschen, hier sind die Buttons zum vertauschen von
206
zwei nebeneinanderliegenden Spalten.
207
Events: onclick="onClickFlip__(SPALTENNUMMER, SPALTENNUMMER)"
208 -->
209
<tr id="ROW2" align="center">
210
<td id="R2C1" class="disabled" align="right"><a
211
href="javascript:popUp('help/tauschen.html')">Spalten
212
tauschen</a> </td>
213
214
<td id="R2C2" class="nonvisible"><input type="button"
215
id="flipr0" value=" >> "
216
onclick="onClickFlip__(0, 1)" /></td>
217
218
<td id="R2C3" class="nonvisible"><input type="button"
219
id="flipl1" value=" << "
220
onclick="onClickFlip__(0, 1)" /> <input type="button"
221
id="flipr1" value=" >> "
222
onclick="onClickFlip__(1, 2)" /></td>
223
224
<td id="R2C4" class="nonvisible"><input type="button"
225
id="flipl2" value=" << "
226
onclick="onClickFlip__(1, 2)" /> <input type="button"
227
id="flipr2" value=" >> "
228
onclick="onClickFlip__(2, 3)" /></td>
229
230
<td id="R2C5" class="nonvisible"><input type="button"
231
id="flipl3" value=" << "
232
onclick="onClickFlip__(2, 3)" /> <input type="button"
233
id="flipr3" value=" >> "
234
onclick="onClickFlip__(3, 4)" /></td>
235
236
<td id="R2C6" class="nonvisible"><input type="button"
237
id="flipl4" value=" << "
238
onclick="onClickFlip__(3, 4)" /> <input type="button"
239
id="flipr4" value=" >> "
240
onclick="onClickFlip__(4, 5)" /></td>
241
242
<td id="R2C7" class="nonvisible"><input type="button"
243
id="flipl5" value=" << "
244
onclick="onClickFlip__(4, 5)" /> <input type="button"
245
id="flipr5" value=" >> "
246
onclick="onClickFlip__(5, 6)" /></td>
247
248
<td id="R2C8" class="nonvisible"><input type="button"
249
id="flipl6" value=" << "
250
onclick="onClickFlip__(5, 6)" /> <input type="button"
251
id="flipr6" value=" >> "
252
onclick="onClickFlip__(6, 7)" /></td>
253
254
<td id="R2C9" class="nonvisible"><input type="button"
255
id="flipl7" value=" << "
256
onclick="onClickFlip__(6, 7)" /> <input type="button"
257
id="flipr7" value=" >> "
258
onclick="onClickFlip__(7, 8)" /></td>
259
260
<td id="R2C10" class="nonvisible"><input type="button"
261
id="flipl8" value=" << "
262
onclick="onClickFlip__(7, 8)" /> <input type="button"
263
id="flipr8" value=" >> "
264
onclick="onClickFlip__(8, 9)" /></td>
265
266
<td id="R2C11" class="nonvisible"><input type="button"
267
id="flipl9" value=" << "
268
onclick="onClickFlip__(8, 9)" /></td>
269
</tr>
270
271 <!-- 4. Zeile: Feld, hier sind die Dropdownfelder mit den Attributen;
272
wird dynamisch durch "onChangeTabellen()" gefüllt und
Datei: statistik.html
Anhang
Seite: 5 von 20
Seite: 5 von 20
<td id="R3C9" class="nonvisible"><select name="Feld7" size="1"
<td id="R3C8" class="nonvisible"><select name="Feld6" size="1"
onchange="onChangeFeld_(6)">
<option>
</option>
</select> <br />
<input class="disabled" type="text" name="Tabelle6" size="20"
readonly="readonly" /></td>
<td id="R3C7" class="nonvisible"><select name="Feld5" size="1"
onchange="onChangeFeld_(5)">
<option>
</option>
</select> <br />
<input class="disabled" type="text" name="Tabelle5" size="20"
readonly="readonly" /></td>
<td id="R3C6" class="nonvisible"><select name="Feld4" size="1"
onchange="onChangeFeld_(4)">
<option>
</option>
</select> <br />
<input class="disabled" type="text" name="Tabelle4" size="20"
readonly="readonly" /></td>
<td id="R3C5" class="nonvisible"><select name="Feld3" size="1"
onchange="onChangeFeld_(3)">
<option>
</option>
</select> <br />
<input class="disabled" type="text" name="Tabelle3" size="20"
readonly="readonly" /></td>
<td id="R3C4" class="nonvisible"><select name="Feld2" size="1"
onchange="onChangeFeld_(2)">
<option>
</option>
</select> <br />
<input class="disabled" type="text" name="Tabelle2" size="20"
readonly="readonly" /></td>
<td id="R3C3" class="nonvisible"><select name="Feld1" size="1"
onchange="onChangeFeld_(1)">
<option>
</option>
</select> <br />
<input class="disabled" type="text" name="Tabelle1" size="20"
readonly="readonly" /></td>
<td id="R3C2" class="nonvisible"><select name="Feld0" size="1"
onchange="onChangeFeld_(0)">
<option>
</option>
</select> <br />
<input class="disabled" type="text" name="Tabelle0" size="20"
readonly="readonly" /></td>
<tr id="ROW3" align="center">
<td id="R3C1" class="disabled" align="right"><a
href="javascript:popUp('help/Felder.html')">Feld</a>
<br />
<a href="javascript:popUp('help/Tabelle.html')">aus
Tabelle</a> </td>
die readonly Felder mit den Tabellennamen des ausgewählten
Attributs
Events: onchange="onChangeFeld_(SPALTENNUMMER)"
Datei: statistik.html
273
274
275
276 -->
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
Datei: statistik.html
Seite: 6 von 20
4 von 71
Datei: statistik.html
Seite: 6 von 20
341
onchange="onChangeFeld_(7)">
342
<option>
343
</option>
344
</select> <br />
345
<input class="disabled" type="text" name="Tabelle7" size="20"
346
readonly="readonly" /></td>
347
348
<td id="R3C10" class="nonvisible"><select name="Feld8"
349
size="1" onchange="onChangeFeld_(8)">
350
<option>
351
</option>
352
</select> <br />
353
<input class="disabled" type="text" name="Tabelle8" size="20"
354
readonly="readonly" /></td>
355
356
<td id="R3C11" class="nonvisible"><select name="Feld9"
357
size="1" onchange="onChangeFeld_(9)">
358
<option>
359
</option>
360
</select> <br />
361
<input class="disabled" type="text" name="Tabelle9" size="20"
362
readonly="readonly" /></td>
363
</tr>
364
365 <!-- 5. Zeile: anzeigen / sortieren / Spaltenüberschrift;
366
eine Checkbox für die Anzeige des Attributs;
367
eine Dropdownliste mit drei Werten (LEER, asc, desc) zum sortieren
368
ein Textfeld zum eingeben eines Alias für diese Spalte
369
Events: onclick="onClickFeld_anz(SPALTENNUMMER)"
370
onchange="onChangeFeld_sort()"
371
onchange="onChangeAlias_(SPALTENNUMMER)"
372 -->
373
<tr id="ROW4" align="center">
374
<td id="R4C1" class="disabled" align="right">
375
<p><a
376
href="javascript:popUp('help/anzeigen.html')">anzeigen</a>
377
/ <a
378
href="javascript:popUp('help/sortieren.html')">sortieren</
379
<a
380
href="javascript:popUp('help/alias.html')">Spaltenüberschr
381
</td>
382
383
<td id="R4C2" class="nonvisible"><input type="checkbox"
384
name="Feld0anz" onclick="onClickFeld_anz(0)" /><select
385
name="Feld0sort" size="1" onchange="onChangeFeld_sort()">
386
<option>
387
</option>
388
389
<option value=" asc">
390
aufsteigend
391
</option>
392
393
<option value=" desc">
394
absteigend
395
</option>
396
</select> <br />
397
<input type="text" name="Alias0" onchange="onChangeAlias_(0)"
398
size="20" /></td>
399
400
<td id="R4C3" class="nonvisible"><input type="checkbox"
401
name="Feld1anz" onclick="onClickFeld_anz(1)" /><select
402
name="Feld1sort" size="1" onchange="onChangeFeld_sort()">
403
<option>
404
</option>
405
406
<option value=" asc">
407
aufsteigend
408
</option>
Datei: statistik.html
Anhang
Datei: statistik.html
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
Datei: statistik.html
<option value=" asc">
aufsteigend
</option>
Seite: 7 von 20
<td id="R4C7" class="nonvisible"><input type="checkbox"
name="Feld5anz" onclick="onClickFeld_anz(5)" /><select
name="Feld5sort" size="1" onchange="onChangeFeld_sort()">
<option>
</option>
<option value=" desc">
absteigend
</option>
</select> <br />
<input type="text" name="Alias4" onchange="onChangeAlias_(4)"
size="20" /></td>
<option value=" asc">
aufsteigend
</option>
<td id="R4C6" class="nonvisible"><input type="checkbox"
name="Feld4anz" onclick="onClickFeld_anz(4)" /><select
name="Feld4sort" size="1" onchange="onChangeFeld_sort()">
<option>
</option>
<option value=" desc">
absteigend
</option>
</select> <br />
<input type="text" name="Alias3" onchange="onChangeAlias_(3)"
size="20" /></td>
<option value=" asc">
aufsteigend
</option>
<td id="R4C5" class="nonvisible"><input type="checkbox"
name="Feld3anz" onclick="onClickFeld_anz(3)" /><select
name="Feld3sort" size="1" onchange="onChangeFeld_sort()">
<option>
</option>
<option value=" desc">
absteigend
</option>
</select> <br />
<input type="text" name="Alias2" onchange="onChangeAlias_(2)"
size="20" /></td>
<option value=" asc">
aufsteigend
</option>
<td id="R4C4" class="nonvisible"><input type="checkbox"
name="Feld2anz" onclick="onClickFeld_anz(2)" /> <select
name="Feld2sort" size="1" onchange="onChangeFeld_sort()">
<option>
</option>
<option value=" desc">
absteigend
</option>
</select> <br />
<input type="text" name="Alias1" onchange="onChangeAlias_(1)"
size="20" /></td>
Seite: 7 von 20
5 von 71
Datei: statistik.html
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
Datei: statistik.html
Anhang
<option value=" asc">
aufsteigend
</option>
Seite: 8 von 20
<td id="R4C11" class="nonvisible"><input type="checkbox"
name="Feld9anz" onclick="onClickFeld_anz(9)" /> <select
name="Feld9sort" size="1" onchange="onChangeFeld_sort()">
<option>
</option>
<option value=" desc">
absteigend
</option>
</select> <br />
<input type="text" name="Alias8" onchange="onChangeAlias_(8)"
size="20" /></td>
<option value=" asc">
aufsteigend
</option>
<td id="R4C10" class="nonvisible"><input type="checkbox"
name="Feld8anz" onclick="onClickFeld_anz(8)" /><select
name="Feld8sort" size="1" onchange="onChangeFeld_sort()">
<option>
</option>
<option value=" desc">
absteigend
</option>
</select> <br />
<input type="text" name="Alias7" onchange="onChangeAlias_(7)"
size="20" /></td>
<option value=" asc">
aufsteigend
</option>
<td id="R4C9" class="nonvisible"><input type="checkbox"
name="Feld7anz" onclick="onClickFeld_anz(7)" /><select
name="Feld7sort" size="1" onchange="onChangeFeld_sort()">
<option>
</option>
<option value=" desc">
absteigend
</option>
</select> <br />
<input type="text" name="Alias6" onchange="onChangeAlias_(6)"
size="20" /></td>
<option value=" asc">
aufsteigend
</option>
<td id="R4C8" class="nonvisible"><input type="checkbox"
name="Feld6anz" onclick="onClickFeld_anz(6)" /><select
name="Feld6sort" size="1" onchange="onChangeFeld_sort()">
<option>
</option>
<option value=" desc">
absteigend
</option>
</select> <br />
<input type="text" name="Alias5" onchange="onChangeAlias_(5)"
size="20" /></td>
Seite: 8 von 20
Seite: 9 von 20
Datei: statistik.html
Seite: 9 von 20
545
546
<option value=" desc">
547
absteigend
548
</option>
549
</select> <br />
550
<input type="text" name="Alias9" onchange="onChangeAlias_(9)"
551
size="20" /></td>
552
</tr>
553
554 <!-- 6. Zeile: verknüpfen mit / aus Tabelle, mit einer Vergleichsoperatorenliste
555
(dynamisch gefüllt in onLoadStatBody()) und
556
der Liste der wählbaren Attributen siehe 4. Zeile
557
Events: onclick="onCheckBox1(this.checked)"
558
onchange="onChangeCond_0()"
559
onchange="onChangeFeld_join()"
560 -->
561
<tr id="ROW5" align="center">
562
<td id="R5C1" align="right"><input type="checkbox"
563
name="CheckBox1" onclick="onCheckBox1(this.checked)" /><a
564
href="javascript:popUp('help/join.html')">verknüpfen
565
mit</a> <br />
566
<a href="javascript:popUp('help/Tabelle.html')">aus
567
Tabelle</a> </td>
568
569
<td id="R5C2" class="nonvisible"><select name="Cond00"
570
size="1" onchange="onChangeCond_0()">
571
<option>
572
</option>
573
</select><select name="Feld0join" size="1"
574
onchange="onChangeFeld_join()">
575
<option>
576
</option>
577
</select> <br />
578
<input class="disabled" type="text" name="VTabelle0"
579
size="20" readonly="readonly" /></td>
580
581
<td id="R5C3" class="nonvisible"><select name="Cond10"
582
size="1" onchange="onChangeCond_0()">
583
<option>
584
</option>
585
</select><select name="Feld1join" size="1"
586
onchange="onChangeFeld_join()">
587
<option>
588
</option>
589
</select> <br />
590
<input class="disabled" type="text" name="VTabelle1"
591
size="20" readonly="readonly" /></td>
592
593
<td id="R5C4" class="nonvisible"><select name="Cond20"
594
size="1" onchange="onChangeCond_0()">
595
<option>
596
</option>
597
</select><select name="Feld2join" size="1"
598
onchange="onChangeFeld_join()">
599
<option>
600
</option>
601
</select> <br />
602
<input class="disabled" type="text" name="VTabelle2"
603
size="20" readonly="readonly" /></td>
604
605
<td id="R5C5" class="nonvisible"><select name="Cond30"
606
size="1" onchange="onChangeCond_0()">
607
<option>
608
</option>
609
</select><select name="Feld3join" size="1"
610
onchange="onChangeFeld_join()">
611
<option>
612
</option>
Datei: statistik.html
6 von 71
Datei: statistik.html
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
Datei: statistik.html
Anhang
Seite: 10 von 20
<td id="R5C11" class="nonvisible"><select name="Cond90"
size="1" onchange="onChangeCond_0()">
<option>
</option>
<td id="R5C10" class="nonvisible"><select name="Cond80"
size="1" onchange="onChangeCond_0()">
<option>
</option>
</select><select name="Feld8join" size="1"
onchange="onChangeFeld_join()">
<option>
</option>
</select> <br />
<input class="disabled" type="text" name="VTabelle8"
size="20" readonly="readonly" /></td>
<td id="R5C9" class="nonvisible"><select name="Cond70"
size="1" onchange="onChangeCond_0()">
<option>
</option>
</select><select name="Feld7join" size="1"
onchange="onChangeFeld_join()">
<option>
</option>
</select> <br />
<input class="disabled" type="text" name="VTabelle7"
size="20" readonly="readonly" /></td>
<td id="R5C8" class="nonvisible"><select name="Cond60"
size="1" onchange="onChangeCond_0()">
<option>
</option>
</select><select name="Feld6join" size="1"
onchange="onChangeFeld_join()">
<option>
</option>
</select> <br />
<input class="disabled" type="text" name="VTabelle6"
size="20" readonly="readonly" /></td>
<td id="R5C7" class="nonvisible"><select name="Cond50"
size="1" onchange="onChangeCond_0()">
<option>
</option>
</select><select name="Feld5join" size="1"
onchange="onChangeFeld_join()">
<option>
</option>
</select> <br />
<input class="disabled" type="text" name="VTabelle5"
size="20" readonly="readonly" /></td>
<td id="R5C6" class="nonvisible"><select name="Cond40"
size="1" onchange="onChangeCond_0()">
<option>
</option>
</select><select name="Feld4join" size="1"
onchange="onChangeFeld_join()">
<option>
</option>
</select> <br />
<input class="disabled" type="text" name="VTabelle4"
size="20" readonly="readonly" /></td>
</select> <br />
<input class="disabled" type="text" name="VTabelle3"
size="20" readonly="readonly" /></td>
Seite: 10 von 20
Seite: 11 von 20
Datei: statistik.html
Seite: 11 von 20
681
</select><select name="Feld9join" size="1"
682
onchange="onChangeFeld_join()">
683
<option>
684
</option>
685
</select> <br />
686
<input class="disabled" type="text" name="VTabelle9"
687
size="20" readonly="readonly" /></td>
688
</tr>
689
690 <!-- 7. Zeile: Bedingung, mit Vergleichoperatorenliste und Textfeld
691
Events: onclick="onCheckBox2(this.checked)"
692
onchange="check(TEXTFELD, SPALTENNUMMER, 1)"
693 -->
694
<tr id="ROW6" align="center">
695
<td id="R6C1" align="right"><input type="checkbox"
696
name="CheckBox2" onclick="onCheckBox2(this.checked)" /><a
697
href="javascript:popUp('help/Bedingung.html')">Bedingung</a>
698
</td>
699
700
<td id="R6C2" class="nonvisible"><select name="Cond01"
701
size="1"
702
onchange="check(document.StatistikFormular.Where0, 0, 1)">
703
<option>
704
</option>
705
</select><input type="text" name="Where0"
706
onchange="check(this, 0, 1)" size="20" /></td>
707
708
<td id="R6C3" class="nonvisible"><select name="Cond11"
709
size="1"
710
onchange="check(document.StatistikFormular.Where1, 1, 1)">
711
<option>
712
</option>
713
</select><input type="text" name="Where1"
714
onchange="check(this, 1, 1)" size="20" /></td>
715
716
<td id="R6C4" class="nonvisible"><select name="Cond21"
717
size="1"
718
onchange="check(document.StatistikFormular.Where2, 2, 1)">
719
<option>
720
</option>
721
</select><input type="text" name="Where2"
722
onchange="check(this, 2, 1)" size="20" /></td>
723
724
<td id="R6C5" class="nonvisible"><select name="Cond31"
725
size="1"
726
onchange="check(document.StatistikFormular.Where3, 3, 1)">
727
<option>
728
</option>
729
</select><input type="text" name="Where3"
730
onchange="check(this, 3, 1)" size="20" /></td>
731
732
<td id="R6C6" class="nonvisible"><select name="Cond41"
733
size="1"
734
onchange="check(document.StatistikFormular.Where4, 4, 1)">
735
<option>
736
</option>
737
</select><input type="text" name="Where4"
738
onchange="check(this, 4, 1)" size="20" /></td>
739
740
<td id="R6C7" class="nonvisible"><select name="Cond51"
741
size="1"
742
onchange="check(document.StatistikFormular.Where5, 5, 1)">
743
<option>
744
</option>
745
</select><input type="text" name="Where5"
746
onchange="check(this, 5, 1)" size="20" /></td>
747
748
<td id="R6C8" class="nonvisible"><select name="Cond61"
Datei: statistik.html
Seite: 12 von 20
7 von 71
Datei: statistik.html
Seite: 12 von 20
749
size="1"
750
onchange="check(document.StatistikFormular.Where6, 6, 1)">
751
<option>
752
</option>
753
</select><input type="text" name="Where6"
754
onchange="check(this, 6, 1)" size="20" /></td>
755
756
<td id="R6C9" class="nonvisible"><select name="Cond71"
757
size="1"
758
onchange="check(document.StatistikFormular.Where7, 7, 1)">
759
<option>
760
</option>
761
</select><input type="text" name="Where7"
762
onchange="check(this, 7, 1)" size="20" /></td>
763
764
<td id="R6C10" class="nonvisible"><select name="Cond81"
765
size="1"
766
onchange="check(document.StatistikFormular.Where8, 8, 1)">
767
<option>
768
</option>
769
</select><input type="text" name="Where8"
770
onchange="check(this, 8, 1)" size="20" /></td>
771
772
<td id="R6C11" class="nonvisible"><select name="Cond91"
773
size="1"
774
onchange="check(document.StatistikFormular.Where9, 9, 1)">
775
<option>
776
</option>
777
</select><input type="text" name="Where9"
778
onchange="check(this, 9, 1)" size="20" /></td>
779
</tr>
780
781 <!-- 8. Zeile: 'oder' 1, mit Vergleichoperatorenliste und Textfeld
782
Events: onclick="onCheckBox3(this.checked)"
783
onchange="check(TEXTFELD, SPALTENNUMMER, 2)"
784 -->
785
<tr id="ROW7" class="nonvisible" align="center">
786
<td id="R7C1" align="right"><input type="checkbox"
787
name="CheckBox3" onclick="onCheckBox3(this.checked)" /><a
788
href="javascript:popUp('help/Bedingung.html')">oder</a>
789
</td>
790
791
<td id="R7C2" class="nonvisible"><select name="Cond02"
792
size="1"
793
onchange="check(document.StatistikFormular.Where0Or1, 0, 2)">
794
<option>
795
</option>
796
</select><input type="text" name="Where0Or1"
797
onchange="check(this, 0, 2)" size="20" /></td>
798
799
<td id="R7C3" class="nonvisible"><select name="Cond12"
800
size="1"
801
onchange="check(document.StatistikFormular.Where1Or1, 1, 2)">
802
<option>
803
</option>
804
</select><input type="text" name="Where1Or1"
805
onchange="check(this, 1, 2)" size="20" /></td>
806
807
<td id="R7C4" class="nonvisible"><select name="Cond22"
808
size="1"
809
onchange="check(document.StatistikFormular.Where2Or1, 2, 2)">
810
<option>
811
</option>
812
</select><input type="text" name="Where2Or1"
813
onchange="check(this, 2, 2)" size="20" /></td>
814
815
<td id="R7C5" class="nonvisible"><select name="Cond32"
816
size="1"
Datei: statistik.html
Anhang
Seite: 13 von 20
Datei: statistik.html
Seite: 13 von 20
817
onchange="check(document.StatistikFormular.Where3Or1, 3, 2)">
818
<option>
819
</option>
820
</select><input type="text" name="Where3Or1"
821
onchange="check(this, 3, 2)" size="20" /></td>
822
823
<td id="R7C6" class="nonvisible"><select name="Cond42"
824
size="1"
825
onchange="check(document.StatistikFormular.Where4Or1, 4, 2)">
826
<option>
827
</option>
828
</select><input type="text" name="Where4Or1"
829
onchange="check(this, 4, 2)" size="20" /></td>
830
831
<td id="R7C7" class="nonvisible"><select name="Cond52"
832
size="1"
833
onchange="check(document.StatistikFormular.Where5Or1, 5, 2)">
834
<option>
835
</option>
836
</select><input type="text" name="Where5Or1"
837
onchange="check(this, 5, 2)" size="20" /></td>
838
839
<td id="R7C8" class="nonvisible"><select name="Cond62"
840
size="1"
841
onchange="check(document.StatistikFormular.Where6Or1, 6, 2)">
842
<option>
843
</option>
844
</select><input type="text" name="Where6Or1"
845
onchange="check(this, 6, 2)" size="20" /></td>
846
847
<td id="R7C9" class="nonvisible"><select name="Cond72"
848
size="1"
849
onchange="check(document.StatistikFormular.Where7Or1, 7, 2)">
850
<option>
851
</option>
852
</select><input type="text" name="Where7Or1"
853
onchange="check(this, 7, 2)" size="20" /></td>
854
855
<td id="R7C10" class="nonvisible"><select name="Cond82"
856
size="1"
857
onchange="check(document.StatistikFormular.Where8Or1, 8, 2)">
858
<option>
859
</option>
860
</select><input type="text" name="Where8Or1"
861
onchange="check(this, 8, 2)" size="20" /></td>
862
863
<td id="R7C11" class="nonvisible"><select name="Cond92"
864
size="1"
865
onchange="check(document.StatistikFormular.Where9Or1, 9, 2)">
866
<option>
867
</option>
868
</select><input type="text" name="Where9Or1"
869
onchange="check(this, 9, 2)" size="20" /></td>
870
</tr>
871
872 <!-- 9. Zeile: 'oder' 2, mit Vergleichoperatorenliste und Textfeld
873
Events: onclick="onCheckBox4(this.checked)"
874
onchange="check(TEXTFELD, SPALTENNUMMER, 3)"
875 -->
876
<tr id="ROW8" class="nonvisible" align="center">
877
<td id="R8C1" align="right"><input type="checkbox"
878
name="CheckBox4" onclick="onCheckBox4(this.checked)" /><a
879
href="javascript:popUp('help/Bedingung.html')">oder</a>
880
</td>
881
882
<td id="R8C2" class="nonvisible"><select name="Cond03"
883
size="1"
884
onchange="check(document.StatistikFormular.Where0Or2, 0, 3)">
Datei: statistik.html
8 von 71
Datei: statistik.html
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
Datei: statistik.html
Anhang
Seite: 14 von 20
<td id="R8C10" class="nonvisible"><select name="Cond83"
size="1"
onchange="check(document.StatistikFormular.Where8Or2, 8, 3)">
<option>
</option>
</select><input type="text" name="Where8Or2"
onchange="check(this, 8, 3)" size="20" /></td>
<td id="R8C9" class="nonvisible"><select name="Cond73"
size="1"
onchange="check(document.StatistikFormular.Where7Or2, 7, 3)">
<option>
</option>
</select><input type="text" name="Where7Or2"
onchange="check(this, 7, 3)" size="20" /></td>
<td id="R8C8" class="nonvisible"><select name="Cond63"
size="1"
onchange="check(document.StatistikFormular.Where6Or2, 6, 3)">
<option>
</option>
</select><input type="text" name="Where6Or2"
onchange="check(this, 6, 3)" size="20" /></td>
<td id="R8C7" class="nonvisible"><select name="Cond53"
size="1"
onchange="check(document.StatistikFormular.Where5Or2, 5, 3)">
<option>
</option>
</select><input type="text" name="Where5Or2"
onchange="check(this, 5, 3)" size="20" /></td>
<td id="R8C6" class="nonvisible"><select name="Cond43"
size="1"
onchange="check(document.StatistikFormular.Where4Or2, 4, 3)">
<option>
</option>
</select><input type="text" name="Where4Or2"
onchange="check(this, 4, 3)" size="20" /></td>
<td id="R8C5" class="nonvisible"><select name="Cond33"
size="1"
onchange="check(document.StatistikFormular.Where3Or2, 3, 3)">
<option>
</option>
</select><input type="text" name="Where3Or2"
onchange="check(this, 3, 3)" size="20" /></td>
<td id="R8C4" class="nonvisible"><select name="Cond23"
size="1"
onchange="check(document.StatistikFormular.Where2Or2, 2, 3)">
<option>
</option>
</select><input type="text" name="Where2Or2"
onchange="check(this, 2, 3)" size="20" /></td>
<td id="R8C3" class="nonvisible"><select name="Cond13"
size="1"
onchange="check(document.StatistikFormular.Where1Or2, 1, 3)">
<option>
</option>
</select><input type="text" name="Where1Or2"
onchange="check(this, 1, 3)" size="20" /></td>
<option>
</option>
</select><input type="text" name="Where0Or2"
onchange="check(this, 0, 3)" size="20" /></td>
Seite: 14 von 20
Seite: 15 von 20
Datei: statistik.html
Seite: 15 von 20
953
954
<td id="R8C11" class="nonvisible"><select name="Cond93"
955
size="1"
956
onchange="check(document.StatistikFormular.Where9Or2, 9, 3)">
957
<option>
958
</option>
959
</select><input type="text" name="Where9Or2"
960
onchange="check(this, 9, 3)" size="20" /></td>
961
</tr>
962
963 <!-- 10. Zeile: Funktion, Auswahl der Aggregatfunktionen, Dropdownliste wird in
964
onLoadStatBody() befüllt
965
Events: onclick="onCheckBox5(this.checked)"
966
onchange="onChangeFeld_group()"
967 -->
968
<tr id="ROW9" align="center">
969
<td id="R9C1" align="right"><input type="checkbox"
970
name="CheckBox5" onclick="onCheckBox5(this.checked)" /><a
971
href="javascript:popUp('help/Funktionen.html')">Funktion</a>
972
</td>
973
974
<td id="R9C2" class="nonvisible"><select name="Feld0group"
975
size="1" onchange="onChangeFeld_group()">
976
<option>
977
</option>
978
</select></td>
979
980
<td id="R9C3" class="nonvisible"><select name="Feld1group"
981
size="1" onchange="onChangeFeld_group()">
982
<option>
983
</option>
984
</select></td>
985
986
<td id="R9C4" class="nonvisible"><select name="Feld2group"
987
size="1" onchange="onChangeFeld_group()">
988
<option>
989
</option>
990
</select></td>
991
992
<td id="R9C5" class="nonvisible"><select name="Feld3group"
993
size="1" onchange="onChangeFeld_group()">
994
<option>
995
</option>
996
</select></td>
997
998
<td id="R9C6" class="nonvisible"><select name="Feld4group"
999
size="1" onchange="onChangeFeld_group()">
1000
<option>
1001
</option>
1002
</select></td>
1003
1004
<td id="R9C7" class="nonvisible"><select name="Feld5group"
1005
size="1" onchange="onChangeFeld_group()">
1006
<option>
1007
</option>
1008
</select></td>
1009
1010
<td id="R9C8" class="nonvisible"><select name="Feld6group"
1011
size="1" onchange="onChangeFeld_group()">
1012
<option>
1013
</option>
1014
</select></td>
1015
1016
<td id="R9C9" class="nonvisible"><select name="Feld7group"
1017
size="1" onchange="onChangeFeld_group()">
1018
<option>
1019
</option>
1020
</select></td>
Datei: statistik.html
Seite: 16 von 20
9 von 71
Datei: statistik.html
Seite: 16 von 20
1021
1022
<td id="R9C10" class="nonvisible"><select name="Feld8group"
1023
size="1" onchange="onChangeFeld_group()">
1024
<option>
1025
</option>
1026
</select></td>
1027
1028
<td id="R9C11" class="nonvisible"><select name="Feld9group"
1029
size="1" onchange="onChangeFeld_group()">
1030
<option>
1031
</option>
1032
</select></td>
1033
</tr>
1034
1035 <!-- 11. Zeile: Bedingungen für die Aggregatfunktionen, gleicher Aufbau wie
1036
Zeilen 7 - 9
1037
Events: onclick="onCheckBox6(this.checked)"
1038
onchange="check(TEXTFELD, SPALTENNUMMER, 4)"
1039 -->
1040
<tr id="ROW10" class="nonvisible" align="center">
1041
<td id="R10C1" align="right"><input type="checkbox"
1042
name="CheckBox6" onclick="onCheckBox6(this.checked)" /><a
1043
href="javascript:popUp('help/GBedingung.html')">Bedingung
1044
für Gruppe</a> </td>
1045
1046
<td id="R10C2" class="nonvisible"><select name="Cond04"
1047
size="1"
1048
onchange="check(document.StatistikFormular.Having0, 0, 4)">
1049
<option>
1050
</option>
1051
</select><input type="text" name="Having0"
1052
onchange="check(this, 0, 4)" size="20" /></td>
1053
1054
<td id="R10C3" class="nonvisible"><select name="Cond14"
1055
size="1"
1056
onchange="check(document.StatistikFormular.Having1, 1, 4)">
1057
<option>
1058
</option>
1059
</select><input type="text" name="Having1"
1060
onchange="check(this, 1, 4)" size="20" /></td>
1061
1062
<td id="R10C4" class="nonvisible"><select name="Cond24"
1063
size="1"
1064
onchange="check(document.StatistikFormular.Having2, 2, 4)">
1065
<option>
1066
</option>
1067
</select><input type="text" name="Having2"
1068
onchange="check(this, 2, 4)" size="20" /></td>
1069
1070
<td id="R10C5" class="nonvisible"><select name="Cond34"
1071
size="1"
1072
onchange="check(document.StatistikFormular.Having3, 3, 4)">
1073
<option>
1074
</option>
1075
</select><input type="text" name="Having3"
1076
onchange="check(this, 3, 4)" size="20" /></td>
1077
1078
<td id="R10C6" class="nonvisible"><select name="Cond44"
1079
size="1"
1080
onchange="check(document.StatistikFormular.Having4, 4, 4)">
1081
<option>
1082
</option>
1083
</select><input type="text" name="Having4"
1084
onchange="check(this, 4, 4)" size="20" /></td>
1085
1086
<td id="R10C7" class="nonvisible"><select name="Cond54"
1087
size="1"
1088
onchange="check(document.StatistikFormular.Having5, 5, 4)">
Datei: statistik.html
Anhang
Seite: 17 von 20
Datei: statistik.html
Seite: 17 von 20
1089
<option>
1090
</option>
1091
</select><input type="text" name="Having5"
1092
onchange="check(this, 5, 4)" size="20" /></td>
1093
1094
<td id="R10C8" class="nonvisible"><select name="Cond64"
1095
size="1"
1096
onchange="check(document.StatistikFormular.Having6, 6, 4)">
1097
<option>
1098
</option>
1099
</select><input type="text" name="Having6"
1100
onchange="check(this, 6, 4)" size="20" /></td>
1101
1102
<td id="R10C9" class="nonvisible"><select name="Cond74"
1103
size="1"
1104
onchange="check(document.StatistikFormular.Having7, 7, 4)">
1105
<option>
1106
</option>
1107
</select><input type="text" name="Having7"
1108
onchange="check(this, 7, 4)" size="20" /></td>
1109
1110
<td id="R10C10" class="nonvisible"><select name="Cond84"
1111
size="1"
1112
onchange="check(document.StatistikFormular.Having8, 8, 4)">
1113
<option>
1114
</option>
1115
</select><input type="text" name="Having8"
1116
onchange="check(this, 8, 4)" size="20" /></td>
1117
1118
<td id="R10C11" class="nonvisible"><select name="Cond94"
1119
size="1"
1120
onchange="check(document.StatistikFormular.Having9, 9, 4)">
1121
<option>
1122
</option>
1123
</select><input type="text" name="Having9"
1124
onchange="check(this, 9, 4)" size="20" /></td>
1125
</tr>
1126
1127 <!-- 12. Zeile: Bedingungen für die Aggregatfunktionen, gleicher Aufbau wie
1128
Zeilen 7 - 9
1129
Events: onclick="onCheckBox7(this.checked)"
1130
onchange="check(TEXTFELD, SPALTENNUMMER, 5)"
1131 -->
1132
<tr id="ROW11" class="nonvisible" align="center">
1133
<td id="R11C1" align="right"><input type="checkbox"
1134
name="CheckBox7" onclick="onCheckBox7(this.checked)" /><a
1135
href="javascript:popUp('help/GBedingung.html')">oder</a>
1136
</td>
1137
1138
<td id="R11C2" class="nonvisible"><select name="Cond05"
1139
size="1"
1140
onchange="check(document.StatistikFormular.Having0Or1, 0, 5)">
1141
<option>
1142
</option>
1143
</select><input type="text" name="Having0Or1"
1144
onchange="check(this, 0, 5)" size="20" /></td>
1145
1146
<td id="R11C3" class="nonvisible"><select name="Cond15"
1147
size="1"
1148
onchange="check(document.StatistikFormular.Having1Or1, 1, 5)">
1149
<option>
1150
</option>
1151
</select><input type="text" name="Having1Or1"
1152
onchange="check(this, 1, 5)" size="20" /></td>
1153
1154
<td id="R11C4" class="nonvisible"><select name="Cond25"
1155
size="1"
1156
onchange="check(document.StatistikFormular.Having2Or1, 2, 5)">
Datei: statistik.html
Seite: 18 von 20
10 von 71
Datei: statistik.html
Seite: 18 von 20
1157
<option>
1158
</option>
1159
</select><input type="text" name="Having2Or1"
1160
onchange="check(this, 2, 5)" size="20" /></td>
1161
1162
<td id="R11C5" class="nonvisible"><select name="Cond35"
1163
size="1"
1164
onchange="check(document.StatistikFormular.Having3Or1, 3, 5)">
1165
<option>
1166
</option>
1167
</select><input type="text" name="Having3Or1"
1168
onchange="check(this, 3, 5)" size="20" /></td>
1169
1170
<td id="R11C6" class="nonvisible"><select name="Cond45"
1171
size="1"
1172
onchange="check(document.StatistikFormular.Having4Or1, 4, 5)">
1173
<option>
1174
</option>
1175
</select><input type="text" name="Having4Or1"
1176
onchange="check(this, 4, 5)" size="20" /></td>
1177
1178
<td id="R11C7" class="nonvisible"><select name="Cond55"
1179
size="1"
1180
onchange="check(document.StatistikFormular.Having5Or1, 5, 5)">
1181
<option>
1182
</option>
1183
</select><input type="text" name="Having5Or1"
1184
onchange="check(this, 5, 5)" size="20" /></td>
1185
1186
<td id="R11C8" class="nonvisible"><select name="Cond65"
1187
size="1"
1188
onchange="check(document.StatistikFormular.Having6Or1, 6, 5)">
1189
<option>
1190
</option>
1191
</select><input type="text" name="Having6Or1"
1192
onchange="check(this, 6, 5)" size="20" /></td>
1193
1194
<td id="R11C9" class="nonvisible"><select name="Cond75"
1195
size="1"
1196
onchange="check(document.StatistikFormular.Having7Or1, 7, 5)">
1197
<option>
1198
</option>
1199
</select><input type="text" name="Having7Or1"
1200
onchange="check(this, 7, 5)" size="20" /></td>
1201
1202
<td id="R11C10" class="nonvisible"><select name="Cond85"
1203
size="1"
1204
onchange="check(document.StatistikFormular.Having8Or1, 8, 5)">
1205
<option>
1206
</option>
1207
</select><input type="text" name="Having8Or1"
1208
onchange="check(this, 8, 5)" size="20" /></td>
1209
1210
<td id="R11C11" class="nonvisible"><select name="Cond95"
1211
size="1"
1212
onchange="check(document.StatistikFormular.Having9Or1, 9, 5)">
1213
<option>
1214
</option>
1215
</select><input type="text" name="Having9Or1"
1216
onchange="check(this, 9, 5)" size="20" /></td>
1217
</tr>
1218
1219 <!-- 13. Zeile: Bedingungen für die Aggregatfunktionen, gleicher Aufbau wie
1220
Zeilen 7 - 9
1221
Events: onclick="onCheckBox8(this.checked)"
1222
onchange="check(TEXTFELD, SPALTENNUMMER, 6)"
1223 -->
1224
<tr id="ROW12" class="nonvisible" align="center">
Datei: statistik.html
Anhang
Datei: statistik.html
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
Datei: statistik.html
Seite: 19 von 20
<td id="R12C9" class="nonvisible"><select name="Cond76"
size="1"
onchange="check(document.StatistikFormular.Having7Or2, 7, 6)">
<option>
</option>
</select><input type="text" name="Having7Or2"
onchange="check(this, 7, 6)" size="20" /></td>
<td id="R12C8" class="nonvisible"><select name="Cond66"
size="1"
onchange="check(document.StatistikFormular.Having6Or2, 6, 6)">
<option>
</option>
</select><input type="text" name="Having6Or2"
onchange="check(this, 6, 6)" size="20" /></td>
<td id="R12C7" class="nonvisible"><select name="Cond56"
size="1"
onchange="check(document.StatistikFormular.Having5Or2, 5, 6)">
<option>
</option>
</select><input type="text" name="Having5Or2"
onchange="check(this, 5, 6)" size="20" /></td>
<td id="R12C6" class="nonvisible"><select name="Cond46"
size="1"
onchange="check(document.StatistikFormular.Having4Or2, 4, 6)">
<option>
</option>
</select><input type="text" name="Having4Or2"
onchange="check(this, 4, 6)" size="20" /></td>
<td id="R12C5" class="nonvisible"><select name="Cond36"
size="1"
onchange="check(document.StatistikFormular.Having3Or2, 3, 6)">
<option>
</option>
</select><input type="text" name="Having3Or2"
onchange="check(this, 3, 6)" size="20" /></td>
<td id="R12C4" class="nonvisible"><select name="Cond26"
size="1"
onchange="check(document.StatistikFormular.Having2Or2, 2, 6)">
<option>
</option>
</select><input type="text" name="Having2Or2"
onchange="check(this, 2, 6)" size="20" /></td>
<td id="R12C3" class="nonvisible"><select name="Cond16"
size="1"
onchange="check(document.StatistikFormular.Having1Or2, 1, 6)">
<option>
</option>
</select><input type="text" name="Having1Or2"
onchange="check(this, 1, 6)" size="20" /></td>
<td id="R12C2" class="nonvisible"><select name="Cond06"
size="1"
onchange="check(document.StatistikFormular.Having0Or2, 0, 6)">
<option>
</option>
</select><input type="text" name="Having0Or2"
onchange="check(this, 0, 6)" size="20" /></td>
<td id="R12C1" align="right"><input type="checkbox"
name="CheckBox8" onclick="onCheckBox8(this.checked)" /><a
href="javascript:popUp('help/GBedingung.html')">oder</a>
</td>
Seite: 19 von 20
11 von 71
<td id="R12C10" class="nonvisible"><select name="Cond86"
size="1"
onchange="check(document.StatistikFormular.Having8Or2, 8, 6)">
<option>
</option>
</select><input type="text" name="Having8Or2"
onchange="check(this, 8, 6)" size="20" /></td>
Seite: 20 von 20
Seite: 20 von 20
<!-- Datum, Autor, valid XHTML, valid CSS -->
<p style="text-align: right">2004-10-01 <a
href="mailto:[email protected]">Hilmar Falkenberg</a> <a
href="http://validator.w3.org/check?uri=referer"><img
style="border:0;width:88px;height:31px"
src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!"
height="31" width="88" /></a> <a
href="http://jigsaw.w3.org/css-validator/"><img
style="border:0;width:88px;height:31px"
src="http://jigsaw.w3.org/css-validator/images/vcss"
alt="Valid CSS!" /></a></p>
</body>
</html>
<td id="R14C2" colspan="10"><textarea class="disabled"
name="query" cols="115" rows="7" readonly="readonly"></textarea></td>
</tr>
</table>
</form>
<!-- 15. Zeile: das große Textfeld, wo der erzeugte SQL rein geschrieben wird
Events: onclick="onClickStart()"
onclick="onClickSave()"
onclick="onClickNew()"
-->
<tr id="ROW14" class="disabled">
<td id="R14C1" align="right"><a
href="javascript:popUp('help/SQL.html')">erzeugter
SQL</a> </td>
<!-- 14. Zeile: Drei Buttons (Abfrage starten, Abfrage speichern, alles zurücksetzen
und ein Link zu den gespeicherten Abfragen
Events: onclick="onClickStart()"
onclick="onClickSave()"
onclick="onClickNew()"
-->
<tr id="ROW13">
<td id="R13C1" align="left" colspan="11"><input type="hidden"
name="STATID" value="" /> <input type="hidden" name="doWhat"
value="execute" /> <input type="button"
value="Abfrage starten" onclick="onClickStart()" /> <input
type="button" value="Abfrage speichern"
onclick="onClickSave()" /> <input type="button"
value="alles zurücksetzen?" onclick="onClickNew()" /> <a
href="Statistiken?requery=yes">zu den gespeicherten
Statistiken</a> </td>
</tr>
<td id="R12C11" class="nonvisible"><select name="Cond96"
size="1"
onchange="check(document.StatistikFormular.Having9Or2, 9, 6)">
<option>
</option>
</select><input type="text" name="Having9Or2"
onchange="check(this, 9, 6)" size="20" /></td>
</tr>
Datei: statistik.html
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
Datei: statistik.html
Anhang
Seite: 1 von 3
Seite: 1 von 3
if (month < 1 || month > 12) {
// Monat testen
alert("Der Monat muss zwischen 1 und 12 sein.");
dateField.focus();
return false;
}
if (day < 1 || day > 31) {
// Tag testen
alert("Der Tag muss zwischen 1 und 31 sein.");
dateField.focus();
return false;
}
if ((month==4 || month==6 || month==9 || month==11) && day==31) {
// Tag je nach Monat testen
alert("Der Monat "+month+" hat keine 31 Tage!")
dateField.focus();
return false
}
if (month == 2) {
// 29. Februar Test
var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
if (day>29 || (day==29 && !isleap)) {
alert("Der Februar hat " + year + " keine " + day + " Tage!");
dateField.focus();
return false;
if (matchArray_de != null) {
// zerlegen des Datums in die einzelnen
day
= parseInt(matchArray_de[1],10); // Bestandteile, je nachdem, welches vo
month = parseInt(matchArray_de[3],10); // den beiden Formaten nun vorliegt.
year = parseInt(matchArray_de[4],10); //
}
if (matchArray_INGRES != null) {
year = parseInt(matchArray_INGRES[1],10);
month = parseInt(matchArray_INGRES[2],10);
day
= parseInt(matchArray_INGRES[3],10);
}
if (matchArray_de == null && matchArray_INGRES == null) {
// keines der beiden Pattern passt!
alert("Dies: "+dateField.value+"\nist kein gültiges Datum!\n\n"+
"Bitte geben Sie ein Datum in der Form TT.MM.JJJJ oder 'JJJJ-MM-DD' ein.
dateField.focus();
return false;
}
//////////////////////////////////////////////////////////////////////////////
// Überprüft auf folgende Datumformate:
// DD/MM/YY DD/MM/YYYY DD-MM-YY DD-MM-YYYY DD.MM.YY DD.MM.YYYY 'YYYY-MM-DD'
// Setzt den Feldwert auf: 'YYYY-MM-DD' incl. der Anführungsstriche!!!
// Wird die Jahreszahl nur zweistellig eingegeben wird immer 20xx angenommen!
//---------------------------------------------------------------------------function isValidDate(dateField){
var day, month, year; //zum speichern der einzelnen Werte
// die beiden Regulären-Ausdrücke zum Patternmatching
// 2004-08-26 http://developer.netscape.com/viewsource/angus_strings.html
var date_de
= /(\d{1,2})(-|\.)(\d{1,2})\2(\d{4}|\d{2})/;
var date_INGRES = /\'(\d{4})\-(\d{2})\-(\d{2})\'/;
var matchArray_de
= dateField.value.match(date_de);
// ist es deutsch?
var matchArray_INGRES = dateField.value.match(date_INGRES); // oder DB-Ingres?
//////////////////////////////////////////////////////////////////////////////
// File: check.js
Version: $Revision: 1.10 $
// Autor: Hilmar Falkenberg
$Date: 2004/10/04 19:44:49 $
//
// Beschreibung:
//
Stellt verschiedene Funktionen zur Überprüfung von Datenfeldern zur
//
Verfügung. Dabei gibt jede Funktion immer 'true' oder 'false' zurück.
//
Außerdem wird ggf. der Wert des Feldes konvertiert. So wird z.B. bei
//
isValidDate() aus dem Datum 29.02.2004 --> '2004-02-29' incl. der
//
Anführungsstriche!!!
//============================================================================
Datei: check.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: check.js
12 von 71
}
//
//
//
//
//
//
//
//
incl. der Anführungsstriche
zurückgegeben!
'YYYY-MM-DD'
Jetzt noch die Ausgabe richtig
formatieren. D.h. es wird
Seite: 2 von 3
value = "'" + newValue + "'";
while(quot_index != -1){
newValue += value.substring(0, quot_index) + "''";
value = value.substring(quot_index + 1);
quot_index = value.indexOf("'");
}
newValue += value;
Seite: 2 von 3
return true;
}
//////////////////////////////////////////////////////////////////////////////
// aus Kompatibilitätsgründen noch beibehalten --> function isIntLowerThan()
//---------------------------------------------------------------------------function checkDatensatz(zahlenField, max){
return isIntLowerThan(zahlenField, max);
}
//////////////////////////////////////////////////////////////////////////////
// Überprüft, ob der eingegebene Wert ein INTEGER ist, und zwischen 1 und
// dem übergebenen Maximum ist. Dabei wird die JAVASCRIPT Funktion
// "parseInt()" verwendet!
//---------------------------------------------------------------------------function isIntLowerThan(intField, max){with (intField){
var zahl = parseInt(value,10);
if(zahl != 'NaN' && !(1 <= zahl && zahl <= max)){
alert("Bitte geben Sie eine ganze Zahl zwischen 1 und "
+ max.toString() + " ein!");
focus();
return false;
}
value = zahl;
return true;
}}
//////////////////////////////////////////////////////////////////////////////
// Überprüft, ob der eingegebene Wert ein INTEGER ist. Dabei wird die
// JAVASCRIPT Funktion "parseInt()" verwendet!
//---------------------------------------------------------------------------function isInt(intField){with (intField){
var intPattern = /\d+/;
var matchArray
= value.match(intPattern);
if(matchArray){
value = parseInt(matchArray[0],10);
return true;
}
alert("Bitte geben Sie eine ganze Zahl ein!");
return false;
}}
//////////////////////////////////////////////////////////////////////////////
// Maskiert den eingegebenen Wert als einen STRING mit ' (Single-Quote)
// Falls es schon in einfachen Anführungszeichen steht passiert nichts!
//---------------------------------------------------------------------------function isString(stringField){with (stringField){
var isQuoted = (value.charAt(0) == "'") && (value.charAt(value.length - 1) == "'"
if(!isQuoted){
var quot_index = value.indexOf("'");
var newValue = '';
dateField.value = "'";
if(year < 100) dateField.value += '20';
if(year < 10) dateField.value += '0';
dateField.value += year.toString() + "-";
if(month < 10) dateField.value += '0';
dateField.value += month.toString() + "-";
if(day < 10) dateField.value += '0';
dateField.value += day.toString() + "'";
}
Datei: check.js
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Datei: check.js
Anhang
Seite: 3 von 3
Seite: 3 von 3
}}
//////////////////////////////////////////////////////////////////////////////
// Überprüft, ob der eingegebene Wert ein FLOAT ist. Dabei wird zuerst
// getestet, ob die Zahl mit einem Komma oder mit einem Punkt eingegeben wurde
// und dann wird die JAVASCRIPT Funktion "parseFloat()" verwendet!
//---------------------------------------------------------------------------function isFloat(intField){with (intField){
var floatPattern = /((\d+)(\,|\.)(\d+))|(\d+)/;
var matchArray
= value.match(floatPattern);
if(matchArray){
if(matchArray[1])
// Die Zahl wurde mit einem Komma eingegeben
value = parseFloat(matchArray[2]+"."+matchArray[4]);
else
value = parseFloat(matchArray[5]);
return true;
}
alert("Bitte geben Sie eine Zahl ein!");
return false;
}}
//////////////////////////////////////////////////////////////////////////////
// Überprüft, ob der eingegebene Wert ein INTEGER ist. Dabei wird die
// JAVASCRIPT Funktion "parseInt()" verwendet!
//---------------------------------------------------------------------------function isIntList(intField){with (intField){
var intPattern = /\((\s*\d+\s*\,\s*)+\d+\s*\)/;
var matchArray = value.match(intPattern);
if(matchArray){
value = matchArray[0];
return true;
}
alert("Bitte geben Sie eine Liste von Zahlen ein!\n"
+"In der Form: (0, 8, 15, 42)");
return false;
}}
return true;
}
return true;
Datei: check.js
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
Datei: check.js
13 von 71
Seite: 1 von 1
Seite: 1 von 1
}
//////////////////////////////////////////////////////////////////////////////
// testet ob Cookies verwendet werden dürfen, bzw. vom Client eingeschaltet
// sind - ggf. wird eine Meldung mit der Bitte zum einschalten erzeugt
//---------------------------------------------------------------------------function checkCookie(){
setCookie("CookieTest", "OK");
if (!getCookie("CookieTest")){
alert('Bitte aktivieren Sie COOKIES in Ihrem Browser,'
+ '\num die volle Funktionalität dieser Seite nutzen zu können!');
return false;
}
else{
eraseCookie("CookieTest");
return true;
}
}
//////////////////////////////////////////////////////////////////////////////
// löscht den Cookie 'name', bzw. setzt das Verfallsdatum auf 1970
//---------------------------------------------------------------------------function eraseCookie(name){
document.cookie = name + "=; expires=Thu, 01-Jan-70 00:00:01 GMT";
}
// in Diskussionsforen im Internet werden die einzelnen De-maskierungs// möglichkeiten heftig diskutiert. Mit 'unescape()' gibt es z.Z. die
// wenigsten Probleme (vgl. setCookie)
//return java.net.URLDecoder.decode(cook);
//return decodeURIComponent(cook);
//return decodeURI(cook);
return unescape(cook);
}
i++;
}
return null;
//////////////////////////////////////////////////////////////////////////////
// setzt einen Cookie mit 'name', auf den 'wert'
//---------------------------------------------------------------------------function setCookie(name, wert){
// in Diskussionsforen im Internet werden die einzelnen Maskierungs// möglichkeiten heftig diskutiert. Mit 'escape()' gibt es z.Z. die
// wenigsten Probleme (vgl. getCookie)
document.cookie = name + '=' + escape(wert);
//document.cookie = name + '=' + encodeURI(wert);
//document.cookie = name + '=' + encodeURIComponent(wert);
//document.cookie = name + '=' + java.net.URLEncoder.encode(wert);
}
//////////////////////////////////////////////////////////////////////////////
// gibt den Wert des Cookies 'name' zurück
//---------------------------------------------------------------------------function getCookie(name){
var i=0; //Suchposition im Cookie
var suche = name + "=";
while (i < document.cookie.length){
if (document.cookie.substring(i, i + suche.length) == suche){
var ende = document.cookie.indexOf(";", i + suche.length);
ende = (ende > -1) ? ende : document.cookie.length;
var cook = document.cookie.substring(i + suche.length, ende);
//////////////////////////////////////////////////////////////////////////////
// File: cookie.js
Version: $Revision: 1.2 $
// Autor: Hilmar Falkenberg
$Date: 2004/10/04 19:51:36 $
//
// Beschreibung:
//
Allgemeine Cookie Funktionen...
//============================================================================
Datei: cookie.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
Datei: cookie.js
Anhang
Seite: 1 von 2
// alle Spalten ausblenden
for(var i = showFeldUpTo; i > 0 ; i--){
feldcombo[i].selectedIndex = 0;
onChangeFeld_(i);
}
// Zeilen ausblenden
visi("ROW2", false);
visi("ROW3", false);
visi("ROW4", false);
visi("ROW5", false);
visi("ROW6", false);
visi("ROW9", false);
Seite: 1 von 2
}
//////////////////////////////////////////////////////////////////////////////
// bereitet den Anfrageneditor für eine neue Anfrage vor, d.h. alle Cookies
// löschen und überflüssige Felder / Tabellenzellen ausblenden
//---------------------------------------------------------------------------function neu(){
// Cookies löschen
eraseCookie("TABLE");
for(var i=0; i<10; i++)
eraseCookie("FELD"+i);
eraseCookie("CHECK");
eraseCookie("FRAGE");
eraseCookie("STATID");
saveCheck();
setCookie("CHECK", cook_CHECK);
setCookie("FRAGE", cook_FRAGE);
setCookie("TABLE", cook_TABLE);
for(var i=0; i<10; i++)
setCookie("FELD"+i, cook_FELD[i]);
//////////////////////////////////////////////////////////////////////////////
// speichert die Wahrheitswerte der Zeilen-Checkboxen in dem String cook_CHECK
// damit beim wiedereinlesen einer Anfrage festgestellt werden kann, welche
// Zeilen angezeigt werden müssen
//---------------------------------------------------------------------------function saveCheck(){
cook_CHECK = showFeldUpTo + '|';
cook_CHECK += document.StatistikFormular.CheckBox1.checked +'|';
cook_CHECK += document.StatistikFormular.CheckBox2.checked +'|';
cook_CHECK += document.StatistikFormular.CheckBox3.checked +'|';
cook_CHECK += document.StatistikFormular.CheckBox4.checked +'|';
cook_CHECK += document.StatistikFormular.CheckBox5.checked +'|';
cook_CHECK += document.StatistikFormular.CheckBox6.checked +'|';
cook_CHECK += document.StatistikFormular.CheckBox7.checked +'|';
cook_CHECK += document.StatistikFormular.CheckBox8.checked +'|';
}
//////////////////////////////////////////////////////////////////////////////
// löscht die alten Cookies und setzt die aktuellen Werte
//---------------------------------------------------------------------------function saveCookies(){
eraseCookie("TABLE");
for(var i=0; i<10; i++)
eraseCookie("FELD"+i);
eraseCookie("CHECK");
eraseCookie("FRAGE");
//////////////////////////////////////////////////////////////////////////////
// File: stat_cookies.js
Version: $Revision: 1.3 $
// Autor: Hilmar Falkenberg
$Date: 2004/10/04 20:02:13 $
//
// Beschreibung: stellt die Cookie Funktionen speziell für den Anfrageneditor
// zur Verfügung
//============================================================================
Datei: stat_cookies.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: stat_cookies.js
14 von 71
Seite: 2 von 2
Seite: 2 von 2
}
//////////////////////////////////////////////////////////////////////////////
// speichert die Werte der Cookies wieder in den entsprechenden Strings, aus
// denen dann die Einstellungen ausgelesen werden können (s. wiederherstellen)
//---------------------------------------------------------------------------function restore(){
cook_TABLE = getCookie("TABLE");
for(var i=0; i<10; i++)
cook_FELD[i] = getCookie("FELD"+i);
cook_CHECK = getCookie("CHECK");
cook_FRAGE = getCookie("FRAGE");
}o
// alle Textfelder leeren
document.StatistikFormular.reset();
document.StatistikFormular.STATID.value = '';
document.StatistikFormular.frage.value = '';
document.location.search = '';
// Verknüpfung, Bedingungen und Funktionen ausschalten
onCheckBox1(false);
onCheckBox2(false);
onCheckBox5(false);
Datei: stat_cookies.js
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
Datei: stat_cookies.js
Anhang
Seite: 1 von 10
var tabellenname = null;
sql_from = 'FROM
';
cook_TABLE = '';
Seite: 1 von 10
}
//////////////////////////////////////////////////////////////////////////////
// baut den String mit der FROM-Klausel auf und füllt die Dropdownlisten der
// 4. und 6. Zeile, also die Attribute der ausgewählten Tabellen
//---------------------------------------------------------------------------function fill_feld(formular, k){
if(k>=10) return;
showFeldUpTo = 0;
showRow[2] = false;
}
nextChild = joincombo[k].firstChild;
while (nextChild){
joincombo[k].removeChild(nextChild);
nextChild = joincombo[k].firstChild;
}
// Auswahlliste der 6. Zeile
joincombo[k].options.length = 0;
joincombo[k].options[0] = new Option ("", "");
joincombo[k].options[0].selected = true;
for(var k = 0; k < feldcombo.length; k++){
var nextChild = feldcombo[k].firstChild;
while (nextChild){
feldcombo[k].removeChild(nextChild);
nextChild = feldcombo[k].firstChild;
}
// Auswahlliste der 4. Zeile
feldcombo[k].options.length = 0;
feldcombo[k].options[0] = new Option ("", "");
feldcombo[k].options[0].selected = true;
feldcombo[k].options[STAR] = new Option ("* (alle)", "*");
//////////////////////////////////////////////////////////////////////////////
// löscht alle Optionen (Attribute der Tabellen) aus den Dropdownlisten der
// 4. und 6. Zeile
//---------------------------------------------------------------------------function empty_feld(){
cook_TABLE = '';
inBenutzung = new Array();
inBenutzung[0] = new myOption("","","");
inBenutzung[STAR] = new myOption("* (alle)","*","");
inBenutzung[STAR].table = "";
//////////////////////////////////////////////////////////////////////////////
// File: stat_erstellen.js
Version: $Revision: 1.3 $
// Autor: Hilmar Falkenberg
$Date: 2004/10/04 19:45:01 $
//
// Beschreibung: verschiedene Funktionen für den Anfrageneditor
//
// DIE SQL-Anweisung wird mit setSelect() erzeugt!
//
// Funktionsliste:
//
empty_feld()
//
fill_feld()
//
popUp()
//
setColor()
//
setSelect()
//
show()
//
showRowCol()
//
visi()
//
wiederherstellen()
//============================================================================
Datei: stat_erstellen.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: stat_erstellen.js
15 von 71
Seite: 2 von 10
// alle eingestellten Werte in den Strings für die Cookies speichern
if(feldcombo[i].selectedIndex > NICHTS){
var akt_feld = feldcombo[i].value;
cook_FELD[i] += feldcombo[i].selectedIndex
+ "|";
cook_FELD[i] += anzeigecheck[i].checked
+ "|";
//gehe durch alle 10 Felder..
for (var i = 0; i < feldcombo.length; i++){
setColor("R4C" + (2 + i), COLOR_NICHTS);
setColor("R5C" + (2 + i), COLOR_NICHTS);
setColor("R6C" + (2 + i), COLOR_NICHTS);
setColor("R7C" + (2 + i), COLOR_NICHTS);
setColor("R8C" + (2 + i), COLOR_NICHTS);
setColor("R9C" + (2 + i), COLOR_NICHTS);
setColor("R10C" + (2 + i), COLOR_NICHTS);
setColor("R11C" + (2 + i), COLOR_NICHTS);
setColor("R12C" + (2 + i), COLOR_NICHTS);
//alte Cookiewerte zurücksetzen
for(var i=0; i<10; i++)
cook_FELD[i] = '';
//lokale Variablen zum zwischenspeichern von TeilStrings...
var and0 = '';
var and1 = '';
var and2 = '';
var oder = '';
var join = '';
var hav_and0 = '';
var hav_and1 = '';
var hav_and2 = '';
var hav_oder = '';
var feldfunkt = null;
}
//////////////////////////////////////////////////////////////////////////////
// SELECT, WHERE, GROUP BY, HAVING, ORDER BY-Klausel als einzelnen Strings
// werden nach und nach aufgebaut,
//---------------------------------------------------------------------------function setSelect(){
//SQL-Anweisungen initialisieren
sql_select = 'SELECT
';
sql_where
= 'WHERE
';
sql_groupby = 'GROUP BY ';
sql_having = 'HAVING
';
sql_orderby = 'ORDER BY ';
}
inBenutzung[STAR].table = inBenutzung[STAR].table.substr(0, inBenutzung[STAR].tab
}
}
Seite: 2 von 10
for(var j = 0; j < felder[i].length; j++){
if(k ==0){
inBenutzung[feldcombo[k].length] = felder[i][j];
inBenutzung[feldcombo[k].length].table = tabellenname;
}
feldcombo[k].options[feldcombo[k].length] = new Option(felder[i][j].n
joincombo[k].options[joincombo[k].length] = new Option(felder[i][j].n
}
with(document.StatistikFormular.Tabellen){
for (var i = 0; i < length; i++){
if (options[i].selected){
tabellenname = options[i].label;
inBenutzung[STAR].table += tabellenname + " & ";
cook_TABLE += i + '|';
sql_from += options[i].value + ', ';
feldcombo[k].appendChild(OptionGroup(tabellenname));
joincombo[k].appendChild(OptionGroup(tabellenname));
Datei: stat_erstellen.js
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Datei: stat_erstellen.js
Anhang
}
+=
+=
+=
+=
+=
+=
+=
+=
+=
+=
+=
+=
+=
+=
+=
+=
+=
sortcombo[i].selectedIndex
aliasnamen[i].value
comparecombo[i][0].selectedIndex
joincombo[i].selectedIndex
comparecombo[i][1].selectedIndex
wherefelder[i][0].value
comparecombo[i][2].selectedIndex
wherefelder[i][1].value
comparecombo[i][3].selectedIndex
wherefelder[i][2].value
groupcombo[i].selectedIndex
comparecombo[i][4].selectedIndex
havingfelder[i][0].value
comparecombo[i][5].selectedIndex
havingfelder[i][1].value
comparecombo[i][6].selectedIndex
havingfelder[i][2].value
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
"|";
"|";
"|";
"|";
"|";
"|";
"|";
"|";
"|";
"|";
"|";
"|";
"|";
"|";
"|";
"|";
"|";
Seite: 3 von 10
Seite: 3 von 10
/**********************************************************************/
// die einzelnen Teile der SELECT-Clause
/**********************************************************************/
//Falls dieses Feld angezeigt werden soll...
if(anzeigecheck[i].checked && feldcombo[i].selectedIndex > NICHTS){
setColor("R4C" + (2 + i), COLOR_ANZEIGEN);
//Falls die Aggregatfunktionen eingeschaltet sind...
if(document.StatistikFormular.CheckBox5.checked){
//wenn Bedingung gewählt wurde bzw. überhaupt kein Feld...
if(groupcombo[i].selectedIndex == WHERE){
groupcombo[i].selectedIndex = GROUPBY;
setColor("R9C" + (2 + i), COLOR_GROUPBY);
}
else{
//falls '* (alle)' ausgewählt wurde...
if(feldcombo[i].selectedIndex == STAR){
//setze automatisch auf COUNT(*)
groupcombo[i].options[6].selected = true;
if(aliasnamen[i].value == '* (alle)')
aliasnamen[i].value = 'Anzahl';
}
//wenn gruppiert werden soll...
if(groupcombo[i].selectedIndex == GROUPBY){
setColor("R9C" + (2 + i), COLOR_GROUPBY);
sql_select += akt_feld;
feldfunkt = akt_feld;
}
else { // bei allen Aggregatfunktionen
setColor("R9C" + (2 + i), COLOR_FUNKTION);
feldfunkt = groupcombo[i].value
+ akt_feld + ')';
sql_select += feldfunkt;
}
}
/**********************************************************************/
// selbiges für die Verknüpfungen (JOIN)
/**********************************************************************/
if(inBenutzung && inBenutzung[joincombo[i].selectedIndex])
vtabellen[i].value = inBenutzung[joincombo[i].selectedIndex].table;
else
vtabellen[i].value = '';
/**********************************************************************/
// Benutzerhinweis, welches Feld aus welcher Tabelle stammt
/**********************************************************************/
if(inBenutzung && inBenutzung[feldcombo[i].selectedIndex])
tabellen[i].value = inBenutzung[feldcombo[i].selectedIndex].table;
else
tabellen[i].value = '';
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
cook_FELD[i]
Datei: stat_erstellen.js
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
Datei: stat_erstellen.js
16 von 71
Seite: 4 von 10
Seite: 4 von 10
if(comparecombo[i][3].selectedIndex > NOTNULL && comparecombo[i][3].sele
and2 += akt_feld + comparecombo[i][3].value + wherefelder[i][2].value
else if(comparecombo[i][3].selectedIndex == SUBQUERY){
}
//oder
if(document.StatistikFormular.CheckBox4.checked && comparecombo[i][3].selec
if(wherefelder[i][2].value || comparecombo[i][3].selectedIndex <= NOTNULL){
setColor("R8C" + (2 + i), COLOR_BEDINGUNG);
if(comparecombo[i][2].selectedIndex > NOTNULL && comparecombo[i][2].sele
and1 += akt_feld + comparecombo[i][2].value + wherefelder[i][1].value
else if(comparecombo[i][2].selectedIndex == SUBQUERY){
and1 += wherefelder[i][1].value + ' AND ';
setColor("R7C" + (2 + i), COLOR_SUBQUERY);
}
else if(comparecombo[i][2].selectedIndex <= NOTNULL)
and1 += akt_feld + comparecombo[i][2].value + ' AND ';
}
//oder
if(document.StatistikFormular.CheckBox3.checked && comparecombo[i][2].selec
if(wherefelder[i][1].value || comparecombo[i][2].selectedIndex <= NOTNULL){
setColor("R7C" + (2 + i), COLOR_BEDINGUNG);
if(comparecombo[i][1].selectedIndex > NOTNULL && comparecombo[i][1].sele
and0 += akt_feld + comparecombo[i][1].value + wherefelder[i][0].value
else if(comparecombo[i][1].selectedIndex == SUBQUERY){
and0 += wherefelder[i][0].value + ' AND ';
setColor("R6C" + (2 + i), COLOR_SUBQUERY);
}
else if(comparecombo[i][1].selectedIndex <= NOTNULL)
and0 += akt_feld + comparecombo[i][1].value + ' AND ';
//Bedingung
if(document.StatistikFormular.CheckBox2.checked && comparecombo[i][1].selec
if(wherefelder[i][0].value || comparecombo[i][1].selectedIndex <= NOTNULL){
setColor("R6C" + (2 + i), COLOR_BEDINGUNG);
/**********************************************************************/
// die einzelnen Teile der WHERE-Clause
/**********************************************************************/
//nur wenn EIN echtes Feld ausgwählt wurde...
if(feldcombo[i].selectedIndex > STAR){
//falls eine Verknüpfung [JOIN] erstellt werden soll...
if(document.StatistikFormular.CheckBox1.checked)
if(joincombo[i].selectedIndex != NICHTS && comparecombo[i][0].selectedIndex
join += akt_feld + comparecombo[i][0].value;
join += joincombo[i].value;
join += ' AND ';
setColor("R5C" + (2 + i), COLOR_JOIN);
}
}
else{ // bei SELECT * gibt es kein Alias !!!
if(feldcombo[i].selectedIndex == STAR){
aliasnamen[i].value = '';
}
sql_select += akt_feld;
}
// Hinzufügen des Alias
if(aliasnamen[i].value)
sql_select += ' AS "' + aliasnamen[i].value + '"';
sql_select += ', ';
}// SELECT-Klausel ist damit fertig
else{ // wenn es nicht angezeigt wird oder kein Feld ausgewählt wurde,
// kann auch der alias weg...
anzeigecheck[i].checked = false;
aliasnamen[i].value = '';
}
Datei: stat_erstellen.js
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
Datei: stat_erstellen.js
Anhang
Seite: 5 von 10
Seite: 5 von 10
}
//oder
if(document.StatistikFormular.CheckBox7.checked && comparecombo[i][5].selec
if(havingfelder[i][1].value || comparecombo[i][5].selectedIndex <= NOTNULL)
setColor("R11C" + (2 + i), COLOR_BEDINGUNG);
if(comparecombo[i][4].selectedIndex > NOTNULL && comparecombo[i][4].sele
hav_and0 += feldfunkt + comparecombo[i][4].value + havingfelder[i][0]
else if(comparecombo[i][4].selectedIndex == SUBQUERY){
hav_and0 += havingfelder[i][0].value + ' AND ';
setColor("R10C" + (2 + i), COLOR_SUBQUERY);
}
else if(comparecombo[i][4].selectedIndex <= NOTNULL)
hav_and0 += feldfunkt + comparecombo[i][4].value + ' AND ';
//Bedingung für Gruppe (wenn es eine Having-Condition eingegeben wurde...)
if(document.StatistikFormular.CheckBox6.checked && comparecombo[i][4].selec
if(havingfelder[i][0].value || comparecombo[i][4].selectedIndex <= NOTNULL)
setColor("R10C" + (2 + i), COLOR_BEDINGUNG);
if(anzeigecheck[i].checked && document.StatistikFormular.CheckBox5.checked){
//wenn wirklich gruppiert werden soll...
if(groupcombo[i].selectedIndex == GROUPBY && feldcombo[i].selectedIndex > S
sql_groupby += akt_feld + ', ';
}
/**********************************************************************/
// die GROUP BY-Klausel & HAVING-Klausel...
/**********************************************************************/
if(groupcombo[i].selectedIndex == NICHTS){
havingfelder[i][0].value = '';
havingfelder[i][1].value = '';
havingfelder[i][2].value = '';
comparecombo[i][4].selectedIndex = NICHTS;
comparecombo[i][5].selectedIndex = NICHTS;
comparecombo[i][6].selectedIndex = NICHTS;
}
}
} // Falls SELECT * FROM ... kann man immernoch ein Subquery als Bedingung ang
else if(feldcombo[i].selectedIndex == STAR){
// 1. mögliches Subquery
if(document.StatistikFormular.CheckBox2.checked
&& wherefelder[i][0].value
&& comparecombo[i][1].selectedIndex == SUBQUERY){
and0 += wherefelder[i][0].value + ' AND ';
setColor("R6C" + (2 + i), COLOR_SUBQUERY);
}
// 2. mögliches Subquery
if(document.StatistikFormular.CheckBox3.checked
&& wherefelder[i][1].value
&& comparecombo[i][2].selectedIndex == SUBQUERY){
and0 += wherefelder[i][1].value + ' AND ';
setColor("R7C" + (2 + i), COLOR_SUBQUERY);
}
// 3. mögliches Subquery
if(document.StatistikFormular.CheckBox4.checked
&& wherefelder[i][2].value
&& comparecombo[i][3].selectedIndex == SUBQUERY){
and0 += wherefelder[i][2].value + ' AND ';
setColor("R8C" + (2 + i), COLOR_SUBQUERY);
}
}//WHERE ist damit fast fertig, Rest folgt weiter unten
}
else if(comparecombo[i][3].selectedIndex <= NOTNULL)
and2 += akt_feld + comparecombo[i][3].value + ' AND ';
and2 += wherefelder[i][2].value + ' AND ';
setColor("R8C" + (2 + i), COLOR_SUBQUERY);
Datei: stat_erstellen.js
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
Datei: stat_erstellen.js
17 von 71
}
}
/**********************************************************************/
// die ORDER BY-Klausel...
/**********************************************************************/
if(feldcombo[i].selectedIndex > STAR && sortcombo[i].value){
if(aliasnamen[i].value)
sql_orderby += '"' + aliasnamen[i].value + '"' + sortcombo[i].value + ',
else
sql_orderby += akt_feld + sortcombo[i].value + ', ';
}
else
sortcombo[i].options[0].selected = true;
if(comparecombo[i][6].selectedIndex > NOTNULL && comparecombo[i][6].sele
hav_and2 += feldfunkt + comparecombo[i][6].value + havingfelder[i][2]
else if(comparecombo[i][6].selectedIndex == SUBQUERY){
hav_and2 += havingfelder[i][2].value + ' AND ';
setColor("R12C" + (2 + i), COLOR_SUBQUERY);
}
else if(comparecombo[i][6].selectedIndex <= NOTNULL)
hav_and2 += feldfunkt + comparecombo[i][6].value + ' AND ';
}
//oder
if(document.StatistikFormular.CheckBox8.checked && comparecombo[i][6].selec
if(havingfelder[i][2].value || comparecombo[i][6].selectedIndex <= NOTNULL)
setColor("R12C" + (2 + i), COLOR_BEDINGUNG);
if(hav_oder.length > 0)
sql_having += hav_oder.substring(0, hav_oder.length - 5);
else
Seite: 6 von 10
/**********************************************************************/
//endgültiges zusammensetzen der Having-Klausel...
/**********************************************************************/
if(hav_and0)
hav_oder += '(' + hav_and0.substring(0, hav_and0.length - 5) + ')\n\tOR ';
if(hav_and1)
hav_oder += '(' + hav_and1.substring(0, hav_and1.length - 5) + ')\n\tOR ';
if(hav_and2)
hav_oder += '(' + hav_and2.substring(0, hav_and2.length - 5) + ')\n\tOR ';
/**********************************************************************/
//endgültiges zusammensetzen der Where-Klausel...
/**********************************************************************/
if(and0)
oder += '(' + and0.substring(0, and0.length - 5) + ')\n\tOR ';
if(and1)
oder += '(' + and1.substring(0, and1.length - 5) + ')\n\tOR ';
if(and2)
oder += '(' + and2.substring(0, and2.length - 5) + ')\n\tOR ';
if(join.length > 0 && oder.length > 0)
sql_where += join + '\n\t(' + oder.substring(0, oder.length - 5) + ')';
else if(join.length > 0)
sql_where += join.substring(0, join.length - 5);
else if(oder.length > 0)
sql_where += oder.substring(0, oder.length - 5);
else
sql_where = null;
}
Seite: 6 von 10
if(comparecombo[i][5].selectedIndex > NOTNULL && comparecombo[i][5].sele
hav_and1 += feldfunkt + comparecombo[i][5].value + havingfelder[i][1]
else if(comparecombo[i][5].selectedIndex == SUBQUERY){
hav_and1 += havingfelder[i][1].value + ' AND ';
setColor("R11C" + (2 + i), COLOR_SUBQUERY);
}
else if(comparecombo[i][5].selectedIndex <= NOTNULL)
hav_and1 += feldfunkt + comparecombo[i][5].value + ' AND ';
Datei: stat_erstellen.js
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
Datei: stat_erstellen.js
Anhang
Seite: 7 von 10
if(cook_CHECK){
// wiederherstellen der ganzen Checkboxen für die Zeilen
//die evtl. vorhandene LfdNr der Statistik wiederherstellen
document.StatistikFormular.STATID.value = getCookie("STATID");
Seite: 7 von 10
}
}
//////////////////////////////////////////////////////////////////////////////
// macht HTML-Element mit der ID = nr, sichtbar oder unsichtbar
//---------------------------------------------------------------------------function visi(nr, onoff){
if (document.getElementById){
var vista = onoff ? 'visible' : 'hidden';
var element = document.getElementById(nr);
if(element)
element.style.visibility = vista;
}
}
//////////////////////////////////////////////////////////////////////////////
// macht die Zelle(row=Zeile, col=Spalte) der Tabelle sichtbar/unsichtbar
//---------------------------------------------------------------------------function showRowCol(row, col, onoff){
visi("R" + row + "C" + col, onoff);
}
//////////////////////////////////////////////////////////////////////////////
// setzt die Hintergrundfarbe eines HTML-Elements
//---------------------------------------------------------------------------function setColor(nr, color){
if (document.layers){
document.layers[nr].bgColor = color;
}
else if (document.all){
document.all[nr].bgColor = color;
}
else if (document.getElementById){
document.getElementById(nr).bgColor = color;
}
}
//////////////////////////////////////////////////////////////////////////////
// stellt alle in den Cookies gespeicherten Werte wieder her, sodass die
// zuletzt bearbeitete Anfrage wieder im Editor verfügbar ist
//---------------------------------------------------------------------------function wiederherstellen(){
empty_feld(); //erst alles alte löschen
restore(); //gespeicherte Cookies holen
}
else{
value = '';
}
if(sql_where)
value += sql_where + '\n';
if(sql_groupby.length > 11)
value += sql_groupby.substring(0, sql_groupby.length - 2) + '\n';
if(sql_having)
value += sql_having + '\n';
if(sql_orderby.length > 11)
value += sql_orderby.substring(0, sql_orderby.length - 2);
/**********************************************************************/
// QUERY Ausgabe...
/**********************************************************************/
with(document.StatistikFormular.query){
if(sql_select.length > 11){
value = sql_select.substring(0, sql_select.length - 2) + '\n';
value += sql_from.substring(0, sql_from.length - 2) + '\n';
sql_having = null;
Datei: stat_erstellen.js
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
Datei: stat_erstellen.js
18 von 71
wert = cook_CHECK.substring(0, cook_CHECK.indexOf("|"));
cook_CHECK = cook_CHECK.substring(cook_CHECK.indexOf("|") + 1);
showRow[12] = document.StatistikFormular.CheckBox8.checked = eval(wert);
wert = cook_CHECK.substring(0, cook_CHECK.indexOf("|"));
cook_CHECK = cook_CHECK.substring(cook_CHECK.indexOf("|") + 1);
showRow[11] = document.StatistikFormular.CheckBox7.checked = eval(wert);
visi("ROW12", showRow[11]);
wert = cook_CHECK.substring(0, cook_CHECK.indexOf("|"));
cook_CHECK = cook_CHECK.substring(cook_CHECK.indexOf("|") + 1);
showRow[10] = document.StatistikFormular.CheckBox6.checked = eval(wert);
visi("ROW11", showRow[10]);
wert = cook_CHECK.substring(0, cook_CHECK.indexOf("|"));
cook_CHECK = cook_CHECK.substring(cook_CHECK.indexOf("|") + 1);
showRow[9] = document.StatistikFormular.CheckBox5.checked = eval(wert);
visi("ROW10", showRow[9]);
wert = cook_CHECK.substring(0, cook_CHECK.indexOf("|"));
cook_CHECK = cook_CHECK.substring(cook_CHECK.indexOf("|") + 1);
showRow[8] = document.StatistikFormular.CheckBox4.checked = eval(wert);
wert = cook_CHECK.substring(0, cook_CHECK.indexOf("|"));
cook_CHECK = cook_CHECK.substring(cook_CHECK.indexOf("|") + 1);
showRow[7] = document.StatistikFormular.CheckBox3.checked = eval(wert);
visi("ROW8", showRow[7]);
wert = cook_CHECK.substring(0, cook_CHECK.indexOf("|"));
cook_CHECK = cook_CHECK.substring(cook_CHECK.indexOf("|") + 1);
showRow[6] = document.StatistikFormular.CheckBox2.checked = eval(wert);
visi("ROW7", showRow[6]);
wert = cook_CHECK.substring(0, cook_CHECK.indexOf("|"));
cook_CHECK = cook_CHECK.substring(cook_CHECK.indexOf("|") + 1);
showRow[5] = document.StatistikFormular.CheckBox1.checked = eval(wert);
Seite: 8 von 10
//wird das Feld auch angezeigt...
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
anzeigecheck[i].checked = eval(wert);
var i = 0;
// die einzelnen Spalten wiederherstellen
for( ; i < cook_FELD.length && i < showFeldUpTo; i++)
if(cook_FELD[i]){
//richtiges Feld auswählen...
var wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
feldcombo[i].selectedIndex = wert;
// die benötigeten Dropdownlisten mit den Attributen füllen
for(var i = 0; i <= showFeldUpTo; i++)
fill_feld(document.StatistikFormular, i);
if(cook_TABLE){
// die Tabellenauswahl wiederherstellen
while(cook_TABLE.indexOf("|") != -1){
var tab_index = cook_TABLE.substring(0, cook_TABLE.indexOf("|"));
cook_TABLE = cook_TABLE.substring(cook_TABLE.indexOf("|") + 1);
document.StatistikFormular.Tabellen.options[tab_index].selected = true;
}
}
Seite: 8 von 10
// also, welche Zeilen sind eingeschaltet gewesen?
var wert = cook_CHECK.substring(0, cook_CHECK.indexOf("|"));
cook_CHECK = cook_CHECK.substring(cook_CHECK.indexOf("|") + 1);
showFeldUpTo = wert;
Datei: stat_erstellen.js
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
Datei: stat_erstellen.js
Anhang
Seite: 9 von 10
Seite: 9 von 10
//HAVING-Vergleichsoperator 2
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
comparecombo[i][5].selectedIndex = wert;
//HAVING-Bedigung 2
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
//HAVING-Vergleichsoperator 1
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
comparecombo[i][4].selectedIndex = wert;
//HAVING-Bedigung 1
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
havingfelder[i][0].value = wert;
//welche Funktion wurde gewählt
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
groupcombo[i].selectedIndex = wert;
//WHERE-Vergleichsoperator 3
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
comparecombo[i][3].selectedIndex = wert;
//WHERE-Bedingung 3
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
wherefelder[i][2].value = wert;
//WHERE-Vergleichsoperator 2
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
comparecombo[i][2].selectedIndex = wert;
//WHERE-Bedingung 2
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
wherefelder[i][1].value = wert;
//WHERE-Vergleichsoperator 1
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
comparecombo[i][1].selectedIndex = wert;
//WHERE-Bedingung 1
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
wherefelder[i][0].value = wert;
//wie soll der JOIN bzw. Verknüpfung aussehen...
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
comparecombo[i][0].selectedIndex = wert;
//mit welchem Feld soll verknüpft werden...
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
joincombo[i].selectedIndex = wert;
//hat es evtl. einen Alias...
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
aliasnamen[i].value = wert;
//wie soll es sortiert werden...
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
sortcombo[i].selectedIndex = wert;
Datei: stat_erstellen.js
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
Datei: stat_erstellen.js
19 von 71
}
//die restlichen werden auf den ersten Wert gesetzt
for(; i < feldcombo.length; i++)
feldcombo[i].selectedIndex = 0;
}D
for(var i = showFeldUpTo + 1; i <= 10; i++){
for(var j = 2; j < showRow.length; j++){
showRowCol(j, i + 1, false);
}
visi("flipr" + (i-1), false);
visi("flipl" + (i-1), false);
}
visi("flipr" + (i - 2), false);
visi("flipr" + (i - 3), false);
visi("flipl" + (i - 2), false);
Seite: 10 von 10
show();
setSelect();
}
//////////////////////////////////////////////////////////////////////////////
// öffnet ein PopUp-Fenster, wird hier für die Hilfefenster verwendet
//---------------------------------------------------------------------------function popUp(URL) {
day = new Date();
id = day.getTime();
eval("page" + id + " = window.open(URL, '" + id +
"', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,wid
}
//////////////////////////////////////////////////////////////////////////////
// macht die benötigten Zeilen und Spalten sichtbar, den Rest unsichtbar
//---------------------------------------------------------------------------function show(){
// bis 'showFeldUpTo' müssen alle Spalten angezeigt werden
for(var i = 1; i <= showFeldUpTo; i++){
for(var j = 2; j < showRow.length; j++){
showRowCol(j, i + 1, showRow[j]);
}
if((i - 2) > 0)
visi("flipl" + (i - 2), true);
visi("flipr" + (i - 1), true);
}
// ggf. noch die Frage wiederherstellen
if(cook_FRAGE){
document.StatistikFormular.frage.value = cook_FRAGE;
}
else{
document.StatistikFormular.frage.value = "Bitte geben Sie hier einen aussagekr
}
}
Seite: 10 von 10
//HAVING-Vergleichsoperator 3
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
comparecombo[i][6].selectedIndex = wert;
//HAVING-Bedigung 3
wert = cook_FELD[i].substring(0, cook_FELD[i].indexOf("|"));
cook_FELD[i] = cook_FELD[i].substring(cook_FELD[i].indexOf("|") + 1);
havingfelder[i][2].value = wert;
havingfelder[i][1].value = wert;
Datei: stat_erstellen.js
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
Datei: stat_erstellen.js
Anhang
Seite: 1 von 12
Seite: 1 von 12
// Array mit den Textfeldern 'aus Tabelle', wo der Tabellenname des aus// gewählten Attributs hineingeschrieben wird
tabellen = new Array(
document.StatistikFormular.Tabelle0,
document.StatistikFormular.Tabelle1,
document.StatistikFormular.Tabelle2,
document.StatistikFormular.Tabelle3,
document.StatistikFormular.Tabelle4,
document.StatistikFormular.Tabelle5,
document.StatistikFormular.Tabelle6,
document.StatistikFormular.Tabelle7,
document.StatistikFormular.Tabelle8,
document.StatistikFormular.Tabelle9
);
// Array mit den Dropdownlisten für die Attribute aus der 4. Zeile
feldcombo = new Array(
document.StatistikFormular.Feld0,
document.StatistikFormular.Feld1,
document.StatistikFormular.Feld2,
document.StatistikFormular.Feld3,
document.StatistikFormular.Feld4,
document.StatistikFormular.Feld5,
document.StatistikFormular.Feld6,
document.StatistikFormular.Feld7,
document.StatistikFormular.Feld8,
document.StatistikFormular.Feld9
);
// Array mit den Checkboxen für die Anzeige eines Attributs im SELECT
anzeigecheck = new Array(
document.StatistikFormular.Feld0anz,
document.StatistikFormular.Feld1anz,
document.StatistikFormular.Feld2anz,
document.StatistikFormular.Feld3anz,
document.StatistikFormular.Feld4anz,
document.StatistikFormular.Feld5anz,
document.StatistikFormular.Feld6anz,
document.StatistikFormular.Feld7anz,
document.StatistikFormular.Feld8anz,
document.StatistikFormular.Feld9anz
);
// Array mit den Dropdownlisten für die Sortierung
sortcombo = new Array(
document.StatistikFormular.Feld0sort,
document.StatistikFormular.Feld1sort,
document.StatistikFormular.Feld2sort,
document.StatistikFormular.Feld3sort,
document.StatistikFormular.Feld4sort,
document.StatistikFormular.Feld5sort,
document.StatistikFormular.Feld6sort,
document.StatistikFormular.Feld7sort,
document.StatistikFormular.Feld8sort,
document.StatistikFormular.Feld9sort
//////////////////////////////////////////////////////////////////////////////
// wird aufgerufen, wenn der BODY des Anfrageneditors geladen wird
// es werden einige Felder initialisiert, die einen einfacheren Zugriff auf
// die einzelnen Steuerelemente des Formulars erlauben
//---------------------------------------------------------------------------function onLoadStatBody(){
checkCookie(); // falls keine Cookies erlaubt sind, gibt es eine Meldung!
//////////////////////////////////////////////////////////////////////////////
// File: stat_events.js
Version: $Revision: 1.4 $
// Autor: Hilmar Falkenberg
$Date: 2004/10/04 21:09:05 $
//
// Beschreibung: hier sind alle Funktionen, die von einem Javascript bzw.
// von dem Browser Eventhandler angestoßen werden zusammengefasst
//============================================================================
Datei: stat_events.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: stat_events.js
20 von 71
Seite: 2 von 12
Seite: 2 von 12
);
// Array mit den Textfeldern für die jeweiligen Aliasnamen 'AS'
aliasnamen = new Array(
document.StatistikFormular.Alias0,
document.StatistikFormular.Alias1,
document.StatistikFormular.Alias2,
document.StatistikFormular.Alias3,
document.StatistikFormular.Alias4,
document.StatistikFormular.Alias5,
document.StatistikFormular.Alias6,
document.StatistikFormular.Alias7,
document.StatistikFormular.Alias8,
document.StatistikFormular.Alias9
);
// Array mit den Dropdownlisten für die Aggregatfunktionen
groupcombo = new Array(
document.StatistikFormular.Feld0group,
document.StatistikFormular.Feld1group,
document.StatistikFormular.Feld2group,
document.StatistikFormular.Feld3group,
document.StatistikFormular.Feld4group,
document.StatistikFormular.Feld5group,
document.StatistikFormular.Feld6group,
document.StatistikFormular.Feld7group,
document.StatistikFormular.Feld8group,
document.StatistikFormular.Feld9group
);
// Array mit den Dropdownlisten für die Attribute aus der 6. Zeile
joincombo = new Array(
document.StatistikFormular.Feld0join,
document.StatistikFormular.Feld1join,
document.StatistikFormular.Feld2join,
document.StatistikFormular.Feld3join,
document.StatistikFormular.Feld4join,
document.StatistikFormular.Feld5join,
document.StatistikFormular.Feld6join,
document.StatistikFormular.Feld7join,
document.StatistikFormular.Feld8join,
document.StatistikFormular.Feld9join
);
// Array mit den Textfeldern 'aus Tabelle', wo der Tabellenname des aus// gewählten Attributs hineingeschrieben wird, diesmal das Verknüpfte
vtabellen = new Array(
document.StatistikFormular.VTabelle0,
document.StatistikFormular.VTabelle1,
document.StatistikFormular.VTabelle2,
document.StatistikFormular.VTabelle3,
document.StatistikFormular.VTabelle4,
document.StatistikFormular.VTabelle5,
document.StatistikFormular.VTabelle6,
document.StatistikFormular.VTabelle7,
document.StatistikFormular.VTabelle8,
document.StatistikFormular.VTabelle9
);
// zweidimensionales Array mit den Textfeldern für die Bedingungen
wherefelder = new Array(
new Array(document.StatistikFormular.Where0,
document.StatistikFormular.Where0Or1,
document.StatistikFormular.Where0Or2),
new Array(document.StatistikFormular.Where1,
document.StatistikFormular.Where1Or1,
document.StatistikFormular.Where1Or2),
new Array(document.StatistikFormular.Where2,
document.StatistikFormular.Where2Or1,
document.StatistikFormular.Where2Or2),
new Array(document.StatistikFormular.Where3,
document.StatistikFormular.Where3Or1,
document.StatistikFormular.Where3Or2),
Datei: stat_events.js
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Datei: stat_events.js
Anhang
Seite: 3 von 12
Seite: 3 von 12
);
// zweidimensionales Array mit den Textfeldern für die Gruppen-Bedingungen
havingfelder = new Array(
new Array(document.StatistikFormular.Having0,
document.StatistikFormular.Having0Or1,
document.StatistikFormular.Having0Or2),
new Array(document.StatistikFormular.Having1,
document.StatistikFormular.Having1Or1,
document.StatistikFormular.Having1Or2),
new Array(document.StatistikFormular.Having2,
document.StatistikFormular.Having2Or1,
document.StatistikFormular.Having2Or2),
new Array(document.StatistikFormular.Having3,
document.StatistikFormular.Having3Or1,
document.StatistikFormular.Having3Or2),
new Array(document.StatistikFormular.Having4,
document.StatistikFormular.Having4Or1,
document.StatistikFormular.Having4Or2),
new Array(document.StatistikFormular.Having5,
document.StatistikFormular.Having5Or1,
document.StatistikFormular.Having5Or2),
new Array(document.StatistikFormular.Having6,
document.StatistikFormular.Having6Or1,
document.StatistikFormular.Having6Or2),
new Array(document.StatistikFormular.Having7,
document.StatistikFormular.Having7Or1,
document.StatistikFormular.Having7Or2),
new Array(document.StatistikFormular.Having8,
document.StatistikFormular.Having8Or1,
document.StatistikFormular.Having8Or2),
new Array(document.StatistikFormular.Having9,
document.StatistikFormular.Having9Or1,
document.StatistikFormular.Having9Or2)
);
// zweidimensionales Array mit den Dropdownlisten für die Vergleichsoperatoren
comparecombo = new Array(
new Array(document.StatistikFormular.Cond00,
document.StatistikFormular.Cond01,
document.StatistikFormular.Cond02,
document.StatistikFormular.Cond03,
document.StatistikFormular.Cond04,
document.StatistikFormular.Cond05,
document.StatistikFormular.Cond06),
new Array(document.StatistikFormular.Cond10,
document.StatistikFormular.Cond11,
document.StatistikFormular.Cond12,
document.StatistikFormular.Cond13,
document.StatistikFormular.Cond14,
document.StatistikFormular.Cond15,
document.StatistikFormular.Cond16),
new Array(document.StatistikFormular.Where4,
document.StatistikFormular.Where4Or1,
document.StatistikFormular.Where4Or2),
new Array(document.StatistikFormular.Where5,
document.StatistikFormular.Where5Or1,
document.StatistikFormular.Where5Or2),
new Array(document.StatistikFormular.Where6,
document.StatistikFormular.Where6Or1,
document.StatistikFormular.Where6Or2),
new Array(document.StatistikFormular.Where7,
document.StatistikFormular.Where7Or1,
document.StatistikFormular.Where7Or2),
new Array(document.StatistikFormular.Where8,
document.StatistikFormular.Where8Or1,
document.StatistikFormular.Where8Or2),
new Array(document.StatistikFormular.Where9,
document.StatistikFormular.Where9Or1,
document.StatistikFormular.Where9Or2)
Datei: stat_events.js
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
Datei: stat_events.js
21 von 71
Seite: 4 von 12
Seite: 4 von 12
// füllen der Vergleichsoperatoren-Dropdownlisten, ebenfalls dynamisch mit Javasc
// füllen der Aggregatfunktions-Dropdownliste mit den möglichen Werten
// so kann der Anfrageneditor leichter um Funktionen erweitert werden (s. stat_gl
for (var i = 0; i < funktionen.length; i++){
for(var j = 0; j < groupcombo.length; j++){
groupcombo[j].options[i] = new Option(funktionen[i].name, funktionen[i].val
groupcombo[j].options[i].selected = (i == 2); // gruppieren als DEFAULT-Wer
}
}
);
new Array(document.StatistikFormular.Cond20,
document.StatistikFormular.Cond21,
document.StatistikFormular.Cond22,
document.StatistikFormular.Cond23,
document.StatistikFormular.Cond24,
document.StatistikFormular.Cond25,
document.StatistikFormular.Cond26),
new Array(document.StatistikFormular.Cond30,
document.StatistikFormular.Cond31,
document.StatistikFormular.Cond32,
document.StatistikFormular.Cond33,
document.StatistikFormular.Cond34,
document.StatistikFormular.Cond35,
document.StatistikFormular.Cond36),
new Array(document.StatistikFormular.Cond40,
document.StatistikFormular.Cond41,
document.StatistikFormular.Cond42,
document.StatistikFormular.Cond43,
document.StatistikFormular.Cond44,
document.StatistikFormular.Cond45,
document.StatistikFormular.Cond46),
new Array(document.StatistikFormular.Cond50,
document.StatistikFormular.Cond51,
document.StatistikFormular.Cond52,
document.StatistikFormular.Cond53,
document.StatistikFormular.Cond54,
document.StatistikFormular.Cond55,
document.StatistikFormular.Cond56),
new Array(document.StatistikFormular.Cond60,
document.StatistikFormular.Cond61,
document.StatistikFormular.Cond62,
document.StatistikFormular.Cond63,
document.StatistikFormular.Cond64,
document.StatistikFormular.Cond65,
document.StatistikFormular.Cond66),
new Array(document.StatistikFormular.Cond70,
document.StatistikFormular.Cond71,
document.StatistikFormular.Cond72,
document.StatistikFormular.Cond73,
document.StatistikFormular.Cond74,
document.StatistikFormular.Cond75,
document.StatistikFormular.Cond76),
new Array(document.StatistikFormular.Cond80,
document.StatistikFormular.Cond81,
document.StatistikFormular.Cond82,
document.StatistikFormular.Cond83,
document.StatistikFormular.Cond84,
document.StatistikFormular.Cond85,
document.StatistikFormular.Cond86),
new Array(document.StatistikFormular.Cond90,
document.StatistikFormular.Cond91,
document.StatistikFormular.Cond92,
document.StatistikFormular.Cond93,
document.StatistikFormular.Cond94,
document.StatistikFormular.Cond95,
document.StatistikFormular.Cond96)
Datei: stat_events.js
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
Datei: stat_events.js
Anhang
Seite: 5 von 12
// Sortierungs-Dropdownliste
// Anzeigecheckbox
save = anzeigecheck[left].checked;
anzeigecheck[left].checked = anzeigecheck[right].checked;
anzeigecheck[right].checked = save;
Seite: 5 von 12
}
//////////////////////////////////////////////////////////////////////////////
// setzt bei veränderter Frage den String für den entsprechenden Cookie
//---------------------------------------------------------------------------function onChangeFrage(wert){
cook_FRAGE = wert;
}
//////////////////////////////////////////////////////////////////////////////
// wenn eine andere Tabelle in der 2. Zeile ausgewählt wurde, müssen alle
// Spalten mit den neuen Attributen gefüllt werden
//---------------------------------------------------------------------------function onChangeTabellen(){
empty_feld();
// alle Spalten löschen
showFeldUpTo = 1;
// nur die erste Spalte anzeigen
fill_feld(document.StatistikFormular, 0); // die erste Spalte mit Attributen füll
visi("ROW2", true);
visi("ROW3", true);
visi("ROW4", true);
visi("ROW5", true);
visi("ROW6", true);
visi("ROW9", true);
show();
setSelect();
}
//////////////////////////////////////////////////////////////////////////////
// wird durch die Spaltentauschen Buttons aufgerufen
// es werden alle Werte einer Spalte nach und nach vertauscht.
//---------------------------------------------------------------------------function onClickFlip__(left, right){
if(left >= 0 && right < 10){
// ausgewähltes Attribut
var save = feldcombo[left].selectedIndex;
feldcombo[left].selectedIndex = feldcombo[right].selectedIndex;
feldcombo[right].selectedIndex = save;
// wie wurde der Anfrageneditor gestartet? soll eine NEUE Anfrage erstellt werden
// oder soll die letzte bearbeitet werden? (s. Aufruf von statistik.html)
if(document.location.search && -1 != document.location.search.indexOf("neu"))
neu();
else
wiederherstellen();
// SQL-Klauseln initialisieren
sql_select
= 'SELECT * ';
sql_from
= 'FROM ';
sql_where
= null;
sql_groupby = null;
sql_having
= null;
sql_orderby = null;
// so können später auch SQL-Funktionen/Prädikate wie z.B. 'between' o.ä. ergänzt
for(var j = 0; j < comparecombo.length; j++){
var joinindex = 0;
for (var i = 0; i < compare.length; i++){
if((i > 2 && i < 9) || i == NICHTS){ // bei der Venküpfung sind nur Verglei
comparecombo[j][0].options[joinindex] = new Option(compare[i].name, comp
joinindex++;
}
for(var k = 1; k < comparecombo[j].length; k++)
comparecombo[j][k].options[i] = new Option(compare[i].name, compare[i].v
}
}
Datei: stat_events.js
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
Datei: stat_events.js
22 von 71
Seite: 6 von 12
Seite: 6 von 12
// Vergleichsoperatorenliste
save = comparecombo[left][5].selectedIndex;
comparecombo[left][5].selectedIndex = comparecombo[right][5].selectedIndex;
comparecombo[right][5].selectedIndex = save;
// Bedingungswert
save = havingfelder[left][0].value;
havingfelder[left][0].value = havingfelder[right][0].value;
havingfelder[right][0].value = save;
// Vergleichsoperatorenliste
save = comparecombo[left][4].selectedIndex;
comparecombo[left][4].selectedIndex = comparecombo[right][4].selectedIndex;
comparecombo[right][4].selectedIndex = save;
// verwendete Funktion
save = groupcombo[left].selectedIndex;
groupcombo[left].selectedIndex = groupcombo[right].selectedIndex;
groupcombo[right].selectedIndex = save;
// Bedingungswert
save = wherefelder[left][2].value;
wherefelder[left][2].value = wherefelder[right][2].value;
wherefelder[right][2].value = save;
// Vergleichsoperatorenliste
save = comparecombo[left][3].selectedIndex;
comparecombo[left][3].selectedIndex = comparecombo[right][3].selectedIndex;
comparecombo[right][3].selectedIndex = save;
// Bedingungswert
save = wherefelder[left][1].value;
wherefelder[left][1].value = wherefelder[right][1].value;
wherefelder[right][1].value = save;
// Vergleichsoperatorenliste
save = comparecombo[left][2].selectedIndex;
comparecombo[left][2].selectedIndex = comparecombo[right][2].selectedIndex;
comparecombo[right][2].selectedIndex = save;
// Bedingungswert
save = wherefelder[left][0].value;
wherefelder[left][0].value = wherefelder[right][0].value;
wherefelder[right][0].value = save;
// Vergleichsoperatorenliste
save = comparecombo[left][1].selectedIndex;
comparecombo[left][1].selectedIndex = comparecombo[right][1].selectedIndex;
comparecombo[right][1].selectedIndex = save;
// verknüpftes Attribut
save = joincombo[left].selectedIndex;
joincombo[left].selectedIndex = joincombo[right].selectedIndex;
joincombo[right].selectedIndex = save;
// Vergleichsoperatorenliste
save = comparecombo[left][0].selectedIndex;
comparecombo[left][0].selectedIndex = comparecombo[right][0].selectedIndex;
comparecombo[right][0].selectedIndex = save;
// eingetragene Aliasnamen (Spaltenüberschriften)
save = aliasnamen[left].value;
aliasnamen[left].value = aliasnamen[right].value;
aliasnamen[right].value = save;
save = sortcombo[left].selectedIndex;
sortcombo[left].selectedIndex = sortcombo[right].selectedIndex;
sortcombo[right].selectedIndex = save;
Datei: stat_events.js
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
Datei: stat_events.js
Anhang
Seite: 7 von 12
showFeldUpTo -= 1;
show();
setSelect();
// Zellen-Anzeige aktualisieren
// SQL-Anzeige aktualisieren
Seite: 7 von 12
// Spaltentauschenleiste anzeigen (mehr als ein Attribut gewählt) oder
// nicht anzeigen (ein oder kein Attribut ausgewählt)
if(showFeldUpTo <= 2)
showRow[2] = false;
else
showRow[2] = true;
}
// ggf. leere Spalte nach hinten durchtauschen
for(var i = nr; i < showFeldUpTo; i++)
onClickFlip__(i, i + 1);
setSelect(); // nun noch den SQL aktualisieren
}
}
//////////////////////////////////////////////////////////////////////////////
// wenn ein anderes Attribut ausgewählt wird,
// muss ggf. eine weitere Spalte angezeigt werden oder evtl. gelöscht (leeres
// Attribut ausgewählt)
//---------------------------------------------------------------------------function onChangeFeld_(nr){
if(feldcombo[nr].selectedIndex > NICHTS){
// eine Spalte mehr anzeigen
showFeldUpTo = (2 + nr) > showFeldUpTo ? (2 + nr) : showFeldUpTo;
showFeldUpTo = 10 < showFeldUpTo ? 11 : showFeldUpTo;
if(showFeldUpTo < 11)
fill_feld(document.StatistikFormular, (nr + 1));
}
else {
// eine Spalte weniger anzeigen
anzeigecheck[nr].checked = false;
sortcombo[nr].selectedIndex = NICHTS;
aliasnamen[nr].value = '';
comparecombo[nr][0].selectedIndex = NICHTS;
comparecombo[nr][1].selectedIndex = NICHTS;
comparecombo[nr][2].selectedIndex = NICHTS;
comparecombo[nr][3].selectedIndex = NICHTS;
comparecombo[nr][4].selectedIndex = NICHTS;
comparecombo[nr][5].selectedIndex = NICHTS;
comparecombo[nr][6].selectedIndex = NICHTS;
joincombo[nr].selectedIndex = NICHTS;
wherefelder[nr][0].value = '';
wherefelder[nr][1].value = '';
wherefelder[nr][2].value = '';
havingfelder[nr][0].value = '';
havingfelder[nr][1].value = '';
havingfelder[nr][2].value = '';
// Bedingungswert
save = havingfelder[left][2].value;
havingfelder[left][2].value = havingfelder[right][2].value;
havingfelder[right][2].value = save;
// Vergleichsoperatorenliste
save = comparecombo[left][6].selectedIndex;
comparecombo[left][6].selectedIndex = comparecombo[right][6].selectedIndex;
comparecombo[right][6].selectedIndex = save;
// Bedingungswert
save = havingfelder[left][1].value;
havingfelder[left][1].value = havingfelder[right][1].value;
havingfelder[right][1].value = save;
Datei: stat_events.js
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
Datei: stat_events.js
23 von 71
Seite: 8 von 12
Seite: 8 von 12
}
//////////////////////////////////////////////////////////////////////////////
if(onoff){
show();
setSelect();
}
else {
// Bedingung ausgeschaltet, dann muss ggf. die nächste ODER-Zeile
// ebenfalls ausgeblendet werden
document.StatistikFormular.CheckBox3.checked = onoff;
onCheckBox3(onoff);
}
}
//////////////////////////////////////////////////////////////////////////////
// wird bei einem Klick auf eine Attribut-Anzeigen-Checkbox aufgerufen
//---------------------------------------------------------------------------function onClickFeld_anz(nr){
if(anzeigecheck[nr].checked && feldcombo[nr].selectedIndex){
if(!aliasnamen[nr].value)
// falls noch kein Alias vergeben wurde setze den Attributsnamen ein
aliasnamen[nr].value = inBenutzung[feldcombo[nr].selectedIndex].name;
}
else{
// keine Anzeige -> kein Alias
aliasnamen[nr].value = '';
anzeigecheck[nr].checked = false;
}
setSelect();
}
//////////////////////////////////////////////////////////////////////////////
// falls andere Sortierung gewünscht ist, muss nur der SQL angepasst werden
//---------------------------------------------------------------------------function onChangeFeld_sort(){
setSelect();
}
//////////////////////////////////////////////////////////////////////////////
// anderer Aliasname -> gleiche Funktion wie auf Anzeigen-Checkbox klicken
//---------------------------------------------------------------------------function onChangeAlias_(nr){
onClickFeld_anz(nr);
}
//////////////////////////////////////////////////////////////////////////////
// die Zeile für den JOIN bzw. die Verknüpfung ein-/ausschalten
//---------------------------------------------------------------------------function onCheckBox1(onoff){
showRow[5] = onoff;
show();
setSelect();
}
//////////////////////////////////////////////////////////////////////////////
// ändert sich der Vergleichsoperator beim JOIN -> SQL anpassen
//---------------------------------------------------------------------------function onChangeCond_0(){
setSelect();
}
//////////////////////////////////////////////////////////////////////////////
// ändert sich das verknüpfte Attribut beim JOIN -> SQL anpassen
//---------------------------------------------------------------------------function onChangeFeld_join(){
setSelect();
}
//////////////////////////////////////////////////////////////////////////////
// Bedingungen ein-/ausschalten
//---------------------------------------------------------------------------function onCheckBox2(onoff){
showRow[6] = onoff;
visi("ROW7", onoff);
Datei: stat_events.js
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
Datei: stat_events.js
Anhang
Seite: 9 von 12
Seite: 9 von 12
}
//////////////////////////////////////////////////////////////////////////////
if(onoff){
show();
setSelect();
}
else {
// Having-Bedingung ausgeschaltet, dann muss ggf. die nächste ODER-Zeile
// ebenfalls ausgeblendet werden
document.StatistikFormular.CheckBox7.checked = onoff;
onCheckBox7(onoff);
}
}
//////////////////////////////////////////////////////////////////////////////
// andere Aggregatfunktion ausgewählt -> SQL anpassen
//---------------------------------------------------------------------------function onChangeFeld_group(){
setSelect();
}
//////////////////////////////////////////////////////////////////////////////
// Having-Bedingung ein-/ausschalten
//---------------------------------------------------------------------------function onCheckBox6(onoff){
showRow[10] = onoff;
visi("ROW11", onoff);
if(onoff){
show();
setSelect();
}
else {
// Funktionen ausgeschaltet, dann müssen ggf. die Having-Bedingungen
// ebenfalls ausgeblendet werden
document.StatistikFormular.CheckBox6.checked = onoff;
onCheckBox6(onoff);
}
}
//////////////////////////////////////////////////////////////////////////////
// ODER_2 ein-/ausschalten
//---------------------------------------------------------------------------function onCheckBox4(onoff){
showRow[8] = onoff;
show();
setSelect();
}
//////////////////////////////////////////////////////////////////////////////
// Funktionen ein-/ausschalten
//---------------------------------------------------------------------------function onCheckBox5(onoff){
showRow[9] = onoff;
visi("ROW10", onoff);
if(onoff){
show();
setSelect();
}
else {
// ODER_1 ausgeschaltet, dann muss ggf. die nächste ODER-Zeile
// ebenfalls ausgeblendet werden
document.StatistikFormular.CheckBox4.checked = onoff;
onCheckBox4(onoff);
}
// ODER_1 ein-/ausschalten
//---------------------------------------------------------------------------function onCheckBox3(onoff){
showRow[7] = onoff;
visi("ROW8", onoff);
Datei: stat_events.js
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
Datei: stat_events.js
24 von 71
Seite: 10 von 12
// Strings werden mit ' maskiert
if(!isOK && textfeld.value && datatype == "VARCHAR"){
isOK = isString(textfeld);
// wird mit einer Liste (IN / NOT IN) verglichen
if(comparecombo[index][condi].selectedIndex == NOTIN
|| comparecombo[index][condi].selectedIndex == IN){
if(!isOK && textfeld.value && datatype == "INTEGER")
// nur Listen aus Integern werden z.Z. überprüft
isOK = isIntList(textfeld);
}
Seite: 10 von 12
// wenn die Aggragatfunktion COUNT verwendet wird, muss es Integer sein
if(!isOK && textfeld.value && groupcombo[index].selectedIndex == COUNT
&& comparecombo[index][condi].selectedIndex != NICHTS){
isOK = isInt(textfeld);
}
// bei IS [NOT] NULL wird nur das Feld geleert...
if(comparecombo[index][condi].selectedIndex <= NOTNULL){
textfeld.value = '';
isOK = true;
}
// beim SUBQUERY wird nichts überprüft!!!
if(comparecombo[index][condi].selectedIndex == SUBQUERY){
//in diesem Fall sollte der Benutzer schon wissen, was er tut!
isOK = true;
}
else if(feldcombo[index].selectedIndex > STAR){
// es wurde nicht SELECT * gewählt, also Datentyp des Attributs holen
var datatype = inBenutzung[feldcombo[index].selectedIndex].datatype;
// ist alles leer, so ist alles OK
if(null == textfeld.value || textfeld.value.length == 0)
isOK = true;
}
//////////////////////////////////////////////////////////////////////////////
// Having-ODER_2 ein-/ausschalten
//---------------------------------------------------------------------------function onCheckBox8(onoff){
showRow[12] = onoff;
show();
setSelect();
}
//////////////////////////////////////////////////////////////////////////////
// überprüft ein Textfeld, ob der enthaltene Wert zu dem Datentypen des
// Attributs passt und nimmt ggf. Konvertierungen vor
//---------------------------------------------------------------------------function check(textfeld, index, condi) {
var isOK = false;
if(onoff){
show();
setSelect();
}
else {
// Having-ODER_1 ausgeschaltet, dann muss ggf. die nächste ODER-Zeile
// ebenfalls ausgeblendet werden
document.StatistikFormular.CheckBox8.checked = onoff;
onCheckBox8(onoff);
}
// Having-ODER_1 ein-/ausschalten
//---------------------------------------------------------------------------function onCheckBox7(onoff){
showRow[11] = onoff;
visi("ROW12", onoff);
Datei: stat_events.js
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
Datei: stat_events.js
Anhang
Seite: 11 von 12
Seite: 11 von 12
if(isOK)
setSelect();
}
//////////////////////////////////////////////////////////////////////////////
// speichert die aktuelle Anfrage
//---------------------------------------------------------------------------function onClickSave(){
saveCookies();
if(cook_FELD[0].length > 0){
document.StatistikFormular.doWhat.value = "speichern";
document.StatistikFormular.submit();
}
else
alert("Eine leere Abfrage kann nicht gespeichert werden!");
}
//////////////////////////////////////////////////////////////////////////////
// führt die aktuelle Anfrage aus
//---------------------------------------------------------------------------function onClickStart(){
saveCookies();
if(document.StatistikFormular.query.value){
document.StatistikFormular.doWhat.value = "execute";
document.StatistikFormular.submit();
}
else
alert("Sie haben noch keine Abfrage spezifiziert!");
}
//////////////////////////////////////////////////////////////////////////////
// löscht die aktuelle Anfrage (nur die gemachten Einstellungen, aber nicht
// aus der DB) und bereitet den Editor für eine neue Anfrage vor
//----------------------------------------------------------------------------
}
else if(groupcombo[index].selectedIndex == COUNT
&& comparecombo[index][condi].selectedIndex != NICHTS){
// wenn die Aggragatfunktion COUNT verwendet wird, muss es Integer sein
isOK = isInt(textfeld);
}
else if(feldcombo[index].selectedIndex == NICHTS){
// es kann erst eine Bedingung gestellt werden, wenn ein Feld
// ausgewählt wurde
comparecombo[index][condi].selectedIndex = NICHTS;
textfeld.value = '';
alert("Wählen bitte Sie zuerst ein Feld aus,\n"
+ "das diese Bedingung erfüllen soll!");
feldcombo[index].focus();
}
else{
textfeld.value = '';
comparecombo[index][condi].selectedIndex = NICHTS;
isOK = true;
}
// Ganzzahlentest
if(!isOK && textfeld.value && datatype == "INTEGER"){
isOK = isInt(textfeld);
}
// Kommazahlentest
if(!isOK && textfeld.value && datatype == "FLOAT"){
isOK = isFloat(textfeld);
}
// ein Datum, wird in das DB-Format: 'YYYY-MM-DD' konvertiert
if(!isOK && textfeld.value && datatype == "DATE"){
isOK = isValidDate(textfeld);
}
}
Datei: stat_events.js
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
Datei: stat_events.js
Seite: 12 von 12
25 von 71
Datei: stat_events.js
Seite: 12 von 12
749 function onClickNew(){
750
var ok = confirm("ACHTUNG: Alle eingegebenen Daten gehen verloren!");
751
if(ok)
752
neu();
753 }
Datei: stat_events.js
Anhang
Seite: 1 von 2
SQL-Text
'FROM ';
'SELECT * ';
null;
null;
null;
null;
// gibt an, wieviel Spalten angezeigt werden
// wird in fill_feld() gesetzt
// alle anderen werden in setSelect()
// gesetzt
Seite: 1 von 2
// Die implementierten Aggregatfunktionen, mit diesen wird das Array:
// groupcombo[x] gefüllt
var funktionen = new Array(
new myOption("",
"WHERE "),
//0
// Array mit default-Wahrheitswerten, ob die Zeilen angezeigt werden sollen
var showRow = new Array(true,
//Frage
true,
//Tabellen + Hilfetext
false, //Spalten tauschen
true,
//Feld
true,
//anzeige
false, //JOIN
false, //Bedingung
false, //oder
false, //oder
false, //Funktion
false, //Having
false, //oder
false); //oder
// Arrays für die Objekt-Referenzen der Steuerelemente des Formulars
var tabellen
= null;
var vtabellen
= null;
var feldcombo
= null;
var anzeigecheck = null;
var sortcombo
= null;
var aliasnamen
= null;
var groupcombo
= null;
var joincombo
= null;
var wherefelder = null;
var havingfelder = null;
var comparecombo = null;
var inBenutzung = null;
var showFeldUpTo = 1;
// Strings für den
var sql_from
=
var sql_select
=
var sql_where
=
var sql_groupby =
var sql_having
=
var sql_orderby =
// erzeugt nur eine Optionsgruppe, damit die Attribute nach den jeweiligen
// Tabellen gruppiert werden können.
function OptionGroup(label){
var optGroup = document.createElement('optgroup');
optGroup.label = label;
return optGroup;
}
// Diese Javascript-"Klasse" erzeugt die Optionsobjekte für die Attribut// dropdownlisten
function myOption(n,v,typ){
this.name
= n;
this.value
= v;
this.table
= ''; // wird erst bei 'fill_feld()' gesetzt!!!
this.datatype = typ;
}
//////////////////////////////////////////////////////////////////////////////
// File: stat_globals.js
Version: $Revision: 1.2 $
// Autor: Hilmar Falkenberg
$Date: 2004/10/05 08:39:33 $
//
// Beschreibung: In dieser Datei sind alle Gloabalen Variablen zusammenge// fasst, damit man einen bessereb Überblick hat.
//============================================================================
Datei: stat_globals.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: stat_globals.js
26 von 71
myOption("Durchschnitt ",
myOption("gruppieren ",
myOption("Maximum ",
myOption("Minimum ",
myOption("Summe ",
myOption("Anzahl ",
//00
//01
//02
//03
//04
//05
//06
//07
//08
//09
//10
//11
//12
Seite: 2 von 2
"#FFFF00";
"#00FF00";
"#FFFF80";
"#D9FFD9";
"#FFFF00";
"#FF0000";
"#FFFFFF";
// Farbwerte zum hervorheben der besonderen
// Zellen, falls andere Farben gewünscht
// sind, diese hier ändern!
Seite: 2 von 2
//globale Variablen für den COOKIE-Aufbau...
var cook_TABLE = ''; // bekommt die Indizes der ausgewählten Tabellen
var cook_FELD = new Array('','','','','','','','','','');
var cook_CHECK = ''; // true-false, je nachdem, ob die Funktionen eingeschlatet
// sind oder nicht
var cook_FRAGE = ''; // naja, eben die Frage (s. ganz oben auf der HTML-Seite)m
// Hintergrundfarben
var COLOR_JOIN
=
var COLOR_GROUPBY
=
var COLOR_FUNKTION =
var COLOR_ANZEIGEN =
var COLOR_BEDINGUNG =
var COLOR_SUBQUERY =
var COLOR_NICHTS
=
//eigentlich würden sich hierfür Konstanten eignen, aber der InternetExplorer
//gibt Fehlermeldungen bei dieser Syntax:
//const NICHTS
= 0;
//Der meckert dann jedesmal, das 1. Zeichen in der nachfolgenden Zeile an!?!
var NICHTS
= 0; // Konstanten zum vergleichen, welcher Wert gewählt
var ISNULL
= 1; // wurde (s. Array compare oben)
var NOTNULL = 2;
var LITTLE
= 3;
var LEQUAL
= 4;
var EQUAL
= 5;
var GEQUAL
= 6;
var GREATER = 7;
var NOTEQUAL = 8;
var LIKE
= 9;
var IN
= 10;
var NOTIN
= 11;
var SUBQUERY = 12;
var STAR
= 1;
// für SELECT *
var WHERE
= 0;
// die Indizes der Aggregatfunktionen
var AVG
= 1;
var GROUPBY = 2;
var MAX
= 3;
var MIN
= 4;
var SUM
= 5;
var COUNT
= 6;
""),
" IS NULL"),
" IS NOT NULL"),
" < "),
" <= "),
" = "),
" >= "),
" > "),
" <> "),
" LIKE "),
" IN "),
" NOT IN "),
" ")
mit diesen wird das Array:
"AVG("),
//1
"GROUP BY "), //2
"MAX("),
//3
"MIN("),
//4
"SUM("),
//5
"COUNT(")
//6
// Liste der Vergleichsoperatoren,
// comparecombo[x] gefüllt
var compare = new Array(
new myOption("",
new myOption("Ist NULL",
new myOption("Nicht NULL",
new myOption("<",
new myOption("<=",
new myOption("=",
new myOption(">=",
new myOption(">",
new myOption("!=",
new myOption("Wie",
new myOption("in",
new myOption("nicht in",
new myOption("SUBQUERY",
);
);
new
new
new
new
new
new
Datei: stat_globals.js
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
Datei: stat_globals.js
Anhang
Seite: 1 von 5
Seite: 1 von 5
//////////////////////////////////////////////////////////////////////////////
// globales Array mit den Namen der verfügbaren Feldern für jede Tabelle
// zu: new myOption("Beschriftung", "VALUE-Attribut", "Datatype")
// siehe stat_globals.js
// WICHTIG: die Tabellen müssen die gleiche Reihenfolge im Array haben, wie
// sie in der HTML-Seite in der Auswahlliste stehen!!!
//---------------------------------------------------------------------------var felder = new Array(
///////////////////////////////////////////////////////////////////////////
// Tabelle: anerkennungen
// Kürzel: a
new Array(
new myOption("Datum",
"a.datum",
"DATE"),
new myOption("Kommentar",
"a.kommentar",
"VARCHAR"),
new myOption("Leistpunkte",
"a.leistpunkte",
"FLOAT"),
new myOption("Leistung",
"a.leistung",
"VARCHAR"),
new myOption("Matrikel_nr",
"a.matrikel_nr",
"VARCHAR"),
new myOption("Note",
"a.note",
"FLOAT"),
new myOption("Verantwortlich", "a.verantwortlich", "VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: angestr_abschluss
// Kürzel: aa
/***********************************************************************************
// Auswahlmöglichkeiten in der 'statistik.html', in dieser Reihenfolge der
// Tabellen, sollten auch die Array's in der 'felder' (s.u.) Variablen sein.
//---------------------------------------------------------------------------<option value="anerkennungen a"
label="Anerkennungen"
>Ane
<option value="angestr_abschluss aa"
label="Angestr-Abschluss"
>Ang
<option value="diplom d"
label="Diplom"
>Dip
<option value="diplom_pruefungen dp"
label="Diplom-Prüfungen"
>Dip
<option value="diplomarbeiten da"
label="Diplomarbeiten"
>Dip
<option value="fachgebiet f"
label="Fachgebiet"
>Fac
<option value="gruppen g"
label="Gruppen"
>Gru
<option value="industriepraktika i"
label="Industriepraktika"
>Ind
<option value="industriepraktika_ing ii"
label="Industriepraktika (Ing)"
>Ind
<option value="lehrpersonal lp"
label="Lehrpersonal"
>Leh
<option value="lehrstuhl ls"
label="Lehrstuhl"
>Leh
<option value="pruefungsfaecher pf"
label="Prüfungsfächer" >Pr&
<option value="scheine sch"
label="Scheine"
>Sch
<option value="scheintypen scht"
label="Scheintypen"
>Sch
<option value="studienarbeiten sa"
label="Studienarbeiten"
>Stu
<option value="studienfaecher sf"
label="Studienfächer"
>Stu
<option value="studierende s"
label="Studierende"
>Stu
<option value="unterbrechungen u"
label="Unterbrechungen"
>Unt
<option value="veranst_teilnehmer vt"
label="Veranst-Teilnehmer"
>Ver
<option value="veranstaltungen v"
label="Veranstaltungen"
>Ver
<option value="veranstaltungen_fachgebiet vf" label="Veranstaltungen-Fachgebiet">Ver
<option value="veranstaltungstypen vtyp"
label="Veranstaltungstypen"
>Ver
<option value="vordiplom vd"
label="Vordiplom"
>Vor
<option value="vordiplom_pruefungen vdp"
label="Vordiplom-Prüfungen" >Vor
<option value="wird_gehalten_von w"
label="Wird gehalten von"
>Wir
<option value="zertifikat_pruefungen z"
label="Zertifikat-Prüfungen" >Zer
************************************************************************************
//////////////////////////////////////////////////////////////////////////////
// File: stat_schema.js
Version: $Revision: 1.2 $
// Autor: Hilmar Falkenberg
$Date: 2004/10/05 08:48:17 $
//
// Beschreibung: Hier ist sozusagen das Datenbankschema nachgebildet. Die
// Tabellen sind ja schon in der HTML-Seite direkt enthalten, aber die
// Attribute mit angezeigtem Namen, DB-Namen und Datentyp sind hier in einem
// mehrdimensionalem Array gespeichert. Aus diesem werden die Werte, dann in
// fill_feld() in die Dropdownlisten dynamisch, je nachdem welche Tabellen
// ausgewählt wurden, gefüllt. Zum erzeugen dieser Datei, kann das SQL-Script
// javascript.sql verwendet werden, es müssen dann aber noch kleinere
// Anpassungen von Hand erfolgen!
//============================================================================
Datei: stat_schema.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: stat_schema.js
27 von 71
Seite: 2 von 5
Seite: 2 von 5
new Array(
new myOption("Angestr_abschluss_nr", "aa.angestr_abschluss_nr", "INTEGER"),
new myOption("Bezeichnung",
"aa.bezeichnung",
"VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: diplom
// Kürzel: d
new Array(
new myOption("Anmeldedatum",
"d.anmeldedatum",
"DATE")
new myOption("Bemerkung",
"d.bemerkung",
"VARCHA
new myOption("Datum_erstellung_zeugnis", "d.datum_erstellung_zeugnis", "DATE")
new myOption("Datum_letzte_pruefung",
"d.datum_letzte_pruefung",
"DATE")
new myOption("Gesamtnote",
"d.gesamtnote",
"FLOAT"
new myOption("Kommentar",
"d.kommentar",
"VARCHA
new myOption("Matrikel_nr",
"d.matrikel_nr",
"VARCHA
new myOption("Nbestanden_ja_nein",
"d.nbestanden_ja_nein",
"VARCHA
///////////////////////////////////////////////////////////////////////////
// Tabelle: diplom_pruefungen
// Kürzel: dp
new Array(
new myOption("Datum",
"dp.datum",
"DATE"),
new myOption("Fach_nr",
"dp.fach_nr",
"INTEGER"),
new myOption("Kommentar",
"dp.kommentar",
"VARCHAR"),
new myOption("1. Prüfer",
"dp.lehrpersonal_nr_1",
"INTEGER"),
new myOption("2. Prüfer",
"dp.lehrpersonal_nr_2",
"INTEGER"),
new myOption("Matrikel_nr",
"dp.matrikel_nr",
"VARCHAR"),
new myOption("Note",
"dp.note",
"FLOAT"),
new myOption("Wiederholung_ja_nein", "dp.wiederholung_ja_nein", "VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: diplomarbeiten
// Kürzel: da
new Array(
new myOption("Abgabedatum",
"da.abgabedatum",
"DATE"),
new myOption("Anmeldedatum",
"da.anmeldedatum",
"DATE"),
new myOption("Betreuer",
"da.betreuer",
"VARCHAR")
new myOption("Gutachter_1",
"da.gutachter_1",
"INTEGER")
new myOption("Gutachter_2",
"da.gutachter_2",
"INTEGER")
new myOption("Kommentar",
"da.kommentar",
"VARCHAR")
new myOption("Lehrstuhl_nr",
"da.lehrstuhl_nr",
"INTEGER")
new myOption("Matrikel_nr",
"da.matrikel_nr",
"VARCHAR")
new myOption("Note",
"da.note",
"FLOAT"),
new myOption("Thema",
"da.thema",
"VARCHAR")
new myOption("Zurueckgegeben_ja_nein", "da.zurueckgegeben_ja_nein", "VARCHAR")
///////////////////////////////////////////////////////////////////////////
// Tabelle: fachgebiet
// Kürzel: f
new Array(
new myOption("Bezeichnung",
"f.bezeichnung",
"VARCHAR"),
new myOption("Fachgebiet_nr", "f.fachgebiet_nr", "INTEGER")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: gruppen
// Kürzel: g
new Array(
new myOption("Anzahl_akt",
"g.anzahl_akt",
"INTEGER"),
new myOption("Anzahl_max",
"g.anzahl_max",
"INTEGER"),
new myOption("Bemerkung",
"g.bemerkung",
"VARCHAR"),
new myOption("Gruppe_nr",
"g.gruppe_nr",
"INTEGER"),
new myOption("Leiter",
"g.leiter",
"VARCHAR"),
new myOption("Semester",
"g.semester",
"VARCHAR"),
new myOption("Veranstaltung_nr", "g.veranstaltung_nr", "VARCHAR"),
new myOption("Zeit",
"g.zeit",
"DATE")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: industriepraktika
// Kürzel: i
new Array(
new myOption("Anerkannt_ja_nein", "i.anerkannt_ja_nein", "VARCHAR"),
new myOption("Datum",
"i.datum",
"DATE"),
new myOption("Dauer",
"i.dauer",
"INTEGER"),
new myOption("Kommentar",
"i.kommentar",
"VARCHAR"),
Datei: stat_schema.js
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Datei: stat_schema.js
Anhang
Seite: 3 von 5
Seite: 3 von 5
new myOption("Matrikel_nr",
"i.matrikel_nr",
"VARCHAR"),
new myOption("Name_des_betriebes", "i.name_des_betriebes", "VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: industriepraktika_ing
// Kürzel: ii
new Array(
new myOption("Datum_erstellt",
"ii.datum_erstellt",
"DATE"),
new myOption("Dauer_elek_gp",
"ii.dauer_elek_gp",
"INTEGER"),
new myOption("Dauer_fachpraxis", "ii.dauer_fachpraxis", "INTEGER"),
new myOption("Dauer_mech_gp",
"ii.dauer_mech_gp",
"INTEGER"),
new myOption("Matrikel_nr",
"ii.matrikel_nr",
"VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: lehrpersonal
// Kürzel: lp
new Array(
new myOption("Fakultaet",
"lp.fakultaet",
"VARCHAR"),
new myOption("Institut_ja_nein", "lp.institut_ja_nein", "VARCHAR"),
new myOption("Lehrpersonal_nr", "lp.lehrpersonal_nr", "INTEGER"),
new myOption("Lehrstuhl_nr",
"lp.lehrstuhl_nr",
"INTEGER"),
new myOption("Name",
"lp.name",
"VARCHAR"),
new myOption("Titel",
"lp.titel",
"VARCHAR"),
new myOption("Vorname",
"lp.vorname",
"VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: lehrstuhl
// Kürzel: ls
new Array(
new myOption("Bezeichnung", "ls.bezeichnung",
"VARCHAR"),
new myOption("Lehrstuhl_nr", "ls.lehrstuhl_nr",
"INTEGER")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: pruefungsfaecher
// Kürzel: pf
new Array(
new myOption("Bezeichnung", "pf.bezeichnung", "VARCHAR"),
new myOption("Fach_nr",
"pf.fach_nr",
"INTEGER"),
new myOption("Kommentar",
"pf.kommentar",
"VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: scheine
// Kürzel: sch
new Array(
new myOption("Datum",
"sch.datum",
"DATE"),
new myOption("Kommentar",
"sch.kommentar",
"VARCHAR"),
new myOption("Matrikel_nr",
"sch.matrikel_nr",
"VARCHAR"),
new myOption("Note",
"sch.note",
"FLOAT"),
new myOption("Note_ja_nein",
"sch.note_ja_nein",
"VARCHAR"),
new myOption("ScheintypNr",
"sch.scheintyp_nr",
"INTEGER"),
new myOption("Semester",
"sch.semester",
"VARCHAR"),
new myOption("Stundenzahl",
"sch.stundenzahl",
"FLOAT"),
new myOption("Text_zeile_1",
"sch.text_zeile_1",
"VARCHAR"),
new myOption("Text_zeile_2",
"sch.text_zeile_2",
"VARCHAR"),
new myOption("Thema",
"sch.thema",
"VARCHAR"),
new myOption("VeranstaltungNr", "sch.veranstaltung_nr",
"VARCHAR"),
new myOption("Wiederholung",
"sch.wiederholung",
"INTEGER"),
new myOption("Zuordnung",
"sch.zuordnung",
"VARCHAR"),
new myOption("Zurueckgetreten", "sch.zurueckgetreten_ja_nein", "VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: scheintypen
// Kürzel: scht
new Array(
new myOption("bezeichnung", "scht.bezeichnung", "VARCHAR"),
new myOption("scheintyp_nr", "scht.scheintyp_nr", "INTEGER")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: studienarbeiten
// Kürzel: sa
new Array(
new myOption("Beurteilung",
"sa.beurteilung",
"VARCHAR"),
new myOption("Datum",
"sa.datum",
"DATE"),
new myOption("Kommentar",
"sa.kommentar",
"VARCHAR"),
new myOption("Lehrpersonal_nr", "sa.lehrpersonal_nr", "INTEGER"),
Datei: stat_schema.js
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
Datei: stat_schema.js
28 von 71
Seite: 4 von 5
Seite: 4 von 5
new myOption("Matrikel_nr",
"sa.matrikel_nr",
"VARCHAR"),
new myOption("Thema",
"sa.thema",
"VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: studienfaecher
// Kürzel: sf
new Array(
new myOption("Bezeichnung",
"sf.bezeichnung",
"VARCHAR"),
new myOption("Studienfach_nr", "sf.studienfach_nr", "INTEGER")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: studienform
// Kürzel: sfo
new Array(
new myOption("bezeichnung",
"sfo.bezeichnung",
"VARCHAR"),
new myOption("studienform_nr", "sfo.studienform_nr", "VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: studierende
// Kürzel: s
new Array(
new myOption("Abschlussnote",
"s.abschlussnote",
"FLOAT"),
new myOption("Angestr_abschluss_nr",
"s.angestr_abschluss_nr",
"INTEGER"),
new myOption("Email_institut",
"s.email_institut",
"VARCHAR"),
new myOption("Email_privat",
"s.email_privat",
"VARCHAR"),
new myOption("Exmatrikuliert_ja_nein", "s.exmatrikuliert_ja_nein", "VARCHAR"),
new myOption("Fachsemester",
"s.fachsemester",
"INTEGER"),
new myOption("Geburtsdatum",
"s.geburtsdatum",
"DATE"),
new myOption("Geprueft_ja_nein",
"s.geprueft_ja_nein",
"VARCHAR"),
new myOption("Geschlecht",
"s.geschlecht",
"VARCHAR"),
new myOption("Hauptfach_nr",
"s.hauptfach_nr",
"INTEGER"),
new myOption("Kommentar",
"s.kommentar",
"VARCHAR"),
new myOption("Matrikel_nr",
"s.matrikel_nr",
"VARCHAR"),
new myOption("Name",
"s.name",
"VARCHAR"),
new myOption("Nebenfach_nr_1",
"s.nebenfach_nr_1",
"INTEGER"),
new myOption("Nebenfach_nr_2",
"s.nebenfach_nr_2",
"INTEGER"),
new myOption("Ort",
"s.ort",
"VARCHAR"),
new myOption("Plz",
"s.plz",
"VARCHAR"),
new myOption("Strasse",
"s.strasse",
"VARCHAR"),
new myOption("Studienabschluss",
"s.studienabschluss",
"DATE"),
new myOption("Studienbeginn",
"s.studienbeginn",
"DATE"),
new myOption("StudienformNr",
"s.studienform_nr",
"VARCHAR"),
new myOption("Telefon_1",
"s.telefon_1",
"VARCHAR"),
new myOption("Telefon_2",
"s.telefon_2",
"VARCHAR"),
new myOption("Vorname",
"s.vorname",
"VARCHAR"),
new myOption("Zuletzt_bearbeitet",
"s.zuletzt_bearbeitet",
"DATE")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: unterbrechungen
// Kürzel: u
new Array(
new myOption("Beginn",
"u.beginn",
"DATE"),
new myOption("Ende",
"u.ende",
"DATE"),
new myOption("Grund",
"u.grund",
"VARCHAR"),
new myOption("Matrikel_nr", "u.matrikel_nr", "VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: veranst_teilnehmer
// Kürzel: vt
new Array(
new myOption("Gruppe_nr",
"vt.gruppe_nr",
"INTEGER"),
new myOption("Matrikel_nr",
"vt.matrikel_nr",
"VARCHAR"),
new myOption("Semester",
"vt.semester",
"VARCHAR"),
new myOption("Veranstaltung_nr", "vt.veranstaltung_nr", "INTEGER")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: veranstaltungen
// Kürzel: v
new Array(
new myOption("Bezeichnung",
"v.bezeichnung",
"VARCHAR"),
new myOption("Ects_schein",
"v.ects_schein",
"FLOAT"),
new myOption("Ects_univis",
"v.ects_univis",
"FLOAT"),
new myOption("Kommentar",
"v.kommentar",
"VARCHAR"),
new myOption("Semester",
"v.semester",
"VARCHAR"),
Datei: stat_schema.js
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
Datei: stat_schema.js
Anhang
Seite: 5 von 5
Seite: 5 von 5
new myOption("Stundenzahl",
"v.stundenzahl",
"FLOAT"),
new myOption("Teilnehmerzahl_beginn", "v.teilnehmerzahl_beginn", "INTEGER"),
new myOption("Teilnehmerzahl_ende",
"v.teilnehmerzahl_ende",
"INTEGER"),
new myOption("Veranstaltung_nr",
"v.veranstaltung_nr",
"VARCHAR"),
new myOption("Vtyp_nr",
"v.vtyp_nr",
"INTEGER")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: veranstaltungen_fachgebiet
// Kürzel: vf
new Array(
new myOption("Fachgebiet_nr",
"vf.fachgebiet_nr",
"INTEGER"),
new myOption("Lfd_nr",
"vf.lfd_nr",
"INTEGER"),
new myOption("Semester",
"vf.semester",
"VARCHAR"),
new myOption("Veranstaltung_nr", "vf.veranstaltung_nr", "VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: veranstaltungstypen
// Kürzel: vtyp
new Array(
new myOption("Veranstaltungstyp", "vtyp.veranstaltungstyp", "VARCHAR"),
new myOption("Vtyp_nr",
"vtyp.vtyp_nr",
"INTEGER")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: vordiplom
// Kürzel: vd
new Array(
new myOption("Anmeldedatum",
"vd.anmeldedatum",
"DATE"),
new myOption("Bemerkung",
"vd.bemerkung",
"VARCHAR"),
new myOption("Datum_letzte_pruefung", "vd.datum_letzte_pruefung", "DATE"),
new myOption("Gesamtnote",
"vd.gesamtnote",
"FLOAT"),
new myOption("Kommentar",
"vd.kommentar",
"VARCHAR"),
new myOption("Matrikel_nr",
"vd.matrikel_nr",
"VARCHAR"),
new myOption("Nbestanden_ja_nein",
"vd.nbestanden_ja_nein",
"VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: vordiplom_pruefungen
// Kürzel: vdp
new Array(
new myOption("Datum",
"vdp.datum",
"DATE"),
new myOption("Fach_nr",
"vdp.fach_nr",
"INTEGER"),
new myOption("Klausur_ja_nein",
"vdp.klausur_ja_nein",
"VARCHAR"),
new myOption("Kommentar",
"vdp.kommentar",
"VARCHAR"),
new myOption("1. Prüfer",
"vdp.lehrpersonal_nr_1",
"INTEGER"),
new myOption("2. Prüfer",
"vdp.lehrpersonal_nr_2",
"INTEGER"),
new myOption("Matrikel_nr",
"vdp.matrikel_nr",
"VARCHAR"),
new myOption("Note",
"vdp.note",
"FLOAT"),
new myOption("Wiederholung_ja_nein", "vdp.wiederholung_ja_nein", "VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: wird_gehalten_von
// Kürzel: w
new Array(
new myOption("Lehrpersonal_nr", "w.lehrpersonal_nr", "INTEGER"),
new myOption("Semester",
"w.semester",
"VARCHAR"),
new myOption("Veranstaltung_nr", "w.veranstaltung_nr", "VARCHAR")),
///////////////////////////////////////////////////////////////////////////
// Tabelle: zertifikat_pruefungen
// Kürzel: z
new Array(
new myOption("Datum_zeugnis",
"z.datum_zeugnis",
"DATE"),
new myOption("Matrikel_nr",
"z.matrikel_nr",
"VARCHAR"),
new myOption("Pruefungsfach_1", "z.pruefungsfach_1", "INTEGER"),
new myOption("Pruefungsfach_2", "z.pruefungsfach_2", "INTEGER"))
Datei: stat_schema.js
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331 );
Datei: stat_schema.js
29 von 71
Seite: 1 von 1
/* Hintergrundfarbe für readonly-Elemente */
.disabled
{ background-color:#D2D2D2; }
/* Defaultlayout für anfangs nicht sichtbare Elemente */
.nonvisible { visibility:hidden; }
Seite: 1 von 1
/* ///////////////////////////////////////////////////////////////////////////
// File: statistik.css
Version: $Revision: 1.6 $
// Autor: Hilmar Falkenberg
$Date: 2004/10/05 15:47:43 $
//
// Beschreibung: Cascaded Style Sheet für den Anfrageneditor
//========================================================================= */
Datei: statistik.css
1
2
3
4
5
6
7
8
9
10
11
Datei: statistik.css
Anhang
Seite: 1 von 1
Seite: 1 von 1
<td align="right"><a href="javascript:window.close();">Fenster
schließen</a></td>
</tr>
</table>
</body>
</html>
<tr>
<td><a href="javascript:history.back();">zurück</a></td>
<p>Beachten Sie bitte, das gerade beim Benutzen der
<em>Funktionen</em> neue Spaltenüberschriften sinnvoll sind.
Z.B. sollten Sie dann ruhig <em>Summe von X</em> eingeben, um
deutlich zu machen, das es sich um einen berechneten Wert
handelt.</p>
</td>
</tr>
<p>Wenn Sie sich <em>* (alle)</em> Felder ausgeben lassen,
können Sie ebenfalls keine Spaltenüberschrift eingeben!</p>
<tr>
<td colspan="2">
<p>Mit der Spaltenüberschrift, legen Sie eben genau diese für
die Ergebnisliste fest.<br />
Sie können nur für Felder die auch ausgegeben werden eine
Spaltenüberschrift angeben.</p>
<td align="right"><a href="index.html">Hilfe Inhalt</a></td>
</tr>
<body>
<table width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: Spaltenüberschrift</h3>
</td>
<title>HILFE: Spaltenüberschrift</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/alias.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:58 $
==
== Beschreibung: Hilfeseite zu dem Texteingabefeld Spaltenüberschrift
========================================================================== -->
Datei: alias.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Datei: alias.html
30 von 71
Seite: 1 von 1
Seite: 1 von 1
<td align="right"><a href="javascript:window.close();">Fenster
schließen</a></td>
</tr>
</table>
</body>
</html>
<tr>
<td><a href="javascript:history.back();">zurück</a></td>
<p>Dies können Sie dazu verwenden, wenn dieses Feld nur
bestimmte Kriterien erfüllen soll, d.h. einschränkende Wirkung
auf das Ergebnis hat, aber nicht ausgegeben werden soll.<br />
</p>
</td>
</tr>
<tr>
<td colspan="2">
<p>Wenn Sie eine Statistik erstellen, haben Sie immer eine
Ausgabe. Dazu müssen Sie ein Häkchen an dem Feld, das Sie
ausgeben möchten, setzen. Ansonsten wird dieses Feld in der
Ausgabe nicht berücksichtigt.<br />
</p>
<td align="right"><a href="index.html">Hilfe Inhalt</a></td>
</tr>
<body>
<table width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: anzeigen</h3>
</td>
<title>HILFE: anzeigen</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/anzeigen.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:58 $
==
== Beschreibung: Hilfeseite zu den Checkboxen zur Anzeige
========================================================================== -->
Datei: anzeigen.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
Datei: anzeigen.html
Anhang
Seite: 1 von 2
Seite: 1 von 2
<li>
<p><strong>Wie</strong><br />
<em>Wie</em> eignet sich ganz hervorragend zur
Volltextsuche. D.h. Sie können bei einem Textfeld, den
Operator <em>Wie</em> auswählen und dann auf einzelnen
Teile in dem Text prüfen. Z.B. suchen Sie nach
<li>
<p><strong><</strong> / <strong><=</strong> /
<strong>=</strong> / <strong>>=</strong> /
<strong>></strong> / <strong>!=</strong><br />
Dies sind die üblichen Vergleichsoperatoren, wie Sie
sie aus der Schule kennen. Dabei bedeutet
<strong>!=</strong> ungleich.</p>
</li>
<ul>
<li>
<p><strong>Ist NULL</strong> / <strong>Nicht
NULL</strong><br />
Wenn Sie dies auswählen, wird überprüft, ob das Feld in
der Datenbank leer ist, d.h. den besonderen Wert NULL
enthält bzw. einfach keine Daten. Eine leere
Zeichenkette, also z.B. eine Menge von Leezeichen, ist
<em>ungleich</em> NULL!!!</p>
</li>
<p><strong>Die Vergleichsoperatoren</strong></p>
<tr>
<td colspan="2">
<p>Um die Bedingung nutzen zu können muss auch der
entsprechende Haken gesetzt sein!<br />
Wenn Sie nur bestimmte Datensätze haben wollen, können Sie
noch Bedingungen angeben, die die Datensätze erfüllen müssen,
um in die Ergebnisliste aufgenommen zu werden.<br />
Eine Bedingung bezieht sich immer auf das ausgewählte Feld in
dieser Spalte.<br />
Sie können keine Bedingung an das Feld '<em>*
(alle)</em>' stellen.</p>
<td align="right"><a href="index.html">Hilfe Inhalt</a></td>
</tr>
<body>
<table width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: Bedingung (oder)</h3>
</td>
<title>HILFE: Bedingung (oder)</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/Bedingung.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:57 $
==
== Beschreibung: Hilfeseite zu den Bedingungen
========================================================================== -->
Datei: Bedingung.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: Bedingung.html
Seite: 2 von 2
31 von 71
Datei: Bedingung.html
Seite: 2 von 2
69
<em>Matrikel_Nr Wie '555%'</em>, dann werden nur
70
die Studenten mit den Matrikelnummern 555000-555999 in
71
die Ergebnisliste mit aufgenommen. Oder wenn Sie nach
72
<em>Name Wie 'M_ller'</em> suchen, erhalten Sie
73
alle mit den Namen: Müller, Möller, Miller, jedoch
74
keinen Mueller!!!<br />
75
Also das %(Prozentzeichen) steht für 0 oder beliebig
76
viele Buchstaben und der _(Unterstrich) für genau
77
einen.</p>
78
</li>
79
80
<li>
81
<p><strong>in</strong> / <strong>nicht in</strong><br />
82
Hier haben Sie die Möglichkeit eine ganze Liste von
83
Werten einzugeben. D.h. der Wert des ausgewählten Feldes
84
muss entweder <em>in</em> der Liste vorhanden sein, oder
85
eben <em>nicht in</em> der Liste sein.<br />
86
Die Liste muss immer geklammert sein, also z.B.<br />
87
<u>(1.1, 2, 3.3, 4)</u> als eine Liste von
88
(Komma)Zahlen<br />
89
<u>('Anton', 'Berta',
90
'Claus')</u> als Textliste<br />
91
<u>('2001-12-24', '2002-12-23')</u> als
92
Datumsliste<br />
93
Die einzelnen Listeneinträge müssen je nach
94
Felddatentyp formatiert sein (s.u.) und sie müssen mit
95
einem Komma von einander abgetrennt sein.</p>
96
</li>
97
98
<li>
99
<p><strong>SUBQUERY</strong><br />
100
Dies ist wohl die aller mächtigste Möglichkeit eine
101
Ergebnisliste einzuschränken. Alles was Sie hier
102
eintragen, wird <strong>ohne weitere
103
Überprüfung</strong> in die WHERE-Clause des
104
SQL-Statements mit aufgenommen!!! Sie haben hier alle
105
Möglichkeiten, die Ihnen die Datenbank zur Verfügung
106
stellt. D.h. Sie können hier z.B. Unterabfragen
107
(SUBQUERY's), oder Ausdrücke mit ANY, ALL, [NOT]
108
EXISTS, etc. erstellen.<br />
109
Orientieren Sie sich bitte an dem vorgegebenen SQL.</p>
110
</li>
111
</ul>
112
<br /><br />
113
114
<p><strong>Datentypen</strong><br />
115
Je nachdem, was Sie für ein Feld ausgewählt haben, handelt es
116
sich um einen bestimmten Datentyp (<em>ganze Zahlen,
117
Kommazahlen, Text, Datum</em>).<br />
118
Dabei ist zu beachten, das Text immer in einfachen
119
Anführungszeichen stehen muss und ggf. vorhandene
120
Anführungszeichen durch zwei Anführungszeichen ersetzt
121
werden.<br />
122
Datumwerte können Sie auf unterschiedliche Weisen eingeben.
123
Ein Datum sollte, sofern es ein gültiges ist, automatisch in
124
die richtige Form umgewandelt werden.</p>
125
</td>
126
</tr>
127
128
<tr>
129
<td><a href="javascript:history.back();">zurück</a></td>
130
131
<td align="right"><a href="javascript:window.close();">Fenster
132
schließen</a></td>
133
</tr>
134
</table>
135
</body>
136 </html>
Datei: Bedingung.html
Anhang
Seite: 1 von 1
Seite: 1 von 1
<td align="right"><a href="javascript:window.close();">Fenster
schließen</a></td>
</tr>
</table>
</body>
</html>
<tr>
<td><a href="javascript:history.back();">zurück</a></td>
<p>Besondere Bedeutung hat noch der Eintrag '<em>*
(alle)</em>'. Wenn Sie diesen wählen und sich auch
ausgeben lassen, d.h. <em>anzeigen</em> angewählt haben, so
werden alle Felder von allen ausgewählten Tabellen
ausgegeben!</p>
</td>
</tr>
<p>Wenn Sie ein Feld gar nicht mehr benötigen, können Sie
einfach den ersten (leeren) Eintrag auswählen, dann wird das
Feld aus der Statistik entfernt.</p>
<tr>
<td colspan="2">
<p>In diesen Auswahllisten finden Sie gruppiert nach den
Tabellen, die Sie ausgewählt haben und in alphabetischer
Reihenfolge die Ihnen zur Verfügung stehenden Felder.<br />
Wählen Sie zuerst immer ein Feld aus, bevor Sie es
<em>anzeigen</em> oder <em>sortieren</em> oder
<em>Bedingungen</em> spezifizieren wollen.<br />
</p>
<td align="right"><a href="index.html">Hilfe Inhalt</a></td>
</tr>
<body>
<table width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: Feld</h3>
</td>
<title>HILFE: Feld</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/Felder.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:58 $
==
== Beschreibung: Hilfeseite zu den Auswahllisten der FELDER / Attributen
========================================================================== -->
Datei: Felder.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
Datei: Felder.html
32 von 71
Seite: 1 von 1
Seite: 1 von 1
<td align="right"><a href="javascript:window.close();">Fenster
schließen</a></td>
</tr>
</table>
</body>
</html>
<tr>
<td><a href="javascript:history.back();">zurück</a></td>
<p>Bitte vergessen Sie nicht die Statistik zu speichern!!!</p>
</td>
</tr>
<tr>
<td colspan="2">
<p>In dem Texteingabefeld 'Frage' sollten Sie
unbedingt einen eindeutigen Namen für diese Statistik
vergeben.<br />
Diese Statistik können Sie dann später in der <em>Liste der
gespeicherten Statistiken</em> unter genau diesem Namen /
Frage wiederfinden.<br />
Sie dürfen hier auch sämtliche bekannten Sonderzeichen
verwenden!<br />
</p>
<td align="right"><a href="index.html">Hilfe Inhalt</a></td>
</tr>
<body>
<table width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: Frage</h3>
</td>
<title>HILFE: Frage</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/Frage.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:58 $
==
== Beschreibung: Hilfeseite zum Eingabefeld: FRAGE
========================================================================== -->
Datei: Frage.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
Datei: Frage.html
Anhang
Seite: 1 von 2
<p>Bildet die Summe über Zahlenfelder</p>
<li>
<strong>Summe</strong><br />
<p>/ <strong>Minimum</strong><br />
Sind beide auf alle Felder anwendbar (auch auf
Textfelder!)</p>
</li>
<li>
<strong>Maximum</strong>
Seite: 1 von 2
<p>Stellt keine Funktion im eigentlichen Sinne dar,
sondern alle Felder, die angezeigt werden, aber auf die
keine Funktion angewendet wird, werden automatisch
<em>gruppiert</em>. D.h. z.B. können Sie die Anzahl der
Matrikelnummern bestimmen, und nach den Nebenfächern
<em>gruppieren</em>, dann wissen Sie wieviele Studenten
sich auf die verschiedenen Nebenfächer verteilen.</p>
</li>
<li>
<strong>gruppieren</strong><br />
<p>ist berechenbar für Datum und Zahlenfelder</p>
</li>
<ul>
<li>
<strong>Durchschnitt</strong><br />
<tr>
<td colspan="2">
<p>Mit diesen sogenannten <u>Aggregatfunktionen</u> ist es
Ihnen möglich, z.B. eine Durchschnittsnote über alle Scheine
einer<br />
Person zu bestimmen. Folgende Funktionen stehen zur
Verfügung:<br />
</p>
<td align="right"><a href="index.html">Hilfe Inhalt</a></td>
</tr>
<body>
<table width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: Funktion</h3>
</td>
<title>HILFE: Funktion</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/Funktionen.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:58 $
==
== Beschreibung: Hilfeseite zu den FUNKTIONEN
========================================================================== -->
Datei: Funktionen.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: Funktionen.html
Seite: 2 von 2
33 von 71
Datei: Funktionen.html
Seite: 2 von 2
69
</li>
70
71
<li>
72
<strong>Anzahl</strong><br />
73
74
<p>Zählt die <em>Anzahl</em> unterschiedlicher Werte.
75
Gibt immer eine ganze Zahl zurück.</p>
76
</li>
77
</ul>
78
</td>
79
</tr>
80
81
<tr>
82
<td><a href="javascript:history.back();">zurück</a></td>
83
84
<td align="right"><a href="javascript:window.close();">Fenster
85
schließen</a></td>
86
</tr>
87
</table>
88
</body>
89 </html>
Datei: Funktionen.html
Anhang
Seite: 1 von 1
Seite: 1 von 1
<td align="right"><a href="javascript:window.close();">Fenster
schließen</a></td>
</tr>
</table>
</body>
</html>
<tr>
<td><a href="javascript:history.back();">zurück</a></td>
<p>Eine Hilfe zu den Vergleichsoperatoren und weiteren
Datentypen finden Sie bei "<a
href="Bedingung.html">Bedingung</a>".</p>
</td>
</tr>
<tr>
<td colspan="2">
<p>Hiermit können Sie die Ergebnisliste der Funktionen noch
weiter einschränken. Z.B. wenn Sie nur die Nebenfächer haben
wollen, die von mehr als 10 Studenten belegt sind, dann wählen
Sie die <u>Matrikelnummer</u> und <u>Nebenfachnummer</u> aus,
bilden die <u>Anzahl</u> über die <u>Matrikelnummer</u>,
<u>gruppieren</u> nach den <u>Nebenfächern</u> und geben als
<u>Bedingung</u> für die <u>Anzahl der Matrikelnummern</u>
einfach <strong>>= 10</strong> ein.<br />
Beachten Sie bitte, das <em>Anzahl</em> immer eine ganze Zahl
zurückgibt und <em>Durchschnitt</em> über Zahlen gebildet eine
Kommazahl zurückgibt.<br />
</p>
<td align="right"><a href="index.html">Hilfe Inhalt</a></td>
</tr>
<body>
<table width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: Bedingung für Gruppe (oder)</h3>
</td>
<title>HILFE: Bedingung für Gruppe</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/GBedingung.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:58 $
==
== Beschreibung: Hilfeseite zu den Bedingungen für eine Gruppe
========================================================================== -->
Datei: GBedingung.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Datei: GBedingung.html
34 von 71
Seite: 1 von 2
Seite: 1 von 2
<p><a href="GBedingung.html">Bedingung für Gruppe</a><br />
<a href="GBedingung.html">- oder</a><br />
</p>
<p><a href="Funktionen.html">Funktion</a><br />
</p>
<p><a href="Bedingung.html">Bedingung</a><br />
<a href="Bedingung.html">- oder</a><br />
</p>
<td>
<p><a href="join.html">verknüpfen mit</a><br />
<a href="Tabelle.html">aus Tabelle</a><br />
</p>
<p><a href="anzeigen.html">anzeigen</a><br />
<a href="sortieren.html">sortieren</a><br />
<a href="alias.html">Spaltenüberschrift</a><br />
</p>
</td>
<p><a href="Felder.html">Feld</a><br />
<a href="Tabelle.html">aus Tabelle</a><br />
</p>
<p><a href="tauschen.html">Spalten tauschen</a><br />
</p>
<tr>
<td valign="top">
<p><a href="Frage.html">Frage</a><br />
</p>
<tr>
<td>
</td>
</tr>
<td align="right"><a href="javascript:window.close();">Fenster
schließen</a></td>
</tr>
<body>
<table border="0" width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: Inhalt</h3>
</td>
<title>HILFE: Inhalt</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/index.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:57 $
==
== Beschreibung: Die Index-Seite für die Hilfe
========================================================================== -->
Datei: index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: index.html
Anhang
Seite: 2 von 2
Datei: index.html
Seite: 2 von 2
69
<p><a href="SQL.html">erzeugter SQL</a><br />
70
</p>
71
</td>
72
</tr>
73
<!--tr><td></td><td valign="bottom" align="right">
74
<a href="javascript:window.close();">Fenster schließen</a></td></tr-->
75
</table>
76
</body>
77 </html>
Datei: index.html
35 von 71
Seite: 1 von 1
Seite: 1 von 1
<td align="right"><a href="javascript:window.close();">Fenster
schließen</a></td>
</tr>
</table>
</body>
</html>
<tr>
<td><a href="javascript:history.back();">zurück</a></td>
<p>Sollten also Ihrer Meinung nach viel zuviele Ergebnisse
geliefert werden, überprüfen Sie auf eine korrekte
Verknüpfung.</p>
</td>
</tr>
<p><strong>WARNUNG:</strong> Wenn Sie mehr als eine Tabelle
auswählen und keine Verknüpfung erstellen, erhalten Sie ggf.
das Kreuzprodukt beider Tabellen!!!</p>
<tr>
<td colspan="2">
<p>Um Verknüpfungen nutzen zu können, müssen Sie auch den
Haken dazu gesetzt haben.<br />
Falls Sie zwei Tabellen ausgewählt haben und diese nun
miteinander in eine Beziehung bringen möchten, z.B. alle
Scheine zu einem Studenten, dann wählen Sie einmal die
'<u>MatrikelNr</u> ' aus der Tabelle
'<u>Studierende</u>' und verknüpfen diese dann mit der
'<u>MatrikelNr</u>' aus der Tabelle
'<u>Scheine</u> '.<br />
Dazu sollten Sie noch den Vergleichsoperator
'<u>=</u>' auswählen.</p>
<td align="right"><a href="index.html">Hilfe Inhalt</a></td>
</tr>
<body>
<table width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: verknüpfen mit</h3>
</td>
<title>HILFE: verknüpfen mit</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/join.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:58 $
==
== Beschreibung: Hilfeseite zum verknüpfen mit JOIN
========================================================================== -->
Datei: join.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
Datei: join.html
Anhang
Seite: 1 von 1
Seite: 1 von 1
<td align="right"><a href="javascript:window.close();">Fenster
schließen</a></td>
</tr>
</table>
</body>
</html>
<tr>
<td><a href="javascript:history.back();">zurück</a></td>
<p>In den Ergebnislisten selbst können Sie nur eine begrenzte
Umsortierung vornehmen. Wenn Sie dort auf die
Spaltenüberschrift eines Feldes klicken, wird das Ergebnis
nach diesem Feld sortiert, aber nur in
<strong>lexikografischer Ordnung</strong>. D.h. das z.B.
Zahlen in der Reihenfolge: 1, 10, 2, 21, 3, 4, etc. sortiert
werden.</p>
</td>
</tr>
<tr>
<td colspan="2">
<p>In dieser Auswahlliste, haben Sie die Möglichkeit (nur wenn
das Feld auch angezeigt wird) eine auf- oder absteigende
Sortierung vorzunehmen. Dabei werden Zahlen und Datum, sowie
Texte in der üblichen Weise sortiert.<br />
</p>
<td align="right"><a href="index.html">Hilfe Inhalt</a></td>
</tr>
<body>
<table width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: sortieren</h3>
</td>
<title>HILFE: sortieren</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/sortieren.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:57 $
==
== Beschreibung: Hilfeseite zur Auswahlliste SORTIEREN
========================================================================== -->
Datei: sortieren.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Datei: sortieren.html
36 von 71
Seite: 1 von 1
Seite: 1 von 1
<td align="right"><a href="javascript:window.close();">Fenster
schließen</a></td>
</tr>
</table>
</body>
</html>
<tr>
<td><a href="javascript:history.back();">zurück</a></td>
<tr>
<td colspan="2">
<p>Dieses Feld dient nur zur Anzeige und Kontrolle für alle
diejenigen, die etwas <a target="new"
href="http://www.sql.org/">SQL (Structured Query Language)</a>
beherrschen.<br />
</p>
</td>
</tr>
<td align="right"><a href="index.html">Hilfe Inhalt</a></td>
</tr>
<body>
<table width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: erzeugter SQL</h3>
</td>
<title>HILFE: erzeugter SQL</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/SQL.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:57 $
==
== Beschreibung: Hilfeseite zu erzeugter SQL
========================================================================== -->
Datei: SQL.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Datei: SQL.html
Anhang
Seite: 1 von 1
Seite: 1 von 1
<td align="right"><a href="javascript:window.close();">Fenster
schließen</a></td>
</tr>
</table>
</body>
</html>
<tr>
<td><a href="javascript:history.back();">zurück</a></td>
<tr>
<td colspan="2">
<p>Je nachdem, welches Feld Sie ausgewählt haben, erscheint
der Name der dazugehörigen Tabelle. Dies dient lediglich zur
Gedächtnisstütze, da manche Feldnamen sich in den
verschiedenen Tabellen wiederholen. Es soll es Ihnen leichter
machen, wenn Sie zwei Tabellen miteinander <em>verknüpfen</em>
wollen.<br />
</p>
</td>
</tr>
<td align="right"><a href="index.html">Hilfe Inhalt</a></td>
</tr>
<body>
<table width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: aus Tabelle</h3>
</td>
<title>HILFE: aus Tabelle</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/Tabelle.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:58 $
==
== Beschreibung: Hilfeseite zu dem grau hinterlegten Feld Tabelle
========================================================================== -->
Datei: Tabelle.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
Datei: Tabelle.html
37 von 71
Seite: 1 von 1
Seite: 1 von 1
<td align="right"><a href="javascript:window.close();">Fenster
schließen</a></td>
</tr>
</table>
</body>
</html>
<tr>
<td><a href="javascript:history.back();">zurück</a></td>
<tr>
<td colspan="2">
<p>Falls Sie mehr als ein Feld ausgewählt haben, können Sie
mit Hilfe der Buttons die Reihenfolge der Felder sehr leicht
verändern.<br />
Die Felder werden in der Ergebnisliste dann in der
Reihenfolge wiedergegeben, in der Sie sie in der Statistik
angegeben haben.<br />
Dabei werden natürlich nur die Felder ausgegeben, bei denen
Sie auch den Haken bei <em>anzeigen</em> gesetzt haben.</p>
</td>
</tr>
<td align="right"><a href="index.html">Hilfe Inhalt</a></td>
</tr>
<body>
<table width="370" align="center" summary="">
<tr>
<td>
<h3>HILFE: Spalten tauschen</h3>
</td>
<title>HILFE: Spalten tauschen</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =========================================================================
== File: help/tauschen.html
Version: $Revision: 1.4 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/05 16:46:59 $
==
== Beschreibung: Hilfeseite zu den SPALTEN-TAUSCHEN-BUTTONS
========================================================================== -->
Datei: tauschen.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Datei: tauschen.html
Anhang
Seite: 1 von 1
Seite: 1 von 1
//////////////////////////////////////////////////////////////////////////////
// löscht die Anfrage mit der STATID == nr == lfd_nr aus der Datenbank
//---------------------------------------------------------------------------function deleteStat(formular, nr){
var ok = confirm("Sind Sie sicher, daß Sie die Statistik Nr." + nr
+ " löschen wollen?");
if(ok){
formular.doWhat.value = "delete";
formular.submit();
return true;
}
else
return false;
}
//////////////////////////////////////////////////////////////////////////////
// führt die Anfrage aus und gibt das Ergebnis als HTML aus (s. Stylesheet:
// stat_antwort.xsl)
//---------------------------------------------------------------------------function executeStat(formular){
formular.doWhat.value = "execute";
formular.submit();
return true;
}
//////////////////////////////////////////////////////////////////////////////
// lädt die Anfrage in den Anfrageneditor zum bearbeiten
//---------------------------------------------------------------------------function editStat(formular){
formular.doWhat.value = "edit";
formular.submit();
return true;
}
//////////////////////////////////////////////////////////////////////////////
// führt die Anfrage aus und gibt das Ergebnis im XML-Format zurück (s.
// DocTypeDefinition: sdbdocument.dtd)
//---------------------------------------------------------------------------function asXML(formular){
formular.doWhat.value = "execute";
formular.form.value = "XML";
formular.submit();
return true;
}
//////////////////////////////////////////////////////////////////////////////
// File: stat_verwalten.js
Version: $Revision: 1.3 $
// Autor: Hilmar Falkenberg
$Date: 2004/10/05 08:57:31 $
//
// Beschreibung: diese Datei wird in dem Stylesheet (stat_gespeicherte.xsl)
// für die Liste der gespeicherten DB-Anfragen benötigt. Es sind die
// Funktionen für die Verwaltung der Anfragen implementiert, d.h. die
// richtigen Aufrufparameter für das Servlet SDBStatistik, werden gesetzt
//============================================================================
Datei: stat_verwalten.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Datei: stat_verwalten.js
38 von 71
Seite: 1 von 3
Seite: 1 von 3
Die Beschreibung der Tabelle
********************************************************************************-->
Beschreibung der ausgeführten Aktionen (update/insert/delete)
********************************************************************************-->
<xsl:template match="executed">
<h3 class="highlighted">
<xsl:apply-templates />
</h3>
</xsl:template>
<!--****************************************************************************
Das HTML-Grundgerüst
********************************************************************************-->
<xsl:template match="sdb">
<html>
<head>
<title> Studierenden Datenbank - gespeicherte Abfragen </title>
<link rel="stylesheet" type="text/css"
href="styles/general_layout.css" />
<script language="JavaScript" src="scripts/stat_verwalten.js"
type="text/javascript">
</script>
</head>
<body>
<table border="0" width="800" align="center">
<tr>
<td colspan="2">
<xsl:call-template name="insertlogo" />
</td>
</tr>
<tr>
<td align="left">
<a href="statistik.html?neu">Eine neue Statistik
erstellen</a>
</td>
<td align="right">
<a href="Statistiken?requery=yes">Liste aktualisieren</a>
</td>
</tr>
<tr>
<td colspan="2">
<h1
style="text-align:center; margin-top:1cm; margin-bottom:1cm;
Liste der zur Verfügung stehenden Abfragen</h1>
</td>
</tr>
<tr>
<td colspan="2">
<xsl:apply-templates select="executed" />
<xsl:apply-templates select="resultset/table" />
<xsl:apply-templates select="resultset/error" />
<xsl:apply-templates select="error" />
</td>
</tr>
</table>
</body>
</html>
</xsl:template>
<!--****************************************************************************
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- $Revision: 1.5 $ $Date: 2004/09/11 19:32:47 $ -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="ISO-8859-1" indent="yes" method="html" />
<xsl:include href="logo.xsl" />
<xsl:param name="order_by_column">0</xsl:param>
<!--****************************************************************************
Datei: stat_gespeicherte.xsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: stat_gespeicherte.xsl
Anhang
Seite: 2 von 3
Datei: stat_gespeicherte.xsl
Seite: 2 von 3
69
<xsl:template match="table">
70
<table border="1" cellpadding="4" cellspacing="0" width="800">
71
<colgroup>
72
<col align="center" width="20" />
73
<col align="center" width="50" />
74
<col align="center" width="200" />
75
<col align="center" width="150" />
76
</colgroup>
77
<thead>
78
<tr class="tabelhead">
79
<th>
80
<a><xsl:attribute
81
name="href">Statistiken?xmlparam=order_by_column:1</xsl:attribu
82
Nr</a>
83
</th>
84
<th>
85
<a><xsl:attribute
86
name="href">Statistiken?xmlparam=order_by_column:2</xsl:attribu
87
erstellt</a>
88
</th>
89
<th>
90
<a><xsl:attribute
91
name="href">Statistiken?xmlparam=order_by_column:3</xsl:attribu
92
Bezeichnung / Frage</a>
93
</th>
94
<th>Aktion</th>
95
</tr>
96
</thead>
97
<tbody>
98
<xsl:apply-templates select="../results/row" >
99
<xsl:sort select="./col[number($order_by_column)]" />
100
</xsl:apply-templates>
101
</tbody>
102
</table>
103
<table border="0" width="800">
104
<tr>
105
<td>
106
<a href="javascript:history.back()">zurück</a>
107
</td>
108
<td align="right">
109
<a href="Statistiken?requery=yes">Liste aktualisieren</a>
110
</td>
111
</tr>
112
</table>
113
</xsl:template>
114
<!--****************************************************************************
115
116 Die einzelnen Zeilen
117 ********************************************************************************-->
118
<xsl:template match="results/row">
119
<tr>
120
<xsl:attribute name="class">
121
<xsl:if test="0=position() mod 2">secondrow</xsl:if>
122
</xsl:attribute>
123
<form method="post" action="Statistiken">
124
<td align="right">
125
<xsl:value-of select="./col[1]" />
126
</td>
127
<td align="center">
128
<xsl:value-of select="./col[2]" />
129
</td>
130
<td>
131
<b>
132
<xsl:value-of select="./col[3]" />
133
</b>
134
</td>
135
<td>
136
<input type="hidden" name="STATID" >
Datei: stat_gespeicherte.xsl
Seite: 3 von 3
39 von 71
Datei: stat_gespeicherte.xsl
Seite: 3 von 3
137
<xsl:attribute name="value">
138
<xsl:value-of select="./col[1]" />
139
</xsl:attribute>
140
</input>
141
<input type="hidden" name="doWhat" value="" />
142
<input type="button" value="ausführen"
143
onClick="executeStat(this.form)" />
144
<xsl:if test="string-length(./col[4]) > 0">
145
<input type="button" value="bearbeiten"
146
onClick="editStat(this.form)" />
147
</xsl:if>
148
<input type="button" value="löschen" >
149
<xsl:attribute name="onClick">deleteStat(this.form,<xsl:value-of s
150
/>)</xsl:attribute>
151
</input>
152
<input type="hidden" name="form" value="" />
153
<input type="button" value="als XML" onClick="asXML(this.form);"
154
/>
155
</td>
156
</form>
157
</tr>
158
</xsl:template>
159 </xsl:stylesheet>
Datei: stat_gespeicherte.xsl
Anhang
Seite: 1 von 2
Seite: 1 von 2
gibt eine Navigationsleite zurück
********************************************************************************-->
<xsl:template name="insertnavigation">
<table width="800" style="background-image:url(images/verlauf.jpg)"
border="0" >
<tr>
<td align="left">
<input type="image" src="images/btn_1.gif"
alt="erster Datensatz" name="nav_1" />
</td>
<td align="left">
<input type="image" src="images/btn_2.gif"
alt="10 Datensätze zurück" name="nav_2" />
</td>
<td align="left">
<input type="image" src="images/btn_3.gif"
alt="vorheriger Datensatz" name="nav_3" />
</td>
<td align="center">
<input type="image" src="images/btn_4.gif"
alt="gehe genau zu Datensatz Nr: "
style="vertical-align:middle" name="nav_4" />
<input name="row" type="text" size="4"
style="vertical-align:middle" maxlength="6">
<xsl:attribute name="value">
<xsl:value-of select="/sdb/resultset/results/row/@num" />
</xsl:attribute>
</input>
<font color="#FFFFFF" face="MONOSPACE">
<b> von <xsl:value-of select="/sdb/resultset/results/@count"
/> <xsl:apply-templates select="row" /> </b>
</font>
</td>
<td align="right">
<input type="image" src="images/btn_5.gif"
alt="nächster Datensatz" name="nav_5" />
</td>
<td align="right" >
<input type="image" src="images/btn_6.gif"
alt="10 Datensätze weiter" name="nav_6" />
</td>
<td align="right">
<input type="image" src="images/btn_7.gif"
alt="letzter Datensatz" name="nav_7" />
</td>
</tr>
</table>
gibt die session zurück
********************************************************************************-->
<xsl:template name="sessionid">
<xsl:if test="string-length(/sdb/session/text())>0">;jsessionid=<xsl:apply-tem
select="/sdb/session/text()"/></xsl:if>
</xsl:template>
<!--****************************************************************************
gibt das Logo zurück
********************************************************************************-->
<xsl:template name="insertlogo">
<img src="images/logo.jpg" alt="Studierenden Datenbank V1" border="0">
</img>
</xsl:template>
<!--****************************************************************************
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- $Revision: 1.11 $ $Date: 2004/08/31 14:27:04 $ -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--****************************************************************************
Datei: logo.xsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: logo.xsl
Seite: 2 von 2
40 von 71
Datei: logo.xsl
Seite: 2 von 2
69
</xsl:template>
70
<!--****************************************************************************
71
72 Darstellung evtl. Fehler
73 ********************************************************************************-->
74
<xsl:template match="error">
75
<table bgcolor="#E9E9E9" border="2" width="800">
76
<xsl:for-each select="error">
77
<tr>
78
<td>
79
<h1 style="letter-spacing:3mm; text-decoration:blink; ">
80
<xsl:number count="error" format="1" level="single" />.
81
FEHLER:</h1>
82
<font style="font-family:monospace; color:red; ">
83
<xsl:value-of select="./text()" />
84
</font>
85
</td>
86
</tr>
87
</xsl:for-each>
88
</table>
89
<a href="javascript:history.back()">zurück</a>
90
</xsl:template>
91 </xsl:stylesheet>
Datei: logo.xsl
Anhang
Seite: 1 von 2
Seite: 1 von 2
Die Beschreibung der Tabelle
********************************************************************************-->
<xsl:template match="resultset/table" >
<table border="4" cellpadding="4" cellspacing="0" rules="rows"
width="800">
<colgroup>
<col align="right" width="10" />
<xsl:for-each select="column">
<col>
<xsl:attribute name="width">
<xsl:value-of select="./@size" />
</xsl:attribute>
Das HTML-Grundgerüst
********************************************************************************-->
<xsl:template match="sdb">
<html>
<head>
<title> Studierenden Datenbank - <xsl:value-of
select="formdata/frage" /></title>
<link rel="stylesheet" type="text/css"
href="styles/general_layout.css" />
</head>
<body>
<table border="0" width="800" align="center">
<tr>
<td colspan="2">
<xsl:call-template name="insertlogo" />
</td>
</tr>
<tr>
<td align="left">
<a href="statistik.html?neu">Eine neue Statistik
erstellen</a>
</td>
<td align="right">
<a href="Statistiken?requery=yes">zu den gespeicherten
Statistiken</a>
</td>
</tr>
<tr>
<td colspan="2">
<h1
style="text-align:center; margin-top:1cm; margin-bottom:1cm;
<xsl:value-of select="formdata/frage" />
</h1>
</td>
</tr>
<tr>
<td colspan="2">
<xsl:apply-templates select="resultset/table" />
<xsl:apply-templates select="resultset/error" />
<xsl:apply-templates select="error" />
</td>
</tr>
</table>
</body>
</html>
</xsl:template>
<!--****************************************************************************
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- $Revision: 1.4 $ $Date: 2004/08/31 14:27:04 $ -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="ISO-8859-1" indent="yes" method="html" />
<xsl:include href="logo.xsl" />
<xsl:param name="order_by_column"></xsl:param>
<!--****************************************************************************
Datei: stat_antwort.xsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: stat_antwort.xsl
Seite: 2 von 2
41 von 71
Datei: stat_antwort.xsl
Seite: 2 von 2
69
</col>
70
</xsl:for-each>
71
</colgroup>
72
<tr class="tabelhead">
73
<th align="right">#</th>
74
<xsl:for-each select="column">
75
<th>
76
<a>
77
<xsl:attribute name="href">Statistiken?doWhat=execute&xmlpa
78
select="position()" /></xsl:attribute>
79
<xsl:value-of select="./@name" />
80
</a>
81
</th>
82
</xsl:for-each>
83
</tr>
84
<xsl:apply-templates select="../results/row" >
85
<xsl:sort select="./col[number($order_by_column)]" />
86
</xsl:apply-templates>
87
</table>
88
<table width="800">
89
<tr>
90
<td>
91
<a href="javascript:history.back()">zurück</a>
92
</td>
93
<td align="right">
94
<a><xsl:attribute
95
name="href">javascript:self.print()</xsl:attribute>drucken</a>
96
</td>
97
</tr>
98
</table>
99
</xsl:template>
100
<!--****************************************************************************
101
102 Die Beschreibung der Tabelle
103 ********************************************************************************-->
104
<xsl:template match="row">
105
<tr>
106
<xsl:attribute name="class">
107
<xsl:if test="0=position() mod 2">secondrow</xsl:if>
108
</xsl:attribute>
109
<td align="right">
110
<font color="#C0C0C0">
111
<xsl:number count="row" format="1" level="multiple" />
112
</font>
113
</td>
114
<xsl:for-each select="col">
115
<td>
116
<xsl:value-of select="./text()" />
117
</td>
118
</xsl:for-each>
119
</tr>
120
</xsl:template>
121 </xsl:stylesheet>
Datei: stat_antwort.xsl
Anhang
Seite: 1 von 2
/>
/>
/>
/>
Seite: 1 von 2
<td>
<p style="text-align: right">2004-10-01 <a
href="mailto:[email protected]">Hilmar Falkenberg</a>
<a href="http://validator.w3.org/check?uri=referer"><img
style="border:0;width:88px;height:31px"
src="http://www.w3.org/Icons/valid-xhtml10"
alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
</td>
</tr>
</table>
</body>
<tr>
<p>1. Anweisung: <textarea name="sql" cols="90" rows="7"></textarea><br
2. Anweisung: <textarea name="sql" cols="90" rows="7"></textarea><br
3. Anweisung: <textarea name="sql" cols="90" rows="7"></textarea><br
4. Anweisung: <textarea name="sql" cols="90" rows="7"></textarea><br
Alle Anweisungen zu einer Transaktion zusammenfassen und
<input type="submit" value="ausführen" /></p>
</form>
</td>
</tr>
<tr align="center">
<td>
<form method="post" name="admin" action="Execute">
<!-- Hier könnte noch ein entsprechender Stylesheet angegeben werden, der
die Ergebnisse bzw. Fehlermeldungen anzeigt. Dann sollte allerdings
auch der Parameter form=xml auskommentiert werden! -->
<input type="hidden" name="form" value="XML" /> <input
type="hidden" name="stylesheet" value="" /> <input
type="hidden" name="requery" value="yes" />
<!-- ***************************************************************** -->
<tr align="center">
<td>
<h3>Administratoren Seite für beliebige SQL-Anweisungen an die
SDB</h3>
</td>
</tr>
<body>
<table width="800" align="center"
summary="Tabelle dient nur fürs Layout">
<tr>
<td><img src="images/logo.jpg" alt="Studierenden Datenbank"
border="0" /> </td>
</tr>
<title>Administratoren Seite für beliebige SQL-Anweisungen an die
SDB</title>
</head>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1" />
<meta name="author" content="Hilmar Falkenberg" />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- =======================================================================
== File: administrator.html
Version: $Revision: 1.3 $
== Autor: Hilmar Falkenberg
$Date: 2004/10/04 19:45:13 $
==
== Beschreibung: Mit dieser Seite können bis zu vier SQL-Anweisungen in
== einer Transaktion an die Studierendendatebank gesendet werden.
======================================================================== -->
Datei: administrator.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: administrator.html
42 von 71
Datei: administrator.html
69 </html>
Datei: administrator.html
Anhang
Seite: 2 von 2
Seite: 2 von 2
Seite: 1 von 1
/*Layout für den Tabellenkopf /
*
.tabelhead
{ background-color:#
00
C
C0
C; }
/*Layout für jede zweite e
Zile /
*
.secondrow
{ background-color:#
D9FFD9; }
/*Layout für die INSERT, P
D
UATE, DELETE Meldungen /
*
.highlighted { color:#
FF0000; background-color:#
FFFF00; }
Seite: 1 von 1
/*///////////////////////////////////////////////////////////////////////////
// File: general_layout.css
Version: $Revision: 1.2 $
// Autor: Hilmar Falkenberg
$Date: 2004/10/05 15:44:38 $
//
// Beschreibung: a
Cscaded Style Sheet für die Anzeige der Ergebnislisten
//========================================================================= /
*
Datei: general_layout.css
1
2
3
4
5
6
7
8
9
10
11
12
13
Datei: general_layout.css
43 von 71
Seite: 1 von 1
\g
\q
select 'new myOption("'
+ trim(feld)
+ '","'
+ trim(tabelle)
+ '.'
+ trim(feld)
+ '","'
+ trim(typ)
+ '"),'
from stat_felder
order by tabelle, feld
;
Seite: 1 von 1
-- dieser View soll die Tabellen darstellen, die die Benutzer zur auswahl haben
-- create view stat_tabellen (name, owner) as
-- select table_name, table_owner from iitables
-- where system_use = 'U'
-- and table_name not in ('interne_nummern','super_user','tab_status','nutzer')
-- and table_name not like 'user%'
-- and table_name not like 'stud%'
-- and table_name not like 'stat%'
-- and table_owner not in ('pra03','tomcat')
--;
--- hier werden alle Felder zusammengefasst, die später zur Verfügung stehen sollen
-- create view stat_felder (tabelle, feld, typ, laenge, n, u, s, defaultval) as
-select table_name, column_name, column_datatype, column_length, column_nulls,
-column_updateable, column_system_maintained, column_default_val
-from iicolumns
-where table_name in (select name from stat_tabellen);
--- testoutput
select '<option value="'
+ trim(name)
+ '" label="'
+ trim(name)
+ '">'
+ trim(name)
+ '</option>'
from stat_tabellen
order by name
;
Datei: javascript.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Datei: javascript.sql
Anhang
Seite: 1 von 1
-- zugriff auf neue Tabelle erlauben
grant all on table stat_statistiken to public;
commit;
\g
\q
Seite: 1 von 1
insert into stat_statistiken (lfd_nr, datum, frage, query) values (
3,
date('now'),
'Wer sind die jüngsten Studenten?',
'SELECT s.matrikel_nr AS "Matrikel Nr.", s.name, s.vorname, s.geburtsdatum FROM s
);
-- zwei einfache Abfrage einfügen
insert into stat_statistiken (lfd_nr, datum, frage, query) values (
2,
date('now'),
'Wer sind die ältesten Studenten?',
'SELECT s.matrikel_nr AS "Matrikel Nr", s.name, s.vorname, s.geburtsdatum FROM st
);
-- neue Tabelle anlegen
create table stat_statistiken (
lfd_nr integer not null,
datum date,
frage varchar (100),
query varchar (1000) not null,
-- maximal kann es 20 Cookies geben, jeder Cookie kann maximal 20KB haben
-- jedoch werden die Werte der Cookies mit der JavaScriptfunktion escape()
-- noch entsprechend maskiert. Dadurch koennen ggf. auch mehr als 400KB
-- an Daten entstehen. Ich bezweifele allerdings, das jemand jemals eine
-- solch dermassen grosse Abfrage erstellen wird.
cookie long varchar
) with page_size = 4096;
-- alte Tabelle löschen
-- drop table stat_statistiken;
Datei: stat_statistiken.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Datei: stat_statistiken.sql
44 von 71
Datei: sdbdocument.dtd
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!ELEMENT sdb (session?,formdata?,executed?,resultset*,error?)>
3
<!ELEMENT session (#PCDATA)>
4
<!ELEMENT formdata ANY>
5
<!ELEMENT executed (insert|update|delete|drop|create|grant)*>
6
<!ELEMENT insert (#PCDATA)>
7
<!ATTLIST insert count NMTOKEN #REQUIRED>
8
<!ELEMENT update (#PCDATA)>
9
<!ATTLIST update count NMTOKEN #REQUIRED>
10
<!ELEMENT delete (#PCDATA)>
11
<!ATTLIST delete count NMTOKEN #REQUIRED>
12
<!ELEMENT drop (#PCDATA)>
13
<!ELEMENT create (#PCDATA)>
14
<!ELEMENT grant (#PCDATA)>
15
<!ELEMENT resultset (statement?,table,results)>
16
<!ELEMENT statement (#PCDATA)>
17
<!ELEMENT table (column+)>
18
<!ATTLIST table columns NMTOKEN #REQUIRED>
19
<!ELEMENT column EMPTY>
20
<!ATTLIST column
21
from
NMTOKEN #IMPLIED
22
label
NMTOKEN #REQUIRED
23
name
NMTOKEN #REQUIRED
24
size
NMTOKEN #REQUIRED
25
schema
NMTOKEN #IMPLIED
26
type
(date|float|integer|varchar) #REQUIRED
27
writable (false|true) #REQUIRED
28
>
29
<!ELEMENT results (row*)>
30
<!ATTLIST results count NMTOKEN #REQUIRED>
31
<!ELEMENT row (col+)>
32
<!ATTLIST row num NMTOKEN #IMPLIED>
33
<!ELEMENT col (#PCDATA)>
34
<!ELEMENT error (#PCDATA|error)*>
Datei: sdbdocument.dtd
Anhang
Seite: 1 von 1
Seite: 1 von 1
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpSessionBindingEvent;
javax.servlet.http.HttpSessionBindingListener;
javax.xml.parsers.DocumentBuilder;
javax.xml.parsers.DocumentBuilderFactory;
javax.xml.parsers.ParserConfigurationException;
org.apache.xml.serialize.OutputFormat;
org.apache.xml.serialize.XMLSerializer;
org.w3c.dom.DOMException;
org.w3c.dom.Document;
org.w3c.dom.Element;
org.w3c.dom.Node;
import
import
import
import
import
import
import
import
import
import
import
import
Seite: 1 von 10
/**
* Objecthandle <code>execute</code> für das XML-Element: <span
* class="xml"><executed> </span>
*/
/**
* Objecthandle <code>error</code> für das XML-Element: <span
* class="xml"><error> </span>
*/
private Element
error
= null;
Seite: 1 von 10
/**
* Ähnlich wie bei <code>doctype</code> ist dieser String für die Angabe
* eines bestimmten Zeichensatzes gedacht. Defaultwert ist: "ISO-8859-1"
*/
private String
encoding = "ISO-8859-1";
/**
* Dieser String ist für eine geeignete Doctype-Definition gedacht, falls der
* String nicht leer ist, wird diese dann in <code>toString()</code> in das
* XML hineingeschrieben. <br />
* Eine Basis-Doctype-Definition ist <a
* href="../../../web/doctypes/sdbdocument.dtd">sdbdocument.dtd </a>
*/
private String
doctype = null;
/**
* Mit diesem <code>Document</code> werden alle XML-Elemente erzeugt und
* auch gespeichert.
*/
private Document
doc
= null;
/**
* <p>
* Jedes von den verwendeten Servlets <code>SDBSelect, SDBExecute,
* SDBStatistik</code>
* verwendet ein SDBDocument um alle Inhalte dort als XML zu speichern.
* </p>
* <p>
* Das Dokument wird dazu an das <code>HttpSession</code> -Objekt von den
* Servlets gebunden.
* </p>
*
* @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
* @version $Revision: 1.10 $ $Date: 2004/09/23 15:31:21 $
*/
public class SDBDocument implements HttpSessionBindingListener {
java.io.IOException;
java.io.StringWriter;
java.sql.ResultSet;
java.util.Enumeration;
import
import
import
import
package base;
Datei: SDBDocument.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: SDBDocument.java
45 von 71
execute
= null;
Seite: 2 von 10
Seite: 2 von 10
/**
* Fügt das XML-Element <span class="xml"><formdata> </span> in das
* <code>Document</code> ein.
* @param req Das <code>HttpServletRequest</code> aus dem alle Parameter
* für das Servlet ausgelesen werden und in das <span
* class="xml"><formdata> </span> eingefügt werden.
*/
public void addFormdata(HttpServletRequest req) {
Element newFormdata = this.doc.createElement("formdata");
if (this.formdata != null) {
this.root.replaceChild(newFormdata, this.formdata);
this.formdata = newFormdata;
}
else {
this.formdata = newFormdata;
}
}
catch (ParserConfigurationException e) {
e.printStackTrace();
}
Node session = this.doc.createElement("session");
session.appendChild(this.doc.createTextNode(id));
this.root.appendChild(session);
/**
* Im Konstruktor wird mit einer <code>DocumentBuilderFactory</code> ein
* <code>DocumentBuilder</code> erzeugt und damit dann das
* <code>Document</code> doc initialisiert. Das XML-Root-Element <span
* class="xml"><sdb> </span> wird ebenfalls erzeugt. Das <span
* class="xml"><session> </span> Element wird als erstes Child-Element
* an das Root-Element angehängt.
* @param id eine JSESSIONID die in das XML-Element <span
* class="xml"><session> </span> geschrieben wird.
*/
public SDBDocument(String id) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
this.doc = builder.newDocument();
this.root = this.doc.createElement("sdb");
this.doc.appendChild(this.root);
/**
* Objecthandle <code>sets</code>, um auf alle eingefügten
* <code>SDBResultset</code> schnellen Zugriff zu ermöglichen.
*/
private SDBResultset[] sets
= null;
/**
* Objecthandle <code>root</code> für das XML-Root-Element: <span
* class="xml"><sdb> </span>
*/
private Node
root
= null;
/**
* Objecthandle Liste <code>nodes</code> für die XML-Elemente: <span
* class="xml"><resultset> </span>
*/
private Node[]
nodes
= null;
/**
* Objecthandle <code>formdata</code> für das XML-Element: <span
* class="xml"><formdata> </span>
*/
private Element
formdata = null;
private Element
Datei: SDBDocument.java
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Datei: SDBDocument.java
Anhang
Seite: 3 von 10
/**
* Fügt ein XML-Element <span class="xml"><resultset> </span> in das
* <code>Document</code> ein. Falls der String <code>sql</code> nicht
* <code>null</code> ist, wird das XML-Element <span
* class="xml"><statement> </span> in <span
* class="xml"><resultset> </span>eingefügt.
* @param rs Der <code>ResultSet</code> zum einfügen.
* @param sql Der <code>String</code> für das <span
* class="xml"><statement> </span> Element
*/
public void addResultSet(ResultSet rs, String sql) {
// nur der 1. ResultSet muss explizit gesetzt werden
if (this.sets == null)
setResultSet(rs, sql);
else {
int size = this.sets.length;
/**
* Fügt ein XML-Element <span class="xml"><resultset> </span> in das
* <code>Document</code> ein.
* @param rs Der <code>ResultSet</code> zum einfügen.
* @see SDBDocument#addResultSet(ResultSet, String)
*/
public void addResultSet(ResultSet rs) {
addResultSet(rs, null);
}
/**
* Fügt ein XML-Element <span class="xml"><group> </span> in das
* <code>Document</code> ein.
* @param g Die <code>SDBGroup</code> zum einfügen.
*/
public void addGroup(SDBGroup g) {
this.root.appendChild(g.getGroup());
}
/**
* Zum manuellen setzen von dem XML-Element <span
* class="xml"><formdata> </span>
* @param name Der Name des einzufügenden Parameters
* @param value Der Wert des einzufügenden Parameters
* @see SDBDocument#addFormdata(HttpServletRequest)
*/
public void addFormdata(String name, String value) {
if (this.formdata == null) {
this.formdata = this.doc.createElement("formdata");
this.root.appendChild(this.formdata);
}
Element attrib = this.doc.createElement(name);
attrib.appendChild(this.doc.createCDATASection(value));
this.formdata.appendChild(attrib);
}
}
this.root.appendChild(this.formdata);
Seite: 3 von 10
Enumeration enum = req.getParameterNames();
while (enum.hasMoreElements()) {
String parameter = enum.nextElement().toString();
String[] values = req.getParameterValues(parameter);
for (int i = 0; i < values.length; i++) {
Element attrib = this.doc.createElement(parameter);
attrib.appendChild(this.doc.createCDATASection(values[i]));
this.formdata.appendChild(attrib);
}
}
}
Datei: SDBDocument.java
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
Datei: SDBDocument.java
46 von 71
this.root.appendChild(this.nodes[size]);
Seite: 4 von 10
return toString();
Seite: 4 von 10
/**
* Gibt alle Datensätze eines Resultsets zurück
* @param resultset Nummer des Resultsets
* @return String Das <code>Document</code> als String
* @see SDBDocument#toString()
*/
public String getAll(int resultset) {
if (hasResultSets())
refreshResultset(resultset, this.sets[resultset].getAll());
return toString();
}
}
/**
* Gibt alle Datensätze aller Resultsets zurück
* @return String Das gesamte <code>Document</code> als String
* @see SDBDocument#toString()
*/
public String getAll() {
if (hasResultSets())
for (int i = 0; i < this.sets.length; i++)
refreshResultset(i, this.sets[i].getAll());
/**
* Gibt den Datensatz eines Resultsets mit der absoluten Position zurück
* @param resultset Nummer des Resultsets
* @param absolutPosition Datensatznummer als Absolutwert
* @return String Das <code>Document</code> als String
* @see SDBDocument#toString()
*/
public String getAbsolute(int resultset, int absolutPosition) {
if (hasResultSets())
refreshResultset(resultset,
this.sets[resultset].getAbsolute(absolutPosition));
return toString();
}
/**
* gibt die Anzahl der SDBResultsets zurück.
* @return <code>int</code> gibt die Anzahl der <code>SDBResultset</code>
* zurück.
*/
public int countResultSets() {
if (hasResultSets())
return this.sets.length;
return 0;
}
}
}
this.nodes = newnodes;
this.sets = newset;
newset[size] = new SDBResultset(rs, this.doc, sql);
newnodes[size] = newset[size].getFirst();
for (int i = 0; i < size; i++) {
newnodes[i] = this.nodes[i];
newset[i] = this.sets[i];
}
SDBResultset[] newset = new SDBResultset[size + 1];
Node[] newnodes = new Node[size + 1];
Datei: SDBDocument.java
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
Datei: SDBDocument.java
Anhang
Seite: 5 von 10
/**
* Gibt den nächsten Datensatz eines Resultsets zurück
* @param resultset Nummer des Resultsets
* @return String Das <code>Document</code> als String
* @see SDBDocument#toString()
*/
public String getNext(int resultset) {
if (hasResultSets())
Seite: 5 von 10
/**
* Gibt den letzten Datensatz eines Resultsets zurück
* @param resultset Nummer des Resultsets
* @return String Das <code>Document</code> als String
* @see SDBDocument#toString()
*/
public String getLast(int resultset) {
if (hasResultSets())
refreshResultset(resultset, this.sets[resultset].getLast());
return toString();
}
/**
* Gibt den ersten Datensatz eines Resultsets zurück
* @param resultset Nummer des Resultsets
* @return String Das <code>Document</code> als String
* @see SDBDocument#toString()
*/
public String getFirst(int resultset) {
if (hasResultSets())
refreshResultset(resultset, this.sets[resultset].getFirst());
return toString();
}
/**
* gibt den Encoding-Type zurück
* @return <code>this.encoding</code>
*/
public String getEncoding() {
return this.encoding;
}
/**
* gibt die Doctype-Definition zurück
* @return <code>this.doctype</code>
*/
public String getDoctype() {
return this.doctype;
}
/**
* gibt das <code>Document</code> zurück
* @return das <code>Document</code>
* @see SDBDocument#toString()
*/
public Document getDoc() {
return this.doc;
}
/**
* Gibt die Anzahl der Datensätze eines Resultsets zurück
* @param resultset Nummer des Resultsets
* @return int die Anzahl der Datensätze des Resultsets
*/
public int getCount(int resultset) {
if (hasResultSets())
return this.sets[resultset].getCount();
return 0;
}
Datei: SDBDocument.java
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
Datei: SDBDocument.java
47 von 71
/**
* Ist das gesamte <code>Document</code> OK?
* @return boolean <code>true</code> alle Resultsets sind ok,
* <code>false</code> mindestens einResultset ist nicht ok
*/
public boolean isValid() {
boolean returnValue = true;
/**
* Ist ein Resultset leer?
* @param resultset Nummer des Resultsets
* @return boolean
*/
public boolean isEmpty(int resultset) {
if (hasResultSets())
return this.sets[resultset].isEmpty();
return true;
}
/**
* Wurde mindestens ein Resultset gesetzt?
* @return boolean
*/
public boolean hasResultSets() {
return this.sets != null;
}
Seite: 6 von 10
/**
* Gibt den relativen Datensatz eines Resultsets zurück
* @param resultset Nummer des Resultsets
* @param relativePosition relative Position, um die der Cursor verschoben
* wird.
* @return String Das <code>Document</code> als String
* @see SDBDocument#toString()
*/
public String getRelative(int resultset, int relativePosition) {
if (hasResultSets())
refreshResultset(resultset,
this.sets[resultset].getRelative(relativePosition));
return toString();
}
/**
* Gibt den vorherigen Datensatz eines Resultsets zurück
* @param resultset Nummer des Resultsets
* @return String Das <code>Document</code> als String
* @see SDBDocument#toString()
*/
public String getPrevious(int resultset) {
if (hasResultSets())
refreshResultset(resultset, this.sets[resultset].getPrevious());
return toString();
}
/**
* Gibt die aktuelle Coursorposition eines Resultsets zurück
* @param resultset Nummer des zu untersuchenden Resultsets
* @return int die Position des Cursors
*/
public int getPosition(int resultset) {
if (hasResultSets())
return this.sets[resultset].getPosition();
return -1;
}
}
Seite: 6 von 10
refreshResultset(resultset, this.sets[resultset].getNext());
return toString();
Datei: SDBDocument.java
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
Datei: SDBDocument.java
Anhang
return returnValue;
Seite: 7 von 10
}
Element newError = this.doc.createElement("error");
newError.appendChild(this.doc.createTextNode(err));
this.error.appendChild(newError);
/**
* Setzt eine Fehlermeldung
* @param err Fügt eine Fehlermeldung in das Document ein.
*/
public void setError(String err) {
if (this.error == null) {
this.error = this.doc.createElement("error");
this.root.appendChild(this.error);
}
/**
* Setzt den Encoding-Type
* @param enc zu setzender Encoding-Type
*/
public void setEncoding(String enc) {
this.encoding = enc;
}
/**
* Setzt den Doctype
* @param dtd zu setzender Doctype
*/
public void setDoctype(String dtd) {
this.doctype = dtd;
}
Seite: 7 von 10
/**
* Entfernt das <span class="xml"><error> </span> Element aus dem
* Document
*/
public void removeOldErrors() {
if (this.error != null)
this.root.removeChild(this.error);
this.error = null;
}
/**
* Ersetzt ein <span class="xml"><resultset> </span>
* @param number Nummer des zu ersetzenden <span
* class="xml"><resultset> </span>
* @param newResultset neuer <span class="xml"><resultset> </span>
*/
private void refreshResultset(int number, Node newResultset) {
try {
this.root.replaceChild(newResultset, this.nodes[number]);
this.nodes[number] = newResultset;
}
catch (DOMException e) {
e.printStackTrace();
}
}
}
if (this.sets != null) {
int i = 0;
while (returnValue && i < this.sets.length)
returnValue = this.sets[i].isValid();
}
else
return false;
Datei: SDBDocument.java
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
Datei: SDBDocument.java
48 von 71
Seite: 8 von 10
Seite: 8 von 10
/**
* Gibt das Dokument als String im XML-Format zurück. Dabei hat jedes
* Dokument in etwa folgende Struktur:
* <ul>
* <span class="xml"><sdb> </span>
* <ul>
* <span class="xml"><session> </span> <span class="data">eine
* JSESSIONID </span> <span class="xml"></session> </span> <br />[
* <span class="xml"><formdata> </span> <br />
* <ul>
* [<PARAMETER>Daten dieses Paramters, der an das Servlet geschickt
* wurde</ PARAMETER>]* <br />
* </ul>
* <span class="xml"></formdata> </span>]? <br />[ <span
* class="xml"><resultset> </span> <br />
* <ul>[ <span class="xml"><statement> </span> <span
* class="data">select * from studierende </span> <span
* class="xml"></statement> </span>]? <br />
* <span class="xml"><table columns=" </span> <span
* class="data">Anzahl der Spalten </span> <span class="xml">">
* </span> <br />
* <ul>[ <span class="xml"><column name=" </span> <span
* class="data">Spaltenname </span> <span class="xml">" size="
* </span> <span class="data">Datenfeldgröße </span> <span
* class="xml">" type=" </span> <span class="data">Datentyp </span>
* <span class="xml">" writable=" </span> <span class="data">true |
* false </span> <span class="xml">"/> </span>]+ <br />
* </ul>
* <span class="xml"></table> </span> <br />
}
this.root.appendChild(this.nodes[0]);
this.sets[0] = new SDBResultset(rs, this.doc, sql);
this.nodes[0] = this.sets[0].getFirst();
/**
* Setzt den ersten <code>ResultSet</code> im Document.
* @param rs Erster <code>ResultSet</code> der in das Document eingefügt
* wird.
* @param sql Das SQL-Statement, das den <code>ResultSet</code> erzeugt
* hat.
* @see SDBDocument#addResultSet(ResultSet, String)
*/
private void setResultSet(ResultSet rs, String sql) {
this.sets = new SDBResultset[1];
this.nodes = new Node[1];
}
Element newExecute = this.doc.createElement(exe);
if (count >= 0)
newExecute.setAttribute("count", String.valueOf(count));
newExecute.appendChild(this.doc.createTextNode(msg));
this.execute.appendChild(newExecute);
/**
* Fügt ein <span class="xml"><executed> </span> in das Document ein,
* bzw. ergänzt die bisherigen Meldungen.
* @param exe Was wurde ausgeführt?
* @param msg Welche Meldung soll angezeigt werden?
* @param count Wieviele Datensätze sind betroffen?
*/
public void setExecute(String exe, String msg, int count) {
if (this.execute == null) {
this.execute = this.doc.createElement("executed");
this.root.appendChild(this.execute);
}
Datei: SDBDocument.java
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
Datei: SDBDocument.java
Anhang
Seite: 9 von 10
Seite: 9 von 10
/**
* Gibt einfach alle Resourcen wieder frei.
* @param arg0 wird nicht verwendet, ist vom Interface vorgegeben
* @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.
* arg0)
*/
/**
* Nur für das Interfaces implementiert.
* @param arg0 wird nicht verwendet, ist vom Interface vorgegeben
* @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.ht
* arg0)
*/
public void valueBound(HttpSessionBindingEvent arg0) {
// was soll schon großartiges passieren?
}
}
try {
XMLSerializer serializer = new XMLSerializer(writer, format);
serializer.serialize(this.doc);
return writer.getBuffer().toString();
}
catch (IOException e) {
return e.toString();
}
if (this.doctype != null) {
format.setDoctype(null, this.doctype);
format.setStandalone(false);
}
else
format.setStandalone(true);
if (this.encoding != null)
format.setEncoding(this.encoding);
* <span class="xml"><results count=" </span> <span
* class="data">Anzahl der Datensätze </span> <span
* class="xml">"> </span> <br />
* <ul>[ <span class="xml"><row num=" </span> <span
* class="data">Datensatznummer </span> <span class="xml">"> </span>
* <br />
* <ul>[ <span class="xml"><col> </span> <span
* class="data">irgendwelche Daten </span> <span class="xml"></col>
* </span>]+ <br />
* </ul>
* <span class="xml"></row> </span>]* <br />
* </ul>
* <span class="xml"></results> </span> <br />
* </ul>
* <span class="xml"></resultset> </span>]* <br />[ <span
* class="xml"><error> </span> <br />
* <ul>[ <span class="xml"><error> </span> <span class="data">eine
* Fehlermeldung </span> <span class="xml"></error> </span>]+ <br />
* </ul>
* <span class="xml"></error> </span>]? <br />
* </ul>
* <span class="xml"></sdb> </span> <br />
* </ul>
* vgl. <a href="../../../web/doctypes/sdbdocument.dtd">sdbdocument.dtd </a>
* @see SDBDocument#doctype
* @see java.lang.Object#toString()
*/
public String toString() {
StringWriter writer = new StringWriter();
OutputFormat format = new OutputFormat();
format.setIndenting(true);
Datei: SDBDocument.java
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
Datei: SDBDocument.java
49 von 71
Datei: SDBDocument.java
613
public void valueUnbound(HttpSessionBindingEvent arg0) {
614
this.doc = null;
615
this.doctype = null;
616
this.encoding = null;
617
this.nodes = null;
618
this.root = null;
619
this.sets = null;
620
}
621 }>
Datei: SDBDocument.java
Anhang
Seite: 10 von 10
Seite: 10 von 10
org.w3c.dom.Document;
org.w3c.dom.Element;
org.w3c.dom.Node;
org.w3c.dom.NodeList;
Seite: 1 von 2
/**
* Fügt ein Element in die Liste ein.
* @param element das eingefügt wird
*/
void addElement(Element element) {
this.lastindex++;
if (this.list.length <= this.lastindex)
Seite: 1 von 2
/**
* Standardkonstruktor, legt neues Element[] mit Kapazität =
* INITIANALCAPACITY an.
* @param document zum erzeugen von neuen <code>Element</code> Objekten.
*/
public SDBElementList(Document document) {
this.doc = document;
this.list = new Element[INITIANALCAPACITY];
}
/**
* <code>root</code>, Das Root-Element, an das die anderen Elemente als
* Child angehängt werden.
*/
protected Element
root
= null;
/**
* <code>list</code>, Array für die Zwischenspeicherung der
* <code>Element</code> Objekte
*/
protected Element[] list
= null;
/**
* <code>lastindex</code>, Index für des letzten belegten Feldes im Array
*/
protected int
lastindex
= -1;
/**
* <code></code>, Document zum erzeugen von neuen <code>Element</code>
* Objekten.
*/
protected Document doc
= null;
/**
* Iinitialgröße des verwendeten Array <code>INITIANALCAPACITY</code>.
* Default: 10
*/
public static int
INITIANALCAPACITY = 10;
/**
* <p>
* Dynamische Liste für <code>Element</code> Objekte.
* </p>
* <p>
* Wenn die Kapazität nicht ausreicht, wird die Liste verdoppelt. Da sie nur
* gefüllt wird und nie Elemente entnommen werden, ist keine Funktion zum
* Halbieren vorgesehen. Lediglich, wenn die Liste fertig gefüllt ist, kann mit
* <code>trimArray()</code> die Liste auf eine optimale Größe getrimmt werden.
* </p>
* @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
* @version $Revision: 1.3 $ $Date: 2004/09/16 14:27:24 $
*/
public class SDBElementList {
import
import
import
import
package base;
Datei: SDBElementList.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: SDBElementList.java
50 von 71
this.list[this.lastindex] = element;
this.list = newlist;
Seite: 2 von 2
}
this.list = newlist;
Seite: 2 von 2
/**
* Passt das Array der Liste optimal an, d.h. das Array wird so groß, wie
* Elemente in der Liste gespeichert sind.
*/
protected void trimArray() {
Element[] newlist = new Element[this.lastindex + 1];
for (int i = 0; i < newlist.length; i++)
newlist[i] = this.list[i];
/**
* Ist die Liste leer?
* @return boolean, true->Liste ist leer, false->Liste ist nicht leer
*/
public boolean isEmpty() {
return this.lastindex == -1;
}
/**
* Gibt das Basis-Document zurück
* @return Document, das Basis-Document
*/
public Document getDocument() {
return this.doc;
}
/**
* Gibt die Anzahl der Elemente zurück
* @return int, Anzahl der Elemente
*/
public int getCount() {
return this.lastindex + 1;
}
}
/**
* Vergrößert das Array um <code>size</code>
* @param size größe um die das Array vergrößert wird.
*/
protected void enlargeArray(int size) {
Element[] newlist = new Element[this.list.length + size];
for (int i = 0; i < this.lastindex; i++)
newlist[i] = this.list[i];
/**
* Löscht alle Child-Elements von dem Root-Element
*/
protected void clear() {
NodeList l = this.root.getChildNodes();
int i = 0;
Node n = l.item(i);
while (n != null) {
this.root.removeChild(n);
i++;
n = l.item(i);
}
}
}
enlargeArray(this.lastindex);
Datei: SDBElementList.java
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 }
Datei: SDBElementList.java
Anhang
Seite: 1 von 4
Seite: 1 von 4
/**
* Erzeugt eine neue Gruppe mit dem Root-Element <span
* class="xml"><group> </span>und den Datensätzen des ResultSets zur
* Auswahl
* @param document zum Erzeugen der XML-Elemente
/**
* Erzeugt eine neue Gruppe mit dem Root-Element <span
* class="xml"><group> </span>. <br />
* Standardmäßig ist die Gruppe eine <code>SELECT</code> Gruppe, d.h. eine
* Auswahlliste.
* @param document zum Erzeugen der XML-Elemente
*/
public SDBGroup(Document document) {
super(document);
this.root = this.doc.createElement("group");
setType(SELECT); //wird als Defaultwert genommen
}
/**
* <code>subgroup</code> stellt eine Untergruppe bei gruppierten
* Auswahllisten dar
*/
private Element
subgroup = null;
/**
* <code>multiple</code> gibt an, ob mehrfachauswahlen möglich sind
*/
private boolean
multiple = false;
/**
* <code>grouped</code> gibt an, ob eine <code>SELECT</code> Auswahlliste
* gruppiert sein soll
*/
private boolean
grouped = false;
/**
* <code>CHECKBOX</code> entspricht dem HTML-Tag
*/
public static final int CHECKBOX = 3;
//"checkbox";
/**
* <code>RADIO</code> entspricht dem HTML-Tag
*/
public static final int RADIO
= 2;
//"radio";
/**
* <code>SELECT</code> entspricht dem HTML-Tag
*/
public static final int SELECT
= 1;
//"select"; DEFAULT
/**
* Eine XML-Darstellung von verschiedenen Gruppen:
* <p>
* <code>CHECKBOX</code> 'Häckchen-Kiste' <br />
* <code>RADIO</code> 'Entweder oder' Auswahlpunkte <br />
* <code>SELECT</code> 'aufklappbare Auswahlliste'
* </p>
* @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
* @version $Revision: 1.3 $ $Date: 2004/09/16 14:27:23 $
*/
public class SDBGroup extends SDBElementList {
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.sql.ResultSet;
import java.sql.SQLException;
package base;
Datei: SDBGroup.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: SDBGroup.java
51 von 71
Seite: 2 von 4
/**
* Gibt den Gruppennamen zurück
* @return der Gruppenname
Seite: 2 von 4
/**
* Gibt das vollständige <span class="xml"><group> </span>Element
* zurück
* @return Element das <span class="xml"><group> </span>Element
*/
public Element getGroup() {
return this.root;
}
/**
* Legt fest, für welche Spalten diese Gruppe anwendbar sein soll.
* @param colname Spaltenname zu dem die Gruppe gehört
*/
public void forColumn(String colname) {
Element col = this.doc.createElement("column");
col.setAttribute("name", colname);
this.root.appendChild(col);
}
}
if (isGrouped())
this.subgroup.appendChild(ge.getElement());
else
this.root.appendChild(ge.getElement());
/**
* Fügt eine Auswahloption in die Gruppe bzw. aktuelle Untergruppe ein
* @param ge Auswahloption die eingefügt werden soll
*/
protected void addElement(SDBGroupElement ge) {
super.addElement(ge.getElement());
}
try {
// die einzelnen Auswahlmöglichkeiten eintragen
while (rs.next()) {
String key = rs.getString("KEY");
String val = rs.getString("VAL");
SDBGroupElement element = new SDBGroupElement(this.doc, key, val);
addElement(element);
}
rs.close();
rs.getStatement().close();
}
catch (SQLException e) {
Element err = this.doc.createElement("error");
err.appendChild(this.doc.createTextNode(e.toString()));
addElement(err);
}
// für welche Spalten des zugehörigen Stylesheet bzw. ResultSet soll
// diese Gruppe sein
for (int i = 0; forColumns != null && i < forColumns.length; i++)
forColumn(forColumns[i]);
* @param rs mit zwei Spalten (<code>KEY</code> und <code>VALUE</code>)
* @param name der Gruppe, zum zusammenhalten von Checkboxen und Radiobuttons
* @param forColumns eine Stringliste, in der die Spaltennamen eingetragen
* werden sollen, für die diese Gruppe eine Anwenderunterstützung sein soll.
*/
public SDBGroup(Document document, ResultSet rs, String name,
String[] forColumns) {
this(document);
setName(name);
Datei: SDBGroup.java
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Datei: SDBGroup.java
Anhang
Seite: 3 von 4
/**
/**
* Setzt den Namen einer Gruppe
* @param namestr der neue Gruppenname
*/
public void setName(String namestr) {
this.root.setAttribute("name", namestr);
}
/**
* Schaltet Mehrfachauswahl ein oder aus
* @param multi
*/
public void setMultiple(boolean multi) {
this.multiple = multi;
if (multi)
this.root.setAttribute("multiple", "1");
else
this.root.setAttribute("multiple", "0");
}
Seite: 3 von 4
/**
* Eröffnet eine neue Untergruppe, in die ggf. die nächsten Options-Elemente
* einegefügt werden
* @param group neuer Untergruppenname
*/
public void newSubgroup(String group) {
this.grouped = true;
this.root.setAttribute("grouped", "1");
this.subgroup = this.doc.createElement("subgroup");
this.subgroup.setAttribute("name", group);
this.root.appendChild(this.subgroup);
}
/**
* Gibt an, ob Mehrfachauswahlen erlaubt sind
* @return true->Mehrfachauswahlen sind erlaubt, false->Mehrfachauswahlen
* sind nicht erlaubt
*/
public boolean isMultiple() {
return this.multiple;
}
/**
* Gibt zurück, ob die Gruppe Untergruppen hat oder nicht
* @return true->Gruppe hat Untergruppen, false->Gruppe hat keine
* Untergruppen
*/
public boolean isGrouped() {
return this.grouped;
}
/**
* Gibt den Gruppentyp zurück
* @return Typ der Gruppe
* @see SDBGroup#CHECKBOX
* @see SDBGroup#RADIO
* @see SDBGroup#SELECT
*/
public String getType() {
return this.root.getAttribute("type");
}
*/
public String getName() {
return this.root.getAttribute("name");
}
Datei: SDBGroup.java
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
Datei: SDBGroup.java
52 von 71
}
switch (typ) {
case CHECKBOX:
type = "checkbox";
break;
case RADIO:
type = "radio";
break;
default:
type = "select";
}
this.root.setAttribute("type", type);
* Legt den Typ einer Gruppe fest
* @param typ der zu setzende Typ
* @see SDBGroup#CHECKBOX
* @see SDBGroup#RADIO
* @see SDBGroup#SELECT
*/
public void setType(int typ) {
String type;
Datei: SDBGroup.java
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226 }
Datei: SDBGroup.java
Anhang
Seite: 4 von 4
Seite: 4 von 4
Seite: 1 von 2
this.root.appendChild(k);
this.root.appendChild(v);
/**
* Setzt diese Gruppen-Option als Ausgewählt. <br />
* <span class="xml"><e selected="1"> </span>
*/
/**
* Gibt diese Gruppen-Option zurück
* @return Element die Gruppen-Option
*/
public Element getElement() {
return this.root;
}
}
k.appendChild(this.doc.createTextNode(key.trim()));
v.appendChild(this.doc.createTextNode(val.trim()));
Element k = this.doc.createElement("k");
Element v = this.doc.createElement("v");
Seite: 1 von 2
/**
* <p>
* Standardkonstruktor, erzeugt die vollständige Gruppen-Option:
* </p>
* <p>
* <span class="xml"><e> </span>
* <ul>
* <span class="xml"><k> </span> <span class="data">KEY-Wert </span>
* <span class="xml"></k> </span> <br />
* <span class="xml"><v> </span> <span class="data">VALUE-Wert </span>
* <span class="xml"></v> </span> <br />
* </ul>
* <span class="xml"></e> </span>
* </p>
* @param document zum erzeugen der XML-Elemente
* @param key Wert des Schlüsselelements als String
* @param val Wert des Werteelelements als String
*/
public SDBGroupElement(Document document, String key, String val) {
this.doc = document;
this.root = this.doc.createElement("e");
/**
* <code>root</code> das Root-Element <span class="xml"><e> </span>
*/
protected Element root = null;
/**
* <code>doc</code> zum erzeugen der Key bzw. Value Elemente
*/
protected Document doc = null;
/**
* Stellt eine XML-Gruppen-Option <span class="xml"><e> </span>bestehend
* aus einem Key <span class="xml"><k> </span>und einem Value <span
* class="xml"><v> </span> dar.
* @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
* @version $Revision: 1.3 $ $Date: 2004/09/16 14:27:24 $
*/
public class SDBGroupElement {
import org.w3c.dom.Document;
import org.w3c.dom.Element;
package base;
Datei: SDBGroupElement.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: SDBGroupElement.java
53 von 71
public void setSelected() {
this.root.setAttribute("selected", "1");
}
Datei: SDBGroupElement.java
69
70
71
72 }
Datei: SDBGroupElement.java
Anhang
Seite: 2 von 2
Seite: 2 von 2
Seite: 1 von 2
/**
* Gibt die aktuelle Cursorposition zurück
* @return int, Position des Cursors
Seite: 1 von 2
/**
* Gibt das von der aktuellen Position aus gesehen nächste Element des
* ResultSets zurück
* @return Element nächstes Element des ResultSets
*/
public Element getNext();
/**
* Gibt das letzte Element des ResultSets zurück
* @return Element letztes Element des ResultSets
*/
public Element getLast();
/**
* Gibt das erste Element des ResultSets zurück
* @return Element erstes Element des ResultSets
*/
public Element getFirst();
/**
* Gibt das Element an der aktuellen Position des Cursors im ResultSet zurück
* @return Element, von der aktuellen Position
*/
public Element getCurrentRow();
/**
* Gibt die Anzahl der Datensätze zurück
* @return int die Anzahl der Datensätze
*/
public int getCount();
/**
* Gibt ein Element mit allen Datensätzen zurück
* @return Element mit allen Datensätzen
*/
public Element getAll();
/**
* <p>
* Interface für die zwischengespeicherten Resultsets
* </p>
* <p>
* Da der verwendete JDBC-Treiber von CA Ingres nicht das vorwärts <strong>und
* </strong> rückwärts durchlaufen eines Reslutsets gestattet, müssen diese für
* die Funktionalität einer Navigationsleiste zwischengespeichert werden.
* Klassen die dieses Interface unterstützen sollten dafür ausreichen.
* </p>
* @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
* @version $Revision: 1.3 $ $Date: 2004/09/16 14:27:23 $
*/
public interface SDBResults {
/**
* Gibt das Element an der absoluten Position im ResultSet zurück
* @param absolutPosition des Elements was zurückgegeben wird
* @return Element, das von der absoluten Position
* @throws IndexOutOfBoundsException, falls die angegebene Position
* außerhalb, der Feldgrenzen liegt
*/
public Element getAbsolute(int absolutPosition)
throws IndexOutOfBoundsException;
import org.w3c.dom.Element;
package base;
Datei: SDBResults.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: SDBResults.java
54 von 71
Seite: 2 von 2
/**
* Gibt an, ob der ResultSet leer ist, oder nicht
* @return boolean, true->leer, false->nicht leer
*/
public boolean isEmpty();
Seite: 2 von 2
/**
* Gibt das von der aktuellen Position aus gesehen um die relative Position
* versetzte Element des ResultSets zurück
* @param relativePosition um die der Cursor weiterbewegt wird.
* @return Element, von der relativen Position
*/
public Element getRelative(int relativePosition);
/**
* Gibt das von der aktuellen Position aus gesehen vorherige Element des
* ResultSets zurück
* @return Element vorherige Element des ResultSets
*/
public Element getPrevious();
*/
public int getPosition();
Datei: SDBResults.java
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 }
Datei: SDBResults.java
Anhang
Seite: 1 von 6
/**
Seite: 1 von 6
/**
* Standardkonstruktor, erzeugt ein neues <span class="xml"><resultset>
* </span>Element in dem übergebenen <code>Document</code>
* @param resultset aus dem die Daten gewonnen werden
* @param document das die Elemente erzeugt
* @param sql für das <span class="xml"><statement> </span> Element
* @see SDBResultset#SDBResultset(ResultSet, Document)
*/
public SDBResultset(ResultSet resultset, Document document, String sql) {
init(resultset, document, sql);
}
/**
* Standardkonstruktor, erzeugt ein neues <span class="xml"><resultset>
* </span>Element in dem übergebenen <code>Document</code>
* @param resultset aus dem die Daten gewonnen werden
* @param document das die Elemente erzeugt
* @see SDBResultset#SDBResultset(ResultSet, Document, String)
*/
public SDBResultset(ResultSet resultset, Document document) {
init(resultset, document, null);
}
/**
* <code>valid</code> gibt an, ob der Resultset ok ist
*/
private boolean
valid
= false;
/**
* <code>root</code> das Root-Element <span class="xml"><resultset>
* </span>
*/
private Element
root
= null;
/**
* <code>results</code> speichert den eigentlichen ResultSet
*/
private SDBResultsImpl results
= null;
/**
* <code>doc</code> zum erzeugen weiterer Elemente
*/
private Document
doc
= null;
/**
* <code>currentnode</code> aktuelles Element, welches ggf. ausgetauscht
* wird.
*/
private Element
currentnode = null;
/**
* Stellt ein XML: <span class="xml"><resultset> </span> Element dar.
*
* @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
* @version $Revision: 1.4 $ $Date: 2004/09/16 14:27:24 $
*/
public class SDBResultset implements SDBResults {
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
package base;
Datei: SDBResultset.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: SDBResultset.java
55 von 71
Seite: 2 von 6
Seite: 2 von 6
/**
* Gibt das <span class="xml"><resultset> </span> Element mit genau
* einem Datensatz zurück (dem Datensatz mit der übergebenen Nummer).
* @see base.SDBResults#getAbsolute(int)
}
}
}
catch (SQLException e) {
setError(e.toString());
}
column.setAttribute("writable",
String.valueOf(rsmd.isDefinitelyWritable(i)));
table.appendChild(column);
///////////////////////////////////////////////////////////////////
// Anfangsbuchstaben großschreiben, die DB macht sonst alles klein
///////////////////////////////////////////////////////////////////
String label = rsmd.getColumnLabel(i);
char first = label.charAt(0);
label = label.replaceFirst(String.valueOf(first),
String.valueOf(Character.toUpperCase(first)));
///////////////////////////////////////////////////////////////////
column.setAttribute("label", label);
//Beschreibung der einzelnen Spalten des ResultSets
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
Element column = this.doc.createElement("column");
column.setAttribute("name", rsmd.getColumnName(i));
column.setAttribute("type", rsmd.getColumnTypeName(i));
// Falls die Datenbank bzw. der JDBC-Treiber die folgenden Attribute
// nicht unterstützt, werden sie auch nicht im XML aufgeführt
if (rsmd.getTableName(i) != null
&& rsmd.getTableName(i).trim().length() > 0) {
column.setAttribute("from", rsmd.getTableName(i));
}
if (rsmd.getSchemaName(i) != null
&& rsmd.getSchemaName(i).trim().length() > 0) {
column.setAttribute("schema", rsmd.getSchemaName(i));
}
column.setAttribute("size",
Integer.toString(rsmd.getColumnDisplaySize(i)));
/**
* Fügt eine Tabellenbeschreibung in das <span class="xml"><resultset>
* </span> Element ein.
* @param rs ResultSet, von dem die Metadata für die Tabellenbeschreibung
* abgefragt werden
*/
private void addTable(ResultSet rs) {
try {
ResultSetMetaData rsmd = rs.getMetaData();
Element table = this.doc.createElement("table");
table.setAttribute("columns", Integer.toString(rsmd.getColumnCount()));
this.root.appendChild(table);
* Fügt das <span class="xml"><statement> </span> Element ein, falls
* eine SQL-Anweisung im Konstruktor mitübergeben wurde
* @param statement SQL-Select-Statement bzw. der Text für das <span
* class="xml"><statement> </span> Element
*/
private void addStatement(String statement) {
if (statement != null) {
Element stm = this.doc.createElement("statement");
this.root.appendChild(stm);
stm.appendChild(this.doc.createTextNode(statement));
}
}
Datei: SDBResultset.java
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Datei: SDBResultset.java
Anhang
Seite: 3 von 6
/**
* Gibt die Position des Cursors zurück.
* @see base.SDBResults#getPosition()
Seite: 3 von 6
/**
* Gibt das <span class="xml"><resultset> </span> Element mit genau
* einem Datensatz zurück (dem nächsten Datensatz).
* @see base.SDBResults#getNext()
*/
public Element getNext() {
setResults(this.results.getNext());
return this.root;
}
/**
* Gibt das <span class="xml"><resultset> </span> Element mit genau
* einem Datensatz zurück (dem letzten Datensatz).
* @see base.SDBResults#getLast()
*/
public Element getLast() {
setResults(this.results.getLast());
return this.root;
}
/**
* Gibt das <span class="xml"><resultset> </span> Element mit genau
* einem Datensatz zurück (dem ersten Datensatz).
* @see base.SDBResults#getFirst()
*/
public Element getFirst() {
setResults(this.results.getFirst());
return this.root;
}
/**
* Gibt das <span class="xml"><resultset> </span> Element mit genau
* einem Datensatz zurück (dem aktuellen Datensatz).
* @see base.SDBResults#getCurrentRow()
*/
public Element getCurrentRow() {
setResults(this.results.getCurrentRow());
return this.root;
}
/**
* Gibt die Anzahl der Datensätze zurück.
* @see base.SDBResults#getCount()
*/
public int getCount() {
return this.results.getCount();
}
/**
* Gibt alle Datensätze innerhalb eines <span class="xml"><resultset>
* </span> Elements zurück.
* @see base.SDBResults#getAll()
*/
public Element getAll() {
setResults(this.results.getAll());
return this.root;
}
*/
public Element getAbsolute(int absolutPosition)
throws IndexOutOfBoundsException {
setResults(this.results.getAbsolute(absolutPosition - 1));
return this.root;
}
Datei: SDBResultset.java
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
Datei: SDBResultset.java
56 von 71
Seite: 4 von 6
// solange der Cursor nicht am Ende ist...
while (resultset.next()) {
Seite: 4 von 6
/**
* <p>
* Speichert die Daten eines ResultSets in einer Liste (
* <code>SDBResultsImpl</code>) als XML-Elemente.
* </p>
* <strong>ACHTUNG! Nebeneffekt: </strong> der übergebene ResultSet und sein
* Statement werden geschlossen, da der jetzige JDBC-Treiber sowieso keine
* Operation zulässt, die den Cursor zurücksetzt. Und da hier zum
* zwischenspeichern der Daten der ResultSet einmal ganz durchlaufen wird,
* ist der Cursor dann am Ende.
* @param resultset der ResultSet, dessen Daten als XML-Elemente gespeichert
* werden sollen.
*/
private void initResults(ResultSet resultset) {
// neue ElementList anlegen
this.results = new SDBResultsImpl(this.doc);
if (resultset != null) {
try {
int colCount = resultset.getMetaData().getColumnCount();
}
addStatement(statement);
addTable(resultset);
initResults(resultset);
/**
* Initialisiert das <span class="xml"><resultset> </span>Element, d.h.
* erzeugt das Root-Element <span class="xml"><resultset> </span> und
* fügt die Elemente <span class="xml"><statement> </span> und <span
* class="xml"><table> </span> ein. Das Element <span
* class="xml"><results> </span> mit den eigentlichen Daten wird erst
* mit Aufruf einer der <code>get</code> -Methoden erzeugt.
* @param resultset der Darzustellende ResultSet
* @param document das Document in das der ResultSet gehört
* @param statement ggf. eine SQL-Anweisung, für das <span
* class="xml"><statement> </span>
*/
private void init(ResultSet resultset, Document document, String statement) {
this.doc = document;
this.root = this.doc.createElement("resultset");
/**
* Gibt das <span class="xml"><resultset> </span> Element mit genau
* einem Datensatz zurück. Datensatz mit der relativen Position.
* @see base.SDBResults#getRelative(int)
*/
public Element getRelative(int relativePosition) {
setResults(this.results.getRelative(relativePosition));
return this.root;
}
/**
* Gibt das <span class="xml"><resultset> </span> Element mit genau
* einem Datensatz zurück (dem vorhergehenden Datensatz).
* @see base.SDBResults#getPrevious()
*/
public Element getPrevious() {
setResults(this.results.getPrevious());
return this.root;
}
*/
public int getPosition() {
return this.results.getPosition();
}
Datei: SDBResultset.java
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
Datei: SDBResultset.java
Anhang
}
}
catch (SQLException e) {
setError(e.toString());
this.valid = false;
}
// ACHTUNG: der ResultSet (und sein Statement) werden immer
// geschlossen
resultset.close();
resultset.getStatement().close();
}
this.valid = true;
// damit nicht zuviel Speicher verbraucht wird
this.results.trimArray();
this.currentnode = this.doc.createElement("error");
Seite: 5 von 6
/**
* Erzeugt eine Fehlermeldung in dem <span class="xml"><resultset>
* </span> Element
* @param msg die Meldung für das <span class="xml"><error> </span>
* Element
*/
private void setError(String msg) {
this.valid = false;
if (this.currentnode != null)
this.root.removeChild(this.currentnode);
/**
* Gibt zurück, ob der ResultSet ok ist, d.h. beim auslesen keine
* <code>SQLException</code> aufgetreten sind.
* @return Returns the valid.
*/
public boolean isValid() {
return this.valid;
}
/**
* Gibt zurück, ob der ResultSet leer ist
* @see base.SDBResults#isEmpty()
*/
public boolean isEmpty() {
return this.results.isEmpty();
}
}
Seite: 5 von 6
// füge die einzelnen Spalten in die Zeile ein -- <col></col>
for (int i = 1; i <= colCount; i++) {
// je nachdem, wie die Spalte heißt, wird entweder explizit
// nach einem Date(), Time(), oder Object() gefragt.
// So wird dann ein gutes Datum bzw. Zeitformat bei der Aus// gabe produziert. Siehe auch: SDBRow.addColumn();
//
// Ingres JDBC-Treiber gibt SQL-DATE-Felder immer als
// JAVA-Timestamp zurück!!! Die haben kein schönes Format.
String label = resultset.getMetaData().getColumnLabel(i);
if (label.toUpperCase().indexOf("DATUM") >= 0)
r.addColumn(resultset.getDate(i));
else if (label.toUpperCase().indexOf("ZEIT") >= 0)
r.addColumn(resultset.getTime(i));
else
r.addColumn(resultset.getObject(i));
}
// </row>
this.results.addElement(r);
// ... lege eine neue Zeile an -- <row>
SDBRow r = new SDBRow(this.doc);
Datei: SDBResultset.java
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
Datei: SDBResultset.java
57 von 71
Seite: 6 von 6
}
this.currentnode = res;
this.root.appendChild(res);
Seite: 6 von 6
/**
* Setzt das <span class="xml"><results> </span>Element auf das
* übergebene. D.h. das alte wird ersetzt.
* @param res neues <span class="xml"><results> </span>Element das
* gesetzt werden soll.
*/
private void setResults(Element res) {
if (this.currentnode != null)
this.root.removeChild(this.currentnode);
}
this.currentnode.appendChild(this.doc.createTextNode(msg));
this.root.appendChild(this.currentnode);
Datei: SDBResultset.java
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358 }
Datei: SDBResultset.java
Anhang
Seite: 1 von 3
Seite: 1 von 3
/**
* Gibt das <span class="xml"><results> </span>Element mit allen
* vorhandenen Datensätzen zurück. Löscht dabei alle alten Childelemente.
* @see base.SDBResults#getAll()
*/
}
// Anzahl der Datensätze in dem Attribut "count" von <results> festhalten
this.root.setAttribute("count", String.valueOf(getCount()));
return this.root;
// wenn nicht leer, dann neues <row>-Element einfügen
if (this.lastindex >= 0) {
Element row = this.list[absolutPosition];
row.setAttribute("num", String.valueOf(absolutPosition + 1));
this.root.appendChild(row);
this.position = absolutPosition;
}
/**
* Gibt das <span class="xml"><results> </span>Element zurück. Löscht
* dabei alle Childelemente aus <span class="xml"><results> </span> und
* fügt nur den Datensatz mit der übergebenen Nummer ein.
* @param absolutPosition die entsprechende Datensatznummer
* @see base.SDBResults#getAbsolute(int)
*/
public Element getAbsolute(int absolutPosition)
throws IndexOutOfBoundsException {
clear(); // alte Childelemente löschen
/**
* Fügt ein <span class="xml"><row> </span>Element in die Liste ein.
* @param row Das <span class="xml"><row> </span>Element in Form eines
* <code>SDBRow</code> Objektes, das eingefügt werden soll
* @see SDBElementList#addElement(Element)
*/
protected void addElement(SDBRow row) {
super.addElement(row.getRow());
}
/**
* Standardkonstruktor, erzeugt das Root- <span class="xml"><results>
* </span>-Element und ruft den Parent-Konstruktor auf.
* @param document zum erzeugen der XML-Elemente
* @see SDBElementList#SDBElementList(Document)
*/
public SDBResultsImpl(Document document) {
super(document);
this.root = this.doc.createElement("results");
}
/**
* <code>position</code> des Cursors
*/
private int position = -1;
/**
* Die Liste zum Zwischenspeichern eines ResultSets und gleichzeitig stellt die
* Klasse das <span class="xml"><results> </span>Element dar.
* @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
* @version $Revision: 1.4 $ $Date: 2004/09/16 14:27:24 $
*/
public class SDBResultsImpl extends SDBElementList implements SDBResults {
import org.w3c.dom.Document;
import org.w3c.dom.Element;
package base;
Datei: SDBResultsImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: SDBResultsImpl.java
58 von 71
return this.root;
Seite: 2 von 3
Seite: 2 von 3
/**
* Errechnet die Absolute Position, des Datensatzes und ruft entsprechend
* <code>getAbsolute()</code> auf. Falls aus dem ResultSet hinausgelaufen
* werden würde, d.h. die obere oder untere Grenze überschritten wird. Wird
* entweder der erste oder letzte Datensatz zurückgegeben.
/**
* Das gleiche wie <code>getRelative(-1)</code>
* @see base.SDBResults#getPrevious()
* @see SDBResultsImpl#getRelative(int)
*/
public Element getPrevious() {
return getRelative(-1);
}
/**
* Gibt die Position des Cursors zurück, oder -1 falls der ResultSet leer
* ist.
* @see base.SDBResults#getPosition()
*/
public int getPosition() {
return !isEmpty() ? this.position : -1;
}
/**
* Das gleiche wie <code>getRelative(1)</code>
* @see base.SDBResults#getNext()
* @see SDBResultsImpl#getRelative(int)
*/
public Element getNext() {
return getRelative(1);
}
/**
* Das gleiche wie <code>getAbsolute(lastindex)</code>
* @see base.SDBResults#getLast()
* @see SDBResultsImpl#getAbsolute(int)
*/
public Element getLast() {
return getAbsolute(this.lastindex);
}
/**
* Das gleiche wie <code>getAbsolute(0)</code>
* @see base.SDBResults#getFirst()
* @see SDBResultsImpl#getAbsolute(int)
*/
public Element getFirst() {
return getAbsolute(0);
}
/**
* Das gleiche wie <code>getRelative(0)</code>
* @see base.SDBResults#getCurrentRow()
* @see SDBResultsImpl#getRelative(int)
*/
public Element getCurrentRow() {
return getRelative(0);
}
}
for (int i = 0; i <= this.lastindex; i++)
this.root.appendChild(this.list[i]);
public Element getAll() {
clear();
Datei: SDBResultsImpl.java
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Datei: SDBResultsImpl.java
Anhang
Datei: SDBResultsImpl.java
137
* @see base.SDBResults#getRelative(int)
138
* @see SDBResultsImpl#getAbsolute(int)
139
*/
140
public Element getRelative(int relativePosition) {
141
int absolutPosition = this.position + relativePosition;
142
143
if (!isEmpty()) {
144
if (absolutPosition <= 0)
145
return getFirst();
146
else if (absolutPosition >= this.lastindex)
147
return getLast();
148
else
149
return getAbsolute(absolutPosition);
150
}
151
152
return null;
153
}
154 }F
Datei: SDBResultsImpl.java
Seite: 3 von 3
Seite: 3 von 3
59 von 71
Seite: 1 von 2
Seite: 1 von 2
/**
* Gibt das Root- <span class="xml"><row> </span>-Element zurück
* @return Element das <span class="xml"><row> </span>Element
*/
public Element getRow() {
}
col.appendChild(this.doc.createTextNode(value));
}
this.root.appendChild(col);
// nur Objekte vom Typ Date werden extra-formatiert
// siehe auch SDBResultset.initResults()
if (o instanceof Date) {
value = DateFormat.getDateInstance(DateFormat.MEDIUM,
Locale.GERMANY).format((Date) o);
}
//TODO ggf. hier weitere Typkonvertierungen???
/**
* Fügt ein <span class="xml"><col> </span>Element ein
* @param o das Objekt, welches mit seiner <code>toString()</code> Methode
* als Text eingefügt wird. Handelt es sich dabei um ein <code>Date</code>
* Objekt, dann wird das Dtum noch folgendermaßen umformatiert:
* <code>DateFormat.getDateInstance(DateFormat.MEDIUM,
* Locale.GERMANY).format((Date) o);</code>
*/
public void addColumn(Object o) {
Element col = this.doc.createElement("col");
if (o != null) {
String value = o.toString().trim();
/**
* Standardkonstruktor, erzeugt das Root- <span class="xml"><row>
* </span>-Element
* @param document zum erzeugen der XML-Elemente
*/
public SDBRow(Document document) {
this.doc = document;
this.root = this.doc.createElement("row");
}
/**
* <code>root</code> das <span class="xml"><row> </span>Element
*/
private Element root = null;
/**
* <code>doc</code> zum erzeugen der <span class="xml"><col>
* </span>Elemente
*/
private Document doc = null;
/**
* Stellt ein <span class="xml"><row> </span>Element dar.
* @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
* @version $Revision: 1.4 $ $Date: 2004/09/16 14:27:23 $
*/
public class SDBRow {
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.sql.Date;
import java.text.DateFormat;
import java.util.Locale;
package base;
Datei: SDBRow.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: SDBRow.java
Anhang
return this.root;
Datei: SDBRow.java
69
70
}
71 }D
Datei: SDBRow.java
Seite: 2 von 2
Seite: 2 von 2
60 von 71
javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax.servlet.http.HttpSession;
javax.xml.transform.Source;
javax.xml.transform.Templates;
javax.xml.transform.Transformer;
javax.xml.transform.TransformerFactory;
javax.xml.transform.stream.StreamResult;
import
import
import
import
import
import
import
import
import
import
Seite: 1 von 5
Seite: 1 von 5
/**
* Schließt die Datenbankverbindung, wenn das Servlet 'zerstört' bzw. die
* Webanwendung beendet wird.
* @see javax.servlet.Servlet#destroy()
*/
public void destroy() {
try {
/**
* Fügt eine Gruppe in ein sessiongebundenes Document ein.
* @param g die Gruppe die eingefügt werden soll
* @param s die Session in der sich das Dokument befindet, in das die Gruppe
* eingefügt werden soll.
*/
protected void addGroup(SDBGroup g, HttpSession s) {
getDocument(s).addGroup(g);
}
/**
* Fügt die an das Servlet gesendeten Parameter in das aktuelle Dokument ein.
* @param r das <code>HttpServletRequest</code> Objekt, dessen Parameter
* eingefügt werden sollen.
* @see SDBDocument#addFormdata(HttpServletRequest)
*/
protected void addFormdata(HttpServletRequest r) {
HttpSession s = r.getSession();
getDocument(s).addFormdata(r);
}
/**
* Objekthandel für die Datenbankverbindung
*/
private Connection db_connection;
/**
* Das BASIS-Servlet, von dem alle anderen SDB-Servlets erben sollten!
* Initialisiert den JDBC-Treiber, stellt Datenbankverbindungen her, übernimmt
* das Management für das sesseiongebunden Document, implementert die
* doPost()-Methode als 'Delegate-Mehtod' an doGet(), gibt die Pfadnamen für
* Stylesheets und Doc-Type-Defintions zurück, stellt Methoden zum einfügen der
* empfangenen Parameter und zum erzeugen von <span class="xml"><group>
* </span>Elementen zur Verfügung.
* @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
* @version $Revision: 1.9 $ $Date: 2004/09/16 14:27:23 $
*/
public abstract class SDBServlet extends HttpServlet {
java.io.IOException;
java.io.PrintWriter;
java.sql.Connection;
java.sql.DriverManager;
java.sql.PreparedStatement;
java.sql.ResultSet;
java.sql.SQLException;
java.sql.Statement;
import
import
import
import
import
import
import
import
package base;
Datei: SDBServlet.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: SDBServlet.java
Anhang
Seite: 2 von 5
return this.db_connection;
Seite: 2 von 5
/**
* Holt das SDBDocument aus der übergebenen Session, oder erzeugt ein neues,
* falls noch keins vorhanden ist.
* @param s Session in der nach dem SDBDocument gesucht wird,
* @return SDBDocument das gefundene oder ein neues SDBDocument
*/
protected SDBDocument getDocument(HttpSession s) {
/**
* Gibt den Default-Pfad für XSL-Stylesheets zurück
* @return String Pfad für XSL-Stylesheets
*/
public String getDefaultStylesheet() {
return getServletContext().getRealPath("stylesheets");
}
/**
* Gibt den Default-Pfad für DTD's zurück
* @return String Pfad für DTD's
*/
public String getDefaultDoctype() {
return getServletContext().getRealPath("doctypes");
}
}
/**
* gibt eine neue Datenbankverbindung zurück
* @return die neue Datenbankverbindung
*/
protected Connection getConnection() {
try {
// Verbindung mit Datenbank herstellen
this.db_connection = DriverManager.getConnection("jdbc:edbc://lionis:IJ7/sd
}
catch (SQLException e) {
e.printStackTrace();
}
/**
* Delegatmethod: Eingaben entgegen nehmen und gleich an doGet() weiter
* geben...
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletReque
* javax.servlet.http.HttpServletResponse)
* @see SDBServlet#doGet(HttpServletRequest, HttpServletResponse)
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
doGet(request, response);
}
/**
* Absichtlich Abstrakte Methode, ein SDB-Servlet, was diese Methode nicht
* implementiert, hätte keinen Sinn.
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletReques
* javax.servlet.http.HttpServletResponse)
*/
public abstract void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException;
}
}
catch (SQLException e) {// tja, was soll man da noch machen?
}
super.destroy();
if (this.db_connection != null)
this.db_connection.close();
Datei: SDBServlet.java
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Datei: SDBServlet.java
61 von 71
Seite: 3 von 5
Seite: 3 von 5
/**
* Tranformiert eine XML Source mit einem XSL Template in den
* <code>Printwriter</code>
* @param xmlSource die XML source, die umgewandelt werden soll
* @param xslSource die XSL source, das Template, das zum umwandeln benutzt
* wird
* @param out ein PrintWriter auf den das Ergebnis geschrieben wird
* @see Transformer#transform(javax.xml.transform.Source,
* javax.xml.transform.Result)
*/
public void process(Source xmlSource, Source xslSource, PrintWriter out) {
TransformerFactory tFactory;
tFactory = TransformerFactory.newInstance();
try {
Templates templates = tFactory.newTemplates(xslSource);
Transformer transformer = templates.newTransformer();
transformer.transform(xmlSource, new StreamResult(out));
}
catch (Exception e) {
e.printStackTrace(out);
}
/**
* Überschreibt das SDBDocument in der Session s, mit einem neuen (leeren)
* SDBDocument.
* @param s Session in der das neue SDBDocument gesetzt wird.
* @return SDBDocument, das neu angelegte SDBDocument
*/
protected SDBDocument newDocument(HttpSession s) {
SDBDocument doc = new SDBDocument(s.getId());
s.setAttribute("DOCUMENT", doc);
return doc;
}
/**
* Gibt an, ob in dieser Session schon ein SDBDocument ist, oder nicht
* @param s Session in der nach einem SDBDocument gesucht wird
* @return boolean, true->es ist ein SDBDocument vorhanden, false->kein
* SDBDocument da
*/
protected boolean isDocumentSet(HttpSession s) {
return null != (SDBDocument) s.getAttribute("DOCUMENT");
}
/**
* Initialisiert den Datenbanktreiber "ca.edbc.jdbc.EdbcDriver"
* @see javax.servlet.GenericServlet#init()
* @throws ServletException
*/
public void init() throws ServletException {
try {
// DB-Treiber initialisieren
Class.forName("ca.edbc.jdbc.EdbcDriver");
}
catch (Exception e) {
e.printStackTrace();
}
super.init();
}
}
if (doc == null) {
doc = new SDBDocument(s.getId());
s.setAttribute("DOCUMENT", doc);
}
return doc;
SDBDocument doc = ((SDBDocument) s.getAttribute("DOCUMENT"));
Datei: SDBServlet.java
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
Datei: SDBServlet.java
Anhang
Seite: 4 von 5
Seite: 4 von 5
/**
* Fügt einen ResultSet in dem an die Session gebundenes SDBDocument ein
* @param rs zu setzender ResultSet
* @param s die HttpSession, wo der ResultSet in das Dokument gesetzt werden
* soll.
/**
* Fügt einen ResultSet in dem an die Session gebundenes SDBDocument ein
* @param rs zu setzender ResultSet
* @param s die HttpSession, wo der ResultSet in das Dokument gesetzt werden
* soll.
* @see SDBServlet#setResultSet(ResultSet, HttpSession, String)
*/
protected void setResultSet(ResultSet rs, HttpSession s) {
setResultSet(rs, s, null);
}
}
// das XML transformieren
transformer.transform(xmlSource, new StreamResult(out));
}
catch (Exception e) {
e.printStackTrace(out);
}
if (xmlparam != null)
// gefundene XSL-Parameter setzen
for (int i = 0; i < xmlparam.length; i++) {
String[] param = xmlparam[i].split(":");
if (param != null && param.length == 2)
transformer.setParameter(param[0], param[1]);
else
doc.setError("XML-Param: " + xmlparam[i]);
}
try {
Templates templates = tFactory.newTemplates(xslSource);
Transformer transformer = templates.newTransformer();
/**
* Tranformiert eine XML Source mit einem XSL Template in den
* <code>Printwriter</code>.<br />
* Zusätzlich werden noch die <code>xmlparam</code> Parameter des
* <code>HttpServletRequest</code> an den XSL-Stylesheet weitergeleitet.
* Ein <code>xmlparam</code> sollte dabei folgende Form haben:
* <p>
* xmlparam=Parameter_Name:Parameter_Wert
* </p>
* @param xmlSource die XML source, die umgewandelt werden soll
* @param xslSource die XSL source, das Template, das zum umwandeln benutzt
* wird
* @param out ein PrintWriter auf den das Ergebnis geschrieben wird
* @param r <code>HttpServletRequest</code> das ggf. einen oder mehrere
* Parameter <code>xmlparam</code> enthält, die an den XSL-Stylesheet
* weitergeleitet werden sollen
* @see Transformer#transform(javax.xml.transform.Source,
* javax.xml.transform.Result)
*/
public void process(Source xmlSource, Source xslSource, PrintWriter out,
HttpServletRequest r) {
TransformerFactory tFactory;
tFactory = TransformerFactory.newInstance();
// durchzureichende Parameter holen
String[] xmlparam = r.getParameterValues("xmlparam");
HttpSession s = r.getSession();
SDBDocument doc = getDocument(s);
}
Datei: SDBServlet.java
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
Datei: SDBServlet.java
62 von 71
Seite: 5 von 5
Seite: 5 von 5
/**
* Führt die SQL-Select-Anweisung aus und fügt einen ResultSet in dem an die
* Session gebundenes SDBDocument ein
* @param sqlQuery die SQL-Select-Anweisung, die den ResultSet erzeugen soll
* @param s die HttpSession, wo der ResultSet in das Dokument gesetzt werden
* @throws SQLException bei Datenbankfehlern
* @see SDBServlet#setResultSet(ResultSet, HttpSession, String)
*/
protected void setResultSet(String sqlQuery, HttpSession s)
throws SQLException {
if (sqlQuery != null
&& sqlQuery.trim().toUpperCase().startsWith("SELECT ")) {
Connection con = getConnection();
if (con != null) {
PreparedStatement stm = con.prepareStatement(sqlQuery,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
setResultSet(stm.executeQuery(), s, sqlQuery);
stm.close();
con.close();
}
else
getDocument(s).setError(
"Es konnte keine Datenbankverbindung hergestellt werden!");
}
else {
getDocument(s).setError("kein Query: \n" + sqlQuery);
}
}
* @param sql Text für das <span class="xml"><statment> </span>Element
* @see SDBDocument#addResultSet(ResultSet, String)
*/
protected void setResultSet(ResultSet rs, HttpSession s, String sql) {
getDocument(s).addResultSet(rs, sql);
}
Datei: SDBServlet.java
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308 }
Datei: SDBServlet.java
Anhang
javax.servlet.ServletException;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax.servlet.http.HttpSession;
javax.xml.transform.Source;
javax.xml.transform.stream.StreamSource;
java.io.IOException;
java.io.PrintWriter;
java.io.StringReader;
java.sql.SQLException;
java.util.Enumeration;
Seite: 1 von 7
Seite: 1 von 7
/**
* Dieses Servlet kann mit einer Reihe von Parametern gesteuert werden. Es
* eignet sich lediglich zur Anzeige nicht jedoch zum Ändern von Daten.
* Entsprechend den Anforderungen für Navigationsleisten bietet es die
* Möglichkeit, immer nur einen Datensatz oder aber alle anzuzeigen.
* <h4>Parameterliste zur Steuerung der Servlets</h4>
* <ul>
* <li><strong>Parameter: requery </strong> <br />
* Wird der Parameter "requery" an das Servlet gesendet, wird ein neues
* SDBDocument angelegt. Diese Funktionalität ist notwendig, weil sonst im Laufe
* einer Session immer mehr <span class="xml"><resultset> </span> Elemente
* in dem SDBDocument gespeichert werden würden und daher in den Stylesheets
* nicht ermittelt werden könnte, welcher Resultset wo angezeigt werden soll.
* Aus diesem Grund sollte bei einem Wechsel zwischen zwei verschiedenen
* Eingabemasken immer auch ein "requery" an das Servlet gesendet werden, es sei
* denn, es werden zwei <span class="xml"><resultset> </span>Elemente
* gewünscht. So kann z.B. in einer ersten Eingabemaske ein Student ausgewählt
* und in einer folgenden seine erworbenen Scheine zusätzlich aufgelistet
* werden. Der Wert des Parameters ist ohne Bedeutung, da nur überprüft wird, ob
* er vorhanden ist. Ist das der Fall, wird ein neues SDBDocument angelegt. Ist
* er nicht an das Servlet gesendet worden, wird das SDBDocument von der
* aktuellen Session weiterverwendet.</li>
* <li><strong>Parameter: query </strong> <br />
* An das Servlet können ein oder mehrere "queries" geschickt werden. Jeder
* String, der als "query" an ein Servlet geschickt wird, wird darauf getestet,
* ob er mit SELECT anfängt. In diesem Fall wird versucht, eine
* Datenbankverbindung herzustellen und die Select-Anweisung auszuführen. Wenn
* dies gelingt, wird ein <span class="xml"><resultset> </span>Element in
* das aktuelle SDBDocument eingefügt, anderenfalls werden entsprechende
* Fehlermeldungen ( <span class="xml"><error> </span> Elemente)erzeugt.
* </li>
* <li><strong>Parameter: nav_[1-7] </strong> <br />
* Alle Parameter, die mit nav_ beginnen, werden dahingehend überprüft, ob
* hinter dem Unterstrich eine Ziffer folgt. Die Ziffern haben dabei folgende
* Bedeutungen:
* <ul>
* 1: Der erste Datensatz wird angezeigt. <br />
* 2: Ausgehend von der aktuellen Position wird um zehn Datensätze
* zurückgerückt. <br />
* 3: Ausgehend von der aktuellen Position wird um einen Datensatz
* zurückgerückt. <br />
* 4: Ist zusätzlich der Parameter row vorhanden und eine Zahl zwischen 1 und
* der Anzahl der Datensätze eingetragen, wird zu dem Datensatz mit dieser
* Nummer gesprungen. <br />
* 5: Ausgehend von der aktuellen Position wird um zehn Datensätze vorgerückt.
* <br />
* 6: Ausgehend von der aktuellen Position wird um einen Datensatz vorgerückt.
* <br />
* 7: Der letzte Datensatz wird angezeigt <br />
* </ul>
import base.SDBDocument;
import base.SDBServlet;
import
import
import
import
import
import
import
import
import
import
import
package servlet;
Datei: SDBSelect.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: SDBSelect.java
Seite: 2 von 7
63 von 71
Datei: SDBSelect.java
Seite: 2 von 7
69 * Falls keine Ziffer zwischen 1 und 7 hinter dem Unterstrich steht, werden alle
70 * Datensätze angezeigt.</li>
71 * <li><strong>Parameter: stylesheet </strong> <br />
72 * Mit dem Parameter stylesheet wird dem Servlet mitgeteilt, welchen Stylesheet
73 * es verwenden soll, um aus den XML-Daten des SDBDocuments eine z.B. HMTL-Seite
74 * zu erzeugen.</li>
75 * <li><strong>Parameter: form </strong> <br />
76 * Dieser Parameter soll die Einstellung verschiedener Ausgabeformate
77 * ermöglichen. Zur Zeit werden aber nur zwei Formate unterstützt. Das
78 * Standardformat ist HTML und wird immer verwendet, auch wenn dieser Parameter
79 * nicht gesetzt wird. Wenn <code>form=xml</code> an das Servlet gesendet
80 * wird, wird der XML-String eines SDBDocuments unverändert gelassen. In der
81 * <code>doGet()</code> -Methode läßt sich vor der Datenausgabe leicht jedes
82 * andere Format einstellen. Da die javax.servlet.http-Technologie es nicht
83 * zulässt, allein durch Angabe eines anderen Stylesheets das Ausgabeformat
84 * einzustellen, muss dieses zusätzlich immer mit der Methode
85 * <code>HttpServletResponse.setContentType()</code> gesetzt werden.</li>
86 * <li><strong>Parameter: xmlparam </strong> <br />
87 * Dieser Parameter gestattet es, an einen Stylesheet selbst wiederum Parameter
88 * weiterzugeben. Diese Technik wird zum Beispiel bei den Statistiken verwendet,
89 * um ein schnelles einfaches Umsortieren der Ergebnislisten zu ermöglichen.
90 * Dazu wird <code>xmlparam=order_by_column:1</code> an das Servlet gesendet,
91 * dieses setzt anschließend in der <code>process()</code> -Methode den
92 * entsprechenden XSL-Parameter <code>order_by_column</code> auf den Wert 1.
93 * In einem Stylesheet kann dann auf den Wert zugegriffen werden und wie in
94 * diesem Beispiel nach der 1. Spalte sortiert werden.</li>
95 * <ul>
96 *
97 * @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
98 * @version $Revision: 1.7 $ $Date: 2004/09/16 14:27:24 $
99 */
100 public class SDBSelect extends SDBServlet {
101
/**
102
* Verarbeitet die in der Klassenbeschreibung (s.o.) angegebenen Parameter.
103
* Funktionsweise:
104
* <ul>
105
* 1. Session anlegen / wiederfinden. <br />
106
* 2. bei "requery" ggf. ein neues Document anlegen (incl. <span
107
* class="xml"><session> </span>Element). <br />
108
* 3. evtl. vorhandene alte Fehlermeldung aus dem Document löschen. <br />
109
* 4. alle Parameter die an das Servlet gesendet wurden in das <span
110
* class="xml"><formdata> </span>Element einfügen. <br />
111
* 5. alle übergebenen "query" ausführen und in das Document die
112
* entsprechenden <span class="xml"><resultset> </span>Elemente
113
* einfügen. 6. ggf. zu bestimmten Datensätzen durch den Parameter nav_[1-7]
114
* navigieren. <br />
115
* 7. Stylesheet aus dem entsprechenden Verzeichnis laden. <br />
116
* 8. je nach angegebenen Ausgabeformat XML-transformieren
117
* </ul>
118
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletReques
119
* javax.servlet.http.HttpServletResponse)
120
*/
121
public void doGet(HttpServletRequest request, HttpServletResponse response)
122
throws IOException, ServletException {
123
Source xsltSource = null, xmlSource = null;
124
String stylesheet = null, xml = "";
125
126
PrintWriter out = response.getWriter();
127
128
// session feststellen
129
HttpSession session = request.getSession(true);
130
131
// ggf. neues SDBDocument anlegen
132
if (request.getParameter("requery") != null)
133
newDocument(session);
134
135
// evtl. alte Fehlermeldungen aus dem SDBDocument löschen
136
getDocument(session).removeOldErrors();
Datei: SDBSelect.java
Anhang
out.flush();
if ("XML".equalsIgnoreCase(request.getParameter("form"))) {
// SDBDocument als XML ausgeben
response.setContentType("text/xml; charset=ISO-8859-1");
out.print(showAllRecords(session));
}
else {
// XML des SDBDocuments mit angegebenem Stylesheet transformieren.
xsltSource = new StreamSource(getDefaultStylesheet() + "/"
+ stylesheet);
response.setContentType("text/html; charset=ISO-8859-1");
if (request.getParameter("xmlparam") != null)
// ggf. noch mit XSL-Parametern transformieren
process(xmlSource, xsltSource, out, request);
else
process(xmlSource, xsltSource, out);
}
// richtigen Stylesheet (je nach Parameterwert "stylesheet") auswählen
stylesheet = request.getParameter("stylesheet");
if (stylesheet == null || !stylesheet.endsWith(".xsl"))
stylesheet = "/einzelansicht.xsl";
// XML-String in eine StreamSource umwandeln
xmlSource = new StreamSource(new StringReader(xml));
// ggf. zu bestimmten Datensatz navigieren
if (isDocumentSet(session))
xml = navigate(request);
else
xml = "Fehler: konnte kein Document in dieser Session anlegen bzw. finden!"
// die "query"s setzen
setQuerys(request);
/**
* Gleiche Funktion wie <code>getFirstRecord(s, 0)</code>
Seite: 3 von 7
/**
* Gibt das SDBDcoument als String zurück, dabei wird in dem ResultSet mit
* der übergebenen Nummer zu dem Datensatz mit der aboluten Position
* gesprungen.
* @param s die aktuelle Session
* @param resNumber Nummer des ResultSets
* @param abs_pos Datensatznummer zu der gesprungen wird.
* @return String das SDBDocument aus der Session
* @see SDBDocument#getAbsolute(int, int)
*/
protected String getAbsolutRecord(HttpSession s, int resNumber, int abs_pos) {
return getDocument(s).getAbsolute(resNumber, abs_pos);
}
/**
* Gleiche Funktion wie <code>getAbsolutRecord(s, 0, abs_pos)</code>
* @param s aktuelle Session
* @param abs_pos Datensatznummer zu der gesprungen wird.
* @return String das SDBDocument aus der Session
* @see SDBSelect#getAbsolutRecord(HttpSession, int, int)
*/
protected String getAbsolutRecord(HttpSession s, int abs_pos) {
return getAbsolutRecord(s, 0, abs_pos);
}
}
Seite: 3 von 7
// alle an das Servlet gesendeten Parameter in das SDBDcoument einfügen
addFormdata(request);
Datei: SDBSelect.java
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
Datei: SDBSelect.java
64 von 71
Seite: 4 von 7
/**
* Gleiche Funktion wie <code>getPreviousRecord(s, 0)</code>
* @param s die aktuelle Session
* @return String das SDBDocument aus der Session
Seite: 4 von 7
/**
* Gibt das SDBDocument der Session zurück, dabei wird in dem ResultSet mit
* der übergebenen Nummer zu dem nächsten Datensatz gesprungen.
* @param s die aktuelle Session
* @param resNumber Nummer des ResultSets
* @return String das SDBDocument aus der Session
* @see SDBDocument#getNext(int)
*/
protected String getNextRecord(HttpSession s, int resNumber) {
return getDocument(s).getNext(resNumber);
}
/**
* Gleiche Funktion wie <code>getNextRecord(s, 0)</code>
* @param s die aktuelle Session
* @return String das SDBDocument aus der Session
* @see SDBSelect#getNextRecord(HttpSession, int)
*/
protected String getNextRecord(HttpSession s) {
return getNextRecord(s, 0);
}
/**
* Gibt das SDBDocument der Session zurück, dabei wird in dem ResultSet mit
* der übergebenen Nummer zu dem letzten Datensatz gesprungen.
* @param s die aktuelle Session
* @param resNumber Nummer des ResultSets
* @return String das SDBDocument aus der Session
* @see SDBDocument#getLast(int)
*/
protected String getLastRecord(HttpSession s, int resNumber) {
return getDocument(s).getLast(resNumber);
}
/**
* Gleiche Funktion wie <code>getLastRecord(s, 0)</code>
* @param s die aktuelle Session
* @return String das SDBDocument aus der Session
* @see SDBSelect#getLastRecord(HttpSession, int)
*/
protected String getLastRecord(HttpSession s) {
return getLastRecord(s, 0);
}
/**
* Gibt das SDBDocument der Session zurück, dabei wird in dem ResultSet mit
* der übergebenen Nummer zu dem ersten Datensatz gesprungen.
* @param s die aktuelle Session
* @param resNumber Nummer des ResultSets
* @return String das SDBDocument aus der Session
* @see SDBDocument#getFirst(int)
*/
protected String getFirstRecord(HttpSession s, int resNumber) {
return getDocument(s).getFirst(resNumber);
}
* @param s die aktuelle Session
* @return String das SDBDocument aus der Session
* @see SDBSelect#getFirstRecord(HttpSession, int)
*/
protected String getFirstRecord(HttpSession s) {
return getFirstRecord(s, 0);
}
Datei: SDBSelect.java
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
Datei: SDBSelect.java
Anhang
Seite: 5 von 7
Seite: 5 von 7
/**
* Sucht nach einem Parameter <code>nav_[1-7]</code>. Wird ein solcher
* gefunden, wird je nach Zahl (s.u.) in dem ersten ResultSet des
* SDBDocuments zu dem entsprechenden Datensatz navigiert und nur dieser
* angezeigt.
* <ul>
* nav_1: Der erste Datensatz wird angezeigt. <br />
* nav_2: Ausgehend von der aktuellen Position wird um zehn Datensätze
* zurückgerückt. <br />
* nav_3: Ausgehend von der aktuellen Position wird um einen Datensatz
* zurückgerückt. <br />
* nav_4: Ist zusätzlich der Parameter row vorhanden und eine Zahl zwischen 1
* und der Anzahl der Datensätze eingetragen, wird zu dem Datensatz mit
* dieser Nummer gesprungen. <br />
* nav_5: Ausgehend von der aktuellen Position wird um zehn Datensätze
* vorgerückt. <br />
* nav_6: Ausgehend von der aktuellen Position wird um einen Datensatz
* vorgerückt. <br />
* nav_7: Der letzte Datensatz wird angezeigt <br />
* </ul>
* Falls keiner dieser Parameter angegeben wurde, werden alle ResultSets mit
* allen Datensätzen angezeigt.
* @param r <code>HttpServletRequest</code> aus der doGet()-Methode
* @return String das SDBDocument aus der Session
*/
protected String navigate(HttpServletRequest r) {
HttpSession s = r.getSession();
/**
* Gibt das SDBDocument der Session zurück, dabei wird in dem ResultSet mit
* der übergebenen Nummer zu der relativen Datensatz-Position gesprungen.
* @param s die aktuelle Session
* @param resNumber Nummer des ResultSets
* @param rel_pos relative Position zu der gesprungen wird.
* @return String das SDBDocument aus der Session
* @see SDBDocument#getRelative(int, int)
*/
protected String getRelativeRecord(HttpSession s, int resNumber, int rel_pos) {
return getDocument(s).getRelative(resNumber, rel_pos);
}
/**
* Gleiche Funktion wie <code>getRelativeRecord(s, 0, rel_pos)</code>
* @param s die aktuelle Session
* @param rel_pos relative Position zu der gesprungen wird.
* @return String das SDBDocument aus der Session
*/
protected String getRelativeRecord(HttpSession s, int rel_pos) {
return getRelativeRecord(s, 0, rel_pos);
}
/**
* Gibt das SDBDocument der Session zurück, dabei wird in dem ResultSet mit
* der übergebenen Nummer zu dem vorhergehenden Datensatz gesprungen.
* @param s die aktuelle Session
* @param resNumber Nummer des ResultSets
* @return String das SDBDocument aus der Session
* @see SDBDocument#getPrevious(int)
*/
protected String getPreviousRecord(HttpSession s, int resNumber) {
return getDocument(s).getPrevious(resNumber);
}
* @see SDBSelect#getPreviousRecord(HttpSession, int)
*/
protected String getPreviousRecord(HttpSession s) {
return getPreviousRecord(s, 0);
}
Datei: SDBSelect.java
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
Datei: SDBSelect.java
65 von 71
Seite: 6 von 7
/**
* Gibt das SDBDocument mit allen ResultSets und jeweils allen Datensätzen
* zurück
* @param s die aktuelle Session
* @return String das SDBDocument aus der Session
* @see SDBDocument#getAll()
*/
protected String showAll(HttpSession s) {
return getDocument(s).getAll();
}
}
// ist der Parameter an das Servlet gesendet worden?
if (query != null && query.length > 0)
for (int i = 0; i < query.length; i++) {
// jeden "query"-String auf ein 'SELECT ' am Anfang überprüfen
if (query[i].trim().length() >= 0
&& query[i].toUpperCase().startsWith("SELECT ")) {
try {
// Query ausführen und ResultSet erzeugen
setResultSet(query[i], s);
}
catch (SQLException e) {
doc.setError(e.toString());
}
}
else
doc.setError("Query: " + query[i]);
}
/**
* Führt die einzelnen SQL-Select-Anweisungen, die in den Parametern "query"
* an das Servlet gesendet wurden aus und erzeugt jeweils ein <span
* class="xml"><resultset> </span>Element in dem SDBDocument der
* aktuellen Session.
* @param r <code>HttpServletRequest</code> aus der doGet()-Methode
* @see SDBServlet#setResultSet(String, HttpSession)
*/
protected void setQuerys(HttpServletRequest r) {
String[] query = r.getParameterValues("query");
HttpSession s = r.getSession();
SDBDocument doc = getDocument(s);
}
Seite: 6 von 7
while (e.hasMoreElements()) {
String nav = e.nextElement().toString();
if (nav.startsWith("nav_"))
switch (nav.charAt(4)) { // nav_X X==4. Position
case '1':
return getFirstRecord(s);
case '2':
return getRelativeRecord(s, -10);
case '3':
return getPreviousRecord(s);
case '4':
int number = Integer.parseInt(r.getParameter("row"));
return getAbsolutRecord(s, number);
case '5':
return getNextRecord(s);
case '6':
return getRelativeRecord(s, 10);
case '7':
return getLastRecord(s);
}
}
return getDocument(s).getAll();
Enumeration e = r.getParameterNames();
Datei: SDBSelect.java
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
Datei: SDBSelect.java
Anhang
Seite: 7 von 7
Seite: 7 von 7
/**
* Gibt das SDBDocument zurück und den ResultSet mit der übergebenen Nummer
* dabei mit allen Datensätzen.
* @param s die aktuelle Session
* @param resNumber Nummer des ResultSets
* @return String das SDBDocument aus der Session
* @see SDBDocument#getAll(int)
*/
protected String showAllRecords(HttpSession s, int resNumber) {
return getDocument(s).getAll(resNumber);
}
/**
* Gibt das SDBDocument zurück und den ersten ResultSet dabei mit allen
* Datensätzen. Die gleiche Funktion wie <code>showAllRecords(s, 0)</code>
* @param s die aktuelle Session
* @return String das SDBDocument aus der Session
* @see SDBSelect#showAllRecords(HttpSession, int)
*/
protected String showAllRecords(HttpSession s) {
return showAllRecords(s, 0);
}
Datei: SDBSelect.java
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432 }}
Datei: SDBSelect.java
66 von 71
base.*;
java.io.*;
java.sql.*;
javax.servlet.*;
javax.servlet.http.*;
javax.xml.transform.*;
javax.xml.transform.stream.*;
Seite: 1 von 3
// Ausgabeformat festlegen und entsprechend ausgeben
if ("XML".equalsIgnoreCase(request.getParameter("form"))) {
// den Stylesheet holen
stylesheet = request.getParameter("stylesheet");
if (stylesheet == null || !stylesheet.endsWith(".xsl"))
stylesheet = "/einzelansicht.xsl";
// aus dem String des SDBDocuments eine Source erzeugen
xmlSource = new StreamSource(new StringReader(xml));
Seite: 1 von 3
if (isDocumentSet(session))
xml = navigate(request); // Navigationsleiste anwenden
else
xml = "Fehler: konnte kein Document in dieser Session anlegen bzw. finden!"
setQuerys(request); // ggf. noch Select-Anweisungen ausführen
execute(request); // SQL-Anweisungen ausführen
addFormdata(request); // hinzufügen der gesendeten Parameter
// ggf. alte Fehlermeldungen löschen, gerade wenn kein neues Document
// angelegt wurde!!
getDocument(session).removeOldErrors();
// ggf. neues SDBDocument anlegen und das alte damit verwerfen
if (request.getParameter("requery") != null)
newDocument(session);
// aktuelle Session erkennen
HttpSession session = request.getSession(true);
PrintWriter out = response.getWriter();
/**
* Mit diesem Servlet können alle Datenbankoperationen ausgeführt werden, die
* der JDBC-Treiber zulässt. Es ist speziell für
* <code>INSERT, UPDATE, DELETE</code> Operationen gedacht. Es werden aber
* genausogut auch <code>CREATE TABLE, DROP TABLE, GRANT...</code> Operationen
* unterstützt. Ansonsten ist die Funktionsweise die gleiche wie bei dem
* Servlet: <code>SDBSelect</code>
* @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
* @version $Revision: 1.4 $ $Date: 2004/09/23 15:31:21 $
*/
public class SDBExecute extends SDBSelect {
/**
* Funktioniert genauso wie bei <code>SDBSelect</code>, nur das nach dem
* <span class="xml"><formdata> </span>Element die in dem Parameter
* "sql" übergebenen Datenbankanweisungen ausgeführt werden und das
* entsprechende <span class="xml"><executed> </span>Element erzeugt
* wird.
* @see SDBSelect#doGet(HttpServletRequest, HttpServletResponse)
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
Source xsltSource = null, xmlSource = null;
String stylesheet = null, xml = "";
import
import
import
import
import
import
import
package servlet;
Datei: SDBExecute.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: SDBExecute.java
Anhang
out.flush();
Seite: 2 von 3
Seite: 2 von 3
if (what.equals("insert"))
message = count + " Datensätze eingefügt";
else if (what.equals("update"))
message = count + " Datensätze überschrieben";
else if (what.equals("delete"))
message = count + " Datensätze gelöscht";
else
message = sql[i].substring(0,
(sql[i].length() > 30 ? 30 : sql[i].length())).trim().
// die SQL-Anweisungen nach und nach ausführen
for (int i = 0; i < sql.length; i++) {
if (sql[i].trim().length() > 0) {
try {
Statement stm = con.createStatement(
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
if (stm.execute(sql[i])) {
// ggf. eine Ergebnisliste erzeugen
setResultSet(stm.getResultSet(), s);
}
else {
// oder eine Meldung, über die durchgeführte Aktion
// erzeugen
String what = sql[i].substring(0, sql[i].indexOf(' ')).trim(
int count = stm.getUpdateCount();
String message = null;
// SQL-Parameterliste checken
if (sql != null && sql.length > 0)
try {
// Datenbankeinstellungen vornehmen
con.setAutoCommit(false);
con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
// Datenbankverbindung aufbauen
Connection con = getConnection();
if (con == null) {
doc.setError("Es konnte keine Datenbankverbindung hergestellt werden!");
return;
}
/**
* Sucht in der Parameterliste des mitgegebenen
* <code>HttpServletRequest</code> nach "sql", alle diese Parameter werden
* in einer Transaktion in der Reihenfolge wie sie an das Servlet geschickt
* wurden ausgeführt.
* @param r das <code>HttpServletRequest</code> in dem nach SQLs gesucht
* wird.
*/
protected void execute(HttpServletRequest r) {
String[] sql = r.getParameterValues("sql");
HttpSession s = r.getSession();
SDBDocument doc = getDocument(s);
boolean error = false;
}
}
else {
xsltSource = new StreamSource(getDefaultStylesheet() + "/"
+ stylesheet);
response.setContentType("text/html; charset=ISO-8859-1");
process(xmlSource, xsltSource, out);
}
response.setContentType("text/xml; charset=ISO-8859-1");
out.print(showAllRecords(session));
Datei: SDBExecute.java
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Datei: SDBExecute.java
67 von 71
}
catch (SQLException e) {
while (e != null) {
doc.setError(e.toString());
e = e.getNextException();
}
error = true;
}
doc.setExecute(what, message, count);
}
stm.close();
con.close();
}
catch (SQLException e) {
doc.setError(e.toString());
try {
con.rollback();
con.close();
}
catch (SQLException e2) {
doc.setError(e2.toString());
}
}
}
}
if (!error)
con.commit(); //keine Fehler -> commit
else
con.rollback(); // bei Fehlern -> rollback
Datei: SDBExecute.java
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
}
168 }r
Datei: SDBExecute.java
Anhang
Seite: 3 von 3
Seite: 3 von 3
javax.servlet.ServletException;
javax.servlet.http.Cookie;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax.servlet.http.HttpSession;
javax.xml.transform.Source;
javax.xml.transform.stream.StreamSource;
import
import
import
import
import
import
import
Seite: 1 von 8
Seite: 1 von 8
for (int i = 0; theCookies != null && i < this.cookie.length;) {
index = theCookies.indexOf("::::");
if (index < 0)
break;
name = theCookies.substring(0, index);
/**
* Konstruktor, bei dem die Cookies aus dem übergebenen
* <code>String</code> extrahiert werden.
* @param theCookies aus dem die <code>Cookies</code> geholt werden.
*/
public StatCookie(String theCookies) {
String name, value;
int index;
/**
* Konstruktor, bei dem die Cookies aus dem übergebenen
* <code>HttpServletRequest</code> geholt werden.
* @param request aus dem die <code>Cookies</code> geholt werden.
*/
public StatCookie(HttpServletRequest request) {
this.cookie = request.getCookies();
}
/**
* Das Servlet zum Verwalten und Ausführen der Datenbankanfragen, die mit dem
* Anfrageneditor erstellt wurden.
* @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
* @version $Revision: 1.8 $ $Date: 2004/09/16 14:27:24 $
*/
public final class SDBStatistik extends SDBSelect {
/**
* Klasse zum umwandeln der Cookies in einen zusammenhängenden String und
* wieder zurück.
* @author <a href="mailto:[email protected]">Hilmar Falkenberg </a>
* @version $Revision$ $Date$
*/
private class StatCookie {
/**
* Array <code>cookie</code> für maximal 20 Cookies, mehr sind in
* Browsern nicht erlaubt (vgl. HTTP-Standard)! <br />
* Cookies für den Anfrageneditor: TABLE, FELD[0-9], CHECK, FUNKT, FRAGE
*/
private Cookie[] cookie = new Cookie[20];
import base.SDBDocument;
java.io.IOException;
java.io.InputStream;
java.io.InputStreamReader;
java.io.PrintWriter;
java.io.StringBufferInputStream;
java.io.StringReader;
java.sql.Connection;
java.sql.PreparedStatement;
java.sql.ResultSet;
java.sql.SQLException;
java.sql.Statement;
import
import
import
import
import
import
import
import
import
import
import
package servlet;
Datei: SDBStatistik.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Datei: SDBStatistik.java
68 von 71
/**
* Die Stringdarstellung eines StatCookies ist: <br />
* <strong>cookie_NAME1::::cookie_WERT1####cookie_NAME2::::cookie_WERT3
* ... </strong> <br />
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < this.cookie.length && this.cookie[i] != null; i++) {
buf.append(this.cookie[i].getName() + "::::"
+ this.cookie[i].getValue() + "####");
}
return buf.toString();
}
Seite: 2 von 8
/**
* Löscht eine Datenbankanfrage aus der Tabelle pra03.stat_statistiken. Dazu
* muss ein Parameter <code>STATID</code> an das Servlet übergeben worden
* sein, in ihm muss die eindeutige Datenbankanfragen-Nummer (lfd_nr)
* enthalten sein, die gelöscht werden soll. <br />
* Anschließend wir die Liste mit den gespeicherten Anfragen angezeigt.
* @param request weitergereicht von <code>doGet()</code>
* @param response weitergereicht von <code>doGet()</code>
* @throws IOException
* @see SDBStatistik#doGet(HttpServletRequest, HttpServletResponse)
/**
* Wandelt einen <code>InputStream</code> in einen <code>String</code> um
* @param in <code>InputStream</code> der umgewandelt werden soll
* @return die Daten des InputStreams als String
* @throws IOException
*/
public static String toString(InputStream in) throws IOException {
char[] charBuffer = new char[1024];
int bytesRead;
InputStreamReader isr = new InputStreamReader(in);
StringBuffer sb = new StringBuffer();
while (-1 != (bytesRead = isr.read(charBuffer, 0, charBuffer.length))) {
sb.append(charBuffer, 0, bytesRead);
}
in.close();
isr.close();
return sb.toString();
}
}
}
Seite: 2 von 8
/**
* Setzt beim Client die Cookies, die sich in dem Array
* <code>cookie</code> befinden.
* @param response Client-Antwort-Objekt
*/
public void addCookies(HttpServletResponse response) {
for (int i = 0; i < this.cookie.length && this.cookie[i] != null; i++) {
response.addCookie(this.cookie[i]);
}
}
}
theCookies = theCookies.substring(index + 4);
index = theCookies.indexOf("####");
if (index < 0)
break;
value = theCookies.substring(0, index);
theCookies = theCookies.substring(index + 4);
if (name != null && value != null) {
this.cookie[i++] = new Cookie(name, value);
}
Datei: SDBStatistik.java
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Datei: SDBStatistik.java
Anhang
Seite: 3 von 8
Seite: 3 von 8
/**
* Sucht nach dem Parameter: "doWhat"
* <ul>
* <li><strong>speichern/save </strong> <br />
* <br />
* Mit diesem Wert wird das Servlet dazu veranlasst, die Cookies auszulesen.
* Je nachdem, ob eine STATID als Parameter mit übergeben wurde, wird ein
* insert (keine STATID) oder ein update (mit entsprechender STATID) auf der
* Tabelle pra03.stat_statistiken vorgenommen. Anschließend wird die Liste
* der gespeicherten Anfragen mit einem Hinweis dargestellt, ob das Speichern
* erfolgreich war.</li>
* <li><strong>bearbeiten/edit </strong> <br />
* Wird einer dieser beiden Werte an das Servlet gesendet, ist ein
* zusätzlicher Parameter STATID unablässig. Es wird dann der Datensatz mit
* der entsprechenden lfd_nr aus der Tabelle pra03.stat_statistiken gelesen
* und die Cookies aus dem long-varchar-Feld werden wieder hergestellt, so
* dass nach einem HttpServletResponse.sendRedirect("statistik.html") eine
}
// Liste der gespeicherten Anfragen erzeugen
liste(request, response);
}
}
else
doc.setError("Es wurde keine Anfrage gelöscht, weil keine STATID übergeben
}
catch (SQLException e) {
doc.setError(e.toString());
}
stm.close();
con.commit();
con.close();
if (stm.execute())
setResultSet(stm.getResultSet(), session);
else {
int count = stm.getUpdateCount();
doc.setExecute("delete", "Abfrage Nr: " + statid
+ " - wurde erfolgreich gelöscht", count);
}
// Anfrage löschen
String sql = "DELETE FROM pra03.stat_statistiken WHERE lfd_nr = ?";
PreparedStatement stm = con.prepareStatement(sql);
stm.setInt(1, statid);
// ist eine STATID übergeben worden?
if (statid != 0) {
Connection con = getConnection();
if (con == null) {
doc.setError("Es konnte keine Datenbankverbindung hergestellt werden!");
}
else {
try {
con.setAutoCommit(false);
con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
// neues Document anlegen
SDBDocument doc = newDocument(session);
addFormdata(request);
*/
private void delete(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// STATID holen
int statid = getStatId(request);
HttpSession session = request.getSession(true);
Datei: SDBStatistik.java
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
Datei: SDBStatistik.java
69 von 71
Seite: 4 von 8
Seite: 4 von 8
if (statid != 0) {
try {
// Anfrage aus der Tabelle pra03.stat_statistiken laden
Connection con = getConnection();
Statement stm = con.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
String sql = "SELECT cookie, frage from pra03.stat_statistiken WHERE lfd
+ statid;
ResultSet rs = stm.executeQuery(sql);
/**
* Lädt eine Anfrage aus der Datenbank in den Anfrageneditor. Dazu wird der
* Parameter STATID benötigt, d.h. die Nummer der Anfrage, die bearbeitet
* werden soll.
* @param request weitergereicht von <code>doGet()</code>
* @param response weitergereicht von <code>doGet()</code>
* @throws IOException
* @see SDBStatistik#doGet(HttpServletRequest, HttpServletResponse)
*/
private void edit(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// Anfragennummer feststellen
int statid = getStatId(request);
}
if (doWhat.equalsIgnoreCase("speichern")
|| doWhat.equalsIgnoreCase("save")) {
save(request, response);
}
else if (doWhat.equalsIgnoreCase("bearbeiten")
|| doWhat.equalsIgnoreCase("edit")) {
edit(request, response);
}
else if (doWhat.equalsIgnoreCase("ausführen")
|| doWhat.equalsIgnoreCase("execute")) {
execute(request, response);
}
else if (doWhat.equalsIgnoreCase("löschen")
|| doWhat.equalsIgnoreCase("delete")) {
delete(request, response);
}
else
liste(request, response);
* Bearbeitung in dem Anfrageneditor vorgenommen werden kann.</li>
* <li><strong>ausführen/execute </strong> <br />
* Diese Werte steuern das Servlet so, dass entweder die aktuelle Anfrage
* gemäß der Eingabe in dem Anfrageneditor ausgeführt wird oder eine aus der
* Liste der gespeicherten Datenbankanfragen ausgewählte Anfrage. Dazu wird
* diese aus der Tabelle pra03.stat_statistiken zuerst ausgelesen und dann
* ausgeführt.</li>
* <li><strong>löschen/delete </strong> <br />
* Der Aufruf des Servlets mit diesen Werten wird nur von der Seite mit den
* gespeicherten Datenbankanfragen vorgenommen und führt dazu, dass die
* Datenbankanfrage mit der lfd_nr (entspricht mitgesendeter STATID) gelöscht
* wird. Anschließend wird wieder die Liste mit den gespeicherten Anfragen
* mit einem Hinweis dargestellt, ob das Löschen erfolgreich war.</li>
* <li><strong>keiner der obigen Werte wurde als "doWhat" an das Servlet
* gesendet </strong> <br />, dann wird die Lsite mit den bisher
* gespeicherten Anfragen dargestellt.</li>
* </ul>
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletReques
* javax.servlet.http.HttpServletResponse)
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String doWhat = request.getParameter("doWhat") + "";
Datei: SDBStatistik.java
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
Datei: SDBStatistik.java
Anhang
Seite: 5 von 8
// um welche Anfrage handelt es sich
int statid = getStatId(request);
SDBDocument doc = newDocument(session);
try {
// Wurde eine Anfrage mitgesendet?
String query = request.getParameter("query");
if (statid != 0 && query == null) {
// keine Anfrage ("query") übergeben, dafür aber eine STATID
Connection con = getConnection();
if (con == null) {
doc.setError("Es konnte keine Datenbankverbindung hergestellt werd
}
else {
// Anfrage mit der ldf_nr = STATID aus der Datenbank laden
String sql = "select frage, query from pra03.stat_statistiken wher
+ statid;
// soll nach einer Spalte umsortiert werden?
String neuSortieren = request.getParameter("xmlparam");
if (neuSortieren == null || !neuSortieren.startsWith("order_by_column")) {
PrintWriter out = response.getWriter();
HttpSession session = request.getSession(true);
/**
* Führt entweder die aktuell im Anfrageneditor befindliche Anfrage aus, oder
* holt die Anfrage mit der übergebenen STATID aus der Datenbank und führt
* diese aus.
* @param request weitergereicht von <code>doGet()</code>
* @param response weitergereicht von <code>doGet()</code>
* @throws IOException
* @see SDBStatistik#doGet(HttpServletRequest, HttpServletResponse)
*/
private void execute(HttpServletRequest request, HttpServletResponse response)
throws IOException {
}
SDBDocument doc = getDocument(request.getSession());
doc.setError(e.toString());
response.setContentType("text/html; charset=ISO-8859-1");
Source xmlSource = new StreamSource(new
StringReader(doc.toString()));
Source xsltSource = new StreamSource(getDefaultStylesheet() +
"/stat_gespeicherte.xsl");
process(xmlSource, xsltSource, response.getWriter());
}
}
// zur Anfrageneditor-HTML-Seite wechseln
response.sendRedirect(response.encodeRedirectURL("statistik.html"));
//
//
//
//
//
//
//
//
}
catch (SQLException e) {
// was soll man hier schon noch großes tun?
// Die Fehlermeldungen werden eh nicht angezeigt!
rs.close();
stm.close();
con.close();
}
Seite: 5 von 8
// Cookies beim Client setzen
cookie.addCookies(response);
response.addCookie(new Cookie("STATID", String.valueOf(statid)));
if (rs.next()) {
// long varchar Feld in Cookies umwandeln
StatCookie cookie = new StatCookie(
toString(rs.getAsciiStream(1)));
Datei: SDBStatistik.java
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
Datei: SDBStatistik.java
70 von 71
}
catch (SQLException e) {
doc.setError(e.toString());
}
}
out.flush();
if (request.getParameter("xmlparam") != null)
process(xmlSource, xsltSource, out, request);
else
process(xmlSource, xsltSource, out);
Seite: 6 von 8
/**
* Erzeugt die Liste mit den bisher gespeicherten Datenbankanfragen. Dabei
/**
* Gibt die an das Servlet gesendete STATID zurück
* @param request weitergereicht von <code>doGet()</code>
* @return int die an das Servlet gesendete STATID
*/
private int getStatId(HttpServletRequest request) {
try {
return Integer.parseInt(request.getParameter("STATID"));
}
catch (NumberFormatException e) {
return 0;
}
}
}
// Anfrage ausführen und <resultset> Element erzeugen
doc.addResultSet(stm.executeQuery(sql), sql);
con.close();
if ("XML".equalsIgnoreCase(request.getParameter("form"))) {
// ggf. das Ergebnis als XML darstellen
response.setContentType("text/xml; charset=ISO-8859-1");
out.print(showAllRecords(session));
}
else {
// ansonsten wird der standard Stylesheet "stat_antwort.xsl" verwendet
Source xmlSource = new StreamSource(new StringReader(
showAllRecords(session)));
Source xsltSource = new StreamSource(getDefaultStylesheet()
+ "/stat_antwort.xsl");
response.setContentType("text/html; charset=ISO-8859-1");
}
Seite: 6 von 8
// konnte die Anfrage geladen werden?
PreparedStatement stm = con.prepareStatement(sql,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stm.executeQuery();
if (rs.next()) {
String frage = rs.getString(1);
doc.addFormdata("frage", frage);
sql = rs.getString(2);
}
else
doc.addFormdata("frage",
"Das hat leider nicht funkioniert!");
rs.close();
}
}
else {
// die übergebene Anfrage direkt ausführen
String frage = request.getParameter("frage");
doc.addFormdata("frage", frage);
setResultSet(query, session);
}
Datei: SDBStatistik.java
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
Datei: SDBStatistik.java
Anhang
Seite: 7 von 8
out.flush();
SDBDocument doc = newDocument(session);
addFormdata(request);
StatCookie cookie = new StatCookie(request);
Seite: 7 von 8
/**
* Speichert die Datenbankanfrage in der Tabelle pra03.stat_statistiken, die
* gerade in dem Anfrageneditor bearbeitet wird. Dazu wird entweder eine neue
* lfd_nr / STATID erzeugt und ein INSERT durchgeführt, falls es sich um eine
* neue Anfrage handelt. Oder es wird die Anfrage mit der in dem Parameter
* STATID, übergebenen lfd_nr ein UPDATE durchgeführt. <br />
* Anschließend wir die Liste mit den gespeicherten Anfragen angezeigt.
* @param request weitergereicht von <code>doGet()</code>
* @param response weitergereicht von <code>doGet()</code>
* @throws IOException
* @see SDBStatistik#doGet(HttpServletRequest, HttpServletResponse)
*/
private void save(HttpServletRequest request, HttpServletResponse response)
throws IOException {
HttpSession session = request.getSession(true);
}
// Ausgabe der Liste, ggf. mit Umordnungsparameter
if (request.getParameter("xmlparam") != null)
process(xmlSource, xsltSource, out, request);
else
process(xmlSource, xsltSource, out);
// Sourcen für die Transformierung vorbereiten, ...
Source xmlSource = new StreamSource(new StringReader(
getDocument(session).getAll()));
// ... dabei wird immer der Stylesheet "stat_gespeicherte.xsl" verwendet
Source xsltSource = new StreamSource(getDefaultStylesheet()
+ "/stat_gespeicherte.xsl");
response.setContentType("text/html; charset=ISO-8859-1");
String neuSortieren = request.getParameter("xmlparam");
// soll evtl. nur neu sortiert werden? Dann braucht kein neuer Resultset
// erzeugt werden
if (neuSortieren == null || !neuSortieren.startsWith("order_by_column"))
try {
String sql = "select lfd_nr, datum, frage, cookie from pra03.stat_statis
setResultSet(sql, session);
}
catch (SQLException e) {
doc.setError(e.toString());
}
// ggf. ein neues Document anlegen?
if (request.getParameter("requery") != null)
doc = newDocument(session);
* berücksichtigte Parameter: "requery", "xmlparam". <br />
* Das "query" ist fest (Liste der gespeicherten Anfragen). Passender
* "stylesheet" ist ebenfalls fest. Die Liste wird immer im HTML-Format
* ausgegeben und nicht als XML, daher kein "form" Parameter!
* @param request weitergereicht von <code>doGet()</code>
* @param response weitergereicht von <code>doGet()</code>
* @throws IOException
* @see SDBStatistik#doGet(HttpServletRequest, HttpServletResponse)
*/
private void liste(HttpServletRequest request, HttpServletResponse response)
throws IOException {
PrintWriter out = response.getWriter();
HttpSession session = request.getSession(true);
// altes Document holen
SDBDocument doc = getDocument(session);
Datei: SDBStatistik.java
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
Datei: SDBStatistik.java
71 von 71
Seite: 8 von 8
}
// Liste der gespeicherten Anfragen erzeugen
liste(request, response);
}
catch (SQLException e) {
doc.setError(e.toString());
}
stm.close();
con.commit();
con.close();
Seite: 8 von 8
// UPDATE bzw. INSERT - Anweisung ausführen
if (stm.execute())
setResultSet(stm.getResultSet(), session);
else {
int count = stm.getUpdateCount();
if (count > 0)
doc.setExecute(update ? "update" : "insert", frage
+ " - wurde erfolgreich gespeichert", count);
}
// zu speichernde Werte in die SQL-Anweisung einsetzen
PreparedStatement stm = con.prepareStatement(sql);
stm.setString(1, frage);
stm.setString(2, query);
String strCookie = cookie.toString();
stm.setAsciiStream(3, new StringBufferInputStream(strCookie),
strCookie.length());
Connection con = getConnection();
if (con == null) {
doc.setError("Es konnte keine Datenbankverbindung hergestellt werden!");
}
else {
try {
con.setAutoCommit(false);
con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
String frage = request.getParameter("frage");
String query = request.getParameter("query");
// UPDATE oder INSERT - Anweisung vorbereiten
if (!update) {
sql = "INSERT INTO pra03.stat_statistiken (lfd_nr, datum, frage, query, coo
+ "SELECT IFNULL(MAX(lfd_nr),0) + 1, DATE('now'), ?, SQUEEZE(?), ? FR
}
else {
sql = "UPDATE pra03.stat_statistiken SET datum = DATE('now'), "
+ "frage = ?, query = SQUEEZE(?), cookie = ? WHERE lfd_nr = "
+ statid;
}
// evtl. vorhandene STATID holen
int statid = getStatId(request);
boolean update = (statid != 0);
String sql;
Datei: SDBStatistik.java
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
}
534 }f
Datei: SDBStatistik.java
Anhang
Herunterladen