Professional Documents
Culture Documents
Relationale
Datenbanksysteme
Eine praktische Einfhrung
Mit zahlreichen Beispielen
und bungsaufgaben
12
Vorwort
Die dateiorientierte Datenhaltung wird heute in betrieblichen Bereichen weitgehend abgelost durch Datenbankmanagementsysteme
(DBMS), vor allem durch die relational orientierten Systeme.
Die Literatur zu diesem Gebiet besteht zum einen aus stark grundlagenorientierten Werken, die die Prinzipien des Datenbank-Entwurfs
und der Implementierung von DBMS behandeln. Zum anderen ndet
man sehr detailreiche Beschreibungen mit Manualcharakter, die die
technischen Aspekte des Umgangs mit DBMS beinhalten. Das vorliegende Buch ist in der Mitte dieser beiden Extreme anzusiedeln.
Wir wollen den Leser durch Vermittlung der wichtigsten Techniken
m
oglichst schnell in die Lage versetzen, eigene Datenbankapplikationen
zu konzipieren und zu implementieren bzw. Verst
andnis f
ur die Hintergr
unde bestehender Datenbankapplikationen zu gewinnen. Durch
die weitgehend knappe Darstellung und Konzentration auf wesentliche Aspekte wollen wir dem Leser das umstandliche Extrahieren des
f
ur ihn wichtigen Materials aus Manualen oder Online-Hilfen ersparen.
Nat
urlich wird sich f
ur spezielle Fragen der Umgang mit Manualen
nicht vermeiden lassen.
Dieses Buch entstand aus einer Lehrveranstaltung u
ber Datenbanken
und Informationssysteme, die regelm
aig im Sommersemester f
ur Studierende der Betriebs- und Volkswirtschaftslehre der Universitat Passau im Vertiefungsgebiet Wirtschaftsinformatik stattndet. Die Veranstaltung besteht aus einer Vorlesung mit zwei Wochenstunden und
einem Praktikum mit vier Wochenstunden. Das Praktikum wird in
vi
Vorwort
komplexerer Ubungsbeispiele
an. Diese orientieren sich alle an kleinen
Datenbanken, die wir u
ber das Internet verf
ugbar machen (siehe dazu
Anhang C).
Das Buch beschaftigt sich ausschlielich mit dem relationalen Daten
modell. Altere
Modelle wie das Netzwerkmodell und das hierarchische
Modell behandeln wir nicht, da sie keine gr
oere Bedeutung mehr haben. Objektorientierte Konzepte nden allm
ahlich Eingang in kommerzielle Datenbanksysteme auch der aktuelle Standard SQL:2003
sowie sein Vorganger SQL:1999 unterst
utzen diese Konzepte , eine
Behandlung w
urde jedoch den Rahmen dieses Buches sprengen. Da
objektorientierte Modelle ebenfalls relationale Techniken verwenden,
sind die Inhalte dieses Buches auch f
ur derartige Modelle relevant.
Die Beispiele des Buches und die Sprachsyntax von SQL und
der behandelten prozeduralen Erweiterung orientieren sich an dem
DBMS PostgreSQL, da dieses lizenzkostenfrei f
ur viele Plattformen
verf
ugbar ist und nur relativ geringe Systemressourcen ben
otigt. Wenn
m
oglich, bem
uhen wir uns allerdings um die Vermeidung PostgreSQLspezischer Elemente. Es hatte jedoch zu weit gef
uhrt, alle u
ber den
Standard hinausgehenden Syntaxelemente und Besonderheiten anderer Systeme aufzuf
uhren. Die Erweiterungen von SQL oder die Gestaltung von graphischen Benutzerober
achen sind bei vielen anderen
Systemen im Prinzip verwandt, so dass auch f
ur den Leser, der ein
anderes DBMS einsetzt, die Lekt
ure sinnvoll ist. Da PostgreSQL frei
verf
ugbar ist (Open Source), steht es dem Leser in jedem Fall of
fen, sich das System zu Ubungszwecken
zu installieren (siehe dazu
Anhang B.1), ein normaler PC reicht hierzu aus.
Das erste Kapitel dieses Buches f
uhrt kurz in die Thematik der Daten-
Vorwort
vii
banksysteme ein, grenzt sie von klassischen Dateisystemen ab, formuliert Forderungen an ein DBMS und seine Leistungsf
ahigkeit und stellt
ihre allgemeine Architektur vor.
Im zweiten Kapitel werden das Relationenmodell und das EntityRelationship-Modell beschrieben und die wichtigsten Basisoperationen
auf Relationen vorgestellt. Diese Operationen werden im dritten Kapitel anhand von SQL als Datenmanipulationssprache konkret implementierbar.
Im vierten Kapitel wird der Datenbank-Entwurf u
ber die Vermeidung von Anomalien durch Normalisierung behandelt und anschlieend die Datenbankdenition und die Formulierung von Integrit
atsbedingungen mit SQL eingef
uhrt.
Das f
unfte Kapitel behandelt die Aspekte eines Datenbankadministrators: Transaktionskonzepte, Probleme des Mehrbenutzerbetriebs und
Zugrisrechte sowie die Verf
ugbarkeit von Systeminformationen. Im
sechsten Kapitel wird eine prozedurale Erweiterung von SQL mit ihren Kontrollstrukturen, dem Cursor-Konzept, der Fehlerbehandlung
sowie Triggern und Funktionen beschrieben.
F
ur manche Applikationen reichen auch diese Erweiterungen nicht.
Deshalb wird im siebten Kapitel darauf eingegangen, wie SQLSprachelemente in einer h
oheren Sprache verwendet werden konnen.
Wir zeigen sowohl die Einbettung in C unter Verwendung von
mittlerweile in den SQL-Standard aufgenommenen Embedded SQLKonstrukten, als auch den Datenbankzugri in der vor allem im Bereich der WWW-Programmierung weit verbreiteten Sprache Perl.
F
ur die Bereitstellung von Inhalten im World Wide Web, insbesondere bei der Realisierung von E-Commerce-Anwendungen wie z. B.
Shopsystemen, sind Datenbanken mittlerweile unverzichtbar geworden. Daher erscheint es uns wichtig, in einem zus
atzlichen Kapitel auf
M
oglichkeiten zur WWW-Integration von Datenbanken einzugehen.
Graphische Werkzeuge f
ur Datenbankadministration und -design sind
insbesondere bei komplexen Datenbankstrukturen auerst n
utzlich.
Wir stellen daher in einem separaten Kapitel einige dieser f
ur PostgreSQL verf
ugbaren Werkzeuge vor. Die Konzepte dieser Administra-
viii
Vorwort
im Juli 2004
Inhaltsverzeichnis
1. Was sind Datenbanksysteme?
1.1. Unterschiede von DBMS zu klassischen Dateisystemen
1.2. Forderungen an ein DBMS
1.3. Abstraktionsebenen im DBMS
1
1
4
5
2. Formale Modelle f
ur Datenbanken
2.1. Das Relationenmodell
2.2. Das Entity-Relationship-Modell
2.3. Vom Entity-Relationship- zum Relationenmodell
2.4. Wichtige Operationen auf Relationen (Tabellen)
2.5. Zusatzforderungen f
ur relationale DBMS
7
7
9
11
12
19
20
20
22
24
37
58
60
68
4. Datenbank-Entwurf
4.1. Anomalien in Datenbanken
4.2. Normalformen von Relationen
4.3. Dekomposition
4.4. Datenbankdenition mit SQL
73
73
75
82
84
5. Datenbankbetrieb
5.1. Das Transaktionskonzept in Datenbanksystemen
5.2. Mehrbenutzerbetrieb
5.3. Transaktionen und Constraints
5.4. Datenschutz und Zugrisrechte
5.5. Zugri auf Datenbank-Metadaten
96
96
98
102
104
111
112
112
114
116
135
7. Datenbankzugri in h
oheren Programmiersprachen
7.1. Embedded SQL
143
143
Inhaltsverzeichnis
7.2. Die DBI-Schnittstelle f
ur Perl
7.3. Portablilit
at der Zugrisverfahren
149
159
162
162
165
167
168
171
175
176
185
188
192
194
194
195
198
Literatur
202
A. Syntaxdiagramme
203
B. Software-Bezugsquellen
B.1. PostgreSQL
B.2. Linux
B.3. Cygwin f
ur Windows
B.4. Perl und Perl-Module
B.5. Apache
B.6. Weitere relationale Open Source-Datenbanksysteme
205
205
205
206
206
206
207
C. WWW-Site f
ur dieses Buch
208
209
E. Ubungsaufgaben
E.1. Musterdatenbank THEATER
E.2. Musterdatenbank HOTEL
E.3. Musterdatenbank VHS
212
212
227
242
F. SQL-Kommandoreferenz
254
Abbildungsverzeichnis
255
Stichwortverzeichnis
260
Wir wollen dies an einem Beispiel illustrieren: Ein Versicherungsunternehmen bietet Haftpicht- und Rechtsschutzversicherungen an.
Zur Verwaltung der Haftpicht- bzw. Rechtsschutzversicherten existieren jeweils separate Anwendungsprogramme, die u. a. eigene
Adressdateien f
ur ihren Versichertenstamm verwenden. Die MarketingAbteilung verwendet mit ihrem eigenen Programm diese Adressdateien f
ur Werbeaktionen. Abb. 1 zeigt schematisch den Zugri der
Programme auf diese Daten.
Programm
"Haftpflicht"
Haftpflichtversicherungsdaten
und Adressen von Versicherten
physische
Datei
Programm
"Rechtsschutz"
Rechtsschutzversicherungsdaten
und Adressen von Versicherten
Programm
"Marketing"
physische
Datei
liest
Andert
ein Mitarbeiter der Haftpichtabteilung die Adressdaten eines Haftpichtversicherten, der auch rechtsschutzversichert ist, so ist
evtl. daf
ur Sorge zu tragen, dass auch bei den Rechtsschutzdaten die
Adresse ge
andert wird. Stimmen die Adressdaten nicht u
berein, so hat
die Marketing-Abteilung Zugri auf zwei verschiedene Adressen desselben Kunden. Die Adressen unterscheiden sich evtl. nur durch kleine
orthographische Merkmale. Dies f
uhrt z. B. dazu, dass der Kunde zwei
Werbesendungen erh
alt. (Jeder Postbezieher hat vermutlich diesen Effekt schon erlebt.)
Im DBMS erhalten die verschiedenen Programme keinen Zugri auf die
physischen (d. h. die auf der Festplatte abgelegten) Dateien. Die Daten
benden sich in nicht-redundanter Form in der physischen Datenbank,
die durch das DBMS vor dem Anwender gekapselt wird.
F
ur die verschiedenen Anwendungsprogramme stellt das DBMS die
ben
otigten logischen Dateien zur Verf
ugung und u
bernimmt die konsistente Verkn
upfung der logischen Dateien mit den physischen Datenbest
anden (Abb. 2).
logische Datei 1
Programm
"Rechtsschutz"
logische Datei 2
Programm
"Marketing"
logische Datei 3
DBMS
physische
Datenbank
Andert
das Haftpichtprogramm eine Adresse in der logischen Datei 1,
so andert sich diese Adresse automatisch auch in der logischen Datei 2
in derselben Weise. Physisch ist sie nur einmal in der Datenbank enthalten und die Marketing-Abteilung greift in der logischen Datei 3 auf
ein und dieselbe Adresse zu.
Fassen wir die Nachteile der Dateisysteme zusammen:
Doppelte Datenhaltung,
Datenbanksystem
DBMSSoftware
Anwendungsprogramme / Anfragen
gespeicherte
Datenbankdefinition
(Metadaten)
gespeicherte
Datenbank
Strukturexibilit
at: Die Struktur der Daten sollte ver
anderbar
sein (man denke etwa an die Umstellung von Postleitzahl- oder
W
ahrungssystemen).
Mehrbenutzerbetrieb: gleichzeitiger Zugri mehrerer Benutzer auf
die Datenbank.
Zugangssicherungs- und Datenschutzaufgaben sollen vom DBMS unterst
utzt werden.
Gew
ahrleistung von Datenintegritat: Die Daten sollen vollst
andig
und semantisch korrekt sein.
Datensicherheit: Sicherheitsspeicherung (Backups) und Rekonstruktionsverfahren (Rollforward) sollten vom DBMS unterst
utzt werden.
Wie bei allen komplexen Softwareprodukten werden diese Forderungen
nicht s
amtlich von allen DBMS erf
ullt. Jedoch kommen ihnen viele
Produkte schon recht nahe.
Weitere Beurteilungskriterien f
ur die Qualit
at eines DBMS k
onnen f
ur
Kaufentscheidungen eine wichtige Rolle spielen:
Verf
ugbarkeit f
ur verschiedene Rechnerplattformen,
Reaktionszeiten auf Abfragen oder Datenmanipulationen (hierzu
gibt es als Richtlinie standardisierte Benchmarktests),
Ressourcennutzung,
Nationalsprachenunterst
utzung,
verf
ugbare Erg
anzungstools z. B. zur Dateneingabe, Abfragenausf
uhrung, Berichtserstellung, Ober
achenerstellung, DatenbankEntwurf, Anwendungsentwicklung, Navigation in komplexen Datenbanken, Unterst
utzung der Systemadministration.
Externe Ebene
Individuelle Benutzersicht
Konzeptionelle Ebene
gespeicherte
Datenbank
2. Formale Modelle f
ur Datenbanken
Die meisten heute eingesetzten DBMS basieren auf dem relationalen
Modell, das durch E. F. Codd in dem Artikel [Co1970] begr
undet
wurde. Das relationale Modell beruht auf dem Prinzip, dass alle Informationen in Tabellen (Relationen) abgelegt werden konnen. In diesem
Abschnitt gehen wir auf die mathematischen Grundlagen dieses Modells ein.
2. Formale Modelle f
ur Datenbanken
mit
mit
mit
mit
NAME,
TELNR,
ZINR,
PNR.
NAME
TELNR
ZINR
PNR
Mller
Schulze
4321
3241
130
217
32077
17317
Meier
Schmid
4938
4411
222
104
Huber
3241
217
22512
21314
15991
Spaltennamen <=>
Attributnamen
{TELNR,ZINR} {NAME}
{ZINR}
{NAME}
Funktionale Abh
angigkeiten werden in der Praxis nicht durch Analyse
der konkreten Relation (die sich ja andern kann), sondern durch die beabsichtigte Interpretation der Attribute festgelegt. So gilt etwa bei der
konkreten Relation MITARB die Abh
angigkeit {NAME} {PNR},
die jedoch dann nicht mehr gegeben ist, wenn zwei Mitarbeiter mit
gleichem Nachnamen in der Firma beschaftigt sind. Wir werden in
Abschnitt 4.2 nochmals genauer auf funktionale Abh
angigkeiten eingehen.
ussel f
ur R, falls
Eine Teilmenge X {A1 , . . . , An } heit Superschl
gilt
X {A1 , . . . , An }
d. h. durch einen Superschl
ussel sind die Werte aller Attribute eindeutig bestimmt, also das Element der Relation eindeutig identiziert.
X heit Schl
ussel, falls gilt
X {A1 , . . . , An }
d. h. X ist minimaler Superschl
ussel. Das ist gleichbedeutend damit, dass kein Attribut aus X entfernt werden kann, ohne dass die
Schl
usseleigenschaft verloren geht.
Man beachte, dass jeder Schl
ussel gleichzeitig auch Superschl
ussel ist!
Ein Prim
arschl
ussel ist ein beim Datenbank-Entwurf ausgezeichneter Schl
ussel. Grunds
atzlich kann jeder Schl
ussel als Primarschl
ussel
ausgew
ahlt werden. Im konkreten Fall wird man denjenigen Schl
ussel
verwenden, der am ezientesten eingesetzt werden kann, z. B. den
Schl
ussel mit den wenigsten Attributen.
Wir werden k
unftig in Relations- und Tabellendarstellungen die Attribute des Prim
arschl
ussels unterstreichen.
Attribute einer Relation, die Teil eines Schl
ussels sind, spielen in der
Datenbanktheorie eine besondere Rolle. Wir geben ihnen daher eine
spezielle Bezeichnung: Ein Attribut A einer Relation R heit prim,
falls A Teil (irgend)eines Schl
ussels ist. Ansonsten heit A nichtprim.
10
2. Formale Modelle f
ur Datenbanken
Als Entity bezeichnet man dabei ein existierendes Objekt, das von
anderen Objekten unterscheidbar ist. Ein Entitytyp stellt eine Kollektion (Objekttyp) von Entities mit gleichen Merkmalen dar. Eine
Relationship (Beziehung) ist die Assoziation mehrerer (hier: zweier)
Entities nach bestimmten Gesichtspunkten. Ein Relationship-Typ
ist schlielich ein Objekttyp von Relationships.
Die sogenannte Komplexit
at von Relationship-Typen legt man u
ber
eine Klasseneinteilung fest. Seien E 1 , E2 Entitytypen und R E1 E2
Relationship-Typ. Dann gibt es folgende Klassen von RelationshipTypen (Abb. 6):
ochstens eine Entity
1:1-Beziehung: Jeder Entity in E1 wird durch R h
in E2 zugeordnet und umgekehrt.
ochstens eine Entity
1:n-Beziehung: Jeder Entity in E2 wird durch R h
ankung in der anderen
in E1 zugeordnet (keine Beschr
Richtung).
ochstens eine Entity
n:1-Beziehung: Jeder Entity in E1 wird durch R h
ankung in der anderen
in E2 zugeordnet (keine Beschr
Richtung).
m:n-Beziehung: Beliebige Zuordnung von Entities in E 1 zu Entities in
oglich.
E2 m
1:1-Beziehung
E1
E2
1:n-Beziehung
E1
E2
n:1-Beziehung
E1
E2
m:n-Beziehung
E1
E2
= Entity
= Relationship
11
Nachname
Pid
Strae
Vorname
PERSONAL
Ort
Einstellung
Gehalt
Aid
Bezeichnung
Ort
ABTEILUNG
arbeitet_in
ist
Vorgesetzter
von
= Entity
PROJEKT
ist_zugeteilt
= Relationship
= Attribut
Projid
Name
Abb. 7: Beispiel f
ur eine durch ein
Entity-Relationship-Diagramm dargestellte Datenbank
12
2. Formale Modelle f
ur Datenbanken
13
2.4.1. Selektionsoperationen
Auswahl (Select):
Dies ist die Auswahl von Datens
atzen einer Relation, die bestimmte
Bedingungen erf
ullen, i. Z. bedingung (R).
Beispiel 2.7.: Die Auswahl aller Datens
atze der Relation PERSONAL, deren Attributwert des Attributes Aid gleich 5 ist, geschieht
mit:
Aid=5 (P ERSON AL) =
{(205,Huber,Hilde,Passauer Str. 2a,Augsburg,
27.05.1991,4995.05,57,5),
(57,Klement,Karl,Kirchfeldstr. 3,Bad T
olz,
04.10.1990,6011.44,350,5)}
Projektion:
Darunter verstehen wir die Auswahl bestimmter Spalten einer Tabelle
(= Werte bestimmter Attribute einer Relation), i. Z. attribut liste (R).
Beispiel 2.8.: Auswahl der Spalten Ort und Aid aus der Relation
14
2. Formale Modelle f
ur Datenbanken
PERSONAL:
Ort,Aid (P ERSON AL) =
{(M
unchen,8), (Augsburg,5), (Freising,8),
(Bad T
olz,5), (M
unchen,1)}
15
Ubersichtlichkeit
weggelassene Spalten sind durch . . . gekennzeichnet.)
Joins mit Gleichheitsbedingungen tauchen am h
augsten auf und werden als Equi-Joins bezeichnet. (Im Prinzip sind jedoch beliebige Bedingungen m
oglich.)
16
2. Formale Modelle f
ur Datenbanken
PERSONAL
Pid
Nachname
128
Meyer
Huber
Schmidt
205
107
411
57
350
...
...
Frisch
Klement
Berger
Vorges_Id
Aid
107
57
350
5
8
107
350
(NULL)
5
1
ABTEILUNG
Aid
Bezeichnung
Ort
Betriebsleitung
Auendienst
Mnchen
5
8
Produktion
Mnchen
Olching
Nachname
128
Meyer
Huber
205
107
411
57
350
Schmidt
...
...
PERSONAL.Aid
ABTEILUNG.Aid
Bezeichnung
ABTEILUNG.Ort
8
5
Produktion
Auendienst
Olching
Mnchen
8
8
Produktion
Produktion
Olching
Olching
Auendienst
Mnchen
Betriebsleitung
Mnchen
5
8
Frisch
Klement
8
5
Berger
17
NAL2 ansprechbar. Es soll nun ein Join mit der Bedingung PERuhrt werden. Die
SONAL.Vorges Id = PERSONAL2.Pid durchgef
entstehende Relation soll auf PERSONAL.Nachname und PERSONAL2.Nachname projiziert werden (Abb. 11).
PERSONAL
Pid
Nachname
128
205
Meyer
Huber
107
Schmidt
Frisch
411
57
350
...
Vorges_Id
Aid
107
57
8
5
350
107
8
8
Klement
350
Berger
(NULL)
5
1
...
=
Pid
Nachname
Vorges_Id
Aid
128
Meyer
107
205
107
Huber
Schmidt
57
350
5
8
411
57
Frisch
107
Klement
Berger
350
(NULL)
5
1
350
...
...
PERSONAL2
P ERSON AL2) =
{(Meyer,Schmidt), (Huber,Klement), (Schmidt,Berger),
(Frisch,Schmidt), (Klement,Berger)}
Man beachte, dass die Ergebnisrelation kein Tupel mit erster Komponente Berger enthalt. Dies ist durch den NULL-Wert des Attriullt niemals einen
butes Vorges Id bedingt. Ein NULL-Attributwert erf
herk
ommlichen logischen Vergleich.
18
2. Formale Modelle f
ur Datenbanken
2.4.2. Aggregationsoperationen
Es gibt eine Anzahl von Aggregationsfunktionen, die auf alle oder einen
gewissen Teil der Datensatze einer Tabelle angewendet werden:
COUNT: Z
ahlen von Datens
atzen bzw. Elementen
SUM: Aufsummieren von numerischen Werten
MINIMUM: Minimumsberechnung einer Reihe von numerischen
Werten
MAXIMUM: Maximumsberechnung einer Reihe von numerischen
Werten
AVERAGE: Berechnung des Durchschnitts (arithmetischen Mittels)
einer Reihe von numerischen Werten.
Diese Funktionen werden jeweils auf Mengen von Datens
atzen angewendet, bei denen bestimmte Attributwerte gleich sind. I. Z.
attribute zur gruppierung Ff unktion attribut, ... (R)
Tabelle PERSONAL
Pid
Nachname
128
205
107
Meyer
Huber
Schmidt
411
57
350
Frisch
Klement
Berger
group
count
...
Vorges_Id
Aid
8
...
107
57
350
107
350
5
8
8
5
(NULL)
2.5. Zusatzforderungen f
ur relationale DBMS
19
Hier wurden keine Gruppierungsattribute angegeben, da sich die Funktion auf die gesamte Tabelle beziehen soll.
2.5. Zusatzforderungen f
ur relationale DBMS
Zusatzlich zu den in Abschnitt 1.2 aufgelisteten Forderungen an allgemeine Datenbanksysteme gibt es f
ur relationale Systeme weitergehende Forderungen. Auf die wichtigsten gehen wir im folgenden kurz
ein, f
ur eine vollst
andige Darstellung sei der Leser etwa auf [Da2004]
verwiesen.
Informationsregel: Alle Informationen werden nur auf eine Weise,
n
amlich durch Attributwerte von Datens
atzen (Zeilen) in Tabellen
dargestellt.
Zugrisgarantie: Auf jeden Wert in der Datenbank kann durch
Angabe des Tabellennamens, des Spaltennamens und des Primarschl
usselwertes zugegrien werden.
Nicht bekannte Information: Es gibt einen besonderen Attributwert
NULL, der nicht vorhandene oder unbekannte Informationen darstellt. Dieser Wert kann von allen anderen Werten, die in der Datenbank gespeichert werden k
onnen, unterschieden werden.
Datenbankkatalog: Die Beschreibungen aller vorhandenen Datenbankobjekte stehen wie Benutzerdaten in Tabellenform zur Verf
ugung.
Datenbank-Sprache: Es gibt eine Sprache, die sowohl interaktiv als
auch in Applikationen verwendet werden kann und DDL-, DMLund DCL-Operationen (siehe Abb. 4 auf S. 6 sowie Abschnitt 3.3.2)
unterst
utzt.
Mengenorientierung: Insert-, Update-, Delete-Befehle auf Tabellen
arbeiten mengenorientiert (z. B. sollten zwei identische Datensatze
nicht vorkommen).
Integrit
atsunabh
angigkeit: Integrit
atsregeln werden im Datenbankkatalog abgelegt und in Datenbank-Sprache formuliert.
Uberwachung
der Datenbankintegrit
at
21
Netzwerkf
ahigkeit und Unterst
utzung von Client/Server-Umgebungen
Unterst
utzung verteilter Datenbanksysteme
Portabilit
at, d. h. Einsetzbarkeit auf verschiedenen Plattformen
Der prinzipielle Aufbau eines Datenbank-Servers und der Zugri darauf ist schematisch in Abb. 13 dargestellt.
Server host
Client host
"frontend"
Prozesse
"backend"Prozesse
..
.
Datenbank
Server
Proze
Datenbank
Netzwerk
Proze
Client host
Hauptspeicher
Datenbank
Pufferspeicher
"frontend"
Prozesse
Festplatten
speicher
Netzwerk
DatenbankDateien
22
3.2. SQL-Standards
SQL ist die Abk
urzung f
ur Structured Query Language (Strukturierte Abfragesprache). Die Sprache wurde Mitte der 70er Jahre
in den IBM-Forschungslabors entworfen. Eine erste Standardisierung
erfolgte im Jahr 1986 durch den Standard SQL-86 (dieser wird manchmal auch als SQL-87-Standard bezeichnet, da die Publikation erst Anfang 1987 erfolgte).
Es folgten die Standards SQL-89 und SQL-92; letzterer ist z. B. in
[MeSi1993] ausf
uhrlich beschrieben. Der Standard, an dem sich viele
aktuelle SQL-Implementierungen orientieren, ist Ende 1999 in Kraft
getreten und wird daher als SQL:1999 bezeichnet. 1 SQL:1999 ist sehr
umfangreich und in f
unf Teile gegliedert, die jeweils in einem eigenen
Standardisierungsdokument beschrieben werden ([SQL1999]).
SQL:1999 versucht insbesondere der Tatsache Rechnung zu tragen, dass SQL keine isolierte Abfragesprache ist, sondern mit der
Auenwelt etwa u
ber sog. Host-Programmiersprachen wie z. B.
C oder C++ kommunizieren muss. Die Hersteller von Datenbankprodukten hatten in dieser Hinsicht schon l
anger eigene (herstellerspezische) Losungen bereitgestellt; der Standard versucht nun,
einen allgemeing
ultigen Rahmen zu denieren, auch um eine gewisse
Unabh
angigkeit von Host-Applikationen und verwendeten Datenbanksystemen zu erreichen.
Die Grundlage von SQL:1999 ist Core SQL, das die Teile des Standards beinhaltet, die von einer SQL:1999-konformen Implementierung
mindestens erf
ullt werden m
ussen.
1
3.2. SQL-Standards
23
24
3.3.1. Einf
uhrende Beispiele f
ur SQL-Statements
Um vorweg einen Eindruck von SQL zu vermitteln, stellen wir im
folgenden einige der bei der Beschreibung der Datenbankoperationen
in Abschnitt 2.4 gegebenen Beispiele hier in SQL-Syntax vor. Wir
beschranken uns jetzt noch auf reine Leseoperationen, die Informationen aus der Datenbank extrahieren, jedoch nichts an der Datenbank
andern. Solche Leseoperationen werden in SQL mit dem SELECTStatement vorgenommen.
25
TabellenListe
GROUP BY aid;
GROUP BYKlausel
26
Auswahl (Select):
SELECT * FROM personal WHERE aid = 5;
Projektion:
SELECT ort, aid FROM personal;
Vereinigung:
SELECT ort FROM personal
UNION
SELECT ort FROM abteilung;
Kartesisches Produkt:
SELECT * FROM abteilung, projekt;
oder auch
SELECT * FROM abteilung CROSS JOIN projekt;
Equi-Join:
SELECT * FROM personal JOIN abteilung USING (aid);
wobei hier auch gleich die Spalte aid nur einmal in der Ergebnistabelle auftritt.
Self-Join:
SELECT r1.nachname, r2.nachname
FROM personal r1 JOIN personal r2
ON r1.vorges id = r2.pid;
Aggregation: Angestellte in jeder Abteilung:
SELECT aid, COUNT(pid) FROM personal
GROUP BY aid;
Aggregation: H
ochste Personalnummer:
SELECT MAX(pid) FROM personal;
Darunter f
allt das Erzeugen, Andern
und L
oschen von Datenbankobjekten (z. B. Tabellen) (CREATE, ALTER, DROP) sowie die Erteilung oder das Entziehen von Zugrisrechten (GRANT, REVOKE).
27
28
Jedes Objekt in der Datenbank ist einem Schema zugeordnet. Innerhalb eines Schemas m
ussen Objektnamen eindeutig sein. In Mehrbenutzersystemen ist es u
blich, f
ur jeden Benutzer ein eigenes Schema zu
denieren (analog einem Heimatverzeichnis bei Betriebssystemen).
Die Syntax (Schreibweise) f
ur die Bezeichnung von Objekten bzw. Objektteilen ist in Abb. 15 dargestellt.
objekt
schema
teil
29
3.3.4. Datentypen
Attribute von Tabellen m
ussen einem festen Datentyp zugeordnet werden.
F
ur uns interessant sind folgende SQL-Datentypen:
INTEGER
(Aquivalente
Bezeichnung: INT.) Ganze Zahlen im Intervall von 231 bis 231 1.
BIGINT
Ganze Zahlen im Intervall von 263 bis 263 1. (Der
SQL-Standard spricht hier nur davon, dass BIGINT
einen mindestens ebenso groen Darstellungsbereich
hat wie INTEGER.)
NUMERIC(p,s) Festpunktzahlen mit h
ochstens p signikanten Stellen
(d. h. die Anzahl der g
ultigen Stellen vor und hinter
dem Dezimalpunkt) und s Stellen hinter dem Dezimalpunkt (p 1, s 0). In PostgreSQL k
onnen bis zu
1000 signikante Stellen gespeichert werden.
NUMERIC(p)
entspricht NUMERIC(p,0).
REAL
Gleitpunktzahlen mit einfacher Genauigkeit. Darstellungsbereich und Genauigkeit sind implementierungsabh
angig (sowohl vom DBMS als auch von der Systemplattform, auf dem das DBMS l
auft); auf den
meisten PostgreSQL-Plattformen liegt der absolutbetragsm
aige Darstellungsbereich zwischen 10 37 und
+37
10
bei einer Genauigkeit (Anzahl der signikanten
Stellen) von 6 Dezimalstellen.
30
DOUBLE PRECISION
Gleitpunktzahlen mit doppelter Genauigkeit. Auch
hier sind Darstellungsbereich und Genauigkeit wie
bei REAL implementierungsabh
angig. Auf den meisten PostgreSQL-Plattformen liegt der absolutbetragsm
aige Darstellungsbereich zwischen 10 307 und
308
bei einer Genauigkeit von mindestens 15 Dezi10
malstellen.
CHARACTER(s) (Aquivalente
Bezeichnung: CHAR.) Zeichenketten mit
fester L
ange (Anzahl der Zeichen) von s. K
urzere Zeichenketten werden bei Speicherung in diesem Datentyp
am Ende mit Leerzeichen auf die L
ange s aufgef
ullt.
CHARACTER VARYING(s)
(Aquivalente
Bezeichnung: VARCHAR.) Zeichenketten
variabler L
ange mit einer Maximall
ange von s Zeichen.
TEXT
Zeichenketten beliebiger Lange. Dieser Typ ist nicht
im SQL-Standard deniert.
DATE
Datumsangaben.
TIME
Uhrzeitangaben.
TIMESTAMP
Zeitpunktangaben (Datum und Uhrzeit).
INTERVAL
Zeitdauer. Im SQL-Standard heit dieser Typ INTERVAL SECOND.
BYTEA
Beliebige Binardaten. Im SQL-Standard gibt es einen
ahnlichen Datentyp BINARY LARGE OBJECT.
In SQL ist es moglich, Wertelisten (in Verbindung mit entsprechenden
Vergleichsoperatoren, siehe unten) anzugeben; dazu listet man die betreenden Werte durch Kommata getrennt auf und setzt das Ganze in
runde Klammern, etwa
(Buchhaltung,Vertrieb,Einkauf)
Der spezielle Wert NULL dient zur Darstellung von unbekannten Werten in Tabellenspalten. NULL geh
ort keinem der oben beschriebenen
Datentypen an. NULL ist insbesondere nicht zu verwechseln mit der
Zahlenkonstante 0, die einen konkreten Wert, eben die Zahl Null darstellt, w
ahrend NULL einen unbekannten oder nicht verf
ugbaren Wert
darstellt. NULL wird in Ausdr
ucken gesondert behandelt (siehe unten).
3.3.5. Ausdr
ucke
Diese konnen ahnlich wie bei anderen Programmiersprachen gewohnt
gebildet werden. F
ur arithmetische Ausdr
ucke gibt es die Opera-
31
32
Datentyp s1
CHARACTER
CHARACTER
CH. VARYING
CH. VARYING
Datentyp s2
CHARACTER
CH. VARYING
CHARACTER
CH. VARYING
Ausdruck
Ergebnis
Meier LIKE M%
wahr
WMeier LIKE M% falsch
wahr
Meier LIKE M %
wahr
Mei LIKE M %
falsch
Me LIKE M %
Abb. 17: Ergebnisse von Vergleichen mit Patterns
Zusatzlich gibt es noch folgende Listenoperatoren, die mit Listen arbeiten und logische Werte liefern:
x IN liste
Testet, ob x in der liste vorkommt.
x NOT IN liste Testet, ob x nicht in der liste vorkommt.
x = ANY liste Testet, ob x mit irgendeinem Element der liste
u
bereinstimmt. Statt = kann man hier auch einen der
anderen Vergleichsoperatoren verwenden. Der Operator = ANY entspricht dem Operator IN.
33
DATE
INTERVAL
INTEGER
TIMESTAMP
TIMESTAMP INTERVAL
INTERVAL
INTERVAL , /
INTEGER
INTERVAL
INTERVAL
Abb. 18: Arithmetik mit Datums- und Zeitangaben
34
tabelle
schema
spalte
view
ausdruck
operator
ausdruck
AND
OR
ausdruck
NOT
ausdruck
ausdruck
listenoperator
ausdruck
nulloperator
funktion
ausdruck
ausdruck
CAST
ausdruck
AS
datentyp
3.3.6. Funktionen
SQL bietet f
ur die Auswertung von Ergebnissen einer Datenbankabfrage zwei Klassen von Funktionen an:
Skalare Funktionen, die auf einem Resultatwert (z. B. auch dem
Wert eines Attributs) arbeiten. Dieser Typ von Funktionen kann
in SELECT-Listen und WHERE-Klauseln verwendet werden.
Aggregationsfunktionen, die f
ur eine Gruppe von Resultatwerten (einer Gruppe von Tabellenzeilen) einen Wert liefern. Dieser Typ von
35
36
3.3.7. Datentypkonversion
Wird in einem Ausdruck ein anderer Datentyp ben
otigt, als tats
achlich
verwendet wird, so erfolgt automatisch eine Typkonversion in den
ben
otigten Datentyp, soweit dies Sinn macht. Diesen Vorgang bezeichnet man als implizite Typkonversion.
37
(keine Uberraschungen).
In F
allen, wo keine implizite Typkonversion moglich ist, aber eine Konversion gew
unscht wird bzw. erforderlich ist, muss sie mit dem speziellen CAST-Operator vorgenommen werden:
CAST (e AS t)
konvertiert den Typ des Ausdrucks e in den Datentyp t, wenn dies
sinnvoll m
oglich ist.
Spezielle Konversionsfunktionen, die beim Umwandeln von eingegebenen Daten in Datentypen der Datenbank sowie beim Ausgeben von
Werten der Datenbank zur Anwendung kommen, stellen wir in Abschnitt 3.7 vor.
38
etwas komplexer als die hier dargestellte Version; wir beschranken uns
zun
achst auf die am h
augsten ben
otigten Teile und verfeinern das
Syntaxdiagramm sp
ater bei Bedarf entsprechend.
Die folgenden Konstrukte sind dabei neu:
DISTINCT
ALL
angegeben, werden auch mehrfach vorkommende gleiche Datensatze mehrfach in die Ergebnistabelle u
bernommen.
s alias
ist der Name, den die betreende Spalte in der Ergebnistabelle erhalten soll. Wird hier nichts angegeben, so
ist der Spaltenname gleich dem Ausdruck.
t alias
join klausel
siehe Abschnitt 3.4.5. Eine join klausel kann auch einfach ein Name einer Tabelle sein.
bedingung
position
39
,
SELECT
tabelle
DISTINCT
schema
view
ALL
ausdruck
AS
s_alias
,
...
FROM
...
tabelle
schema
view
t_alias
join_klausel
...
...
WHERE
bedingung
...
...
GROUP BY
ausdruck
,
HAVING
bedingung
,
...
...
UNION
selectstatement
UNION ALL
INTERSECT
EXCEPT
...
,
ORDER BY
ausdruck
position
ASC
DESC
...
40
ASC
DESC
absteigende Sortierung.
F
ur jeden der selektierten Datens
atze werden die Werte der Spalten
bzw. Ausdr
ucke in der SELECT-Liste in die Ergebnistabelle, die dann
am Bildschirm dargestellt wird, u
bernommen.
Die FROM-Klausel kann weggelassen werden, wenn sich das SELECTStatement nicht auf Tabellen st
utzt, z. B. liefert
SELECT CURRENT TIMESTAMP;
das aktuelle Datum und die aktuelle Uhrzeit.
Einfache Beispiele f
ur SELECT-Statements hatten wir bereits in Abschnitt 3.3.1 gegeben; wir werden im folgenden genauer auf die etwas
komplexeren Konstrukte eingehen.
Die Ergebnistabelle besteht aus den Zeilen der Ergebnistabellen von abfrage 1 und abfrage 2 , wobei mehrfach vorkommende Zeilen entfernt werden.
UNION ALL wie bei UNION, aber doppelte Zeilen bleiben erhalten.
INTERSECT Die Ergebnistabelle besteht aus den Zeilen, die sowohl in
der Ergebnistabelle von abfrage 1 als auch in der von abfrage 2 auftreten.
EXCEPT
41
42
Projid
Gruppierung durch
GROUP BY
count(pid)
durch HAVING
selektiert
Name
Pid
128
ja
3
8
11
411
205
411
nein
11
107
ja
43
3.4.5. Joins
Joins dienen bekanntlich dazu, zwei oder mehr Tabellen nach gewissen Kriterien zu verkn
upfen. Diese Verkn
upfungskriterien kann man
stets als Bedingungen in einer WHERE-Klausel angeben. Der groe
Nachteil an dieser Vorgehensweise ist jedoch, dass dadurch die JoinBedingungen nicht explizit als solche zu erkennen sind (die Abfrage
kann ja auch noch andere Bedingungen enthalten).
Daher gibt es im SQL-Standard die M
oglichkeit, Joins in einer Abfrage
mit einer JOIN-Klausel explizit zu spezizieren. 5 Die Syntax einer sol5
44
view
join_klausel
t_alias
AS
join_klausel
join_klausel
INNER
LEFT
RIGHT
FULL
JOIN
join_klausel
OUTER
ON
USING
ausdruck
join_spalte
CROSS
join_klausel
JOIN
NATURAL
join_klausel
INNER
LEFT
RIGHT
FULL
OUTER
45
46
T1 JOIN T2 ON
T1 .s1 = T2 .s1 AND T1 .s2 = T2 .s2 AND . . . T1 .sn = T2 .sn
allerdings mit dem sehr erw
unschten Unterschied, dass bei der
USING-Form die Spalten s1 , s2 , . . . , sn nur einmal in der Ergebnistabelle vorkommen, wahrend bei der ON-Form diese Spalten jeweils
doppelt vertreten sind, da sie ja in T1 und T2 vorkommen. Um von der
komfortablen USING-Form zu protieren, muss man allerdings schon
beim Datenbank-Entwurf darauf achten, dass Attribute (Spalten), die
in einem Equi-Join verwendet werden sollen, jeweils den gleichen Namen haben.
Natural Inner Joins sind ein Sonderfall der Inner Joins in der
USING-Form: Hier werden alle in T1 und T2 gleichen Spaltennamen
zur Konstruktion des Equi-Join verwendet. Sind also s 1 , s2 , . . . , sn die
Namen aller Spalten, die sowohl in T1 als auch in T2 vorkommen, so
entspricht
T1 NATURAL JOIN T2
der Klausel
T1 JOIN T2 USING (s1 , s2 , . . . , sn )
Beispiel 3.10.: Wir wollen einen Equi-Join der Tabellen PERSONAL
und ZUORDNUNG u
ber das gemeinsame Attribut pid konstruieren.
Die entsprechende Verbindung der beiden Tabellen ist in Abb. 23 dargestellt. (Wir haben in die Darstellung der PERSONAL-Tabelle aus
Ubersichtsgr
unden nur die Spalten pid und nachname aufgenommen.)
ZUORDNUNG
PERSONAL
Pid
Nachname
128
205
107
411
57
350
Meyer
Huber
Schmidt
Frisch
Klement
Berger
...
Pid
Projid
128
411
107
411
205
3
11
11
3
8
=
Abb. 23: Konstruktion eines Equi-Join der
Tabellen PERSONAL und ZUORDNUNG
47
Pid
Nachname
128
Meyer
411
107
411
205
Frisch
Schmidt
Frisch
Huber
...
ZUORDNUNG.
Pid
Projid
128
411
3
11
107
411
205
11
3
8
Nachname
128
Meyer
411
107
Frisch
Schmidt
411
Frisch
205
Huber
...
Projid
3
11
11
3
8
48
Man sieht hier sehr deutlich, dass sich entsprechende Abfragen bei
Ausnutzung der durch die Tabellenstruktur festgelegten Gegebenheiten wesentlich k
urzer und pr
agnanter formulieren lassen.
Das folgende Beispiel zeigt die Konstruktion eines Natural-Join mit
drei Tabellen.
Beispiel 3.11.: Es soll eine Liste erzeugt werden, die die Zuordnung
von Mitarbeiternamen zu Projektnamen darstellt. Jede Zeile der Ergebnistabelle soll also den Nachnamen eines Mitarbeiters und den Namen eines Projekts, dem dieser Mitarbeiter zugeordnet ist, enthalten.
Da hier die Tabellen jeweils u
ber die gleichen Spaltennamen verkn
upft
werden k
onnen, lautet die Abfrage einfach:
SELECT personal.nachname, projekt.name
FROM personal NATURAL JOIN zuordnung
NATURAL JOIN projekt;
Wir haben in dieser Abfrage in der Select-Liste die Spaltennamen mit
den Tabellennamen qualiziert, um klarzumachen, woher die Attribute
stammen. Da die Spaltennamen jedoch hier eindeutig sind, h
atten wir
auch nur die Spaltennamen angeben k
onnen. Die Konstruktion des
Join ist mit den relevanten Spalten der beteiligten Tabellen in Abb. 26
gezeigt.
Obwohl die Syntax der obigen Abfrage den Eindruck erweckt, dass die
drei Tabellen gleichzeitig miteinander verkn
upft werden (das Resultat der gesamten Abfrage entspricht auch wirklich dieser Vorstellung),
wird bei der Ausf
uhrung der Abfrage tats
achlich erst PERSONAL mit
ZUORDNUNG und dann das Resultat mit PROJEKT verkn
upft, da
die Joins, wenn sie nicht geklammert sind, von links nach rechts abgearbeitet werden. Wollen wir erreichen, dass zun
achst ZUORDNUNG
mit PROJEKT und das Resultat dann mit PERSONAL verkn
upft
wird, m
ussen wir Klammern setzen:
SELECT personal.nachname, projekt.name
FROM personal NATURAL JOIN
(zuordnung NATURAL JOIN projekt);
Das Ergebnis ist aber dasselbe wie bei der ungeklammerten JOINKlausel. Das ist nicht weiter verwunderlich, da es bei Inner Joins f
ur
das Ergebnis nicht auf die Ausf
uhrungsreihenfolge ankommt (diese
kann aber wohl Auswirkungen auf die Ezienz der Abfrage haben).
ZUORDNUNG
Pid
Nachname
Pid
128
205
107
Meyer
128
Huber
Schmidt
411
107
11
11
411
57
Frisch
411
205
3
8
350
Klement
Berger
49
PROJEKT
Projid Name
Projid
SELECT ...
PERSONAL.nachname
Meyer
Huber
Schmidt
Frisch
Frisch
PROJEKT.name
Druckauftrag Fa. Karl
Beratung Fa. Seidl
Werbung Fa. Rieger
Werbung Fa. Rieger
Druckauftrag Fa. Karl
50
R2.NACHNAME
Schmidt
Klement
Berger
Schmidt
Berger
51
R2.NACHNAME
Schmidt
Klement
Berger
Schmidt
Berger
R1.NACHNAME
Huber
Meyer
Frisch
Schmidt
Klement
R2.NACHNAME
Klement
Schmidt
Schmidt
Meyer
Huber
Berger
Berger
Frisch
b)
52
PERSONAL.PID COUNT(PROJID)
57
0
107
1
128
1
205
1
350
0
411
2
b)
ZUORDNUNG
Pid
128
411
107
411
205
NULL
Projid
3
11
GROUP BY
pid
COUNT(projid)
Pid
128
Projid
3
205
107
8
11
411
411
11
3
57
350
NULL
NULL
0
0
1
1
1
11
3
8
NULL
53
54
GROUP BY aid
);
In der Unterabfrage werden zun
achst die Mitarbeiterzahlen in den einzelnen Abteilungen bestimmt; f
ur die Hauptabfrage interessiert nur
diejenige Abteilung, deren Mitarbeiterzahl groer oder gleich allen
Mitarbeiterzahlen in den Abteilungen ist.
Die eben beschriebene Art von Subquery wird bei Ausf
uhrung der
umschlieenden Anweisung genau einmal ausgef
uhrt.
Korrelierte Subquerys werden hingegen f
ur jeden Datensatz, den
das die Subquery umschlieende Statement bearbeitet, ausgef
uhrt.
Eine korrelierte Subquery liegt dann vor, wenn in der Subquery eine
Tabelle der Hauptquery verwendet wird, die nicht in der TabellenListe der Subquery vorkommt. Liegt etwa eine SELECT-Abfrage der
folgenden Form vor:
SELECT . . . FROM T1
WHERE T1 .a IN (
SELECT . . . FROM T2
WHERE T1 .b = T2 .c
);
so ist die Subquery korreliert, da innerhalb der Subquery Bezug auf
die Tabelle T1 genommen wird, die jedoch in der FROM-Liste der
Subquery nicht vorkommt (die Namen T1 und T2 seien hierbei verschieden). Folglich ist T1 die Tabelle aus der Hauptquery; dort kommt
sie auch in der FROM-Liste vor.
Beispiel 3.18.: F
ur jede Abteilung soll der Abteilungsname zusammen mit dem Mitarbeiter mit der hochsten Personalnummer ausgegeben werden:
SELECT bezeichnung, nachname
FROM personal p JOIN abteilung USING (aid)
WHERE p.pid = (
SELECT MAX(pid) FROM personal
WHERE p.aid = aid
);
Zu beachten ist, dass innerhalb einer Subquery keine ORDER BYKlausel vorkommen darf. Diese ware ohnehin sinnlos, da die Resultate
einer Subquery ja nicht direkt zur Ausgabe verwendet werden.
55
56
PERSONAL.Nachname
128
205
Meyer
Huber
107
411
Schmidt
Frisch
411
Frisch
...
ZUORDNUNG.Projid
3
8
...
11
11
projid <> 11
57
58
59
view
CREATE VIEW
schema
...
AS
s_alias
...
subquery
60
3.6. Datenmodikationen
3.6.1. Einf
ugen von Daten in eine Tabelle
Mit der Anweisung INSERT INTO werden eine oder mehrere Zeilen
in eine Tabelle eingef
ugt. Das Syntaxdiagramm dieser Anweisung ist
in Abb. 33 zu sehen.
tabelle
INSERT INTO
schema
view
spalte
...
,
...
VALUES
ausdruck
DEFAULT VALUES
subquery
Hier bedeutet:
spalte
VALUES
3.6. Datenmodikationen
61
62
Man beachte die Angabe von DISTINCT in der Subquery, damit jeder
Ort nur einmal aufgenommen wird.
Bei Datenbanksystemen, die die Modizierung von Views unterst
utzen, kann eine INSERT INTO-Operation auch auf Views angewendet werden. Diese Operation andert dann in Wirklichkeit die
Basistabelle, auf die sich die View st
utzt. Damit eine View modizierbar ist, muss sie allerdings eine bestimmte Struktur aufweisen
im Prinzip dergestalt, dass in eine View einzuf
ugende Datens
atze eindeutig auf Datens
atze in der Basistabelle abgebildet werden k
onnen.
Damit d
urfen modizierbare Views keine Konstrukte wie Joins, Mengenoperatoren, GROUP BY-Klauseln, Aggregationsfunktionen sowie
den DISTINCT-Operator enthalten.
In PostgreSQL ist INSERT INTO bei Views zunachst nicht moglich.
Eine PostgreSQL-spezische Methode, dies doch und mit einer
gr
oeren Flexibilit
at als im SQL-Standard zu erm
oglichen, wird in
Abschnitt 3.6.4 vorgestellt.
3.6.2. Andern
bereits vorhandener Daten
Mit der Anweisung UPDATE (Abb. 34) werden ein oder mehrere bereits vorhandene Datens
atze in einer Tabelle geandert.
...
tabelle
UPDATE
schema
view
,
...
SET
spalte
...
ausdruck
(
subquery
...
WHERE
bedingung
Hier bedeutet:
spalte
Name der Spalte, die aktualisiert werden soll.
ausdruck legt den neuen Wert f
ur die betreende Spalte fest.
3.6. Datenmodikationen
subquery
WHERE
63
64
F
ur das Andern
von Daten in Views gelten die gleichen Einschrankungen wie bei INSERT INTO.
3.6.3. L
oschen von Daten
Die Anweisung DELETE FROM (Abb. 35) l
oscht Datensatze aus einer
Tabelle.
DELETE
tabelle
FROM
schema
...
view
...
WHERE
bedingung
3.6. Datenmodikationen
65
CREATE RULE
name
AS
ON
SELECT
...
INSERT
UPDATE
DELETE
...
...
tabelle
TO
schema
view
...
...
WHERE
...
bedingung
NOTHING
DO
INSTEAD
sql_statement
(
sql_statement
Hierbei bedeutet:
name
Name der Regel, die deniert werden soll. Dieser muss
pro Tabelle bzw. View eindeutig sein.
66
3.6. Datenmodikationen
67
68
69
werden, also z. B. die Zahl 1234 in die Zeichenkette aus dem Zeichen
1, gefolgt von 2, gefolgt von 3, gefolgt von 4.
Da es wie oben ausgef
uhrt f
ur ein- und dieselbe Information durchaus verschiedene Repr
asentationen geben kann, w
ahlt das Datenbanksystem im konkreten Fall zun
achst eine Standarddarstellung. Diese
ist DBMS-spezisch und nicht standardisiert. Andererseits gibt es
in vielen DBMS auch die M
oglichkeit, u
ber entsprechende Umwandlungsfunktionen eine spezielle Darstellung zu erreichen. Die folgenden
Ausf
uhrungen dazu beziehen sich auf PostgreSQL, sind aber in vielen
DBMS in ahnlicher Form zu nden.
Beispiel 3.36.: Die Abfrage
SELECT pid FROM personal;
liefert erwartungsgema
128
205
107
411
57
350
wobei hier zu bemerken ist, dass die Ausgabe rechtsb
undig (alle
Hunderter-, Zehner- und Einerstellen u
bereinander) erfolgt. Will man
hingegen eine Darstellung mit einer festen Stellenzahl und f
uhrenden
Nullen haben, muss man sich der im folgenden besprochenen Konvertierungsfunktion bedienen.
Die Konvertierungsfunktion
TO CHAR(n,f )
wandelt einen numerischen Wert n in eine Zeichenkette um, wobei die
Formatzeichenkette (Formatstring) f angibt, wie die gelieferte Zeiuckliefert. F
ur jeden Teil der
chenkette aussehen soll, die TO CHAR zur
Ausgabezeichenkette enthalt f ein Formatzeichen, das die Belegung
des entsprechenden Teils der Ausgabezeichenkette festlegt.
Die wichtigsten Formatzeichen sind:
9 steht f
ur eine Stelle der Zahl. Steht auf der betreenden Position
eine f
uhrende Null, wird diese durch ein Leerzeichen dargestellt.
0 steht f
ur eine Stelle der Zahl. Eine f
uhrende Null wird auch als
Null dargestellt.
70
D
71
Bei der Eingabe von Datenbankinhalten (z. B. in einem INSERTStatement) spielen Konvertierungsfunktionen f
ur die numerischen und
Zeichenketten-Datentypen keine besonders wichtige Rolle, da u
ber die
implizite Typkonversion (siehe Abschnitt 3.3.7) bereits alles automatisch erledigt wird. Hingegen hat eine Konvertierungsfunktion f
ur Zeichenketten in Datums- oder Zeitangaben durchaus eine wichtige Berechtigung.
Obwohl PostgreSQL viel exibler bei der Erkennung von Datumsund Zeitangaben ist, als es der SQL-Standard erfordert, kommt man
in manchen F
allen nicht um eine explizite Konvertierung herum.
Nat
urlich ist eine explizite Konvertierung auch dann n
otig, wenn man
gewahrleisten will, dass Datums- und Zeitangaben in einem bestimmten Format vorgenommen werden. Die inverse Umwandlungsfunktion f
ur Zeichenketten in Datumsangaben lautet
TO DATE(s,f )
und wandelt eine Zeichenkette s im Format f (Formatzeichen wie
oben) in einen Wert vom Typ TIMESTAMP (der dann implizit je
nach Bedarf in einen Wert vom Typ DATE oder TIME ungewandelt
werden kann) um.
72
Beispiel 3.39.: Um f
ur den im Beispiel auf Seite 61 neu eingestellten
Mitarbeiter Michael M
uller das Einstellungsdatum auf den 10.02.2004
zu setzen, k
onnten wir folgende SQL-Abfrage verwenden:
UPDATE personal
SET einstellung=20040210 WHERE pid=427;
Verwendet man hingegen
UPDATE personal
SET einstellung=10.02.2004 WHERE pid=427;
so stellt man bei einem zur Kontrolle ausgef
uhrten SELECT
m
oglicherweise fest, dass hier je nach den Kongurationseinstellungen von PostgreSQL der 02.10.2004 als Einstellungsdatum gesetzt
wurde. Um zu erreichen, dass auch dieses Datumsformat richtig interpretiert wird, schreiben wir
UPDATE personal
SET einstellung=TO DATE(10.02.2004,DD.MM.YYYY)
WHERE pid=427;
Sehr interessante Moglichkeiten hat man in PostgreSQL bei der Eingabe von Intervallen. Diese werden als Stringliteral als Folge von
zahl einheit
angegeben, wobei einheit die Werte second, minute, hour, day, week,
month oder year (und die Pluralbildungen davon) haben kann. Ein
Zeitintervall von 3 Tagen, 12 Stunden und 15 Minuten kann dann
durch das Stringliteral
3 days 12 hours 15 minutes
dargestellt werden. Alternativ kann man den Stunden-, Minuten- und
Sekundenanteil auch im Format
hh:mm:ss
angeben, so dass obiges Intervall auch durch das Stringliteral
3 days 12:15:00
repr
asentiert wird.
Die Ausgabe von Intervallwerten erfolgt analog dem Eingabeformat;
der Stunden-, Minuten- und Sekundenanteil wird stets in dem oben
angegebenen Alternativformat dargestellt.
4. Datenbank-Entwurf
Im letzten Abschnitt haben wir mit einer bereits vorhandenen Datenbank (mit schon vorhandenen Tabellen) gearbeitet. In der Praxis muss
jedoch vor der Benutzung einer Datenbank erst ihr Entwurf erfolgen.
Wir wissen, dass alle Informationen in relationalen Datenbanken in
Form von Tabellen (Relationen) gespeichert werden. Folglich versteht
man unter dem Entwurf (engl.: Design) einer Datenbank die Denition geeigneter Tabellen, die die gew
unschten Informationen speichern
sollen.
Die anfallenden Informationen liegen jedoch in den meisten Fallen
nicht direkt in Relationenform vor, oder zumindest nicht in einer solchen Form, die sich gut f
ur die Darstellung in einer Datenbank eignet.
Was ist nun eine gute Form f
ur ein Relationenschema (= Relationsname + Attribute) in einer Datenbank? Hier gibt es im wesentlichen
zwei Beurteilungskriterien:
Logische Ebene: Wie leicht kann der Benutzer das Relationenschema
und die Bedeutung seiner Attribute interpretieren? Je leichter dem
Benutzer die Interpretation f
allt, umso leichter fallt ihm die Formulierung von Abfragen, und umso weniger Fehler wird er machen.
Physikalische Ebene: Wie ezient wird die auf dem Schema aufgebaute Relation gespeichert, geandert und abgerufen?
Wir werden nun Probleme behandeln, die bei schlechten Relationenschemata in Datenbanken auftreten k
onnen.
74
4. Datenbank-Entwurf
F
ur jeden Kunden sei h
ochstens ein Eintrag in BESTELLUNGEN vorhanden (dann ist {KUNDE} Schl
ussel von BESTELLUNGEN). Die
Relation habe den in Abb. 37 dargstellten Inhalt.
KUNDE
ORT
VERTRETER
MENGE
Auer
Blank
Passau
Regensburg
1
2
9
20
Christ
Dorn
Mnchen
Passau
3
1
3
5
Anderungsanomalie:
Andert
sich der zustandige Vertreter f
ur das
Gebiet Passau, m
ussen mehrere Tupel geandert werden, da die Zuordnung Vertreter Ort mehrfach in der Tabelle abgelegt ist.
L
osung: Deniere zwei Tabellen
BESTELL1 (KUNDE, ORT, MENGE)
ZUST (ORT, VERTRETER)
so dass die Information, welcher Vertreter f
ur welches Gebiet zustandig
ist, nur noch einmal abgelegt wird.
L
oschanomalie: Wird ein Kunde gel
oscht, weil z. Zt. keine Bestellungen von ihm vorliegen, geht die Information u
ber seinen Standort
verloren.
L
osung: Wir zerlegen obige Tabelle BESTELL1 weiter in
BESTELLM (KUNDE, MENGE)
und
STANDORT (KUNDE, ORT)
Somit gehen bei L
oschungen in BESTELLM keine Standortinformationen mehr verloren.
Einf
uge-(Eintrage-)Anomalie: Ein neuer Datensatz kann nur dann
in BESTELLUNGEN eingetragen werden, wenn alle vier Attributwerte bekannt sind (nach dem theoretischen Relationenmodell m
ussen
bei einem Element der Relation alle Werte bekannt sein NULL-Werte
gibt es im theoretischen Relationenmodell nicht). In der Praxis wird
75
76
4. Datenbank-Entwurf
NAME
HOBBIES(HNAME,PRIOR)
17
Beyer
22
9
63
Schneider
Mitterer
Schmitt
{(Theater,1), (Reisen,1)}
{(Wandern,1), (Schwimmen,2)}
{(Radfahren,1)}
77
78
4. Datenbank-Entwurf
NR
NAME
NR
HNAME
PRIOR
17
Beyer
Schneider
Mitterer
Schmitt
17
Radfahren
17
17
22
22
9
9
63
Musikhren
Schwimmen
Theater
Reisen
Wandern
3
2
1
1
1
1
2
22
9
63
Schwimmen
Radfahren
79
{PLCODE} {PLCODE,SAAL,PLATZ,REIHE,
PREIS,GROESSE}
a2: {SAAL,PLATZ}
{PLCODE,SAAL,PLATZ,REIHE,
PREIS,GROESSE}
Nat
urlich ist die Saalgr
oe durch die Saalnummer bestimmt:
a3: {SAAL}
{GROESSE}
Zusatzlich nehmen wir an, dass der Preis eines Platzes nur durch seine
Reihe bestimmt ist:
a4: {REIHE}
{PREIS}
a1:
SAAL
PLATZ
REIHE
PREIS
GROESSE
a1
a2
a3
a4
Das Attribut GROESSE ist von {SAAL}, einer echten Teilmenge des
Schl
ussels {SAAL,PLATZ}, funktional abh
angig und verletzt somit
die Bedingung f
ur die zweite Normalform.
Wir normalisieren, indem wir das storende Attribut GROESSE
aus KINO entfernen (das verbleibende Relationenschema nennen wir
KINO1) und zusammen mit dem Attribut SAAL, von dem GROESSE
abh
angig ist, in ein eigenes Relationenschema KINO2 aufnehmen. (In
diesem ist logischerweise SAAL ein Schl
ussel.) Es ergibt sich also das
in Abb. 41 dargestellte Bild.
W
ahrend im urspr
unglichen Relationenschema KINO noch eine
Anderungsanomalie
bei der Anderung
der Zahl von Sitzpl
atzen in einem Saal vorhanden war, ist diese Anomalie durch die Normalisierung
verschwunden.
80
4. Datenbank-Entwurf
KINO1
PLCODE
SAAL
PLATZ
REIHE
PREIS
a1
a2
a4
KINO2
SAAL
GROESSE
a3
Anderungsanomalien
bei Anderung
des Eintrittspreises sind durch den
81
KINO1B
SAAL
PLATZ
REIHE
a1
REIHE
PREIS
a4
a2
KINO2
SAAL
GROESSE
a3
82
4. Datenbank-Entwurf
KINO
28 Bytes
KINO1A 16 Bytes
KINO1B 12 Bytes
KINO2
8 Bytes
4.3. Dekomposition
Bei der Herstellung der zweiten oder dritten Normalform hatten wir
storende funktionale Abh
angigkeiten durch Aufspaltung einer Relation in zwei Relationen entfernt. Dieses Verfahren kann auf beliebige
funktionale Abh
angigkeiten angewendet werden und funktioniert formal wie folgt:
Sei R(A) Relationenschema mit Attributmenge A. Seien X, Y A
und gelte X Y . Dann heien die Relationenschemata
R1 (A \ Y )
und
R2 (X Y )
4.3. Dekomposition
83
ORT
VERTRETER
MENGE
ZUST
ORT
MENGE
ORT
VERTRETER
Wie man leicht erkennt, ist sowohl BESTELL1 als auch ZUST in drit
ter Normalform. Wir haben nun zwar die Anderungsanomalie
f
ur die
Zuordnung Vertreter Ort beseitigt, aber die in Abschnitt 4.1 beschriebene Loschanomalie bleibt bestehen. Um diese zu beseitigen, ist
eine Dekomposition der Relation BESTELL1 bez
uglich der funktionalen Abh
angigkeit {KUNDE} {ORT} erforderlich. Das Resultat
sieht man in Abb. 45.
BESTELL1A
KUNDE
MENGE
ZUST
ORT
VERTRETER
BESTELL1B
KUNDE
ORT
84
4. Datenbank-Entwurf
tabelle
CREATE TABLE
schema
,
...
spalte
datentyp
DEFAULT
ausdruck
...
spalten_constraint
tabellen_constraint
...
AS
subquery
Hierbei bedeutet:
spalte
datentyp
DEFAULT ausdruck
AS subquery
tabellen constraint
spalten constraint
85
immer anzugeben, sofern nicht mit einer ASKlausel gleichzeitig Daten in die Tabelle eingef
ugt werden.
Bezeichnet den Standardwert, der beim Einf
ugen neuer Datenwerte in die betreende
Spalte eingetragen wird, wenn beim Einf
ugen
kein Wert daf
ur angegeben ist.
Die Werte der durch die Unterabfrage gelieferten Ergebnistabelle werden sofort in die neu denierte Tabelle eingef
ugt. Bei dieser Form des
CREATE TABLE-Statements d
urfen bei der
Spaltendenition keine Datentypen angegeben
werden, da sich diese aus der Unterabfrage ergeben.
siehe Abschnitt 4.4.3.
siehe Abschnitt 4.4.3.
86
4. Datenbank-Entwurf
Augsburg
Bad T
olz
Freising
M
unchen
Mit dem SQL-Befehl DROP TABLE kann man eine Tabelle (einschlielich aller enthaltenen Datens
atze) l
oschen.
Beispiel 4.9.: L
oschen der gerade erzeugten Tabelle WOHNORTE:
DROP TABLE wohnorte;
4.4.2. Andern
von Tabellendenitionen
Die Denition einer bereits vorhandenen Tabelle kann mit ALTER
TABLE geandert werden (Abb. 47).
schema
...
ADD
...
tabelle
ALTER TABLE
COLUMN
spalte
datentyp
spalten_constraint
tabellen_constraint
ALTER
COLUMN
spalte
SET DEFAULT
DROP DEFAULT
SET
NOT NULL
DROP
DROP
COLUMN
CONSTRAINT
spalte
constraint
87
Hierbei bedeuten:
ADD
Hinzuf
ugen einer neuen Spalte oder eines Tabellenconstraints. F
ur alle Datens
atze, die sich bereits in
der Tabelle benden, erh
alt die neue Spalte einen
NULL-Wert.
ALTER
Setzen bzw. Loschen von DEFAULT-Werten einer
Spalte sowie Setzen und Loschen von NOT NULLConstraints (siehe folgenden Abschnitt). Die Formen SET NOT NULL und DROP NOT NULL sind
nicht im SQL-Standard enthalten.
DROP COLUMN
Die angegebene Spalte wird aus der Tabelle entfernt. Dabei gehen selbstverst
andlich auch alle Inhalte der betreenden Spalte verloren.
DROP CONSTRAINT Entfernt den Constraint mit dem Namen constraint
aus der Tabellendenition.
Beispiel 4.10.: Die Tabelle PERSONAL soll um eine Spalte Zulage erganzt werden, in der besondere Zahlungen, die ein Mitarbeiter
zus
atzlich zum normalen Gehalt erh
alt, erfasst werden. Es wird angenommen, dass die Zulagen kleiner als 1000 EUR sind und auf Cent
genau angegeben werden:
ALTER TABLE personal ADD zulage NUMERIC(5,2);
Beispiel 4.11.: Um die soeben angelegte Spalte Zulage wieder zu
l
oschen, gibt man die Anweisung
ALTER TABLE personal DROP COLUMN zulage;
4.4.3. Constraints
Um die Verwaltung von Tabellen zu erleichtern sowie die Integritat einer Datenbank zu sichern, kann man Integrit
atsbedingungen (integrity
constraints) f
ur Tabellen festlegen.
Es gibt folgende Integrit
atsbedingungen:
NOT NULL-Constraint auf Spalten. Dieser stellt sicher, dass die
betreende Spalte niemals einen NULL-Wert enthalt.
UNIQUE-Constraint auf einer Menge von Spalten. Damit wird sichergestellt, dass in der betreenden Spaltenmenge kein Eintrag
ausgenommen eventuelle NULL-Werte doppelt auftritt.
PRIMARY KEY-Constraint auf einer Menge von Spalten. Dieser
Constraint legt den Primarschl
ussel der Tabelle fest und stellt sicher,
88
4. Datenbank-Entwurf
Anderung
von Datens
atzen m
ussen die resultierenden Datensatze die
vorhandenen Constraints erf
ullen. Auch das L
oschen von Datens
atzen
aus Tabellen ist nur dann moglich, wenn dadurch keine vorhandenen
Constraints verletzt werden.
Die Syntax der Constraintdenition im CREATE TABLE- bzw. ALTER TABLE-Statement geht aus Abb. 48 (Tabellenconstraints) bzw.
Abb. 49 (Spaltenconstraints) hervor.
Hierbei bedeutet:
CONSTRAINT
FOREIGN KEY
REFERENCES
89
...
constraint
CONSTRAINT
...
UNIQUE
PRIMARY KEY
...
spalte
,
FOREIGN KEY
spalte
REFERENCES
tabelle
schema
spalte
ON DELETE CASCADE
CHECK
bedingung
...
DEFERRABLE
INITIALLY DEFERRED
NOT DEFERRABLE
INITIALLY IMMEDIATE
ON DELETE
CASCADE
DEFERRABLE
NOT DEFERRABLE Hier wird festgelegt, ob die normalerweise sofort
nach Ausf
uhrung eines Statements stattndende
Pr
ufung auf G
ultigkeit eines Constraints auf einen
sp
ateren Zeitpunkt n
amlich dem Ende einer Transaktion (siehe Abschnitt 5.1) verlegt werden kann.
Standardm
aig ist keine Verlegung m
oglich (NOT
DEFERRABLE); wenn diese moglich sein soll, muss DEFERRABLE angegeben werden.
90
4. Datenbank-Entwurf
...
CONSTRAINT
...
constraint
UNIQUE
PRIMARY KEY
NOT NULL
REFERENCES
tabelle
schema
spalte
.
ON DELETE CASCADE
CHECK
bedingung
...
DEFERRABLE
INITIALLY DEFERRED
NOT DEFERRABLE
INITIALLY IMMEDIATE
INITIALLY DEFERRED
INITIALLY IMMEDIATE
Hier legt man den grunds
atzlichen Zeitpunkt der
Pr
ufung der Constraintg
ultikeit fest. INITIALLY
IMMEDIATE bedeutet, dass die G
ultigkeit nach jedem
Statement gepr
uft wird (dies kann jedoch, soweit
zus
atzlich DEFERRABLE angegeben ist, geandert werden). Bei INITIALLY DEFERRED wird die G
ultigkeit
erst am Transaktionsende gepr
uft (dies kann jedoch in einer Transaktion ge
andert werden). Ist
diese Klausel nicht angegeben, wird INITIALLY IMMEDIATE angenommen. In PostgreSQL besteht im
Gegensatz zum SQL-Standard die Einschr
ankung,
dass der DEFERRED-Modus nur f
ur FOREIGN
KEY-Constraints gew
ahlt werden kann.
Beispiel 4.12.: Am Beispiel unserer Firmendatenbank wollen wir die
Verwendung von Constraints im praktischen Beispiel demonstrieren:
Prim
arschl
ussel:
PERSONAL: {Pid}
ABTEILUNG: {Aid}
PROJEKT: {Projid}
91
92
4. Datenbank-Entwurf
93
Mit der ON DELETE CASCADE-Klausel bei der Denition des entsprechenden Constraints liee sich dies auch automatisieren.
4.4.4. Indizes
Indizes sind Strukturen, die auf Tabellen eingerichtet werden k
onnen.
Mit Hilfe eines Index laufen Zugrie auf Daten in der Tabelle im allgemeinen schneller ab als ohne Index. Die Syntax f
ur Datenbankabfragen
andert sich bei Verwendung eines Index nicht; ein Index wirkt sich lediglich auf die Ausf
uhrungsgeschwindigkeit eines Tabellenzugris aus.
Ein Index auf eine Datenbanktabelle kann mit einem Index am Schluss
eines Buches verglichen werden: Anstatt das ganze Buch von vorn bis
hinten nach der gew
unschten Information zu durchsuchen, konsultiert
man den Index, der direkt die Stelle angibt, an der die Information
steht.
Sobald man einen Index erzeugt, wird er automatisch vom Datenbank
system benutzt und verwaltet, d. h. alle Anderungen
an den Daten der
Tabelle werden auch im Index ber
ucksichtigt.
Jeder Index einer Tabelle wird auf einer Menge von Spalten deniert.
Es werden dann in Abfragen die Tabellenzugrie beschleunigt, die in
der WHERE-Klausel Bezug auf eine indizierte Spalte nehmen. Abfragen mit ORDER BY-Klausel werden ebenfalls beschleunigt, wenn
sie nach indizierten Spalten sortiert werden.
Es ist m
oglich und durchaus sinnvoll, mehrere Indizes auf einer Tabelle
94
4. Datenbank-Entwurf
M S
F H
Berger
Frisch
Huber
Klement Meyer
Mller
Schmidt
PERSONAL
128 Meyer
205
107
411
Huber
Schmidt
Frisch
57
350
Klement
Berger
Mller
427
...
...
...
...
...
...
...
Aus dem Beispiel wird deutlich, dass das Aufsuchen des Datensatzes
M
uller ohne Index 7 Zugrie ben
otigt (da es der letzte Datensatz ist,
muss die gesamte Tabelle durchsucht werden), bei Verwendung des
Index werden hingegen nur 3 Zugrie ben
otigt (Besuch der Knoten
K, M
u S, M
uller).
Ein Index wird umso ezienter, je mehr Eintr
age die Tabelle enth
alt.
Ein Index wird mit dem Kommando CREATE INDEX erzeugt
(Abb. 51).
Hierbei bedeutet:
index Name des zu erzeugenden Index.
ON
Tabelle, auf der der Index erzeugt wird.
spalte Liste der Spalten, auf denen der Index deniert werden soll.
95
CREATE INDEX
schema
...
tabelle
ON
schema
...
index
spalte
5. Datenbankbetrieb
In diesem Abschnitt soll auf praktische Probleme im laufenden Datenbankbetrieb und ihre Handhabung mit SQL eingegangen werden.
Anderungen,
die mit DML-Statements am Datenbestand vorgenommen werden, sind zun
achst nur vorl
aug sie konnen mit DCLStatements entweder endg
ultig ausgef
uhrt oder zur
uckgenommen werden. Dies ist die Grundlage des Transaktionskonzepts.
Eine Transaktion ist eine logisch zusammengehorende Folge von Datenbankoperationen (die u
ber SQL-Statements realisiert werden). Eine
Transaktion ist unteilbar (atomar): Entweder alle durch die Transak
tion bewirkten Anderungen
werden in die Datenbank u
bernommen
m
ussen entweder alle durch die Transaktion bewirkten Anderungen
u
bernommen oder aber alle Anderungen
verworfen werden. Die
Ubernahme
ndet statt, wenn das COMMIT-Statement ausgef
uhrt
wird. Wird wegen eines Systemabsturzes COMMIT nicht ausgef
uhrt,
97
Zeit
START TRANSACTION;
UPDATE girokonto
SET saldo = saldo 1000
WHERE kontonr = 24637;
UPDATE sparkonto
SET saldo = saldo + 1000
WHERE kontonr = 90955;
COMMIT;
98
5. Datenbankbetrieb
5.2. Mehrbenutzerbetrieb
Im praktischen Einsatz von Datenbanksystemen bedeutet Mehrbenutzerbetrieb nicht nur, dass mehrere Benutzer jeweils gleichzeitig auf
ihre eigenen Tabellen zugreifen, sondern vor allem, dass mehrere Benutzer parallel auf die gleichen Tabellen zugreifen k
onnen. Bei parallelen Zugrien auf die gleichen Daten konnen folgende Probleme auftreten:
dirty reads:
Eine Transaktion T1 liest Daten einer Transaktion T2, die noch nicht
mit COMMIT permanent gemacht wurden. T1 liest also Daten, die
noch gar nicht wirklich existieren.
Nicht wiederholbare Leseoperationen (nonrepeatable reads):
In einer Transaktion liefern zwei identische Abfragen verschiedene
Resultate, wenn zwischen der Ausf
uhrung der beiden Abfragen eine
Verlorene Anderungen:
Andern
der gesperrten Daten durch andere Transaktionen. Der Lesezugri durch andere Transaktionen wird nicht eingeschr
ankt.
5.2. Mehrbenutzerbetrieb
99
Man kann Sperren auf ganze Tabellen oder nur auf gewisse Datensatze
anwenden.
Kann eine Transaktion eine Sperre nicht setzen, weil eine andere bereits gesetzte Sperre dies verhindert, wartet die Transaktion, bis das
Setzen der Sperre wieder moglich ist. Hierdurch kann es zu sogenannten Deadlock-Situationen kommen, in denen zwei Transaktionen gegenseitig auf die Freigabe von Datens
atzen warten.
In Abb. 53 ist eine typische Deadlock-Situation dargestellt.
Transaktionen
Zeit
T1
T2
Sperren
D1
D2
X (T1)
Lese D1
ndere D2
Gib alle Sperren frei
X (T2)
Deadlock
T1 wartet auf Freigabe von D2 durch T2,
was niemals passiert, da gleichzeitig
T2 auf Freigabe von D1 durch T1 wartet.
dirty reads
m
oglich
nicht m
oglich
nicht m
oglich
nicht m
oglich
nonrep. reads
m
oglich
m
oglich
nicht m
oglich
nicht m
oglich
phantom reads
m
oglich
m
oglich
m
oglich
nicht m
oglich
100
5. Datenbankbetrieb
In PostgreSQL gibt es nur die Transaktionsmodi READ COMMITTED und SERIALIZABLE. Der Modus einer Transaktion wird beim
Starten der Transaktion mit START TRANSACTION vorgenommen.
Die Syntax dieses Statements ergibt sich aus Abb. 55.
...
START TRANSACTION
ISOLATION LEVEL
READ COMMITTED
SERIALIZABLE
...
READ WRITE
READ ONLY
keine Anderungsabfragen
(INSERT, UPDATE, DELETE) sowie keine
Anderungen
am Datenbankschema durch DDL-Statements erlaubt.
Eine Schreib-/Lese-Transaktion kann bereits vorhandene Daten
andern (mit UPDATE und DELETE) oder auch mit der in
Abb. 56 gezeigten FOR UPDATE-Klausel eines SELECT-Statements
zur Anderung
vormerken. In diesen F
allen werden die betroenen Datens
atze automatisch mit einer Lese-Sperre versehen, so dass
Anderungen
nur von genau einer Transaktion ausgef
uhrt werden
k
onnen.
FOR UPDATE
OF
tabelle
schema
view
5.2. Mehrbenutzerbetrieb
101
Bei der FOR UPDATE-Klausel gibt man die Namen von Tabellen
an, deren selektierte Datensatze mit einer Lese-Sperre versehen werden sollen, also bei evtl. konkurrierenden Transaktionen als ge
andert
angesehen werden sollen. Sind keine Tabellen angegeben, werden die
betroenen Datens
atze aller Tabellen in der Abfrage gesperrt. Im SQLStandard muss jeweils eine Tabellenspalte angegeben werden, diese ist
jedoch irrelevant, da Sperren zeilen- und nicht feldweise gesetzt werden.
Alle Sperren werden bei Transaktionsende automatisch aufgehoben.
Das Transaktionsende ist gleichzeitig die einzige M
oglichkeit, Sperren
aufzuheben.
Dirty reads k
onnen in PostgreSQL nicht vorkommen, da w
ahrend
der Ausf
uhrung einer Abfrage stets die bei Beginn der Abfrage vorliegenden Daten verwendet werden (READ COMMITED-Modus). Man
beachte aber, dass z. B. zwei verschiedene SELECT-Statements in der
gleichen Transaktion durchaus verschiedene Resultate liefern konnen,
n
amlich dann, wenn eine andere Transaktion inzwischen Anderungen
mit COMMIT abgeschlossen hat.
Eine READ COMMITED-Transaktion T1, die Daten andern will, die
mittlerweile (seit Beginn von T1) von einer anderen Transaktion T2
102
5. Datenbankbetrieb
nur T1 die Daten letztlich andert. Wird hingegen T2 mit COMMIT beendet, so wird T1 mit einem impliziten ROLLBACK (und Fehlermeldung an die Instanz, die die Transaktion angestoen hat) abgebrochen,
denn eine Transaktion im Modus SERIALIZABLE kann keine Daten andern, die seit dem Beginn dieser Transaktion von einer anderen
Transaktion modiziert wurden T1 w
urde ja sonst moglicherweise
COMMIT;
UPDATE 1
UPDATE personal
SET gehalt=4650.55
WHERE pid=411;
NACHNAME GEHALT
Frisch
4520.67
START TRANSACTION;
T1
COMMIT;
UPDATE 1
wird verzgert,
bis T1 seine Sperre
entfernt hat
UPDATE personal
SET strasse=Goethestr. 12a
WHERE pid=411;
START TRANSACTION;
T2
entfernt Sperre
ndert Wert
setzt Sperre
entfernt Sperre
ndert Wert
setzt Sperre
Kirchfeldstr. 3
Grnaustr. 11
Karl
Bernhard
Michael
Klement
Berger
Mller
57
350
427
Hilde
Huber
128
205
Frisch
Klement
Berger
Mller
411
57
350
427
Michael
Bernhard
Friedrich
Schmidt
107
Steffi
Markus
Nachname
Meyer
Pid
Vorname
Goethestr. 12a
Friedrich
Frisch
411
Hauptstr. 5
Grnaustr. 11
Kirchfeldstr. 3
Goethestr. 12a
Mnchner Str. 7
Passauer Str. 2a
Hilblestr. 17
Strae
Hauptstr. 5
Mnchner Str. 7
Passauer Str. 2a
Hilde
Steffi
Hilblestr. 17
Schmidt
Strae
Vorname
Hauptstr. 5
Markus
Michael
Grnaustr. 11
Kirchfeldstr. 3
Karl
Bernhard
Dachauer Str. 22
Friedrich
Mnchner Str. 7
Passauer Str. 2a
Hilde
Steffi
Hilblestr. 17
Strae
Markus
Vorname
Hauptstr. 5
Grnaustr. 11
Kirchfeldstr. 3
Dachauer Str. 22
Mnchner Str. 7
Passauer Str. 2a
Hilblestr. 17
Strae
107
Huber
205
Mller
427
Nachname
Berger
350
Meyer
Klement
57
128
Frisch
411
Pid
Schmidt
Huber
205
107
Nachname
Meyer
128
Michael
Mller
427
Pid
Bernhard
Berger
Karl
Klement
57
350
Friedrich
Frisch
Steffi
Schmidt
107
411
Hilde
Huber
205
Vorname
Markus
Nachname
Meyer
128
Pid
...
...
...
...
...
...
...
...
4105.30
8748.92
6011.44
4650.55
5722.00
4995.05
4327.50
Gehalt
4105.30
8748.92
6011.44
4650.55
5722.00
4995.05
4327.50
Gehalt
4105.30
8748.92
6011.44
4650.55
5722.00
4995.05
4327.50
Gehalt
4105.30
8748.92
6011.44
4650.55
5722.00
4995.05
4327.50
Gehalt
104
5. Datenbankbetrieb
Standardverhalten wird constraintspezisch bereits bei der Denition des Constraints mit INITIALLY DEFERRED bzw. INITIALLY IMMEDIATE festgelegt.
Will man in einer konkreten Transaktion das Standardverhalten aller
oder bestimmter Constraints andern, so kann man dies mit dem SET
CONSTRAINTS-Statement erreichen, dessen Syntax in Abb. 58 dargestellt ist.
SET CONSTRAINTS
ALL
DEFERRED
constraint
IMMEDIATE
Hierbei ist zu beachten, dass ein Constraint nur dann im DEFERREDModus (am Ende einer Transaktion) gepr
uft werden kann, wenn dies
bereits bei der Constraintdenition mit der DEFERRABLE-Klausel
(siehe Abschnitt 4.4.3) erlaubt wurde.
SET CONSTRAINTS bezieht sich nur auf die aktuelle Transaktion, nach
dem Ende der Transaktion wird die G
ultigkeitspr
ufung von Constraints wieder wie bei der Constraintdenition festgelegt vorgenommen.
105
106
5. Datenbankbetrieb
INSERT
,
...
objekt_privileg
GRANT
ALL PRIVILEGES
,
...
ON
objekt
schema
TO
benutzer
PUBLIC
...
WITH GRANT OPTION
...
107
,
...
objekt_privileg
REVOKE
ALL PRIVILEGES
,
...
ON
objekt
schema
FROM
benutzer
PUBLIC
Hierbei bedeutet:
ALL PRIVILEGES
objekt
Ahnliches gilt f
ur die Entziehung von Privilegien mit REVOKE.
Bei Views ist zu beachten, dass lediglich der Eigent
umer einer View
Privilegien auf den Basistabellen haben muss. Der Grantee von Privilegien f
ur eine View ben
otigt keine Privilegien auf den Basistabellen
der View. Damit lassen sich selektive Schutzmechanismen implementieren, die alleine durch Vergabe von Privilegien nicht erreicht werden
k
onnen, wie folgendes Beispiel zeigt.
Beispiel 5.3.: In der Datenbank mit den Tabellen PERSONAL,
ABTEILUNG, PROJEKT und ZUORDNUNG gibt es die Benutzer
FIRMA, LOHNBUERO, PROJEKTMGR und PERSONALVERW.
Alle Tabellen geh
oren dem Benutzer FIRMA. Der Datenschutz soll
nun durch folgende Vorgaben realisiert werden:
Der Benutzer PROJEKTMGR soll SELECT-Zugri auf die Spalten
Id, Nachname, Vorname der Tabelle PERSONAL haben. Er soll alle
Privilegien auf den Tabellen PROJEKT und ZUORDNUNG besitzen.
108
5. Datenbankbetrieb
Nachname
Vorname
Strae
Ort
Einstellung
Gehalt
Vorges_Id
Aid
128
Meyer
Markus
Hilblestr. 17
Mnchen
Huber
Schmidt
Hilde
Steffi
Passauer Str. 2a
Mnchner Str. 7
Augsburg
Freising
4327.50
4995.05
107
205
107
19.01.1994
27.05.1991
Frisch
Klement
Friedrich
Karl
Dachauer Str. 22
Kirchfeldstr. 3
Mnchen
Bad Tlz
5722.00
4520.67
5
8
411
57
02.11.1990
14.09.1995
57
350
8
5
Berger
Bernhard
427
Mller
Michael
Grnaustr. 11
Hauptstr. 5
Mnchen
Mnchen
6011.44
8748.92
107
350
350
04.10.1990
28.05.1993
Vorname
Strae
Ort
Vorname
Strae
Ort
(NULL)
4105.30
(NULL)
(NULL)
Einstellung
Gehalt
Vorges_Id
Aid
Einstellung
Gehalt
Vorges_Id
Aid
View PBDATEN
Pid
Nachname
View PGEHDATEN
Pid
Nachname
109
110
5. Datenbankbetrieb
Benutzer
P11MGR
Lesezugriff
auf DATEN
kein Lesezugriff
auf PERSONAL
und ZUORDNUNG
DATEN
Pid
Nachname
Vorname
PERSONAL
ZUORDNUNG
Pid
Nachname
Vorname
128
205
Meyer
Huber
Markus
Hilde
...
107
Schmidt
Steffi
411
57
Frisch
Klement
Friedrich
Karl
350
Berger
Bernhard
427
Mller
Michael
(NULL)
...
Aid
Pid
Projid
8
5
8
128
411
107
3
11
11
8
5
411
205
3
8
Datenbank
FIRMA
Uber
die View DATEN ist dem Benutzer P11MGR nur Zugri auf
die dunkel hinterlegten Elemente der Tabelle PERSONAL m
oglich,
obwohl die View selbst auf alle Datens
atze der Tabellen PERSONAL
und ZUORDNUG zugreifen kann (und muss).
111
Neudenition einer bereits vorhandenen Funktion. Dies ist insbesondere in der Entwicklungsphase praktisch, da man damit die bereits vor-
113
OR REPLACE
...
name
FUNCTION
schema
RETURNS
...
rckgabetyp
...
parametertyp
,
...
AS
definition
LANGUAGE
sprache
...
...
SECURITY INVOKER
SECURITY DEFINER
114
SECURITY DEFINER Die Funktion wird im Sicherheitskontext des Benutzers, der die Funktion deniert hat (Eigent
umer), ausgef
uhrt. Damit kann in der Funktion beispielsweise der Zugri auf Objekte stattnden, auf die der Benutzer, der die Funktion aufruft, keine Rechte hat, wohl aber der Eigent
umer
der Funktion.
115
DROP
name
FUNCTION
schema
)
parametertyp
,
Funktionen kann man mit DROP FUNCTION (Abb. 64) wieder loschen;
hier sind zus
atzlich zum Namen der Funktion auch die Typen der Parameter (wie bei der Denition) anzugeben, da es in PostgreSQL (wie
z. B. auch in C++) erlaubt ist, verschiedene Funktionen mit unterschiedlicher Parameterisierung unter dem gleichen Namen zu denieren (sog. Overloading).
116
6.3. PL/pgSQL
Bei PL/pgSQL handelt es sich um eine prozedurale Sprache f
ur ein
PostgreSQL-Datenbanksystem. Die Sprache kann als Erweiterung von
SQL angesehen werden, da die bekannten SQL-Datentypen und die
meisten SQL-Konstrukte auch in PL/pgSQL-Programmen verwendet
werden k
onnen.
Wir wollen im folgenden einen Einblick in die M
oglichkeiten von
PL/pgSQL geben, ohne auf jedes einzelne Detail einzugehen. Eine
detaillierte Beschreibung der Sprache ndet sich in der PostgreSQLDokumentation [Pg2004].
Man beachte, dass die Sprachkonstrukte von PL/pgSQL in einer PostgreSQL-Datenbank nur zur Verf
ugung stehen, wenn die Sprache vom
Datenbankadministrator freigeschaltet wurde. 8
Wir setzen f
ur die folgenden Ausf
uhrungen voraus, dass der Leser Basiskenntnisse in einer konventionellen Programmiersprache (PASCAL,
C) besitzt.
PL/pgSQL ist eine blockstrukturierte Sprache: Ein PL/pgSQLProgramm (das nicht alleine, sondern nur als Body einer Funktion
auftreten kann) besteht jeweils aus einem Block. Bl
ocke konnen wiederum beliebig viele verschachtelte Unterbl
ocke enthalten.
Ein PL/pgSQL-Block besteht aus folgenden Teilen in der angegebenen
Reihenfolge:
Deklarationsteil (optional): Dient zur Vereinbarung (Deklaration)
von Variablen und Konstanten und wird mit dem Schl
usselwort DECLARE eingeleitet.
Anweisungsteil: Enth
alt eine Folge von PL/pgSQL-Statements und
SQL-Statements. Er wird mit dem Schl
usselwort BEGIN eingeleitet und mit dem Schl
usselwort END, gefolgt von einem Semikolon,
beendet.
Jede Deklaration und jedes Statement in einem Block wird durch ein
Semikolon abgeschlossen.
8
6.3. PL/pgSQL
117
BEGIN
1
2
3
4
5
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
118
Die Zeilen 36 bilden den Deklarationsteil zur Vereinbarung von Variablen und Konstanten. Als Datentypen bietet PL/pgSQL die SQLDatentypen und folgende Konstrukte:
tabelle.spalte%TYPE entspricht dem Datentyp der angegebenen Tabellenspalte.
tabelle%ROWTYPE
entspricht einem RECORD-Datentyp, wobei
die Komponenten wie die Tabellenspalten
heien und den gleichen Datentyp wie die Tabellenspalten haben.
ur den Funktionsparameter,
In Zeile 6 wird der Name for id als Alias f
der ja eigentlich mit $1 angesprochen wird, vereinbart.
Die Zeilen 722 bilden den Anweisungsteil des Programms. In den
Zeilen 810 wird Information in vereinbarte Variablen selektiert.
SELECT. . . INTO speichert das Ergebnis in die angegebenen Variablen, anstatt es (wie bei einem gewohnlichen SQL-SELECT) auf dem
Bildschirm auszugeben.
Ahnlich
wie bei der R
uckgabe von Werten einer SQL-Funktion wird
nur der erste Datensatz ber
ucksichtigt, wenn die SELECT-Abfrage
mehrere Datensatze liefern w
urde. F
ur den Fall, dass die SELECTAbfrage kein Ergebnis liefert, werden die angegebenen Variablen
auf NULL gesetzt. Die spezielle Systemvariable FOUND gibt nach
Ausf
uhrung einer SELECT. . . INTO-Abfrage Aufschluss dar
uber, ob
die Abfrage mindestens einen Datensatz geliefert hat in diesem Fall
hat FOUND den logischen Wert true, sonst false.
In den Zeilen 1117 bendet sich eine IF. . . THEN. . . ELSE-Kaskade,
die jeweils den Erh
ohungsfaktor auf unterschiedliche Werte setzt.
Das RETURN-Statement in Zeile 21 ist wichtig, da PL/pgSQLFunktionen immer mit RETURN beendet werden m
ussen. Wenn die
Funktion ein Ergebnis liefern soll, muss als Argument von RETURN
der gew
unschte Wert angegeben werden; in unserem Fall einer voidFunktion geben wir nur RETURN an.
Zuweisungen an Variablen geschehen in PL/pgSQL mit
variable := ausdruck ;
Bei Ausdr
ucken k
onnen die gleichen Operationen und Funktionen wie
in interaktivem SQL verwendet werden (soweit dies im Einzelfall sinnvoll ist).
6.3. PL/pgSQL
119
6.3.2. Kontrollstrukturen
Hierunter versteht man Sprachkonstrukte, die die normale Ausf
uhrungsreihenfolge von Anweisungen (sequentiell, also eine Anweisung nach der anderen) beeinussen.
Bedingte Ausf
uhrung (Verzweigung):
1. Form: IF bedingung THEN anweisungen
END IF;
2. Form: IF bedingung THEN anweisungen
ELSE anweisungen
END IF;
3. Form: IF bedingung THEN anweisungen
ELSIF bedingung THEN anweisungen
ELSE anweisungen
END IF;
Einfache Schleife:
LOOP anweisungen END LOOP;
Das Verlassen der Schleife ist mit EXIT m
oglich:
EXIT;
f
uhrt immer zum Verlassen der Schleife,
EXIT WHEN bedingung;
nur dann, wenn die bedingung erf
ullt (TRUE) ist.
WHILE-Schleife:
WHILE bedingung LOOP anweisungen END LOOP;
FOR-Z
ahlschleife:
FOR zaehler IN untergrenze..obergrenze
LOOP anweisungen
END LOOP;
untergrenze und obergrenze m
ussen ganzzahlig sein.
Folgende Ersatzdarstellung entspricht obiger FOR-Schleife:
zaehler := untergrenze;
WHILE zaehler <= obergrenze LOOP
anweisungen
zaehler := zaehler + 1;
END LOOP;
120
OPEN c1;
weitere FETCH
Operationen
cursor
CLOSE c1;
Ergebnistabelle
128
Meyer
205
107
Huber
Schmidt
411
57
Frisch
Klement
350
Berger
427
Mller
128
nn
cursor
Meyer
6.3. PL/pgSQL
121
BEGIN
1
2
3
4
5
OPEN cpnum;
LOOP
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
END LOOP;
26
CLOSE cpnum;
27
RETURN;
28
29
END;
LANGUAGE plpgsql;
122
Man beachte, dass nach jeder FETCH-Operation die spezielle Variable FOUND Aufschluss dar
uber gibt, ob noch ein weiterer Datensatz
vorhanden war. Dies nutzen wir, um in Zeile 11 ggf. die Schleife zu
verlassen, weil alle Datensatze behandelt wurden.
Beispiel 6.5.: Finden des Namens und der Personalnummer des Mitarbeiters mit dem niedrigsten Gehalt. (Dieses Beispiel kann nat
urlich
auch in interaktivem SQL programmiert werden. Es eignet sich jedoch
6.3. PL/pgSQL
1
2
3
4
5
6
7
8
9
10
123
11
12
minid := 0;
13
OPEN c1;
14
LOOP
15
16
17
18
19
20
21
22
END LOOP;
23
CLOSE c1;
24
26
27
RETURN;
25
28
29
END;
LANGUAGE plpgsql;
6.3.4. Fehlerbehandlung
Eine Funktion kann in vielen verschiedenen Kontexten aufgerufen werden (z. B. auch automatisch als Trigger, wie wir in Abschnitt 6.4 sehen
werden), wo es nicht unbedingt die M
oglichkeit gibt, eine Fehlersituation etwa durch Abfrage eines von der Funktion zur
uckgelieferten
Fehlercodes festzustellen.
Daher gibt es in PL/pgSQL die M
oglichkeit, eine sogenannte Ausnahmebedingung (engl. Exception) anzustoen, die den Abbruch
124
BEGIN
1
2
3
4
5
minid := 0;
10
11
12
13
14
15
16
17
18
FOR my_rec IN
SELECT pid, nachname, gehalt
FROM personal
LOOP
IF minid = 0 OR my_rec.gehalt < mingeh THEN
minid := my_rec.pid;
mingeh := my_rec.gehalt;
minname := my_rec.nachname;
END IF;
19
END LOOP;
20
21
22
23
24
25
RETURN;
END;
LANGUAGE plpgsql;
6.3. PL/pgSQL
125
des Projekts, dem der betreende Mitarbeiter zugeordnet ist. Ist der
Mitarbeiter keinem oder mehr als einem Projekt zugeordnet, wird die
Funktion mit einer Ausnahmebedingung abgebrochen.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
126
Id
350
128 Meyer
107 Schmidt
350
107
411 Frisch
Name
Vorges_Id
Berger
57 Klement
107
350
205 Huber
57
6.3. PL/pgSQL
127
In der Praxis tauchen oft verschiedene Fragestellungen im Zusammenhang mit diesen hierarchischen Strukturen auf. Bei unserer
PERSONAL-Tabelle konnen dies etwa folgende Probleme sein:
a) Hierarchiestufe eines Mitarbeiters, d. h. Anzahl der ihm u
bergeordneten Vorgesetzten.
b) Anzahl der direkten und indirekten Untergebenen eines Mitarbeiters.
Die Antwort auf Problem a) l
asst sich folgendermaen nden:
Alle Mitarbeiter, bei denen das Attribut vorges id NULL ist, benden sich auf Hierarchiestufe 0.
Sei r1 Vorgesetzter von r2 . Dann ist die Hierarchiestufe von r2 um 1
gr
oer als die Hierarchiestufe von r 1 .
Um die Hierarchiestufen alle Mitarbeiter zu ermitteln, ist also
ein rekursiver Durchlauf durch die PERSONAL-Tabelle gem
a der
Mitarbeiter-Vorgesetzten-Beziehung erforderlich.
Beispiel 6.8.: Mit der Funktion hstufe soll die Hierarchiestufe des
Mitarbeiters mit der als Parameter u
bergebenen Nummer bestimmt
und zur
uckgeliefert werden. Der Code dieser Funktion ist in Abb. 72
dargestellt. Diese Funktion setzt genau das rekursive Prinzip, das oben
f
ur Problem a) gegeben wurde, um.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
128
Id
Name
350
Vorges_Id
Berger
0
hstufe(350)+1
107 Schmidt
350
57
Klement
350
1
hstufe(57)+1
128 Meyer
107
411 Frisch
107
205 Huber
57
2
hstufe(205)
Wir k
onnten nun die Hierarchiestufe f
ur alle Mitarbeiter unter Verwendung der im letzten Beispiel denierten Funktion mit
SELECT pid, hstufe(pid) FROM personal;
ermitteln. Dies ist jedoch auerst inezient, da hierbei f
ur jeden Mitarbeiter immer wieder die Hierarchie bis zu einem Chef zur
uckverfolgt
wird. Dies ist jedoch gar nicht notwendig, da wie wir im letzten Beispiel gesehen haben bei der Berechnung der Hierarchiestufe eines Mitarbeiters automatisch auch die Hierarchiestufen der
u
bergeordneten Mitarbeiter ermitteln.
Es empehlt sich daher eine andere Vorgehensweise, die wir im folgenden vorstellen wollen: Ausgehend von den Wurzelknoten (Mitarbeiter mit NULL-Attributwert von vorges id) besuchen wir jeden
Knoten (Datensatz) einmal; die jeweilige Hierarchiestufe ergibt sich
dann aus der um 1 erh
ohten Stufe des Vorg
angers. Die Knotenreihenfolge muss dann so gewahlt werden, dass ein Knoten erst dann besucht
wird, wenn der jeweilige Vorg
anger bereits besucht wurde.
6.3. PL/pgSQL
129
1
2
3
128
350
107
411
57
205
F
ur das folgende Beispiel nehmen wir an, dass in unserer Datenbank
eine Tabelle
STUFE (pid INTEGER, level INTEGER)
deniert ist.
Beispiel 6.9.: Mit den in Abb. 75 dargestellten Funktionen
hstufe all() und hstufe all(INTEGER,INTEGER) 10 wird bei Aufruf
von
SELECT href all ();
in die Tabelle STUFE f
ur jeden Mitarbeiter ein Datensatz mit Personalnr. und Hierarchiestufe geschrieben.
Die erste Funktion ohne Parameter die sozusagen zur Initialisierung,
indem die Hierarchiestufen f
ur die Chefs festgelegt werden. Dann
wird jeweils f
ur alle direkten Untergebenen die zweite Funktion mit
Parametern aufgerufen.
hstufe all(parent,plevel) besucht alle Knoten der Struktur ab Wurzelknoten parent auf Hierarchiestufe plevel. Man beachte, dass die
Aufrufe dieser Funktion in den Zeilen 12 und 29 jeweils u
ber ein
PERFORM-Statement erfolgen m
ussen. PERFORM verh
alt sich in
PL/pgSQL wie SELECT INTO mit dem Unterschied, dass ein eventuelles Ergebnis der SELECT-Abfrage verworfen wird. Da unsere Funk10
130
1
2
DECLARE
p RECORD;
BEGIN
FOR p IN
SELECT pid FROM personal
WHERE vorges_id IS NULL
LOOP
8
9
10
11
12
13
14
15
16
17
18
22
DECLARE
parent ALIAS FOR $1;
plevel ALIAS FOR $2;
p RECORD;
23
BEGIN
19
20
21
24
25
26
27
28
29
30
31
32
33
FOR p IN
SELECT pid FROM personal
WHERE vorges_id = parent
LOOP
INSERT INTO stufe VALUES (p.pid, plevel+1);
PERFORM hstufe_all (p.pid, plevel+1);
END LOOP;
RETURN;
END;
LANGUAGE plpgsql;
6.3. PL/pgSQL
131
132
DECLARE
n ALIAS FOR $1;
s INTEGER;
r INTEGER;
p RECORD;
BEGIN
3
4
5
6
9
10
11
12
13
14
15
s := 0;
FOR p IN
SELECT pid FROM personal
WHERE vorges_id = n
LOOP
SELECT untergebene (p.pid) INTO r;
s := s + r + 1;
16
END LOOP;
17
RETURN s;
18
19
END;
LANGUAGE plpgsql;
TEILE(OT,UT,N)
gegeben, wobei ein Datensatz jeweils angibt, welches Bauteil OT
aus wie vielen (N) Bauteilen UT besteht. In Abb. 77 ist als Beispiel die St
uckliste f
ur die Baugruppe Steckdosenleiste gegeben,
die den stark vereinfachten Aufbau einer handels
ublichen 5-fachSteckdosenleiste beschreibt.
Steckdosenleiste
1
Steckdose
Stecker
Mutter
Schraube
Kabel
Draht
6.3. PL/pgSQL
133
F
ur die Bedarfsplanung des Fertigungsbetriebes muss nun die Anzahl
und Art der Komponenten bestimmt werden, aus denen die zu fertigenden Baugruppen bestehen.
Beispiel 6.12.: Wir denieren eine Funktion numcomp, die f
ur einen
gegebenen Baugruppennamen grp und einen gegebenen Komponentennamen comp berechnet, aus wie vielen solcher Komponenten die
Baugruppe besteht (Abb. 78).
1
2
DECLARE
grp ALIAS FOR $1;
comp ALIAS FOR $2;
res INTEGER;
r RECORD;
subtotal INTEGER;
BEGIN
3
4
5
6
7
10
11
ELSE
12
res := 0;
13
FOR r IN
SELECT ot, ut, n FROM teile
WHERE ot = grp
LOOP
14
15
16
17
18
19
END LOOP;
20
RETURN res;
21
22
23
END IF;
END;
LANGUAGE plpgsql;
134
19
4
Steckdosenleiste
15
1
*5
1
*
Stecker
Steckdose
3
4
*
Kabel
0
4
*
1
1
Mutter
Schraube
0
Draht
6.4. Trigger
135
6.4. Trigger
(Datenbank-)Trigger sind mit bestimmten Tabellen verkn
upfte
PL/pgSQL-Programme, die immer dann ausgef
uhrt (abgefeuert)
werden, wenn die Tabelle durch INSERT-, UPDATE- oder DELETEAnweisungen ge
andert wird.
H
aug reichen die Mechanismen, die Constraints zur Uberpr
ufung der
Zul
assigkeit einer Tabellenanderung anbieten, nicht aus. U. a. in solchen F
allen werden Trigger verwendet.
Beispiel 6.14.: Es soll sichergestellt werden, dass jeder Mitarbeiter
h
ochstens zwei Projekten zugeordnet wird.
Die Uberpr
ufung dieser Zusatzbedingung ist mit Constraints nicht
m
oglich. Ein Trigger, der vor dem Einf
ugen eines Datensatzes in die
Tabelle zuordnung ausgef
uhrt wird, l
ost das Problem. Der Trigger
m
usste dann folgende Aktionen ausf
uhren:
Ermittle die Anzahl der Eintr
age, die f
ur die neu einzuf
ugende Personalnummer bereits in zuordnung vorhanden sind.
Ist die Anzahl 2 (d. h. es existieren schon zwei oder mehr Zuordnungen vor dem Einf
ugen), melde einen Fehler und brich die
Anderung ab.
Trigger werden mit CREATE TRIGGER (Abb. 80) erzeugt. Das Konzept eines Triggers ist SQL-Standard. PostgreSQL implementiert einen
Teil des Standards. Anstelle der im Standard vorgesehenen Folge von
136
trigger
CREATE TRIGGER
schema
...
OR
...
BEFORE
AFTER
DELETE
tabelle
ON
INSERT
schema
...
UPDATE
...
...
FOR EACH STATEMENT
FOR EACH ROW
...
EXECUTE PROCEDURE
funktion
)
parameter
,
Hierbei bedeutet:
trigger
BEFORE
AFTER
DELETE
INSERT
6.4. Trigger
137
wird f
ur die gesamte Anderungsanweisung
stets einmal ausgef
uhrt, unabh
angig davon,
wie viele Datensatze geandert werden (auch
wenn konkret keine Datens
atze geandert
werden). Standardm
aig werden StatementTriggers deniert.
FOR EACH ROW
Denition eines Zeilentriggers. Dieser wird f
ur
jeden ge
anderten Datensatz genau einmal ausgef
uhrt.
funktion
Name einer in PL/pgSQL denierten Triggerfunktion. Diese muss einen Wert vom speziellen (Pseudo-) Datentyp TRIGGER zur
uckliefern.
parameter
Der Funktion k
onnen optional Parameter
u
bergeben werden, die als Stringliterale anzugeben sind. In diesem Buch wird auf diese
M
oglichkeit nicht weiter eingegangen.
UPDATE
Grunds
atzlich sollte jede Triggerfunktion mit
RETURN new;
beendet werden. Bei BEFORE-Zeilentriggern l
asst sich u
ber diesen
Mechanismus der durch das ausl
osende INSERT- oder UPDATEStatement eingef
ugte bzw. ge
anderte Datensatz modizieren, da letztlich der mit RETURN zur
uckgelieferte Datensatz in die Tabelle
u
bernommen wird.
Ein Sonderfall ist
RETURN NULL;
bei BEFORE-Zeilentriggern. Hierdurch wird die vom ausl
osenden
Statement f
ur diese Zeile vorzunehmende Operation nicht ausgef
uhrt,
ohne dass jedoch eine Ausnahmebedingung (und damit der Abbruch
der Transaktion) veranlasst wird.
Beispiel 6.15.: Der oben vorgestellte Trigger, der eine Zuordnung
eines Mitarbeiters zu hochstens 2 Projekten sicherstellen soll, wird wie
in Abb. 81 gezeigt deniert.
138
DECLARE
nump INTEGER;
BEGIN
6
7
11
12
RETURN new;
8
9
10
13
14
15
16
17
18
19
END;
LANGUAGE plpgsql;
CREATE TRIGGER t_maxproj
BEFORE INSERT OR UPDATE
ON zuordnung
FOR EACH ROW
EXECUTE PROCEDURE f_maxproj ();
6.4. Trigger
139
Uberpr
ufung bereits vorhandener Tabelleninhalte vornehmen, sondern
nur auf Anweisungen wirken, die nach ihrer Denition gegeben werden.
So w
are es im Beispiel kein Fehler, wenn bei Denition von t maxproj
ein Mitarbeiter schon 3 Projekten zugeordnet w
are.
manueller Anderung
des Familienstandes eines Mitarbeiters in einer
Personaltabelle auch das Steuerklassen-Attribut ge
andert wird.
Implementierung von komplexen Sicherheitsmechanismen. Beispiel:
Die Personaltabelle soll nur zu bestimmten Zeiten ge
andert werden
d
urfen.
140
BEGIN
12
13
RETURN new;
4
5
6
7
8
9
10
11
14
15
16
17
18
19
20
END;
LANGUAGE plpgsql;
CREATE TRIGGER t_personal_protokoll
AFTER INSERT OR UPDATE OR DELETE
ON personal
FOR EACH ROW
EXECUTE PROCEDURE f_personal_protokoll ();
6.4. Trigger
141
BEGIN
UPDATE zuordnung
SET projid = new.projid
WHERE projid = old.projid;
RETURN new;
4
5
8
9
10
11
12
13
14
END;
LANGUAGE plpgsql;
CREATE TRIGGER t_new_proj
AFTER UPDATE
ON projekt
FOR EACH ROW
EXECUTE PROCEDURE f_new_proj ();
Anderung
in der Tabelle ZUORDNUNG vornehmen kann. Damit der
Trigger trotzdem funktioniert, muss bei der Denition des Constraints
142
daf
ur gesorgt werden, dass er erst am Ende einer Transaktion u
berpr
uft
wird:
ALTER TABLE zuordnung ADD FOREIGN KEY (projid)
REFERENCES projekt (projid)
DEFERRABLE INITIALLY DEFERRED;
Die Ausf
uhrung eines Triggers kann die Ausf
uhrung anderer Trigger
nach sich ziehen. Dies ist etwa dann der Fall, wenn der Trigger eine
Tabelle andert, auf der ebenfalls ein Trigger deniert ist.
7. Datenbankzugri in h
oheren
Programmiersprachen
Es gibt Datenbankanwendungen, die sich nicht alleine mit den
Datenbank-Sprachen SQL oder PL/pgSQL l
osen lassen, sondern auer
komfortablem Zugri auf eine Datenbank auch die M
oglichkeiten
einer prozeduralen Programmiersprache (z. B. PASCAL, C, Perl)
ben
otigen. Wir werden hier zwei verschiedene Ansatze kennenlernen,
SQL-Anweisungen in einer prozeduralen Programmiersprache der
sog. Host-Programmiersprache zu verwenden.
Uberblick u
ber ESQL geben. Kenntnisse in der Programmiersprache
C setzen wir in diesem Abschnitt voraus.
Embedded SQL ist im SQL-Standard deniert, die PostgreSQLImplementierung ECPG, die wir hier beschreiben, ist zum gr
oten
Teil standardkonform.
Ein C-Programm mit Embedded SQL-Konstrukten (das sog. HostProgramm) muss zunachst durch einen speziellen Precompiler behandelt werden. Dieser ersetzt die ECPG-Konstrukte durch Aufrufe von
Bibliotheksfunktionen, die von dem Datenbanksystem zur Verf
ugung
gestellt werden. Das precompilierte Programm kann dann mit dem
u
blichen Compiler in ausf
uhrbare Form u
bersetzt werden.
144
7. Datenbankzugri in h
oheren Programmiersprachen
Zul
assige Datentypen f
ur Hostvariablen sind die C-Datentypen char,
char[n], int, short, long, float, double sowie der Pseudo-Datentyp
VARCHAR[n]. Letzterer beschreibt eine Zeichenkette mit Lange n
und entspricht in C einer Struktur mit den Komponenten
unsigned short len;
unsigned char arr[n];
wobei len jeweils die tats
achliche Lange der in arr gespeicherten Zeichenkette angibt. Die Zeichenkette in arr muss nicht durch ein Nullbyte terminiert sein (wenn man auf arr mit den C-Stringfunktionen
arbeiten will, muss man die Zeichenkette allerdings selbst durch ein
Nullbyte terminieren).
Die Datentypen der Hostvariablen werden bei der Benutzung in einem
SQL-Statement auf SQL-interne Datentypen abgebildet. Die Typkonversion l
auft automatisch nach Regeln ahnlich den in Abschnitt 3.3.7
beschriebenen ab. Auf diese Weise konnen Werte relativ problemlos
zwischen C und SQL ausgetauscht werden.
Das einzige Problem stellt die Tatsache dar, dass es in SQL den speziellen Wert NULL gibt, der in C keine Entsprechung hat. Um nun
trotzdem auch NULL-Werte austauschen zu konnen, gibt es Indikatorvariablen. Dabei handelt es sich um Variablen vom Typ short,
die mit einer Hostvariable assoziiert sind; ihr Wert bestimmt jeweils,
ob der Wert der Hostvariablen von SQL ignoriert und als NULL-Wert
aufgefasst werden soll.
F
ur Eingabe-Hostvariablen (mit denen Werte an SQL u
bergeben werden sollen) werden die Werte der korrespondierenden Indikatorvariablen folgendermaen interpretiert:
< 0 Der tatsachliche Wert der Hostvariable wird ignoriert, er wird als
NULL angesehen.
0 Der Wert der Hostvariablen wird verwendet.
F
ur Ausgabe-Hostvariablen (mit denen Werte von SQL an C
zur
uckgeliefert werden) lautet die Interpretation der Werte der korrespondierenden Indikatorvariablen wie folgt:
< 0 Es wurde ein NULL-Wert zur
uckgeliefert.
0 Die Hostvariable enth
alt einen g
ultigen Wert.
> 0 Der Wert wurde abgeschnitten, da die Hostvariable nicht lang genug war, um ihn ganz aufnehmen zu k
onnen. Der Wert der Indikatorvariablen gibt in diesem Fall die ben
otigte L
ange an.
Host- und Indikatorvariablen werden im C-Programm wie gew
ohnliche
Variablen deniert, die Denition muss jedoch eingeleitet werden mit
145
146
7. Datenbankzugri in h
oheren Programmiersprachen
EXEC SQL
CONNECT TO
:connectstring
USER
:username
IDENTIFIED BY
:passwort
COMMIT
ROLLBACK
DECLARE
cursor
OPEN
CURSOR FOR
select_statement
cursor
CLOSE
,
FETCH
cursor
INTO
:hostvariable
:indikatorvariable
WHENEVER
NOT FOUND
CONTINUE
SQLERROR
DO
SQLWARNING
GOTO
c_funktionsaufruf
c_label
STOP
sql_statement
wenn vor der Abmeldung mit EXEC SQL DISCONNECT bzw. dem
Programmende ein EXEC SQL COMMIT stattndet.
Fehlerbehandlung
F
ur die Behandlung von Fehlern, die bei der Ausf
uhrung von ECPGKonstrukten auftreten, gibt es verschiedene Methoden. Wir stellen
hier nur die einfachste Methode Verwendung des WHENEVERStatements dar.
Mit einem WHENEVER-Statement kann man f
ur folgende F
alle spezielle Aktionen denieren:
Bei einem SELECT. . . INTO- oder FETCH-Statement wurde kein
Datensatz (mehr) gefunden (NOT FOUND).
147
148
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
7. Datenbankzugri in h
oheren Programmiersprachen
#include <stdio.h>
#include <string.h>
#define READVARCHAR(prompt, str) printf(prompt); gets(str.arr); \
str.len = strlen(str.arr);
#define SKIPLINE while ((c = getchar()), c != \n);
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR nachname[21]; VARCHAR vorname[16]; VARCHAR strasse[31];
VARCHAR ort[21]; VARCHAR abteilung[21];
float gehalt; int pers_id, abt_id;
char *connectstring = "unix:postgresql://localhost/firma";
char *user = "rank";
EXEC SQL END DECLARE SECTION;
void sqlerror ()
{
EXEC SQL WHENEVER SQLERROR CONTINUE;
printf ("\nDatenbankFehler:\n");
printf ("%.70s\n", sqlca.sqlerrm.sqlerrmc);
16
17
18
19
20
21
int main ()
{ int c;
22
23
24
25
26
28
29
30
do {
READVARCHAR ("Abteilung: ", abteilung);
27
31
", vorname);
", ort);
32
33
break;
34
37
notfound:
printf ("Abteilung existiert nicht Eingabe wiederholen!\n");
} while (1);
38
39
40
pers_id++;
printf ("Neue Personalnummer = %d\n", pers_id);
35
36
41
45
46
47
48
42
43
44
exit (0);
49
50
149
Zeile 24 stellt die Verbindung zur Datenbank her. Hier ist im allgemeinen Fall in der Hostvariablen :connectstring ein wie oben beschriebener Connectstring anzugeben.12 In der Hostvariablen :user geben
wir den (DBMS-) Benutzernamen an, mit dem die Anmeldung an der
Datenbank erfolgen soll.
In den Zeilen 2628 werden die Mitarbeiterdaten eingelesen.
Zeile 29 legt fest, dass bei Auftreten einer NOT FOUND-Ausnahmebedingung die Programmausf
uhrung an der mit notfound bezeichneten Stelle des Programms fortgesetzt werden soll.
Die Zeilen 3133 lesen einen Abteilungsnamen ein und holen mit einem
Embedded SQL-Statement die zugehorige Abteilungsnummer aus der
Tabelle ABTEILUNG. Bei Eingabe einer nichtexistenten Abteilung
kommt es zur Ausnahmebedingung NOT FOUND, die hier zur Ausgabe einer Fehlermeldung (Zeile 36) und erneuter Anforderung eines
Abteilungsnamens f
uhrt.
In den Zeilen 3941 wird die h
ochste bereits vergebene Personalnummer ermittelt, um 1 erhoht und als Personalnummer des neuen Mitarbeiters verwendet.
Der Eintrag f
ur den neuen Mitarbeiter wird in den Zeilen 4245 erzeugt.
Wir gehen hier und bei allen weiteren Beispielen, bei denen eine Verbindung zur Datenbank hergestellt wird davon aus, dass die Datenbank rma heit, sich auf dem gleichen Rechner wie die Applikation
bendet (localhost) und die Anmeldung an die Datenbank als Benutzer rank lokal ohne Passwort erfolgen kann.
150
7. Datenbankzugri in h
oheren Programmiersprachen
der man auf besonders einfache Weise jegliche Art von textuellen Daten analysieren und bearbeiten kann. Dar
uber hinaus handelt es sich
bei Perl um eine vollwertige und universelle hohere Programmiersprache, deren Popularit
at nicht nur bei der Anbindung von Datenbanken,
sondern auch bei der Erzeugung von dynamischen WWW-Seiten wir
werden darauf in Abschnitt 8 n
aher eingehen immer mehr steigt.
Perl ist frei verf
ugbar (es handelt sich auch hier um sog. Open
Source-Software, bei der der Quellcode zur Verf
ugung steht 13 ) und
l
auft auf allen Unix-
ahnlichen Betriebssystemen. Implementierungen
f
ur zahlreiche andere Betriebssystemplattformen sind ebenfalls kostenlos verf
ugbar. Deshalb k
onnen Perl-Programme meist ohne jeglichen
Portierungsaufwand auf fast allen g
angigen Hardware- und Betriebssystemplattformen eingesetzt werden. F
ur die Ausf
uhrung von PerlProgrammen wird kein expliziter Compilierungsschritt ben
otigt die
14
Programme werden interpretiert. Der Programmablauf ist trotzdem
recht ezient.
F
ur die folgenden Ausf
uhrungen setzen wir voraus, dass der Leser mit
den Grundlagen von Perl vertraut ist eine Einf
uhrung ndet sich
beispielsweise in [ScCh2001]. Die Beispielprogramme d
urften jedoch
mit den zus
atzlichen Erl
auterungen auch Lesern mit Kenntnissen in
einer anderen h
oheren Programmiersprache grunds
atzlich verstandlich
sein.
DBI (database interface) ist ein Perl-Modul, das sich in den letzten Jahren zu einem de-facto-Standard f
ur den Zugri auf Datenbanken von Perl aus entwickelt hat. DBI stellt eine datenbankunabh
angige (d. h. insbesondere herstellerunabh
angige) Schnittstelle zur
Verf
ugung. DBI bedient sich zur Umsetzung von Datenbankzugrien
auf ein spezisches Datenbanksystem zus
atzlicher DBD-(database
driver)-Module, die speziell auf das jeweils verwendete Datenbanksystem zugeschnitten sind. Ebenso wie Perl sind auch DBI und die
diversen DBD-Module frei verf
ugbar.
Wir werden in diesem Abschnitt u
berblicksm
aig die wichtigsten
Aspekte von DBI behandeln, ohne auch nur ann
ahernd den Anspruch
13
14
Eine ausf
uhrliche Erl
auterung des Begris Open Source ndet sich
beispielsweise in [Op1999].
Tats
achlich wird vor der Ausf
uhrung automatisch ein interner Zwischencode generiert. Dies geschieht jedoch transparent f
ur den Benutzer.
151
Datenbank-Server
DBI-Modul
PerlProgramm
DBD::database-Modul
Datenbank
Clientbibliotheken
17
152
7. Datenbankzugri in h
oheren Programmiersprachen
1
#! /usr/bin/perl w
use DBI;
$sth = $dbh>prepare
("SELECT nachname, vorname FROM personal");
$sth>execute ();
5
6
7
8
9
10
153
7.2.3. Fehlerpr
ufung
Wir hatten in unserem Beispiel keine Fehlerpr
ufung vorgenommen.
Selbstverst
andlich kann es beim Zugri auf eine Datenbank zu den
verschiedensten Fehlersituationen kommen, etwa weil die Verbindung
mit der Datenbank fehlschlagt oder weil das Datenbanksystem eine
154
7. Datenbankzugri in h
oheren Programmiersprachen
155
7.2.4. Unterst
utzung von Transaktionen
DBI unterst
utzt Transaktionen in dem gleichen Umfang wie das
verwendete Datenbanksystem. Standardm
aig f
uhrt DBI allerdings
nach jeder ausgef
uhrten SQL-Anweisung ein implizites COMMIT
durch (sog. AutoCommit-Einstellung). Dies lat sich jedoch abschalten; es stehen dann f
ur jedes Datenbank-Handle die Methoden commit und rollback f
ur den expliziten Abschluss einer Transaktion zur
Verf
ugung. Eine Transaktion wird dann stets mit dem ersten Statement nach commit bzw. rollback oder mit dem ersten Statement
nach Herstellung der Datenbankverbindung begonnen.20
Wir werden in Abschnitt 8.9 nochmals darauf zur
uckkommen. F
ur
ausf
uhrlichere Informationen zur AutoCommit-Funktionalit
at sei auf
die DBI-Dokumentation bzw. auf [DeBu2000] verwiesen.
7.2.5. Werte
ubergabe zwischen Perl und SQL
Wir wir schon in dem Programm aus Abb. 88 gesehen hatten, geschieht
die Ubergabe
von Werten aus SQL an Perl ohne Zuhilfenahme von
ur die umgekehrte Richtung
Hostvariablen wie in Embedded SQL.21 F
20
21
Auf Systemen, wo dieses Modul installiert ist, kann man mit dem Kommando
perldoc DBI
die Online-Dokumentation aufrufen.
In PostgreSQL ist somit ein START TRANSACTION-Statement zum
Beginnen einer Transaktion nicht notwendig.
DBI bietet zwar ein Konstrukt an, das so
ahnlich wie Hostvariablen
funktioniert; dieses ist jedoch nicht notwendig, um Daten zwischen Perl
und SQL auszutauschen. Wir werden dieses Konstrukt daher hier auch
nicht n
aher betrachten.
156
7. Datenbankzugri in h
oheren Programmiersprachen
#! /usr/bin/perl w
use DBI;
$sth = $dbh>prepare
("UPDATE abteilung SET ort=? WHERE bezeichnung=?");
$rows = $sth>execute ($ort,$abt);
6
7
10
$dbh>disconnect ();
F
ur den nicht so gut mit Perl vertrauten Leser: Die chomp-Funktion
entfernt ein am Ende einer Zeichenkette stehendes Zeilentrennzeichen.
Beim Einlesen von Werten u
bernimmt Perl n
amlich anders als etwa
C stets den Zeilentrenner, der die Eingabe beendet.
157
UPDATE abteilung
SET ort=Freising WHERE bezeichnung=Produktion;
ausgef
uhrt. Man beachte, dass sich DBI automatisch um das sogenannte Quoting k
ummert, d. h. es setzt ggf. Werte in die vom Datenbanksystem verlangten Anf
uhrungszeichen.
Der R
uckgabewert der execute-Methode ist die Anzahl der durch
die SQL-Anweisung ge
anderten Datens
atze, die wir zur Kontrolle in
Zeile 9 auf dem Bildschirm ausgeben.
158
7. Datenbankzugri in h
oheren Programmiersprachen
#! /usr/bin/perl w
use DBI;
4
5
6
10
11
12
13
14
$nachname
$vorname
$strasse
$ort
$gehalt
=
=
=
=
=
readvarchar
readvarchar
readvarchar
readvarchar
readvarchar
("Nachname:
("Vorname:
("Strasse:
("Wohnort:
("Gehalt:
");
");
");
");
");
24
25
26
28
29
$pers_id++;
30
31
15
16
17
18
19
20
21
22
23
27
32
33
34
35
36
41
if ($rows) {
print "Einfuegen erfolgt.\n";
} else {
print "Fehler beim Einfuegen.\n";
}
42
$dbh>disconnect ();
37
38
39
40
7.3. Portablilit
at der Zugrisverfahren
159
7.3. Portablilit
at der Zugrisverfahren
Wir haben nun zwei verschiedene Methoden vorgestellt, um von
h
oheren Programmiersprachen aus mit SQL auf Datenbanken zugreifen zu k
onnen.
Der Zugri u
ber Embedded SQL ist im SQL-Standard festgeschrieben und erlaubt die Einstreuung von SQL-Konstrukten in Programme hoherer Programmiersprachen. Welche Programmierspra23
160
7. Datenbankzugri in h
oheren Programmiersprachen
chen unterst
utzt werden, liegt im Ermessen des jeweiligen Datenbankherstellers. Die Verwendung von Embedded SQL-Programmen erfordert den Einsatz spezieller datenbankspezischer Precompiler,
die die Embedded SQL-Konstrukte in Aufrufe entsprechender Routinen der Clientbibliotheken umwandeln. Beim Compilieren und Binden
(Linken) solcher Programmen m
ussen die datenbankspezischen Clientbibliotheken in den ausf
uhrbaren Code eingebunden werden, was
den Programmerstellungsprozess mitunter etwas unhandlich macht.
Hingegen ist DBI eine datenbankunabh
angige Schnittstelle f
ur den Zugri von Datenbanken aus Perl-Programmen heraus. Sind DBI und
die datenbankspezischen DBD-Module auf einem System installiert,
k
onnen entsprechende Perl-Programme ohne jeglichen Compilierungsaufwand ablaufen. Somit gestaltet sich die Benutzung von DBI gegen
uber Embedded SQL wesentlich einfacher, ist allerdings nur in der
Sprache Perl m
oglich.
Abgesehen von diesen entwicklungsumgebungsspezischen Portie
rungsfragen ist nat
urlich auch interessant, welche Anderungen
im
Quellcode bei einem Wechsel des Datenbanksystems notwendig sind.
Soweit die Datenbanksysteme hinsichtlich Embedded SQL dem
SQL-Standard entsprechen, d
urfte haupts
achlich die EXEC SQL
CONNECT-Anweisung anzupassen sein. Bei Perl/DBI ist es ahnlich:
Unter der Voraussetzung, dass f
ur das Ziel-Datenbanksystem ebenfalls
ein DBD-Modul existiert, ist im g
unstigsten Fall nur eine Anpassung
des connect-Aufrufs erforderlich.
Leider ist es damit oft nicht getan, egal ob man die Embedded SQLoder die Perl/DBI-Variante gewahlt hat. Die Probleme liegen im
spezischen SQL-Dialekt, den ein bestimmtes Datenbanksystem unterst
utzt. Macht man beim Zugri auf die Datenbank reichlich von
SQL-Spezialitaten Gebrauch, die nicht standardisiert sind, sind ggf.
sehr viele SQL-Anweisungen an ein anderes Datenbanksystem anzupassen.
Auch wenn man sich nur auf einfache SQL-Anweisungen beschr
ankt,
gibt es erfahrungsgema an einer Stelle trotzdem Probleme wenn
n
amlich Datums- und Zeitangaben mit den von der Datenbank angebotenen Typen verwaltet werden sollen. Da in den g
angigen h
oheren
Programmiersprachen keine aquivalenten Typen existieren (das trit
auch f
ur Perl zu), ist man auf die stets datenbankspezischen
Vorgehensweisen f
ur die Ubertragung
von Datums- und Zeitangaben
zwischen Datenbank und h
oherer Programmiersprache angewiesen.
7.3. Portablilit
at der Zugrisverfahren
161
163
lies Eingabe
analysiere Eingabe
Funktion
Funktion
Funktion
...
Steuerung durch
WindowingSystem
Ereignis
Funktion
1
Funktion
2
Funktion
3
164
Benutzer
SQL
datenbankspezifische
DB-Client-Bibliotheken
Client
Datenbank-Server
Benutzer
GUI
Thin Client
Applikation
SQL
Datenbank
datenbankspezifische
DB-Client-Bibliotheken
Applikations-Server
Datenbank-Server
8.2. Benutzerober
achen im World Wide Web
165
In der Welt der Unix-Betriebssysteme kann mit Hilfe des X-WindowsSystems auf einfache Weise eine Trennung von Applikationsserver und
GUI-Anzeigerechner erreicht werden. Dies geschieht, indem die graphische Darstellung der Applikation nicht an den Rechner gebunden ist,
auf dem die Applikation selbst l
auft, sondern via Netzwerk auf einem
beliebigen anderen Rechner erfolgen kann (Abb. 95). Auf letzterem
muss die sog. X-Server-Software daf
ur sorgen, dass die vom Applikationsserver produzierte Graphikausgabe auf dem Bildschirm angezeigt
wird.
Benutzer
GUI
(Darstellung)
X-Terminal
X-Server
GUI
Applikation
SQL
Datenbank
datenbankspezifische
DB-Client-Bibliotheken
Applikations-Server
Datenbank-Server
Sogenannte X-Terminals sind Rechner, auf denen ausschlielich die XServer-Software zur Anzeige von X-Windows-Applikationen abl
auft. 24
8.2. Benutzerober
achen im World Wide Web
Eine gute Benutzerober
ache sollte idealerweise u
berall also
plattform- und betriebssystemunabh
angig verf
ugbar sein. Wie im
letzten Abschnitt erlautert, ist dies f
ur herk
ommliche graphische
Ober
achen kaum gegeben. Mit dem Aufkommen des World Wide
Web (WWW) hat man jedoch die Moglichkeit, eine Benutzeroberache
24
166
u
ber sog. Web-Formulare abzubilden, die dann die folgenden sehr
w
unschenswerten Eigenschaften besitzt:
Darstellung durch auf den meisten Plattformen verf
ugbare WWWBrowser.
Unterst
utzung des Thin Client-Modells auf Benutzerseite muss lediglich ein WWW-Browser verf
ugbar sein.
Standardisierte Sprache zur Darstellung von WWW-Seiten: HTML
(Hypertext Markup Language).
Standardisiertes Protokoll zum Datenaustausch zwischen WWWBrowser und WWW-Server: HTTP (Hypertext Transfer Protocol).
Standardisiertes Verfahren zum Datenaustausch zwischen WWWBrowser (Benutzer) und Applikation: CGI (Common Gateway Interface).
Eine im WWW realisierte Applikation besteht im einfachsten Fall aus
einer Kollektion von sog. CGI-Skripten, die Formulareingaben verarbeiten und als Ausgabe weitere HTML-Seiten produzieren, die im
WWW-Browser des Benutzers angezeigt werden. 25
Wir wollen im Rahmen dieses Buches nur serverbasierte Applikationen betrachten, bei denen der WWW-Browser auf Benutzerseite
ausschlielich HTML-Seiten anzeigen und Formulareingaben an den
WWW-Server u
bermitteln soll. Es gibt dar
uber hinaus Techniken, bei
denen auch der WWW-Browser sog. aktive Inhalte etwa in Form von
Java- oder JavaScript-Programmen ausf
uhrt und somit die Applikation
nicht mehr rein serverbasiert ist. Obwohl diese Technik groere Freiheit bei der Gestaltung einer Benutzeroberache gewahrt, macht sie
die Erstellung einer solchermaen verteilten Applikation wesentlich
komplizierter. Auerdem werden in den Browser-Implementierungen
immer wieder z. T. schwerwiegende Sicherheitsl
ucken entdeckt, so dass
eine Verwendung aktiver Inhalte in sicherheitskritischen Umgebungen
fraglich scheint.
25
167
Benutzer
WWWServerproze
CGI-Skript
Formular
Ausgabe des
CGI-Skripts
WWW-Browser
Client
Server
168
Benutzer
Ausgabe des
CGI-Skripts
Formular
WWWServerproze
CGI-Skript
SQL
CGI
WWW-Browser
DBI
PerlInterpreter
datenbankspez.
DB-Client-Bibl.
Client
WWW-Server
Datenbank
Datenbank-Server
Abb. 97: Datenbankzugri aus dem WWW mit CGI und DBI
Bei einer per WWW via CGI angebundenen Datenbank ist das Gesamtsystem wie in Abb. 97 dargestellt strukturiert. Die Anbindung von
Datenbanken mit dem DBI-Modul haben wir ja schon in Abschnitt 7.2
behandelt, so dass wir uns hier vor allem auf die Interaktion zwischen
Browser (Benutzer) und CGI-Skript konzentrieren wollen.
Wir illustrieren im folgenden unsere Ausf
uhrungen wieder mit dem
bereits bekannten Beispiel des Eintragens eines neuen Mitarbeiters in
unsere Musterdatenbank. In diesem Fall soll dies nat
urlich per WWW
unter Verwendung von Web-Formularen und CGI-Skripten geschehen.
169
nutzereingaben zu erm
oglichen.26 Ein Web-Formular kann verschiedene Elemente besitzen, mit denen Eingaben vorgenommen bzw. Aktionen veranlasst werden konnen. Die folgende Auistung stellt lediglich eine Auswahl dar:
Textfelder erlauben die Eingabe beliebiger Zeichenketten.
Checkboxen erm
oglichen die An- oder Abwahl vorgegebener Optionen.
Radio-Buttons erm
oglichen die Auswahl einer Option aus verschiedenen M
oglichkeiten.
Wir setzen hier voraus, dass der Leser mit den Grundlagen von HTML
vertraut ist. Eine ausf
uhrliche Darstellung von HTML ndet sich beispielsweise in [MuKe2002].
170
<HTML>
<HEAD><TITLE>Neuanlage Mitarbeiter</TITLE></HEAD>
<BODY>
<H1>Eintrag eines neuen Mitarbeiters</H1>
<FORM ACTION="neumitwww2.pl">
<TABLE>
<TR><TD>Nachname: </TD>
<TD><INPUT TYPE="text" NAME="nachname" ></TD></TR>
<TR><TD>Vorname: </TD>
<TD><INPUT TYPE="text" NAME="vorname" ></TD></TR>
<TR><TD>Straße: </TD> <TD><INPUT TYPE="text" NAME="strasse" ></TD></TR>
<TR><TD>Wohnort: </TD>
<TD><INPUT TYPE="text" NAME="ort" ></TD></TR>
<TR><TD>Gehalt: </TD>
<TD><INPUT TYPE="text" NAME="gehalt" ></TD></TR>
<TR><TD>Abteilung: </TD>
<TD><INPUT TYPE="text" NAME="abteilung" ></TD></TR>
</TABLE>
<INPUT TYPE="submit" NAME="aktion" VALUE="Mitarbeiter anlegen">
<INPUT TYPE="reset" VALUE="Eingaben lschen">
</FORM>
</BODY>
</HTML>
171
tor) sein; da wir hier nur einen Dateinamen angegeben haben, bezieht
er sich auf eine Datei (das CGI-Skript), die serverseitig im gleichen
Verzeichnis abgelegt ist wie das Formular.
Die einzelnen Eingabefelder werden in den Zeilen 712 jeweils mit einem INPUT-Tag festgelegt. Das Attribut TYPE legt die Art des Formularelements fest (hier jeweils ein Textfeld), NAME bestimmt den
Namen des Formularelements. Mit einem weiteren Attribut VALUE
k
onnten wir noch Standardwerte f
ur die Eingabefelder festlegen, z. B.
eine Vorgabe f
ur den Wohnort.
Zeile 14 deniert einen Submit-Button; der Wert wird im Browser
als Beschriftung des Buttons angezeigt. In Zeile 15 spezizieren wir
einen Reset-Button, mit dem alle Formulareingaben geloscht werden
k
onnen.
172
#! /usr/bin/perl wT
use
use
use
use
my ($i,%p,$dbh,$sth,$abt_id,$pers_id,$rows);
print header,
start_html ("Neuanlage Mitarbeiter Ergebnis");
3
4
strict;
CGI qw(:standard);
CGI::Carp qw(fatalsToBrowser);
DBI;
12
foreach $i ("nachname","vorname","strasse","ort",
"gehalt","abteilung") {
$p{$i} = param($i);
}
13
14
9
10
11
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
if (!defined($abt_id)) {
print "Abteilung existiert nicht!",
end_html;
exit;
}
$sth = $dbh>prepare ("SELECT MAX(pid) FROM personal");
$sth>execute ();
($pers_id) = $sth>fetchrow_array ();
$pers_id++;
$sth = $dbh>prepare ("INSERT INTO personal
(pid,nachname,vorname,strasse,ort,
aid,gehalt,einstellung)
VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_DATE)");
$rows = $sth>execute ($pers_id, $p{nachname}, $p{vorname},
$p{strasse}, $p{ort}, $abt_id, $p{gehalt});
38
if ($rows) {
print "Neuer Mitarbeiter mit PersonalId $pers_id ";
print "und AbteilungsId $abt_id eingefügt.";
} else {
print "Fehler beim Einfügen.";
}
39
print end_html;
33
34
35
36
37
In Zeile 3 wird das CGI-Modul geladen. Dieses Modul bietet eine objektorientierte und eine konventionelle Schnittstelle an. Wir verwenden hier aus Gr
unden der Einfachheit die konventionelle Schnittstelle,
mit der auf das CGI-Modul u
ber gewohnliche Funktionsaufrufe zugegrien werden kann; dies geben wir bei der use-Anweisung u
ber die
Klausel qw(:standard) an.
Mit der Anweisung in Zeile 4 wird w
ahrend der Entwicklung eines
173
29
174
175
#! /usr/bin/perl -w
use strict;
use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser);
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
print header,
start_html ("Neuanlage Mitarbeiter"),
h1 ("Eintrag eines neuen Mitarbeiters"),
start_form (-action => "neumitwww2.pl"),
table(
Tr(td("Nachname: "),
td(textfield (-name => "nachname"))),
Tr(td("Vorname: "),
td(textfield (-name => "vorname"))),
Tr(td("Straße: "), td(textfield (-name => "strasse"))),
Tr(td("Wohnort: "),
td(textfield (-name => "ort"))),
Tr(td("Gehalt: "),
td(textfield (-name => "gehalt"))),
Tr(td("Abteilung: "),
td(textfield (-name => "abteilung")))
),
submit (-name => "aktion", -value => "Mitarbeiter anlegen"),
reset (-value => "Eingaben lschen"),
end_form, end_html;
Tats
achlich ist der vom Skript erzeugte HTML-Code geringf
ugig anders als der handgestrickte. Die Unterschiede haben mit der Art der
Daten
ubertragung vom Formular zum Aktions-CGI-Skript zu tun, auf
die wir hier nicht eingehen wollen. Jedenfalls verhalt sich das von diesem
Skript erzeugte Formular f
ur den Benutzer genau so wie das statische
Formular.
176
Web-Formularen u. a. auch f
ur eine komfortable Fehlerbehandlung
, mit der wir uns im folgenden befassen wollen.
Benutzer
nein
Besttigung bzw.
nchste Maske
WWWServerproze
Eingaben
OK?
ja
Aktionen
durchfhren
WWW-Browser
CGI-Skript
Client
Formular
Server
177
178
nochmals pr
asentiert, allerdings mit Hinweisen, an welchen Stellen er
falsche Eingaben gemacht hat.
In Abb. 104 ist gezeigt, wie der Eintrag eines neuen Mitarbeiters unter
Ausschopfung aller Fehlerfalle ablaufen soll. In a) wird das Formular
abgeschickt, ohne dass ein Nachname eingegeben wurde. Der Benutzer
bekommt daraufhin nochmals das gleiche Formular pr
asentiert, allerdings mit dem Hinweis, dass er einen Nachnamen eingeben muss.
Dies tut der Benutzer in b); beim Abschicken dieses Formulars stellt
das System fest, dass es die Abteilung Herstellung nicht gibt und
weist den Benutzer bei erneuter Anzeige des Formulars auf diese Tatsache hin. In c) hat der Benutzer den Abteilungsnamen durch Produktion ersetzt; nun kann das Einf
ugen des neuen Mitarbeiters erfolgen.
Wir wollen uns nun die Realisierung dieser Oberache als CGI-Skript
ansehen. Der Code ist in Abb. 105 und Abb. 106 gezeigt (auf die grau
unterlegten Zeilen werden wir in Abschnitt 8.9 nochmals besonderen
Bezug nehmen). Es f
allt zun
achst auf, dass der Code wesentlich umfangreicher ist als unsere erste Version der Ober
ache aus Abb. 100
und Abb. 102. Dieses Verhalten entspricht aber der allgemeinen Beobachtung im Bereich der Softwareentwicklung, dass eine komfortable
Fehlerbehandlung einen wesentlichen Teil des Codes ausmachen kann.
Wir wollen uns im folgenden diesen Code genauer ansehen.
Die ersten Zeilen des Skripts sind im wesentlichen schon aus der
Vorversion von Abb. 102 bekannt. Allerdings taucht in Zeile 3 das
zus
atzliche Konstrukt *table auf. Damit erreichen wir, dass uns zwei
ugung
zus
atzliche Funktionen start table und end table zur Verf
stehen, mit denen wir Beginn- und Ende-Tags f
ur Tabellen erzeugen
k
onnen. Dies war in der Vorversion nicht notwendig, da wir die Tabelle
mit den Eingabefeldern sozusagen in einem Rutsch als Argument der
Tr-Funktion erzeugt hatten. Wir wollen aber nun die Formularfelder
parameterisieren, d. h. Namen und Bezeichnungen aus einer Variablen
auslesen.
Zeile 6 deniert die vom Skript verwendeten lokalen Variablen:
$i
ist eine Schleifenvariable.
%p
In diesem Hash werden die vom Formular gelieferten Parameter abgelegt.
$dbh
Datenbank-Handle f
ur die Verbindung zur Datenbank.
$sth
Statement-Handle f
ur die jeweils aktive SQL-Anweisung.
ist die aus der Datenbank ermittelte Abteilungs-Id.
$abt id
179
a)
b)
c)
180
#! /usr/bin/perl wT
use
use
use
use
my ($i,%p,$dbh,$sth,$abt_id,$pers_id,$rows,@fields,%fields,%messages);
3
4
8
9
10
strict;
CGI qw(:standard *table);
CGI::Carp qw(fatalsToBrowser);
DBI;
if (%messages)
{ print b("Bitte prüfen Sie Ihre Eingaben!"); }
print start_form (), start_table();
while (@f) {
($k,$v,@f) = @f;
if ($messages{$k}) {
print Tr(td({colspan=>2}, font({color=>"red"},
$messages{$k})));
}
print Tr(td("$v:"), td(textfield(name => $k)));
}
print end_table(),
submit (name => "aktion", value => "Mitarbeiter anlegen"),
reset (value => "Eingaben lschen"),
end_form;
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
# Ausgabe Seitenanfang
print header, start_html ("Neuanlage Mitarbeiter");
# Pruefen, ob Erstaufruf des Formulars
if (!defined(param("aktion"))) {
print h1 ("Eintrag eines neuen Mitarbeiters");
makeform;
print end_html;
exit;
}
# Formulareingaben holen
foreach $i (keys(%fields)) {
$p{$i} = param($i);
}
# Kein Nachname eingegeben?
if (!defined($p{nachname}) || $p{nachname} =~ /^ *$/) {
$messages{nachname} = "Bitte geben Sie einen Nachnamen ein.";
makeform;
print end_html;
exit;
}
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
181
182
Das Erzeugen des Formulars geschieht in einem Unterprogramm makeform in den Zeilen 826. Die in Zeile 9 denierten lokalen Variablen $k und $v werden jeweils zum Ablegen eines Feldnamens und der
zugeh
origen Feldbezeichnung verwendet. In Zeile 10 wird eine lokale
Kopie des Arrays @fields in der Variable @f angelegt, da das Erzeugen des Formulars das Array mit den Feldnamen und -bezeichnungen
zerstort.
Die Zeilen 11 und 12 dienen dazu, eine Information u
ber aufgetretene
Fehler auszugeben. Dies geschieht nur dann, wenn der Hash %messages
Eintr
age enth
alt. Die Information soll im Fettdruck angezeigt werden,
daher wird sie als Argument der vom CGI-Modul zur Verf
ugung gestellten Funktion b verwendet. Damit werden die f
ur den Fettdruck
ben
otigten HTML-Tags erzeugt.
In Zeile 13 werden die f
ur den Beginn des Formulars und der Tabelle
183
184
Wir pr
ufen daher in Zeile 38 einfach, ob der Parameter aktion
das ist der Name des Submit-Buttons in unserem Formular an das
Skript u
bergeben wurde. Wenn das nicht der Fall ist, muss es sich um
den ersten Aufruf unseres Skripts handeln. Wir erzeugen dann eine
Uberschrift
(Zeile 39), generieren das Formular durch Aufruf unseres Unterprogramms (Zeile 40), geben das Endetag f
ur die Seite aus
(Zeile 41) und beenden in Zeile 42 das CGI-Skript.
Ab Zeile 44 wissen wir, dass wir Formulareingaben zu verarbeiten haben. Wir u
bertragen in den Zeilen 4547 die Eingaben in den Hash
%p. In Zeile 49 pr
ufen wir, ob u
berhaupt ein Nachname eingegeben
wurde. Dazu stellen wir sicher, dass der Parameter u
berhaupt vorhanden ist und dass sein Wert nicht nur aus lauter Leerzeichen besteht.
Wenn kein Nachname eingegeben wurde, setzen wir in Zeile 50 die im
Formular anzuzeigende Fehlermeldung, erzeugen dann das Formular
(Zeile 51), geben das Endetag f
ur die Seite aus (Zeile 52) und beenden
in Zeile 53 das CGI-Skript.
F
ur die Pr
ufung, ob der eingegebene Abteilungsname g
ultig ist,
ben
otigen wir eine Datenbankabfrage. Wir stellen daher eine Verbindung zur Datenbank her (Zeile 56) und versuchen, die Abteilungs-Id
aus dem eingegebenen Abteilungsnamen zu ermitteln (Zeilen 5861).
Gelingt dies nicht, wird analog zur Fehlerbehandlung beim Nachnamen die anzuzeigende Fehlermeldung gesetzt, das Formular und das
Endetag ausgegeben und das CGI-Skript beendet (Zeilen 6370).
Man beachte, dass in Zeile 64 explizit die Datenbankverbindung abgebaut wird. Das geschieht zwar u
berlicherweise ohnehin, wenn das
Skript beendet wird, aber in Umgebungen, wo CGI-Skripten von einer st
andig laufenden Instanz des Perl-Interpreters ausgef
uhrt werden,
muss dies nicht notwendigerweise so sein. Man sollte also sichergehen,
dass die Verbindung zur Datenbank beendet wird, indem man sie stets
explizit vor Beendigung des Skripts abbaut.
Die Zeilen 7283 sind in der gleichen Form schon im Skript aus
Abb. 100 aufgetreten. Hier wird die neue Personalnummer ermittelt
und der neue Mitarbeiter eingetragen. In Zeile 85. pr
ufen wir, ob das
Einf
ugen erfolgreich war und geben dem Benutzer ein dementsprechendes Feedback. Konnte der Mitarbeiter eingef
ugt werden, teilen wir dem
Benutzer die Personal-Id und die Abteilungs-Id mit (Zeilen 8688), ansonsten erhalt der Benutzer eine allgemeine Fehlermeldung (Zeilen 90
92). (In einer Produktivversion sollte man eine ausf
uhrlichere Fehleranalyse vornehmen. Aus Gr
unden der Kompaktheit des Codes haben
185
wir hier darauf verzichtet.) Die Funktion p, die in den Zeilen 86, 87
und 90 aufgerufen wird, kommt aus dem CGI-Modul und erzeugt ein
HTML-Tag f
ur den Beginn eines neuen Absatzes.
Der Rest des Skripts baut die Verbindung zur Datenbank ab (Zeile 95)
und erzeugt einen HTML-Link, den der Benutzer anklicken kann, um
das Formular nochmals neu aufzurufen (Zeile 97), damit ein weiterer
Mitarbeiter eingegeben werden kann. Der hier verwendete Funktionsaufruf url() liefert die WWW-Adresse unseres CGI-Skripts. Klickt
der Benutzer auf den Link, wird das Skript ohne Parameter aufgerufen, es wird also ein vollig neues Formular erzeugt. In Zeile 99 wird
schlielich die HTML-Seite abgeschlossen.
186
standig l
auft.31 Dieser Interpreter bekommt dann CGI-Skripten vom
WWW-Server zur Ausf
uhrung u
bergeben. Da der Interpreter nach
Ausf
uhrung eines Skripts nicht beendet wird, bleibt auch der erzeugte
Zwischencode erhalten, so dass bei der n
achsten Ausf
uhrung des gleichen Skripts die Compilierungsphase entf
allt.
Systemumgebungen wie eben beschrieben konnen um sog. persistente
Datenbankverbindungen erweitert werden.32 Hier kann eine Datenbankverbindung auch nach Beendigung eines Skripts bestehen bleiben
und muss beim erneuten Aufruf des Skripts nicht wieder neu aufgebaut werden. Damit w
are auch das zweite Problem des Overheads f
ur
den Verbindungsauf- und -wiederabbau bei Datenbanken gel
ost.
Allerdings k
onnen sich auch damit Transaktionen nicht u
ber mehrere
33
ur liegt darin,
Skripten bzw. Skriptaufrufe erstrecken. Der Grund daf
dass u
blicherweise auf einem WWW-Server nicht nur ein Serverprozess
abl
auft, sondern mehrere, damit nicht nur eine Anforderung (engl. Request) gleichzeitig bearbeitet werden kann (Abb. 107). Die Zuordnung
der eingehenden Requests zu freien Serverprozessen kann nicht in
sinnvoller Weise beeinusst werden.
Request 2
Request 1
Benutzer A
Serverproze 1
Masterproze
Serverproze 2
Request 3
Benutzer B
Request 4
Request 5
Benutzer C
Zeit
Request 6
Serverproze 3
Serverproze 4
WWW-Server
32
33
Dies ist z. B. mit dem Apache-Webserver in Verbindung mit der Seroglich. Informationen hierzu nden sich unvererweiterung mod perl m
ter http://perl.apache.org/.
In Verbindung mit dem Apache-Webserver leistet dies das Perl-Modul
Apache::DBI.
Dies gilt zumindest f
ur das Apache::DBI-Modul.
187
Benutzer
Formular 1
Start
Transaktion
Formular 2
Ende
Transaktion
Rckmeldung
WWW-Browser
Client
WWWServerproze
CGI-Skript
Server
Schickt nun der Benutzer das zweite Formular nicht mehr ab, bleibt die
Transaktion oen und hindert m
oglicherweise andere Benutzer daran,
auf die Datenbank zuzugreifen (Abb. 109). Dieses Problem k
onnte
188
Benutzer
Start
Transaktion
Ende
Transaktion?
WWW-Browser
Formular 2
Formular 1
WWWServerproze
Client
CGI-Skript
Server
OK
413
Benutzer 2
Fehler
(doppelte PID)
413
Hier w
urde also dann versucht, zwei Datensatze mit der gleichen
PID anzulegen. Das Attribut PID sollte aber sinnvollerweise ein
Prim
arschl
ussel der Tabelle PERSONAL sein. Wenn wir die Uberwachung dieser Prim
arschl
usseleigenschaft durch eine Integritatsbe-
189
190
Benutzer 2
t + 0s
t + 2s
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
191
192
Benutzer 2
COMMIT
Verzgerung
COMMIT
193
(Graphischer) Uberblick
u
ber die relationale Datenbankstruktur mit
der M
oglichkeit, auch ohne SQL-Kenntnisse auf Detailinformationen
zuzugreifen.
Komfortable Erstellung und Ausf
uhrung von SQL-Abfragen
Einfache Erzeugung von Datenbankobjekten
Fehlersuch-M
oglichkeit (Debugging) bei der Ausf
uhrung von Abfragen, Funktionen, Triggern
Konkrete Werkzeuge f
ur Datenbankadministration bzw. -design sind
meist spezisch f
ur ein bestimmtes DBMS, auch wenn die Funktionalit
at oft ahnlich ist. Wir stellen hier beispielhaft einige Werkzeuge
vor, die speziell f
ur PostgreSQL vorgesehen sind oder mit PostgreSQL
genutzt werden k
onnen.
9.1. Kommandozeilentools
Naturgem
a wird ein reines Kommandozeilentool obigen Zielen nur
sehr eingeschrankt gerecht werden bei den meisten Datenbanksystemen ist ein solches Tool allerdings im Lieferumfang und bietet somit ohne die Installation zusatzlicher Software die Moglichkeit,
auf eine Datenbank zuzugreifen. Kommandozeilentools ermoglichen
haupts
achlich die interaktive Eingabe von SQL-Statements und geben
das Resultat unmittelbar auf dem Bildschirm aus.
Bei PostgreSQL heit das entsprechende Kommandozeilentool psql;
eine Beispielsitzung unter Verwendung von psql ist in Abb. 114 zu
sehen.
Obwohl der Komfort von Kommandozeilentools nicht besonders hoch
ist, sind sie unentbehrlich
9.2. Zugri u
ber WWW
system% psql U rank d firma
Welcome to psql 7.4.2, the PostgreSQL interactive terminal.
Type:
195
Anmelden an der
Datenbank firma
als Benutzer rank
Zeilenweises Eintippen
einer SQLAbfrage
firma=> \d
List of relations
Schema |
Name
| Type | Owner
+++
public | abteilung | table | rank
public | personal | table | rank
public | projekt
| table | rank
public | teile
| table | rank
public | zuordnung | table | rank
(5 rows)
firma=> \d personal
Table "public.personal"
Column
|
Type
| Modifiers
++
pid
| integer
| not null
nachname
| character varying(20) |
vorname
| character varying(15) |
strasse
| character varying(30) |
ort
| character varying(20) |
einstellung | date
|
gehalt
| numeric(7,2)
|
vorges_id
| integer
|
aid
| integer
|
Indexes:
"personal_pkey" primary key, btree (pid)
firma=> \q
system%
9.2. Zugri u
ber WWW
Software, die einen administrativen Zugri auf eine Datenbank u
ber
WWW gestattet, bringt folgende Vorteile:
F
ur den Zugri von einem vernetzten Client auf die Datenbank ist
nur ein WWW-Browser erforderlich, man benotigt keine zusatzliche
Software (auf dem Client).
196
Plattformunabh
angigkeit auf dem Client es kann jeder vernetzte
Client mit einem WWW-Browser verwendet werden.
Graphikf
ahigkeit ist durch die Mittel von HTML gegeben.
Das Standardtool f
ur den administrativen Zugri auf eine PostgreSQLDatenbank via WWW ist phpPgAdmin. Diese frei verf
ugbare Software
ist in der Sprache PHP programmiert. PHP wird oft f
ur die Realisierung dynamischer Webseiten (als Alternative zu CGI-Skripten)
verwendet und steht auf Webserver-Installationen mit der ApacheServersoftware (siehe Abschnitt B.5) in vielen Fallen bereits standardm
aig zur Verf
ugung. Die Struktur einer Datenbankinstallation
betrachtet mit phpPgAdmin ist in Abb. 115 zu sehen. Der Webserver mit der phpPgAdmin-Software muss nicht identisch mit dem Datenbank-Server sein, was gr
oere Flexibilit
at in einer vernetzten Serverumgebung bedeutet.
Mit phpPgAdmin kann man nicht nur die in Abschnitt 4.4 beschriebenen Datenbankdenitions-Operationen vornehmen, sondern auch
Datenbankabfragen ausf
uhren, so dass phpPgAdmin im Prinzip ein vollwertiger Ersatz f
ur das in Abschnitt 9.1 beschriebene Kommandozeilentool psql ist.
9.2. Zugri u
ber WWW
197
Uber
ein sog. SQL-Worksheet kann man beliebige SQL-Statements auf
der Datenbank ausf
uhren und erh
alt die Ergebnisse in u
bersichtlicher
Form angezeigt. In Abb. 116 ist das SQL-Worksheet mit der auf S. 48
gezeigten Abfrage und das Ergebnis dargestellt.
198
199
200
201
Literatur
[Co1970]
[Da2004]
[DeBu2000]
[EiMe1999]
[ElNa2004]
[GuGuBi2000]
[KeEi2004]
[MeSi1993]
[MuKe2002]
[Op1999]
[Pg2004]
[ScCh2001]
[SQL1999]
[SQL2003]
A. Syntaxdiagramme
Syntaxdiagramme dienen dazu, die richtige Schreibweise (Syntax) von
Sprachkonstrukten anschaulich zu denieren.
Im Prinzip handelt es sich bei einem Syntaxdiagramm um einen Wegeplan mit einem Ausgangs- und einem Endpunkt. Jeder Weg vom
Ausgangs- zum Endpunkt beschreibt ein syntaktisch zul
assiges Sprachkonstrukt. Elemente von Syntaxdiagrammen sind Pfeile, abgerundete
K
asten bzw. Kreise und Rechtecke.
enthalten ein syntaktisches Element, das
Abgerundete K
asten
enthalten
zeichenweise genau so angegeben werden muss. Kreise
jeweils ein Sonderzeichen, das genau so angegeben werden muss. Rechtkennzeichnen Namen von syntaktischen Elementen, die wieecke
derum u
ber ein weiteres Syntaxdiagramm (oder auch manchmal in
Worten) deniert sind. Dieses m
usste an dieser Stelle f
ur das Rechtkennzeichnen zul
assige Wege. Sie
eck substituiert werden. Pfeile
d
urfen jeweils nur in Pfeilrichtung durchlaufen werden.
Betrachten wir beispielsweise das Syntaxdiagramm, das die syntaktische Einheit Zier charakterisieren soll (Abb. 121).
ziffer
204
A. Syntaxdiagramme
1
B. Software-Bezugsquellen
Wir geben im folgenden einige Verweise an, wie man die zum Arbeiten
mit den Beispielen in diesem Buch geeignete Software erhalten kann.
B.1. PostgreSQL
PostgreSQL ist ein lizenzkostenfrei verf
ugbares relationales Datenbanksystem mit objektorientierten Konzepten. Es lauft unter vielen
unix-artigen Betriebssystemen (insbesondere unter Linux) und auch
unter Windows-Betriebssystemen (ab Windows NT). F
ur den Einsatz
unter letzteren ist im Moment noch zus
atzlich die Cygwin-Software
erforderlich (siehe Abschnitt B.3). Eine native Unterst
utzung f
ur
Windows-Betriebssysteme ist in Vorbereitung und wird voraussichtlich
in der n
achsten PostgreSQL-Version vorhanden sein. Zum Zeitpunkt
der Manuskripterstellung f
ur dieses Buch war die PostgreSQL-Version
7.4.2 aktuell.
Weitere Informationen einschlielich Dokumentation und DownloadM
oglichkeit nden sich auf der oziellen PostgreSQL-Homepage unter
http://www.postgresql.org
Das in Abschnitt 9.2 vorgestellte Tool phpPgAdmin ndet sich unter
http://phppgadmin.sourceforge.net
das Tool pgAdmin III aus Abschnitt 9.3 ist zu beziehen von
http://www.pgadmin.org
B.2. Linux
Eine komplette Systemumgebung f
ur PostgreSQL und auch insbesondere f
ur die in Abschnitt 8 beschriebene WWW-Anbindung von Datenbanken lasst sich gut unter dem Open Source-Betriebssystem Linux
aufbauen. Man verwende am besten eine der kompletten Distributionen, die einfach zu installieren sind und viele n
utzliche Softwarepakete
gleich mitbringen. Linux-Distributionen, die u
ber eine verh
altnism
aig
umfangreiche Softwareausstattung verf
ugen, sind z. B.
Slackware Linux
http://www.slackware.com
damit wurden das Manuskript dieser Auage sowie die Beispiele erstellt,
SuSE Linux
http://www.suse.de
und
206
B. Software-Bezugsquellen
B.3. Cygwin f
ur Windows
Die Cygwin-Software stellt unter Windows-Betriebssystemen eine
Unix-Umgebung bereit und erlaubt somit auch den Betrieb einer PostgreSQL-Datenbank unter Windows. Der Download ist m
oglich unter
http://cygwin.com
B.5. Apache
Die ozielle Website des Apache-WWW-Servers ist
http://httpd.apache.org
Hier nden sich ausf
uhrliche Informationen, die Dokumentation und
kostenlose Downloadmoglichkeiten (Apache ist Open Source). Die
oben angegebenen Linux-Distributionen enthalten den Apache-Server
bereits.
F
ur die in Abschnitt 8.8 beschriebene M
oglichkeit, einen PerlInterpreter in Apache direkt einzubinden, nden sich unter
http://perl.apache.org
weitere Informationen.
207
C. WWW-Site f
ur dieses Buch
Leser mit Zugri auf das Internet haben die Moglichkeit, die SQLDenitionen der in diesem Buch verwendeten Musterdatenbanken sowie langere Programmlistings aus den Abschnitten 7 und 8 per WWW
abzurufen, so dass l
astige Tipparbeit entf
allt.
Die URL der betreenden WWW-Site lautet
http://www.rz.uni-passau.de/db-buch/
Hier sind auch Linklisten auf im Text erwahnte Software sowie Aktualisierungen und eventuelle Fehlerkorrekturen zu nden.
TABLE
TABLE
TABLE
TABLE
TABLE
zuordnung CASCADE;
teile CASCADE;
projekt CASCADE;
personal CASCADE;
abteilung CASCADE;
210
projid integer
);
INSERT INTO abteilung VALUES (1, Betriebsleitung, M
unchen);
INSERT INTO abteilung VALUES (5, Auendienst, M
unchen);
INSERT INTO abteilung VALUES (8, Produktion, Olching);
INSERT INTO personal VALUES (128, Meyer, Markus,
Hilblestr. 17, M
unchen, 1994-01-19, 4327.50, 107, 8);
INSERT INTO personal VALUES (205, Huber, Hilde,
Passauer Str. 2a, Augsburg, 1991-05-27, 4995.05, 57, 5);
INSERT INTO personal VALUES (107, Schmidt, Steffi,
M
unchner Str. 7, Freising, 1990-11-02, 5722.00, 350, 8);
INSERT INTO personal VALUES (411, Frisch, Friedrich,
Dachauer Str. 22, M
unchen, 1995-09-14, 4520.67, 107, 8);
INSERT INTO personal VALUES (57, Klement, Karl,
Kirchfeldstr. 3, Bad T
olz, 1990-10-04, 6011.44, 350, 5);
INSERT INTO personal VALUES (350, Berger, Bernhard,
Gr
unaustr. 11, M
unchen, 1993-05-28, 8748.92, NULL, 1);
INSERT INTO projekt VALUES (3, Druckauftrag Fa. Karl);
INSERT INTO projekt VALUES (8, Beratung Fa. Seidl);
INSERT INTO projekt VALUES (11, Werbung Fa. Rieger);
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT
INTO
INTO
INTO
INTO
INTO
INTO
INTO
teile
teile
teile
teile
teile
teile
teile
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
VALUES
INSERT
INSERT
INSERT
INSERT
INSERT
INTO
INTO
INTO
INTO
INTO
zuordnung
zuordnung
zuordnung
zuordnung
zuordnung
VALUES
VALUES
VALUES
VALUES
VALUES
(128,
(411,
(107,
(411,
(205,
3);
11);
11);
3);
8);
211
E. Ubungsaufgaben
Obwohl man sich durch die Lekt
ure von B
uchern (wie etwa diesem)
ein solides Wissen u
ber Datenbanken aneignen kann, erlernt man den
souver
anen praktischen Umgang mit Datenbanken nur durch die aktive
Beschaftigung mit Beispielen.
Zu genau diesem Zweck den praktischen Umgang mit SQL
und PL/pgSQL zu erlernen haben wir eine Kollektion von
Ubungsaufgaben
zusammengestellt. Die Aufgaben sind so gestellt, dass
typische Praxisprobleme auftreten, mit denen man auch in gr
oeren
Real World-Situationen konfrontiert wird. Es werden jeweils zuerst
alle Aufgaben gestellt; die kommentierten Losungen benden sich im
darauf folgenden Abschnitt.
Die Tabelleninhalte sind nur als Beispiel anzusehen; die formulierten
SQL-Befehle m
ussen f
ur jeden in der Situation der Aufgabenstellung
sinnvollen Tabelleninhalt das Verlangte liefern. Verwenden Sie nur
die in den Aufgaben angegebene Information und nicht Information,
die Sie durch Nachschauen in den Tabellen von Hand ermittelt haben.
Bitte beachten Sie, dass wir aus Platzgr
unden bei den den Aufgabenstellungen zugrunde liegenden Musterdatenbanken stets die SQLstandardkompatible Kurzform f
ur Datentypnamen gew
ahlt haben,
also INT statt INTEGER, CHAR statt CHARACTER und VARCHAR statt CHARACTER VARYING.
Enth
alt die Theater, die von der Stadt verwaltet
alt dabei ein eindeuwerden. Die Spalte t id enth
tiges K
urzel f
ur jedes Theater.
PREISE
Enth
alt f
ur jede Platzkategorie (eindeutiges K
urzel in Spalte lage, volle Bezeichnung in Spalte bezeichnung) den Eintrittspreis (Spalte preis).
PLAETZE
ugbaren
Enth
alt f
ur jedes Theater (t id) die verf
Platzkategorien (lage), die Nummern der Reihen,
in denen sich Platze dieser Kategorie benden
213
E. Ubungsaufgaben
214
E.1.1. Aufgaben
zu Abschnitt 2.1/4.4.3
1. Identizieren Sie f
ur jede Tabelle der Datenbank einen (sinnvollen) Prim
arschl
ussel (nicht anhand der Beispieltabellen, sondern
anhand der Bedeutung der Tabellen). Geben Sie Sie die SQLStatements zur Denition dieser Prim
arschl
ussel an.
zu Abschnitt 3.4
2. Es sollen die Bezeichnungen der Platzkategorien ermittelt werden,
die nicht mehr als EUR 50,- kosten. Formulieren Sie einen entsprechenden SQL-Befehl.
3. Formulieren Sie einen SQL-Befehl, der die Anzahl der im Dezember 2004 im Opernhaus stattndenden Au
uhrungen ermittelt.
215
Titel des St
uckes, Veranstaltungsort. Die Ubersicht
soll nach Datum und Uhrzeit aufsteigend sortiert sein.
5. Geben Sie einen SQL-Befehl an, der eine nach der Gesamtzahl der
Pl
atze absteigend sortierte Liste aller Theater erstellt.
6. Erstellen Sie einen SQL-Befehl, der ermittelt, wie viele verschiedene Operetten der Vorstellungsplan zur Zeit enth
alt.
7. Erstellen Sie eine SQL-Abfrage, die die Gesamteinnahmen bei einer
ausverkauften Vorstellung im Stadttheater berechnet.
zu Abschnitt 3.5
8. Erstellen Sie eine View
FREI (v id, lage, anzahl)
die f
ur jede Vorstellungsnummer und jede dort angebotene Platzkategorie die Anzahl der freien Pl
atze liefert. (Hinweis: Sie k
onnen
sich zwei Hilfsviews erzeugen, die jeweils die Gesamtzahl bzw. die
Zahl der reservierten Pl
atze pro Vorstellung und Platzkategorie
berechnen.)
Unter Verwendung der View FREI soll die Anzahl der noch freien
Pl
atze in der Platzkategorie PA1 oder LO f
ur jeden Vorstellungstermin von La Traviata ermittelt werden. Formulieren Sie eine
entsprechende SQL-Abfrage.
zu Abschnitt 3.6
9. Eine neue Vorstellung mit der Nr. 280 und dem Titel Cosi fan
tutte (eine Oper), die am 10. Dezember 2004 um 19:30 Uhr im
Opernhaus stattndet, soll in die Tabelle VORSTELLUNG eingetragen werden. Formulieren Sie einen entsprechenden SQL-Befehl.
10. Die Eintrittskarte f
ur den Platz 1 der Reihe 1 in Platzkategorie R1
f
ur die Vorstellung von Annie, schie los am 01.12.2004 wird
zur
uckgegeben. Aktualisieren Sie die Tabelle RESERVIERUNG.
11. Die Vorstellung Der Zigeunerbaron am 30.11.2004 muss entfallen; f
ur bereits verkaufte Eintrittskarten (= reservierte Pl
atze) wird
der Eintritt zur
uckerstattet. Geben Sie einen SQL-Befehl an, der
die H
ohe des r
uckzuerstattenden Gesamtbetrages berechnet.
Geben Sie weitere SQL-Befehle an, die die Tabellen RESERVIERUNG und VORSTELLUNG aktualisieren.
216
E. Ubungsaufgaben
zu Abschnitt 4.2/4.3
12. Uberf
uhren Sie die Tabelle VORSTELLUNG in die dritte Normalform.
zu Abschnitt 4.4
13. Formulieren Sie einen SQL-Befehl zur Denition der Tabelle VORSTELLUNG.
14. Denieren Sie alle sinnvollen Abh
angigkeits-(FOREIGN KEY)
Constraints f
ur die Tabellen der Datenbank.
zu Abschnitt 5.1/5.2
15. Es sei angenommen, dass u
ber mehrere Arbeitspl
atze auf die Datenbank zugegrien werden kann. Bei der Platzreservierung wird
einem Kunden zun
achst ein Platz angeboten, den dieser dann
durch Kauf der betreenden Eintrittskarte verbindlich reservieren
kann. Welche Tabellenzugrie sind von der Ermittlung eines freien
Platzes bis zur endg
ultigen Reservierung notwendig? Wie kann verhindert werden, dass ein freier Platz an mehreren Arbeitspl
atzen
gleichzeitig angeboten wird? (Das vorgeschlagene Verfahren muss
nicht eektiv arbeiten.)
zu Abschnitt 6
16. Schreiben Sie eine PL/pgSQL-Funktion resplatz, die einen bestimmten Platz f
ur eine bestimmte Vorstellung (gegeben durch Titel und Datum) reserviert (d. h. die Tabelle RESERVIERUNG
entsprechend andert). Die Eingabedaten sollen dabei als Parameter von resplatz wie folgt u
bergeben werden:
resplatz (titel, datum, lage, reihe, platznr)
Es wird angenommen, dass der zu reservierende Platz f
ur die betreende Vorstellung noch nicht reserviert ist.
17. Schreiben Sie eine PL/pgSQL-Funktion reslage, die f
ur eine bestimmte Vorstellungsnummer und eine bestimmte Platzkategorie
einen freien Platz (Reihe und Platznummer) ermittelt, falls ein solcher noch existiert. Die Eingabedaten sollen dabei als Parameter
von reslage wie folgt u
bergeben werden:
reslage (v id, lage)
Das Ergebnis soll als ein Datensatz in die Tabelle
PANSWER (reihe INTEGER, platznr INTEGER)
217
geschrieben werden, soweit es noch einen freien Platz gibt. Ansonsten soll kein Datensatz erzeugt werden.
Es sei in der Datenbank zusatzlich noch eine leere Tabelle
TMPPLATZ (reihe INTEGER, platznr INTEGER)
vorhanden. Diese Tabelle k
onnen Sie beliebig verwenden, z. B. um
sich eine Liste aller Platze (Reihe und Platznummer) der verlangten Platzkategorie in der verlangten Vorstellung anzulegen.
E.1.2. L
osungen
Beim L
osen von konkreten Datenbank-Aufgabenstellungen, die die
Formulierung von SQL-Statements zum Ziel haben, ist es sinnvoll,
nach folgendem Schema vorzugehen:
(i) Klassikation des zu formulierenden Befehls: Sollen Informationen
aus der Datenbank beschat (SELECT), Datenbankinhalte modiziert (INSERT, UPDATE, DELETE) oder die Datenbank
selbst ver
andert werden (DDL-Statements wie CREATE TABLE,
CREATE VIEW, ALTER TABLE, . . . )?
(ii) Welche Tabellen werden f
ur die Datenbankabfrage ben
otigt?
Wie (
uber welche Joins mit welchen Attributen) m
ussen diese
verkn
upft werden?
(iii) Welche weiteren Bedingungen f
ur die Abfrage gibt es? Diese
m
ussen in entsprechende WHERE-Klauseln umgesetzt werden.
(iv) Was soll geliefert bzw. geandert werden?
Durch diese strukturierte Vorgehensweise erleichtert man sich das Erstellen von SQL-Befehlen erheblich.
Nun zu den L
osungen f
ur die einzelnen Aufgaben. Zum besseren
Verstandnis der Tabelle PLAETZE ist der Platzplan f
ur das Theater Mozarthaus, Saal K in Abb. 125 graphisch dargestellt.
1. Aus der Beschreibung der THEATER-Tabelle geht hervor, dass
das Attribut t id ein Theater, also einen Datensatz, eindeutig beussel f
ur THEAstimmt. Damit ist {t id} schon einmal Superschl
TER. Da die einzige echte Teilmenge von {t id} die leere Menge
ussel von
{} ist, die niemals Schl
ussel sein kann, ist {t id} Schl
THEATER. Weitere Schl
ussel sind aus der Tabellenbeschreibung
arschl
ussel:
nicht ersichtlich; wir verwenden also {t id} als Prim
ALTER TABLE theater ADD PRIMARY KEY (t id);
E. Ubungsaufgaben
218
2
1. Rang Teilsicht
12 13 14
16 17 18 19 20
1.15Rang
11 12 13 14 15 16 17 18 19 20
11
2
1
3
2
2
1
3
3
5
4
4
3
10
10 11 12
2
1
10 11 12 13 14 15 16 17 18
Sperrsitz
5
10 11 12 13 14 15 16 17 18
10 11 12 13 14 15 16 17 18
10 11 12 13 14 15 16 17 18
10 11 12 13 14 15 16 17 18
Balkon
3
2
1
3
2
1. Parkett
4
10 11 12 13 14 15 16 17
10 11 12 13 14 15 16 17
10 11 12 13 14
8
7
6
5
4
25 26 27 28
22 23 24 Teilsicht
1.21 Rang
1. Rang
21 22 23 24 25 26 27 28 29 30
3 4 5 Teilsicht
6 7 8 9 10
1.2 Rang
1 2 3 1.
4 Rang
5 6 7 8 9 10
3
2
1
219
220
E. Ubungsaufgaben
WHERE datum >= 20041201 AND datum < 20050101
ORDER BY datum, uhrzeit;
221
E. Ubungsaufgaben
222
9. Wir m
ussen den INSERT-Befehl mit einem SELECT-Statement
kombinieren, da in die VORSTELLUNG-Tabelle das TheaterK
urzel eingetragen werden muss, das wir erst aus der THEATERTabelle ermitteln m
ussen:
INSERT INTO vorstellung
SELECT 280, Cosi fan tutte, Oper, 20041210,
19:30, t id
FROM theater
WHERE bezeichnung = Opernhaus;
Das SELECT-Statement erzeugt genau einen Datensatz (mit
agen), der dann in die
bis auf t id lauter konstanten Eintr
VORSTELLUNG-Tabelle eingef
ugt wird.
10. Es ist klar, dass es sich hier um eine DELETE-Anweisung handelt.
In dieser muss jedoch eine Subquery verwendet werden, um aus
dem Namen des St
uckes und dem Termin die Vorstellungsnummer
zu erhalten.
DELETE FROM reservierung
WHERE reihe = 1 AND platznr = 1 AND lage = R1
AND v id = (
SELECT v id FROM vorstellung
WHERE titel = Annie, schie los
AND datum = 20041201
);
11. F
ur die Berechnung des R
uckerstattungsbetrages benotigen wir offensichtlich die Tabellen RESERVIERUNG, PREISE und VORSTELLUNG (letztere, um die gegebenen Vorstellungsdaten in die
Vorstellungsnummer umzusetzen).
SELECT SUM(preis)
FROM reservierung NATURAL JOIN preise
NATURAL JOIN vorstellung
WHERE titel = Der Zigeunerbaron
AND datum = 20041130;
Wir l
oschen dann die Reservierungen mit:
DELETE FROM reservierung
WHERE v id = (
SELECT v id FROM vorstellung
WHERE titel = Der Zigeunerbaron
AND datum = 20041130
);
223
224
E. Ubungsaufgaben
FOREIGN KEY (v id) REFERENCES vorstellung(v id);
ALTER TABLE reservierung ADD
FOREIGN KEY (lage) REFERENCES preise(lage);
11
DECLARE
in_titel ALIAS FOR $1;
in_datum ALIAS FOR $2;
in_lage ALIAS FOR $3;
in_reihe ALIAS FOR $4;
in_platznr ALIAS FOR $5;
vnr INTEGER;
12
BEGIN
5
6
7
8
9
10
13
14
15
16
17
18
19
225
E. Ubungsaufgaben
226
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
20
21
22
FOR p IN
SELECT * FROM plaetze
WHERE t_id = t_t_id
AND lage = in_lage
LOOP
FOR i IN 1 .. p.anzahl LOOP
INSERT INTO tmpplatz VALUES (p.reihe, i);
END LOOP;
END LOOP;
19
23
24
25
26
27
28
29
30
31
32
OPEN f;
FETCH f INTO fplatz;
36
IF FOUND THEN
INSERT INTO panswer
VALUES (fplatz.reihe, fplatz.platznr);
END IF;
37
RETURN;
33
34
35
38
39
END;
LANGUAGE plpgsql;
227
ZIEL
Enth
alt die Ziele, in denen das Unternehmen Hotels anbieten kann. F
ur jeden Ort ist eine eindeutige Nummer
(zid), das K
urzel des Landes, in dem sich der Ort bendet (lid), sowie der Name des Ortes (ort) angegeben.
Der Ortsname muss bez
uglich verschiedener Lander nicht
eindeutig sein.
228
E. Ubungsaufgaben
229
HOTEL
KUNDE
Enth
alt die Kunden-Gesamtumsatze pro Jahr. F
ur jeden Kunden und jedes Jahr wird ein Datensatz angelegt, soweit der betreende Kunde in diesem Jahr
Hotel
ubernachtungen in Anspruch genommen hat. kid
enth
alt die Kundennummer, jahr das Jahr und betrag
den Umsatz des betreenden Kunden im entsprechenden
Jahr. Dieser errechnet sich aus der Summe der Preise aller
Ubernachtungen,
die der betreende Kunde im betreenden Jahr in Anspruch genommen hat. F
ur das laufende
Jahr (2004) enth
alt betrag den bis jetzt erreichten Jahresumsatz, dabei sind die in der Tabelle BUCHUNG enthaltenen Ums
atze noch nicht ber
ucksichtigt.
230
E. Ubungsaufgaben
E.2.1. Aufgaben
zu Abschnitt 2.1/4.4.3
1. Identizieren Sie f
ur jede Tabelle der gegebenen Datenbank einen
(sinnvollen) Prim
arschl
ussel und geben Sie die SQL-Statements zur
Denition dieser Prim
arschl
ussel an.
zu Abschnitt 3.4
2. Formulieren Sie einen SQL-Befehl, der eine Liste der Hotels
in Nizza/Frankreich liefert, die f
ur ein Einzelzimmer h
ochstens
EUR 50 pro Nacht verlangen.
3. Geben Sie einen SQL-Befehl an, der eine Liste aller Hotels mit
den Angaben Land, Ort, Hotelname liefert. Die Liste soll absteigend nach Kategorienummern (1. Sortierkriterium) und aufsteigend nach dem Preis f
ur ein Doppelzimmer (2. Sortierkriterium)
sortiert sein.
4. Geben Sie einen SQL-Befehl an, der eine Liste aller L
ander liefert,
in denen zur Zeit keine Hotels angeboten werden.
5. Geben Sie einen SQL-Befehl an, der eine Liste aller L
ander mit
der Anzahl der dort angebotenen Hotels erstellt. L
ander, in denen
zur Zeit keine Hotels angeboten werden, sollen nicht in der Liste
stehen.
6. Formulieren Sie einen SQL-Befehl, der Namen und Wohnort aller Kunden ausgibt, die mindestens zwei Hotelaufenthalte gebucht
haben.
7. Gesucht sind die Namen aller Kunden, die einen Hotelaufenthalt
gebucht haben, der eine Hotel
ubernachtung vom 8. auf den 9. September 2004 einschliet. Formulieren Sie einen SQL-Befehl, der
diese Namen liefert.
8. Es soll eine Liste erstellt werden, die f
ur jeden Kunden den Namen
und die Umsatzsumme aus den Jahren 2003 und 2004 (laut Umsatztabelle) enthalt. Kunden ohne Umsatz sollen dabei mit Umsatz 0 in der Tabelle stehen. Formulieren Sie einen entsprechenden
SQL-Befehl.
9. Es soll eine Liste erstellt werden, die f
ur jede Buchung den Kundennamen, den Zielort und das Land, den Hotelnamen, das Anrei-
231
15. Uberf
uhren Sie die Tabelle HOTEL in die dritte Normalform.
zu Abschnitt 4.4
16. Denieren Sie s
amtliche Abh
angigkeits-(FOREIGN KEY) Constraints f
ur die Tabellen der gegebenen Datenbank und geben Sie
die SQL-Statements zur Denition dieser Constraints an.
E. Ubungsaufgaben
232
zu Abschnitt 6
17. Schreiben Sie eine PL/pgSQL-Funktion clean (), die alle Kunden, die 2003 und 2004 keinen Umsatz gemacht haben sowie keinen
Eintrag in der Buchungstabelle haben, aus den Tabellen KUNDE
und UMSATZ entfernt.
18. Schreiben Sie eine PL/pgSQL-Funktion cbuchung (stichtag)
mit einem Parameter stichtag vom Typ DATE, die folgende Aufgabe ausf
uhrt:
Die Kosten eines Hotelaufenthalts der alten Eintrage der
BUCHUNG-Tabelle (das sind diejenigen, bei denen das Abreisedatum vor dem stichtag liegt), sollen den betreenden Kundenumsatzen in der UMSATZ-Tabelle zugeschlagen werden. Anschlieend sollen die alten Eintr
age der BUCHUNG-Tabelle gel
oscht
werden.
Beachten Sie hierbei folgende Hinweise:
Sie k
onnen aus einer Datumsangabe d (kann auch ein Attributwert sein) das Jahr in vierstelligem Format mit dem Ausdruck
TO CHAR(d,YYYY)
ermitteln.
F
ur das Jahr, auf das die Kosten des Hotelaufenthaltes gebucht
werden, ist das Abreisedatum mageblich.
Sie m
ussen evtl. in der UMSATZ-Tabelle einen Datensatz anlegen, wenn f
ur den Kunden und das Jahr noch kein Datensatz
existiert.
E.2.2. L
osungen
Man beachte die allgemeinen L
osungshinweise am Anfang von Abschnitt E.1.2. Die L
osungsskizzen in diesem Abschnitt sind meist etwas k
urzer gehalten als bei der ersten Musterdatenbank, da davon
ausgegangen wird, dass der Leser nun schon etwas Praxis bei der Bearbeitung von Datenbankaufgaben besitzt.
1. Man erkennt ohne Probleme, dass {lid} Schl
ussel von LAND,
{zid} Schl
ussel von ZIEL und {kid} Schl
ussel von KUNDE ist.
Wir zeichnen diese Schl
ussel jeweils als Prim
arschl
ussel aus.
Bei der Beschreibung der Tabelle HOTEL ist vermerkt, dass hnr
nur innerhalb des gleichen Ortes (gleicher Wert von zid) eindeutig ist. Damit bildet {zid,hnr} einen Schl
ussel von HOTEL.
233
Die UMSATZ-Tabelle enthalt pro Kunde und Jahr einen Datensatz. Damit bildet {kid,jahr} einen Schl
ussel von UMSATZ.
Laut den Erl
auterungen zur Tabelle BUCHUNG nimmt ein Kunde
nicht mehrere Buchungen zum gleichen Anreisetermin vor, also ist
{kid,anreise} Schl
ussel von BUCHUNG. Wir zeichnen die gefundenen Schl
ussel jeweils als Prim
arschl
ussel aus.
Die entsprechenden SQL-Statements lauten:
ALTER TABLE land ADD PRIMARY KEY (lid);
ALTER TABLE ziel ADD PRIMARY KEY (zid);
ALTER TABLE kunde ADD PRIMARY KEY (kid);
ALTER TABLE hotel ADD PRIMARY KEY (zid, hnr);
ALTER TABLE umsatz ADD PRIMARY KEY (kid, jahr);
ALTER TABLE buchung ADD PRIMARY KEY (kid, anreise);
2. Um die geforderte Information liefern zu k
onnen, ben
otigen wir
die Tabellen HOTEL, LAND und ZIEL. Diese verkn
upfen wir per
Natural-Join und geben zus
atzlich noch die in der Aufgabe gegebenen Bedingungen an:
SELECT hname
FROM land NATURAL JOIN ziel NATURAL JOIN hotel
WHERE name = Frankreich
AND ort = Nizza
AND pez <= 50;
3. Wir ben
otigen zur L
osung dieser Aufgabe wieder die Tabellen HOTEL, LAND und ZIEL, verkn
upft mit Natural-Joins. Die ORDER
BY-Klausel ergibt sich direkt aus der Aufgabe.
SELECT name, ort, hname
FROM land NATURAL JOIN ziel NATURAL JOIN hotel
ORDER BY kat DESC, pdz;
4. Dies ist ein typisches Beispiel f
ur eine Negativabfrage. Wir l
osen
diese mit einem NOT IN-Konstrukt.
SELECT name FROM land
WHERE lid NOT IN (
SELECT lid FROM ziel NATURAL JOIN hotel
);
5. F
ur die Beschaung der geforderten Informationen ben
otigen wir
oensichtlich die Tabellen HOTEL, LAND und ZIEL, die wie gehabt durch Natural-Joins zu verkn
upfen sind. Der Hinweis, dass
L
ander, in denen keine Hotels angeboten werden, nicht in der Er-
234
E. Ubungsaufgaben
gebnisliste stehen sollen, erspart uns die M
uhe, einen Outer-Join
zu formulieren. Statt dessen lautet die Abfrage einfach:
SELECT name, COUNT(hnr)
FROM land NATURAL JOIN ziel NATURAL JOIN hotel
GROUP BY name;
235
GROUP BY kid;
Die Erzeugung der Ergebnistabelle geschieht nun unter Verwendung dieser Hilfsview, wobei wir durch einen Outer Join mit der
Kundentabelle erreichen, dass auch Kunden ohne Umsatz ausgegeben werden. Damit letztere mit Umsatz 0 erscheinen, verwenden
wir die COALESCE-Funktion:
SELECT name, COALESCE(betrag,0)
FROM kunde NATURAL LEFT JOIN humsatz;
9. F
ur die L
osung dieser Aufgabe brauchen wir mit Ausnahme der
UMSATZ-Tabelle alle Tabellen der Datenbank, also 5 Tabellen.
Die Tabellen LAND, ZIEL, HOTEL und Buchung konnen wie gehabt per Natural-Join verkn
upft werden. Mit der Tabelle KUNDE
ist dies nicht m
oglich, da hier ein zweites Mal das Attribut ORT in
anderer Bedeutung vorkommt. Wir f
uhren daher einen Equi-Join
mit expliziter Angabe des gleichzusetzenden Attributnamens
(KID) durch.
Ansonsten stellt sich noch die Frage, wie man f
ur eine Buchung
jeweils den Preis des gebuchten Aufenthalts berechnet. Der Preis
f
ur eine Ubernachtung
setzt sich zusammen aus dem Preis f
ur ein
Einzelzimmer, multipliziert mit der Zahl der gebuchten Einzelzimmer, und dem Preis f
ur ein Doppelzimmer, multipliziert mit der
236
E. Ubungsaufgaben
fert (Hotels, in denen in der betreenden Nacht nichts belegt ist,
werden nicht aufgef
uhrt):
CREATE VIEW dzbelegt (zid, hnr, anzahl) AS
SELECT zid, hnr, SUM(adz)
FROM hotel NATURAL JOIN buchung
WHERE anreise <= 20040905
AND abreise >= 20040905
GROUP BY zid, hnr;
Nun m
ussen wir f
ur das gew
unschte Hotel nur noch die von der
View gelieferte Anzahl von der vorhandenen Anzahl an Doppelzimmern abziehen. Ein Outer-Join ist jedoch erforderlich, da die
View ja eventuell f
ur das gew
unschte Hotel nichts liefert (wenn
keine Zimmer reserviert sind).
SELECT dzz - COALESCE(anzahl,0)
FROM (land NATURAL JOIN ziel NATURAL JOIN hotel)
NATURAL LEFT JOIN dzbelegt
WHERE name =
Osterreich
AND ort = Linz
AND hname = Am P
ostlingberg;
237
UPDATE hotel
SET pez = 1.1 * pez, pdz = 1.1 * pdz
WHERE zid IN (
SELECT zid
FROM land NATURAL JOIN ziel
WHERE name = Frankreich
);
15. Oensichtlich stort die Abh
angigkeit
{kat} {katname}
Dekomposition liefert
HOTEL1 (zid, hnr, hname, kat, ezz, dzz, pez, pdz)
HOTEL2 (kat, katname)
16. Wir geben f
ur jede (Kind-)Tabelle an, welche Attribute von welchen Attributen in der Eltern-Tabelle abh
angen. Die Angaben zu
Name und Attribut der Eltern-Tabelle stehen dabei rechts vom
Pfeil.
BUCHUNG: kid KUNDE.kid
{zid,hnr} HOTEL.{zid,hnr}
UMSATZ: kid KUNDE.kid
HOTEL: zid ZIEL.zid
ZIEL: lid LAND.lid
Hier die Constraintdenitionen in SQL:
ALTER TABLE buchung
ADD FOREIGN KEY (kid) REFERENCES
ALTER TABLE buchung
ADD FOREIGN KEY (zid, hnr)
REFERENCES hotel(zid, hnr);
ALTER TABLE umsatz
ADD FOREIGN KEY (kid) REFERENCES
ALTER TABLE hotel
ADD FOREIGN KEY (zid) REFERENCES
ALTER TABLE ziel
ADD FOREIGN KEY (lid) REFERENCES
kunde(kid);
kunde(kid);
ziel(zid);
land(lid);
17. Im Prinzip m
ussen wir nur zwei normale SQL-Befehle hintereinander ausf
uhren. Der erste Befehl l
oscht die gew
unschten Datens
atze aus der KUNDE-Tabelle, der zweite die Datensatze aus
der UMSATZ-Tabelle. Das entsprechende PL/pgSQL-Programm
ndet sich in Abb. 129.
E. Ubungsaufgaben
238
BEGIN
4
5
6
7
8
9
10
11
19
20
RETURN;
12
13
14
15
16
17
18
21
22
END;
LANGUAGE plpgsql;
Abb. 129: L
oschen von Karteileichen
Es ist allerdings u
berhaupt nicht klar, warum diese L
osung eigentlich funktioniert: Sind Constraints auf der Datenbank deniert (siehe vorherige Aufgabe), k
onnen diese verletzt werden,
wenn Kunden zuerst aus der KUNDEN-Tabelle gel
oscht werden,
aber noch einen Eintrag in der UMSATZ-Tabelle haben. Damit
w
urde man erwarten, dass die Ausf
uhrung des ersten DELETEStatements in der geschilderten Situation vom Datenbanksystem
abgelehnt und die Aktion abgebrochen wird.
In PostgreSQL funktioniert dies jedoch, weil die G
ultigkeit von
Constraints innerhalb einer Funktion nicht gepr
uft wird, die
Pr
ufung ndet fr
uhestens nach Ausf
uhrung des Statements statt,
das die Funktion aufruft. Zu diesem Zeitpunkt ist in unserem Fall
aber alles wieder in Ordnung, da ja in der Funktion im zweiten
Schritt auch die Eintr
age der entfernten Kunden in der UMSATZTabelle gel
oscht werden.
Um die Funktion prinzipiell auch in Datenbanksystemen anwenden
zu k
onnen, die Constraints innerhalb von Funktionen pr
ufen, kann
239
man wie folgt auf Nummer Sicher gehen: Man beschat sich
zun
achst die nicht zu l
oschenden Kundennummern und speichert
sie in einer temporaren Tabelle. Daf
ur sei in der Datenbank die
Tabelle KTMP vorhanden, die etwa mit
CREATE TABLE ktmp (kid INTEGER);
erzeugt worden sein k
onnte. Nach dem Aufbau der Tabelle KTMP
kann man n
amlich zuerst die Datensatze in der Tabelle UMSATZ,
dann diejenigen in der Tabelle KUNDE l
oschen, so dass sich auch
innerhalb der Funktion keine Integrit
atsverletzungen mehr ergeben. Das verbesserte PL/pgSQL-Programm ist in Abb. 130 abgebildet.
BEGIN
6
7
8
9
10
11
12
13
14
18
19
20
RETURN;
15
16
17
21
22
END;
LANGUAGE plpgsql;
Abb. 130: L
oschen von Karteileichen, verbesserte Version
240
E. Ubungsaufgaben
F
ur jeden dieser Datensatze berechnen wir die Kosten des gebuchten Aufenthalts.
Falls f
ur das betreende Jahr (das Jahr des Abreisedatums) in
der UMSATZ-Tabelle noch kein Datensatz f
ur den Kunden existiert, erzeugen wir zunachst einen mit Umsatz 0.
Dann addieren wir den Umsatz des aktuellen Aufenthaltes zum
vorhandenen Umsatz.
Am Schluss werden alle Buchungen, deren Abreisedatum vor dem
Stichtag liegt, aus der BUCHUNG-Tabelle geloscht.
Der jeweils aktuelle Datensatz der BUCHUNG-Tabelle wird in der
RECORD-Variablen b gespeichert. Den Umsatz des aktuellen Aufenthalts legen wir in der Variablen umsatz buchung ab. In j speichern wir das Jahr des Abreisedatums.
Das Programmlisting ist in Abb. 131 aufgef
uhrt.
Die Schleife in den Zeilen 932 wird f
ur jeden Datensatz in der
BUCHUNG-Tabelle, bei dem das Abreisedatum vor oder an dem
heutigen Tag liegt, ausgef
uhrt. Der gerade behandelte Datensatz
wird in die Variable b geladen (Zeile 9). In den Zeilen 1318 wird
der mit der aktuellen Buchung verbundene Umsatz berechnet und
in die Variable umsatz buchung geschrieben.
Die Zeilen 2022 pr
ufen, ob schon ein geeigneter Datensatz in
der UMSATZ-Tabelle existiert, dem der berechnete Umsatz zugeschlagen werden kann. Da uns bei dieser Auswahlabfrage nur
interessiert, ob es Datensatze gibt, die den spezizierten Bedingungen entsprechen, nicht jedoch die Ergebnistabelle, schreiben
wir PERFORM statt SELECT. . . INTO. Falls kein Datensatz in
der UMSATZ-Tabelle existiert (Zeile 2327), wird per INSERT
ein neuer Datensatz in der UMSATZ-Tabelle erzeugt.
In den Zeilen 2831 wird der Einzelumsatz dem Jahresumsatz des
Kunden zugeschlagen. Dies geschieht per UPDATE-Statement. Es
wird immer ein Datensatz modiziert, da der Fall, dass noch kein
passender Datensatz in der UMSATZ-Tabelle existiert, schon zuvor
behandelt wurde (durch Erzeugung eines passenden Datensatzes).
Schlielich l
oschen die Zeilen 3334 die behandelten Datens
atze
aus der BUCHUNG-Tabelle.
1
2
DECLARE
stichtag ALIAS FOR $1;
b RECORD;
umsatz_buchung umsatz.betrag%TYPE;
j umsatz.jahr%TYPE;
BEGIN
3
4
5
6
9
10
11
12
FOR b IN
SELECT * FROM buchung
WHERE abreise < stichtag
LOOP
18
19
j := TO_CHAR(b.abreise,YYYY);
20
13
14
15
16
17
21
22
23
24
25
26
27
28
29
30
31
32
END LOOP;
33
34
35
RETURN;
36
37
END;
LANGUAGE plpgsql;
241
E. Ubungsaufgaben
242
Gibt an, welche Personen als (jetzige oder ehemalige) Kursteilnehmer registriert sind. Erfasst ist die
eindeutige Teilnehmernummer (tnr), Nachname
(name), Vorname (vorname), Adresse (adresse),
Postleitzahl (plz) und Wohnort (wohnort).
ORTE
Enth
alt die Orte, an denen Kurse stattnden
k
onnen. Angegeben ist jeweils ein eindeutiges
K
urzel (id), der Name des Ortes (name) sowie seine
Adresse (adresse).
GEBUEHREN
KURSE
243
E. Ubungsaufgaben
244
gegeben: Das K
urzel f
ur den Veranstaltungsort
(id), die Anzahl der Abende, an denen der Kurs
stattndet (abende), die Dauer eines Kursabends
in Minuten (dauer), die Preisgruppe des Kurses
(pg), sowie das Datum des Kursbeginns (beginn).
TERMINE
Enth
alt die w
ochentlichen Kurstermine. F
ur jeden
Termin ist angegeben die Kursnummer (knr), die
ersten zwei Buchstaben des Wochentags (tag) und
die Uhrzeit des Beginns (zeit). Es wird angenommen, dass es f
ur den gleichen Kurs nicht zwei Termine am gleichen Wochentag gibt.
E.3.1. Aufgaben
zu Abschnitt 2.1/4.4.3
1. Identizieren Sie f
ur jede Tabelle der Datenbank einen (sinnvollen)
Prim
arschl
ussel und geben Sie die SQL-Statements zur Denition
der Prim
arschl
ussel an.
zu Abschnitt 3.4
2. Eine Liste, die f
ur jeden angebotenen Kurs den Titel und den Veranstaltungsort enth
alt, soll erstellt werden. Geben Sie einen SQLBefehl an, der dies leistet.
3. Geben Sie einen SQL-Befehl an, der die Namen aller nicht von
Kursen genutzten Veranstaltungsorte liefert.
4. Die Titel der Kurse mit der Hochstzahl von Kursabenden sollen
ermittelt werden. Formulieren Sie einen SQL-Befehl, der eine Liste
mit diesen Titeln produziert.
5. Formulieren Sie einen SQL-Befehl, der eine Liste der Namen aller
Kurse erstellt, f
ur die noch kein Leiter bestimmt ist.
245
E. Ubungsaufgaben
246
247
E.3.2. L
osungen
Man beachte die allgemeinen Losungshinweise am Anfang von Abschnitt E.1.2. Auch in diesem Abschnitt halten wir die Losungsskizzen
etwas k
urzer als bei der ersten Musterdatenbank, da wir davon ausgehen, dass der Leser nun schon etwas Praxis bei der Bearbeitung von
Datenbankaufgaben besitzt.
1. Aus den Beschreibungen der Tabellen einfach zu entnehmen sind
Schl
ussel f
ur die Tabellen ORTE ({id}), KURSE ({knr}) und
TEILNEHMER ({tnr}), die wir auch als Primarschl
ussel auszeichnen.
Bei der Tabelle ANMELDUNGEN m
ussen oensichtlich beide
Attribute als Schl
ussel {tnr,knr} verwendet werden, da sich ein
Teilnehmer ja f
ur mehrere Kurse anmelden kann. Bei der Tabelle
TERMINE u
berlegen wir uns, dass Kurse an mehreren Wochentagen, aber laut Erl
auterung nicht mit zwei Terminen am gleichen
Wochentag stattnden k
onnen. Aus diesem Grunde ist {knr,tag}
Schl
ussel von TERMINE. Die eben identizierten Schl
ussel verwenden wir auch als Primarschl
ussel.
Bei der Tabelle GEBUEHREN gilt es zu beachten, dass aufgrund
der geforderten Widerspruchsfreiheit der Datenbank keine zwei Datens
atze mit den gleichen Attributwerten f
ur pg und tnmin existieren k
onnen, d. h. {pg,tnmin} bildet einen Schl
ussel von GEBUEHREN. Mit der gleichen Argumentation erkennt man, dass auch
{pg,tnmax} einen Schl
ussel bildet. Einen dieser beiden Schl
ussel
k
onnen wir als Prim
arschl
ussel auszeichnen.
Die SQL-Statements f
ur die Denition der Prim
arschl
ussel lauten:
ALTER TABLE orte ADD PRIMARY KEY (id);
ALTER TABLE kurse ADD PRIMARY KEY (knr);
ALTER TABLE teilnehmer ADD PRIMARY KEY (tnr);
ALTER TABLE anmeldungen ADD PRIMARY KEY (tnr, knr);
ALTER TABLE termine ADD PRIMARY KEY (knr, tag);
ALTER TABLE gebuehren ADD PRIMARY KEY (pg, tnmin);
2. Wir ben
otigen die Tabellen KURSE und ORTE, die wir per
Natural-Join u
ber das gemeinsame Attribut ID verkn
upfen.
SELECT titel, name
FROM kurse NATURAL JOIN orte;
248
E. Ubungsaufgaben
3. Es handelt sich hier um eine typische Negativabfrage, die wir folgendermaen formulieren k
onnen:
SELECT name FROM orte
WHERE id NOT IN
(SELECT id FROM kurse);
4. Oensichtlich m
ussen wir hier erst per Subquery die H
ochstzahl
von Kursabenden ermitteln, um das gew
unschte Ergebnis zu produzieren:
SELECT titel FROM kurse
WHERE abende =
(SELECT MAX(abende) FROM kurse);
5. Dass ein Kurs noch keinen Leiter hat, l
asst sich daran erkennen,
dass das Attribut LEITER der Tabelle KURSE den Wert NULL
hat. Also:
SELECT titel FROM kurse
WHERE leiter IS NULL;
6. Die Kurstitel entnehmen wir der Tabelle KURSE, die Kursfrequenz
berechnen wir aus der Tabelle TERMINE. Gemeinsames Attribut
der beiden Tabellen ist knr.
SELECT titel, COUNT(tag)
FROM kurse NATURAL JOIN termine
GROUP BY knr, titel;
F
ur die Attribute der GROUP BY-Klausel gilt: TITEL muss aufgef
uhrt sein, da dieses Attribut in der SELECT-Liste auftritt, ohne
Argument einer Gruppenfunktion zu sein. Das eigentliche Gruppierungskriterium ist jedoch die Kursnummer, die deshalb aufgef
uhrt
ist.
7. Das gew
unschte Ergebnis k
onnen wir mit den Tabellen KURSE
und GEBUEHREN ermitteln. Das gemeinsame Attribut ist PG.
Aus der GEBUEHREN-Tabelle muss der Datensatz verwendet
werden, der f
ur eine Teilnehmerzahl von 10 Personen gilt; das ist
genau derjenige, f
ur den gilt: Mindestteilnehmerzahl kleiner oder
gleich 10, H
ochstteilnehmerzahl gr
oer oder gleich 10.
SELECT COUNT(knr)
FROM kurse NATURAL JOIN gebuehren
WHERE tnmin <= 10 AND tnmax >= 10
AND preis <= 150;
249
8. Hier handelt es sich um einen Self-Join mit der Tabelle TEILNEHMER. Da zu einem Teilnehmer auch die Kurse ermittelt werden m
ussen, zu denen er sich angemeldet hat, muss auch die
ANMELDUNGEN-Tabelle in den Self-Join einbezogen werden.
Wir k
onnen das so l
osen, dass wir zwei Mal einen Natural-Join von
TEILNEHMER und ANMELDUNGEN bilden und dem jeweiligen
Resultat einen Tabellen-Alias (t1 bzw. t2) zuordnen. Die Resultate der beiden Natural-Joins werden dann per Equi-Join u
ber das
Attribut knr verkn
upft es interessieren ja nur Paare von Teilnehmern im gleichen Kurs. Doppelt vorkommende Paare eliminieren
wir dadurch, indem wir nur Paare in der Ausgabe zulassen, wo
die Teilnehmernummer des ersten Teilnehmers kleiner ist als die
Teilnehmernummer des zweiten Teilnehmers.
SELECT t1.name, t1.vorname, t2.name, t2.vorname
FROM (teilnehmer NATURAL JOIN anmeldungen) t1
JOIN
(teilnehmer NATURAL JOIN anmeldungen) t2
USING (knr)
WHERE t1.tnr < t2.tnr;
9. Wir ermitteln die Kurstitel aus der Tabelle KURSE und plazieren nur diejenigen Titel in der Ausgabe, f
ur die in GEBUEHREN
lediglich ein zugeh
origer Datensatz existiert, was wir durch Kombination von GROUP BY- und HAVING-Klauseln erreichen:
CREATE VIEW konstant AS
SELECT titel
FROM kurse NATURAL JOIN gebuehren
GROUP BY knr, titel
HAVING COUNT(tnmin) = 1;
10. Wir erzeugen zun
achst eine View, die f
ur jeden Kurs die Mindestteilnehmerzahl liefert:
CREATE VIEW mint (knr, minteil) AS
SELECT knr, MIN(tnmin)
FROM kurse NATURAL JOIN gebuehren
GROUP BY knr;
Mit einer zweiten View bestimmen wir die Zahl der tatsachlichen
Teilnehmer in jedem Kurs. Hierbei m
ussen wir durch einen OuterJoin daf
ur sorgen, dass auch Kurse geliefert werden, f
ur die keine
Anmeldungen vorliegen, also die Teilnehmerzahl gleich Null ist.
CREATE VIEW anm0 (knr, anzahl) AS
250
E. Ubungsaufgaben
SELECT knr, COUNT(tnr)
FROM kurse NATURAL LEFT JOIN anmeldungen
GROUP BY knr;
Man beachte, dass bei COUNT in diesem Fall kein COALESCEKonstrukt erforderlich ist, da COUNT mit einem Argument, das
kein * ist, nur Datens
atze zahlt, bei denen der Wert des Arguments nicht NULL ist. Bei einem durch den Outer-Join erzeugten NULL-Datensatz ist jedoch TNR gleich NULL, wird also von
COUNT nicht gez
ahlt, so dass der richtige Wert 0 geliefert wird.
Die eigentliche Liste wird nun einfach unter Verwendung von
KURSE (f
ur die Titel) und der beiden Views erzeugt:
SELECT titel
FROM kurse NATURAL JOIN mint
NATURAL JOIN anm0
WHERE anzahl < minteil;
11. Wir k
onnen bei dieser Aufgabe die View ANM0 aus der letzten Aufgabe verwenden. Zus
atzlich ben
otigen wir die Tabellen
ANMELDUNGEN, KURSE, GEBUEHREN und TEILNEHMER.
Den jeweils f
ur die Geb
uhrenberechnung mageblichen Datensatz
aus der GEBUEHREN-Tabelle ermitteln wir u
ber die Zahl der
tats
achlich vorliegenden Anmeldungen. F
ur den Datensatz muss
gelten: Tatsachliche Anzahl gr
oer oder gleich minimaler Teilnehmerzahl und kleiner oder gleich maximaler Teilnehmerzahl.
SELECT name, vorname, SUM(preis)
FROM anmeldungen NATURAL JOIN kurse
NATURAL JOIN gebuehren
NATURAL JOIN teilnehmer
NATURAL JOIN anm0
WHERE anzahl >= tnmin AND anzahl <= tnmax
GROUP BY tnr, name, vorname;
12. Gem
a dem Hinweis in der Aufgabe legen wir zun
achst eine View
an, die f
ur jeden Kurs die maximale Teilnehmerzahl angibt:
CREATE VIEW maxt (knr, maxteil) AS
SELECT knr, MAX(tnmax)
FROM kurse NATURAL JOIN gebuehren
GROUP BY knr;
Nun verwenden wir diese View und die drei Tabellen KURSE,
ORTE, GEBUEHREN, um die gew
unschte Auskunft zu erhalten:
SELECT SUM(preis * maxteil)
251
252
E. Ubungsaufgaben
rer Leiter bestimmt, m
ussen mehrere Datensatze in KURSDATEN
geandert werden.
DECLARE
n INTEGER;
BEGIN
8
9
10
253
13
14
15
18
IF n > 0 THEN
RAISE EXCEPTION
Bereits Anmeldung fr gleichen Tag vorhanden!;
END IF;
19
RETURN new;
11
12
16
17
20
21
22
23
24
25
END;
LANGUAGE plpgsql;
CREATE TRIGGER check_anm
BEFORE INSERT ON anmeldungen
FOR EACH ROW
EXECUTE PROCEDURE f_check_anm ();
F. SQL-Kommandoreferenz
Abschnitt
4.4.2
5.1
6.1
4.4.4
4.4.1
6.4
3.5
3.6.3
6.2
4.4.4
4.4.1
6.4
3.5
5.4
3.6.1
5.2
6.3.5
5.4
5.1
3.4
6.3.5
3.4.7
5.2
3.4.3
3.4.4
6.3.1
3.6.2
Abbildungsverzeichnis
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
1:
2:
3:
4:
5:
6:
2
3
4
6
8
10
11
13
16
16
17
18
21
25
28
32
32
33
34
39
42
44
46
47
47
49
50
256
Abb. 28:
Abb. 29:
Abb. 30:
Abbildungsverzeichnis
51
52
52
56
59
60
62
64
65
74
77
78
79
80
81
83
83
83
84
86
89
90
94
95
97
99
99
100
100
103
104
106
107
Abbildungsverzeichnis
257
Abb. 61:
Abb. 62:
108
110
113
115
117
120
121
123
124
125
126
127
128
129
130
132
132
133
134
136
138
140
140
141
146
148
151
152
258
Abbildungsverzeichnis
Abb. 89:
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
90:
91:
92:
93:
94:
95:
96:
97:
98:
Abb. 99:
Abb. 100:
Abb. 101:
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
102:
103:
104:
105:
106:
107:
Abb. 108:
Abb. 109:
Abb. 110:
Abb. 111:
Abb. 112:
Abb.
Abb.
Abb.
Abb.
Abb.
113:
114:
115:
116:
117:
Abb. 118:
Ubergabe
von Daten an eine SQL-Anweisung mit
DBI
Ein komplettes Programm in Perl/DBI
Programmgesteuerter Ablauf einer Ober
ache
Ereignisgesteuerter Ablauf einer Oberache
Fat Client und Datenbank-Server
Thin Client, Applikations- und Datenbank-Server
X-Terminal, Applikations- und Datenbank-Server
Ablauf der Ausf
uhrung eines CGI-Skripts
Datenbankzugri aus dem WWW mit CGI und DBI
Web-Formular zum Eintragen eines neuen
Mitarbeiters
HTML-Code zum Erzeugen des Web-Formulars
CGI-Skript zum Eintragen eines neuen Mitarbeiters
Ergebnisseite des Skripts bei nicht existenter
Abteilung
CGI-Skript zum Erzeugen des Web-Formulars
Fehlerpr
ufung bei Web-Formularen
Ablauf der Korrektur einer fehlerbehafteten Eingabe
Web-Formular mit Fehlerbehandlung (Anfang)
Web-Formular mit Fehlerbehandlung (Fortsetzung)
Bearbeitung von Requests durch vier WWWServerprozesse
Uber
mehrere Formulare verteilte Transaktion
Nicht komplettierte Transaktion
Fast gleichzeitiger Zugri auf ein CGI-Skript durch
zwei Benutzer
Konsequenzen einer race condition
Mehrbenutzerf
ahiges Web-Formular mit
Fehlerbehandlung
Konkurrierende Transaktionen bei Web-Formularen
Eine psql-Beispielsitzung
Datenbankadministration mit phpPgAdmin
Freie SQL-Statements in phpPgAdmin
Datenbankabfrage nach dem Query by examplePrinzip
Musterdatenbank FIRMA in pgAdmin III
156
158
163
163
164
164
165
167
168
170
170
172
174
175
176
179
180
181
186
187
188
188
190
191
192
195
196
197
198
199
Abbildungsverzeichnis
259
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
Abb.
200
201
203
203
204
213
218
225
226
228
238
239
241
243
253
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
Uberpr
ufung von Kursanmeldungen
Stichwortverzeichnis
SQL-Kommandos wurden aus
Gr
unden der Ubersichtlichkeit
nicht in das Stichwortverzeichnis
aufgenommen.
A
Abfrage 5, 20, 25, 38, 4045, 47,
48, 51, 5457, 59, 61, 63
67, 69, 72, 73, 85, 93, 98,
101, 114, 115, 118, 120,
122, 123, 129, 153, 157,
159, 194, 197, 214, 215,
217, 221, 227, 234, 236,
245, 251
-resultat 119, 120
-sprache 6, 22, 23
Abh
angigkeit 8, 9, 75, 76, 78
80, 82, 83, 216, 223, 231,
237, 246, 251
Abh
angigkeitssystem 76, 78
Abstraktionsniveau 20, 151
Administrationsoperation 198
Adminitrationstools 198
Anderungsabfrage
65, 100
Anderungsoperation
139
Aggregation 26, 41
Aggregationsfunktion 18, 34, 36,
41, 42, 62
Aggregationsoperation 25, 51
Aktion
Stichwortverzeichnis
Ausdruck 25, 3033, 3638, 40,
41, 43, 45, 58, 112, 118,
229, 232
Ausf
uhrungsgeschwindigkeit 93
Ausf
uhrungsreihenfolge 48
Ausgabe-Hostvariable 144
Ausgangs-Relationenschema 77,
82
Ausgangsrelation 18, 77
Ausnahmebedingung 123, 125,
137, 149, 253
Autocommit 97, 102, 155, 190
B
B-Baum 93, 94
Backup 5
Basistabelle 58, 62, 6567, 107
Bedingung 13, 1517, 25, 38, 43,
45, 47, 52, 56, 64, 66, 67,
79, 88, 98, 129, 153, 217,
219, 233, 240
Befehl 19, 25, 86, 109, 212, 214
217, 219, 222, 223, 230,
231, 236, 237, 244246,
251
Benchmarktests 5
Benutzer
-aktion 162
-daten 19
-eingabe 157, 167, 169, 177,
183, 187
-kennung 139, 210
-name 28, 105, 149, 152
-ober
ache 6, 162, 164166,
194
-prozess 21
261
-schnittstelle 24
-verwaltung 104
-zugri 21
Berechtigung 71
Betriebssystem 28, 150, 162, 165,
198, 205, 206
Betriebssystemplattform 1, 150,
161
Bibliotheksfunktion 143
Binderegeln 31, 33
Block 116
Boyce-Codd-Normalform
(BCNF) 81
Browser 166168, 171, 173, 174,
183, 185, 195, 196
C
C
-Datentyp 144
-Funktion 147
-Programm 143145, 147
-Variable 145
CGI 166178, 182, 184190, 193,
196, 206
-Skript 169, 188
Client 21, 163166, 195, 196
-bibliothek 151, 160
-software 151, 164
Codierung 193
Command Line Interface (CLI)
162, 164, 165
Compiler 143
Compilierungsaufwand 160
Compilierungsphase 186
Compilierungsschritt 150
262
Stichwortverzeichnis
D
Datei 13, 5, 167, 171, 177, 210,
211
-namen 171
-system 3
-verwaltung 1
Daten
-abstraktion 3
-
anderung 1
-austausch 166
-basis 1
-bestand 2, 92, 96, 242
-ebene 3
-eingabe 5
-haltung 3
-administration 194
-inkonsistenz 96
-integrit
at 5
-konsistenz 99
-manipulation 5
-applikation 5, 6, 177
-modell 6
-architektur 5
-modikationsbefehl 93
-betrieb 96
-sicherheit 3, 5
-denition 196
-speicherung 1
-designer 24
-struktur 58, 93
-ebene 161
Stichwortverzeichnis
263
-integrit
at 20
-konzept 104
Datumsformat 72
-katalog 19
-implementierung 143
-programmierer 162
-programmierung 58
-sicherheit 142
-system 1, 1923, 37, 47, 62,
68, 69, 77, 92, 93, 95, 98,
99, 104, 116, 143, 145,
150155, 157, 159161,
163, 194, 205, 207, 209,
238
-tabelle 93
-theorie 9
-verbindung 155, 184186
-verwalter 105
-verwaltungssystem 1
-zugri 3, 150, 151, 154, 157
Datensatz 1315, 1820, 25, 38,
4043, 45, 49, 50, 5457,
6064, 66, 67, 74, 77, 86
89, 94, 98101, 110, 118
120, 122, 126, 128, 129,
132, 134, 135, 137139,
146, 147, 153, 154, 157,
159, 174, 188, 189, 216
220, 222, 225, 227, 229,
232234, 237, 239, 240,
242, 245, 247252, 263
-bearbeitung 122
-inhalt 138
Datensatz 41
Datenschutz 58, 107
-aufgaben 5
-Applikation 3
DCL 19, 27, 96
DDL 19, 26, 100, 217
Deadlock 99
-Situation 99
Deklaration 116, 122
Deklarationsteil 116, 118, 120
Dekomposition 8284, 223, 237
Dekompositionsoperation 82, 83
Dezimalpunkt 29, 35, 70
Dezimalstellen 29, 30
Dialog 199
DML 19, 26, 96
Domain-Key-Normalform
(DKNF) 81
Download 205, 206
Drei-Ebenen-Modell 5
E
ECPG 143, 145147
Ezienz 48, 185
Einbettung 166
Einf
uge
-operation 61, 157, 174
Einf
ugen 60, 61, 85, 92, 135, 139,
157, 177, 178, 182, 184,
189
264
Stichwortverzeichnis
Eingabe
-auorderung 157
-daten 216
-feld 170, 171, 176, 178, 182
-formular 175
-maske 177
Einzelabfrage 40
Eltern-Datensatz 126
Eltern-Kind-Beziehung 126
Eltern-Tabelle 88, 89, 106, 223,
237, 252
Embedded SQL (ESQL) 143
Entity 911
-typ 1012
Entwicklungsprozess 193
Entwicklungstool 163, 193
Entwicklungsumgebung 193
Entwicklungswerkzeug 162
Entwurf 5, 9, 24, 46, 73, 84
Ergebnis
-liste 114, 234
-relation 14, 15, 17, 18
-tabelle 15, 16, 25, 26, 38,
4046, 4851, 5658, 61,
85, 114, 115, 120, 122,
153, 159, 235, 240
-zeile 63
Ersatzdarstellung 119
Exception 123, 125
F
Fehler
-analyse 184
-ausgabe 173
Stichwortverzeichnis
136138, 147, 156, 170,
173, 178, 182, 185, 194,
198, 199, 212, 216, 219,
224, 227, 232, 235, 238,
239, 242, 253
funktional 8, 9, 75, 76, 7880, 82,
83, 223, 251
Funktionalit
at 42, 155, 190, 194
Funktionsaufruf 172, 174, 185
Funktionsname 129
Funktionsparameter 114, 118
G
Gateway 166
Genauigkeit 29, 30
Gleitpunktzahl 29, 30, 203
Grantee 105107
Grantor 105
Graphical User Interface (GUI)
162165, 176
Gruppenfunktion 36, 41, 42, 234,
248
Gruppierungsattribut 18, 19
Gruppierungskriterium 248
H
Handle 152155, 178
Hash 173, 178, 182184
Hauptabfrage 54
Hauptprogramm 183
Hierarchie 126, 128
-stufe 127129, 131
Hilfsview 58, 215, 221, 231, 234,
235, 245, 246
Host
265
-Applikation 22
-Programm 143, 161
-Programmiersprache
143
22,
-Tag 169
HTTP 166
I
Indikatorvariable 144, 145
Indizes 7, 27, 93, 95
Inferenzregel 75, 76
Information 1, 3, 4, 6, 7, 19, 20,
24, 37, 51, 56, 58, 68,
69, 73, 74, 76, 81, 84, 93,
111, 118, 155, 182, 186,
205, 206, 212, 217, 219,
224, 233, 244
Informations-regel 19
-system 1
Initialisierung 122, 129
Inkonsistenz 1, 3
Instanz 102, 124, 184, 188, 189
Integrit
at 87
Integrit
ats-bedingung 5, 84, 87, 189
-regel 19
-unabh
angigkeit 19
-verletzung 239
Interface 24, 166
266
Interpreter 151, 171, 184186,
206
Iterationskriterium 159
J
Java 23
JavaScript 166
Join 1517, 26, 38, 4253, 5557,
62, 81, 82, 217, 219221,
233236, 247, 249251
Equi- 15, 16, 26, 4547, 56,
235, 249
Natural- 16, 47, 48, 82, 219,
233235, 247, 249
Outer- 49, 51, 220, 221, 234,
236, 249, 250
Self- 16, 26, 38, 50, 249
K
Kind-Tabelle 88
Kommandozeilen
-tool 194, 196
Kommandozeilen-ebene 165
-programm 189
Konformit
at 23
Konformit
ats-ebene 23
Konkatenationsoperator 31
Konsistenz 1, 81, 96, 141, 176
-problem 101
-pr
ufung 3
L
Laufzeitsystem 151
Stichwortverzeichnis
Leseoperation 1, 24, 98
Linux 205, 206
Literal 28, 29, 113, 124
L
oschanomalie 74, 83
L
oschoperation 236
M
Mehrbenutzer
-system 28
Mehrbenutzer-betrieb 1, 5, 98, 185
-umgebung 102, 142, 190
Mengen-operator 40, 41, 62
-orientierung 19
Men
upunkt 162
Metadaten 3, 111
N
Nationalsprachenunterst
utzung
5
Negativabfrage 57, 233, 248
Netzwerk 165
-anbindung 165
-f
ahigkeit 21
-prozess 21
Nichtlinearit
at 162
Nichtschl
usselattribut 80
Normalform 7783, 216, 223, 231,
251
Normalisierung 75, 79, 81, 84
NULL
-Attributwert 17, 128
-Constraint 87, 91
Stichwortverzeichnis
-Datensatz 250
-Operator 33
-Wert 17, 49, 50, 61, 67, 74,
75, 87, 88, 91, 144, 242
Nullbyte 144
O
Objektprivileg 105, 106
Open Source 150, 192, 193, 205
207
Operand 31, 33
Operator 14, 15, 3133, 37, 55
57, 62
Overloading 115, 129
P
Package 23
Parameter 113115, 117, 124,
127, 129, 131, 137, 145,
152, 156, 173, 174, 178,
183185, 199, 216, 223,
224, 232
-name 173
-wert 169
Perl 143, 149151, 153, 155157,
159161, 167, 168, 171,
173, 183186, 193, 206
PHP 166, 196
PL/pgSQL 112, 116118, 120,
122, 123, 129, 135, 137,
143, 153, 212, 216, 224,
232, 237, 239
Portierbarkeit 161, 193
Portierungs-aufwand 150, 161
-fragen 160
267
-schwierigkeit 161
Positivabfrage 55, 57
PostgreSQL 1, 23, 24, 27, 29, 30,
33, 62, 65, 66, 69, 71, 72,
88, 90, 96, 97, 99102,
105, 106, 111, 112, 115,
116, 135, 136, 142, 143,
145, 151, 152, 155, 194,
196, 201, 205207, 209
211, 238, 252
-Superuser 211
Precompiler 143, 147, 160
Prim
arschl
ussel 9, 11, 87, 90, 91,
188, 214, 217219, 230,
232, 233, 244, 247
-eigenschaft 188
-wert 19
Prioritatsregel 99
Privileg 28, 104107, 109, 111,
113, 142, 210
Programm 1, 2, 4, 5, 21, 23, 116,
118, 121, 122, 135, 143
147, 149151, 153157,
159162, 166, 167, 171,
224, 225, 237, 239
-abbruch 147, 154
-ablauf 150
-ausf
uhrung 149
-code 159, 166, 190
-erstellungsprozess 160
-listing 208, 240
-logik 193
-system 1
-teil 162
-version 189
Programmier-
268
-aufwand 1, 3
-ebene 3
-sprache 2224, 30, 33, 112,
116, 117, 143, 149, 150,
159, 160, 167
Programmierung 99, 163, 164,
166, 167, 252
Protokolldatei 173
Protokollierung 96, 139
Pseudo-Datentyp 144
Q
Quellcode 147, 150, 160
Query 22, 122, 134, 197
R
race condition 189
Reaktionszeit 5
Redundanz 1, 4, 81
-freiheit 4
Reexivitat 75
rekursiv 127, 128, 131, 133, 134
Relation 79, 1217, 20, 22, 73
78, 80, 82, 83
Relationen-form 73
-modell 74, 75
-schema 8, 11, 12, 7384, 131
Relationship 1012
Relationsname 15, 73
Reprasentation 68, 69
Rollback 187
R
uckgabetyp 113, 114
R
uckgabewert 113115, 125, 133,
157, 159
Stichwortverzeichnis
Rule-System 66
S
Schema 28, 73, 105, 111, 217
Schleifenbedingung 154
Schleifenvariable 178
Schl
ussel
-attribut 12
-eigenschaft 9, 77, 251
-wert 75
Schl
usselwort 45, 50, 66, 116, 145
Schl
ussel 173
Schnittstelle 20, 150, 151, 160,
172
Schreib-/Lese-Transaktion 100
Schreiboperation 3
Schreibzugri 224
Semantik 67, 76, 138
Server 2022, 97, 145, 152, 164
167, 169, 171, 173, 185,
186, 193, 196, 206
Serverprozess 21, 167, 186, 187
Sicherheit 5, 20, 173
Sicherheits-aspekt 169
-kontext 113, 114
-l
ucke 166
-mechanismus 139
Skript
-aufruf 186
-code 189
-programmierung 187
Stichwortverzeichnis
Software 20, 150, 165, 192, 194
196, 205, 206, 208
-entwicklung 178
-hersteller 193
-paket 205
-produkt 5, 193
-umgebung 4
Sonderzeichen 203
Sortierkriterium 220, 230
Spalten
-constraint 88
-denition 85
-liste 60, 61
-menge 87, 88, 91
-name 19, 38, 4648
-zugri 108
Speicherverwaltung 20
Sperre 98102, 189, 190, 224
Exklusiv- 98, 102, 189, 224
Lese- 98, 100102
SQL 1, 6, 20, 2227, 2931, 33
35, 37, 41, 43, 45, 52, 58,
62, 65, 66, 69, 71, 72, 84,
8688, 90, 91, 9597, 99
102, 105, 106, 111118,
120, 122124, 129, 135
137, 139, 142147, 149,
151153, 155157, 159
162, 178, 194, 196, 197,
201, 205212, 214217,
219, 223, 224, 230233,
237239, 244247, 252
-Datentyp 116, 118
-Dialekt 209
-Implementierung 143
269
-Programm 116
-Standard 23, 27, 143, 147,
159, 160
-Statement 66, 112, 114, 197
-Worksheet 197
Standardwert 61, 84, 85, 171
Statement 24, 25, 27, 37, 4042,
52, 54, 58, 66, 68, 71, 84,
85, 8890, 96, 97, 100
102, 104, 105, 112, 114,
116, 118, 124, 129, 137,
139, 141, 143147, 149,
152155, 178, 194, 197,
201, 209211, 214, 217,
222, 230, 231, 233, 238,
240, 244, 247, 252
String 7, 125, 144
Stringliteral 72, 113, 137
Subquery 5256, 6063, 222, 236,
248, 251
korrelierte 5456
Suchbegri 93
Superschl
ussel 9, 80, 217, 251
Superuser-Privileg 210
Superuser-Recht 105
Syntax 24, 25, 28, 32, 33, 37, 42,
43, 48, 65, 88, 93, 100,
104, 203
-diagramm 37, 38, 58, 60, 84,
112, 145, 203, 204
System
-administration 5
-privileg 104, 105
-tabelle 111
-umgebung 185, 186, 205
-variable 118, 139
270
T
Tabellen-Alias 50, 249
-Liste 25, 54
-beschreibung 217
-constraint 87, 88, 91
-darstellung 9
-denition 60, 61, 85, 87
-eintrag 60, 105, 106
-form 8, 19, 20
-format 183
-inhalt 139, 212
-name 19, 38, 44, 48
-spalte 30, 36, 41, 45, 60, 61,
84, 106, 111, 113, 118,
183
-struktur 48, 170
-zeile 34, 106, 122
-zugri 93, 216, 224
Telnet-Client 165
Text-datei 151
-feld 169, 171
-interface 162
-konstante 28
-literal 28, 29, 31
Thin Client 163, 164, 166
Transaktion 89, 90, 96102, 104,
124, 137, 142, 145, 155,
161, 185190, 224
Transaktions-ende 90, 101, 102
-kontext 97, 102, 124, 145
-kontrolle 1, 145
Stichwortverzeichnis
-konzept 96, 161
-modus 99, 100
-verarbeitung 20
Transitivit
at 75
Trigger 27, 106, 123, 135139,
141, 142, 194, 198, 199,
246, 252, 253
-denition 138, 199
-funktion 137
Typ
-konversion 36, 37, 71, 144
U
Unix-System 151, 165
Unterabfrage 5254, 63, 85
Unterprogramm 157, 182, 184
Update 19, 63, 64, 199
V
Variable 116, 118, 120, 122, 144,
145, 147, 152, 153, 159,
171, 173, 178, 182, 187,
224, 225, 227, 240
Variablenname 171
Variablenwert 169
Verf
ugbarkeit 5, 20, 161
Vergleichs-operation 31
-operator 3033, 53
Verkettungsoperation 37
Verkn
upfung 2, 31, 43, 219
Vernestung 42
View 27, 42, 58, 59, 62, 6467, 81,
105111, 135, 207, 215,
221, 231, 236, 245, 249,
250
Stichwortverzeichnis
W
Web-Formular 166170, 176
-Interface 24
Webserver 186, 193, 196
Website 206
Wurzelknoten 128, 129
WWW
-Adresse 167, 170, 185
-Anbindung 169, 187, 193,
205
-Browser 166, 167, 173, 185,
195, 196
-Ober
ache 177, 192
-Seite 150, 166169, 171, 174
-Server 166, 167, 169, 171,
173, 185, 186, 206
-Serverprozess 167
-Serverumgebung 171
-Site 208
X
X-Server-Software 165
X-Terminal 165
Z
Zahlendarstellung 68
Zahlenkonstante 30
Zahlenwert 68
Zeichenfolge 68
Zeichenkette 7, 3032, 35, 37,
61, 6871, 144, 147, 152,
156, 157, 161, 169, 173
Zeilentrigger 137, 138, 199, 246
Zeitintervall 72
271
Zugrisrecht 26, 28, 142
Zuweisung 118
Zwischencode 150, 185, 186