2224 lines
56 KiB
Plaintext
2224 lines
56 KiB
Plaintext
.so /z/ing_src/macdoc
|
||
.NH 1
|
||
.ds RH \f3QUEL\f1
|
||
.ds RF \f3\*(yy\f1
|
||
.ds CH - % -
|
||
.ds LH Anwendung
|
||
.ds LF \*(vv
|
||
.pn 162
|
||
.LP
|
||
.bp
|
||
.NH 1
|
||
.ft B
|
||
Anwenderdokumentation
|
||
.br
|
||
\*(yy\ 6.3/3 - Teil II
|
||
.ft R
|
||
.sp 5
|
||
.nf
|
||
#############################################################
|
||
#############################################################
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ### # # ##### ###### ###### ##
|
||
## # ## # # # # # # # ##
|
||
## # # # # # # # # # ##
|
||
## # # # # # #### # # ###### ##
|
||
## # # # # # # # # # # ##
|
||
## # # ## # # # # # # ##
|
||
## ### # # ##### ####### ###### ###### ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ####### ####### ### # ##### ##
|
||
## # # # # # # ##
|
||
## # # # # # ##
|
||
## # ##### # # ##### ##
|
||
## # # # # # ##
|
||
## # # # # # ##
|
||
## # ####### ### ####### ####### ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
## ##
|
||
#############################################################
|
||
#############################################################
|
||
|
||
.fi
|
||
.bp
|
||
.NH 2
|
||
.ft B
|
||
Anwendung der QUEL *
|
||
.ft R
|
||
.LP
|
||
.sp 10
|
||
Dieser Einf\o'u"'hrungskurs beschreibt, wie das \*(yy\ 6.3-DBS
|
||
anzuwenden ist.
|
||
Sie sollten in der Lage sein, den angegebenen
|
||
Beispielen zu folgen und die gleichen Ergebnisse zu erhalten.
|
||
Die Datenbank "demo" ist in der ausgelieferten
|
||
Vertriebsversion enthalten.
|
||
Nach den \o'U"'bungen in diesem Kapitel sind sie in der
|
||
Lage die anschliessenden beiden Kapitel besser
|
||
zu verstehen. Es empfiehlt sich auch, das Referenz-Manual
|
||
noch einmal gr\o'u"'ndlich zu lesen.
|
||
.LP
|
||
Die Daten-Manipulations-Sprache, die von
|
||
\*(yy\ 6.3 unterst\o'u"'tzt wird, nennt sich
|
||
QUEL (Query Language) bzw. in Kurzform Query.
|
||
Eine vollst\o'a"'ndige Information zur QUEL wird
|
||
im \*(yy\ 6.3-Referenz-Manual (Teil I) gebracht.
|
||
Dieser Kurs beabsichtigt nicht, jedes
|
||
Detail von \*(yy\ 6.3 zu ber\o'u"'hren.
|
||
Es wird aber versucht, sie zu bef\o'a"'higen,
|
||
die QUEL aktiv zu beherrschen und auf dieser
|
||
Basis Schritt f\o'u"'r Schritt in die Geheimnisse
|
||
von \*(yy\ 6.3 einzusteigen.
|
||
.LP
|
||
Fangen wir mit dem Eintritt in \*(xx\, dem
|
||
Time-Sharing-System, unter dem \*(yy\ 6.3 l\o'a"'uft, an.
|
||
Wenn irgend m\o'o"'glich, benutzen sie ein Terminal,
|
||
das \o'u"'ber Gross- und Kleinbuchstaben verf\o'u"'gt,
|
||
anderenfalls werden sie ein schweres Leben haben.
|
||
Wenn sie an einem Terminal arbeiten, das nur
|
||
Grossbuchstaben hat, geben
|
||
sie "\\\\" anstelle "\\" f\o'u"'r Beispiele dieses
|
||
Einf\o'u"'hrungskurses ein.
|
||
.LP
|
||
Nach Eintritt in das Mehrnutzersystem (Eingabe des "login"-Namens)
|
||
wird auf dem Terminal die Bereitschaft mit "%" angezeigt.
|
||
(Durch \o'A"'nderung von PS1 im .profile "/mnt/ing_db/.profile" auf
|
||
"%" erhalten sie \o'U"'bereinstimmung mit den angef\o'u"'hrten
|
||
Beispielen, wobei "%" vom Terminal ausgegeben wird !)
|
||
Um \*(yy\ 6.3 zu nutzen, geben sie beispielsweise das Kommando:
|
||
.DS L
|
||
|
||
% quel dt
|
||
|
||
.DE
|
||
.LP
|
||
Das veranlasst \*(xx\, die Datenbank "demo" zur
|
||
Nutzung durch \*(yy\ 6.3 bereitzustellen.
|
||
Nach einigen Sekunden erscheint folgendes:
|
||
.DS L
|
||
|
||
ING_db version 6.3/3 login
|
||
Tue Aug 30 14:52:23 1985
|
||
|
||
ING_db>
|
||
*
|
||
|
||
.DE
|
||
.LP
|
||
(Sofern sys/etc/dayfile nicht leer ist
|
||
bzw. die Ausgabe nicht unterdr\o'u"'ckt wird, wird vor
|
||
ING_db> noch
|
||
der Inhalt dieses File's angegeben.)
|
||
Die ersten beiden Zeilen beinhalten die \*(yy\ 6.3-Version
|
||
(in diesem Fall "Version 6.3") und das aktuelle Datum.
|
||
Danach folgt die Ausgabe des "dayfile",
|
||
das Mitteilungen
|
||
- bezogen auf \*(yy\ 6.3 - enth\o'a"'lt.
|
||
Das I N G - d b > zeigt an, dass \*(yy\ 6.3
|
||
bereit ist, ihre Kommandos anzunehmen.
|
||
.LP
|
||
Der Monitor
|
||
erinnert mit einem Stern ("*") am Zeilenanfang daran,
|
||
dass \*(yy\ 6.3
|
||
auf eine Eingabe wartet.
|
||
.br
|
||
Wenn Sie den Monitor zur Ausf\o'u"'hrung der Query
|
||
angewiesen haben, erscheint die Ausschrift
|
||
Zu Beginn arbeiten wir mit einer Relation "teile", die
|
||
folgende Struktur hat:
|
||
.DS L
|
||
|
||
* help teile
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
Relation: teile
|
||
---------
|
||
Besitzer: ing_db
|
||
Tupellaenge: 34
|
||
Verfallsdatum: Tue Apr 26 19:57:10 1988
|
||
Tupelanzahl: 13
|
||
Speicherstruktur: HEAP
|
||
Relationentyp: Nutzerrelation
|
||
|
||
Domaenname Typ Laenge Schluessel
|
||
-------------------------------------------
|
||
tnum i 2
|
||
tname c 20
|
||
farbe c 8
|
||
gewicht i 2
|
||
menge i 2
|
||
-------------------------------------------
|
||
|
||
ING-db:
|
||
.DE
|
||
.LP
|
||
Geben sie das Kommando:
|
||
.DS L
|
||
|
||
* print teile
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
.DE
|
||
.LP
|
||
Die Zeile "print teile" fordert eine Anzeige von
|
||
Daten, die in der Datenbank gespeichert sind.
|
||
Das "\\g" weist den Monitor zur Ausf\o'u"'hrung der
|
||
Query an.
|
||
Die Mitteilung
|
||
.br
|
||
"I N G - d b . . . "
|
||
.br
|
||
informiert, dass \*(yy\ 6.3 ihre Query ausf\o'u"'hrt.
|
||
Der Ausschrift wird noch der Maschinentyp vorangestellt.
|
||
Das Ergebnis sieht dann so aus:
|
||
.DS L
|
||
|
||
Relation: teile
|
||
|
||
|
||
|tnum |tname |farbe |gewich|menge |
|
||
|--------------------------------------------------|
|
||
| 1|Zentraleinheit |rosa | 10| 1|
|
||
| 2|Hauptspeicher |grau | 20| 32|
|
||
| 3|Plattenspeicher |schwarz | 685| 2|
|
||
| 4|Magnetbandspeicher |schwarz | 450| 4|
|
||
| 5|Magnetbaender |grau | 1| 250|
|
||
| 6|Zeilendrucker |gelb | 578| 3|
|
||
| 7|Zeilendruckerpapier |weiss | 15| 95|
|
||
| 8|Terminals |blau | 19| 15|
|
||
| 13|Lochbandleser |schwarz | 107| 0|
|
||
| 14|Lochbandstanzer |schwarz | 147| 0|
|
||
| 9|Konsolpapier |weiss | 2| 350|
|
||
| 10|Kartenleser |grau | 327| 0|
|
||
| 11|Kartenstanzer |grau | 427| 0|
|
||
|--------------------------------------------------|
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
.LP
|
||
Das, was auf Ihrem Terminal angezeigt wurde, ist die "teile"- Relation.
|
||
Intuitiv, eine Relation ist nicht mehr, als eine Tabelle
|
||
mit Zeilen und Spalten.
|
||
.LP
|
||
In diesem Fall ist der Name der Relation "teile".
|
||
Sie hat f\o'u"'nf Spalten (, wir nennen sie Dom\o'a"'nen,)
|
||
bezeichnet mit "tnum" (Teile-Nummer), "tname" (Teile-Bezeichnung),
|
||
"farbe", "gewicht" und "menge" (Bestand).
|
||
Jede Zeile der Relation (genannt Tupel)
|
||
repr\o'a"'sentiert einen Eintrittspunkt (Satz),
|
||
der in diesem Fall ein Teil
|
||
f\o'u"'r eine Computer-Installation bezeichnet.
|
||
Eine Relation kann bis zu 49 Dom\o'a"'nen und eine
|
||
im Grunde genommen unbegrenzte Zahl von Tupeln haben.
|
||
.LP
|
||
Beachten sie, nachdem die Query ausgef\o'u"'hrt ist,
|
||
gibt \*(yy\ 6.3
|
||
.ft B
|
||
"ING_db:"
|
||
.ft R
|
||
aus, w\o'a"'hrend anfangs nach dem
|
||
Eintritt
|
||
.ft B
|
||
"ING_db>"
|
||
.ft R
|
||
angezeigt wurde.
|
||
Wenn sie eine Query eingeben, legt sie \*(yy\ 6.3
|
||
in einem "Arbeitsspeicher" ab.
|
||
Wenn sie
|
||
eine Query falsch eingegeben haben, k\o'o"'nnen sie mit "\\r",
|
||
also "reset" (dh. l\o'o"'schen) den Arbeitsspeicher l\o'o"'schen.
|
||
(Sp\o'a"'ter werden wir Wege kennen lernen,
|
||
um Fehler zu editieren, so, als
|
||
w\o'u"'rden wir die eingegebene Query korrigieren.)
|
||
.LP
|
||
Jederzeit k\o'o"'nnen sie sich den Arbeitsspeicher
|
||
durch Eingabe von "\\p" ansehen.
|
||
Versuchen sie "\\p":
|
||
.DS L
|
||
|
||
* \ep
|
||
print teile
|
||
ING-db:
|
||
*
|
||
|
||
.DE
|
||
.LP
|
||
Der aktuelle Inhalt des Arbeitsspeichers
|
||
wird angezeigt.
|
||
Versuchen sie jetzt "\\r":
|
||
.DS L
|
||
|
||
* \er
|
||
ING_db>
|
||
*
|
||
|
||
.DE
|
||
.LP
|
||
Der Arbeitsspeicher ist jetzt leer.
|
||
Solange
|
||
\*(yy\ 6.3 "ING_db:" ausgibt,
|
||
ist der Arbeitsspeicher nicht-leer;
|
||
solange \*(yy\ 6.3 "ING_db>" ausgibt, ist er leer.
|
||
.LP
|
||
Nachdem eine Query ausgef\o'u"'hrt wurde,
|
||
gibt \*(yy\ 6.3 normalerweise "ING_db:" aus.
|
||
Wenn sie dann eine neue Query eingeben, l\o'o"'scht \*(yy\ 6.3
|
||
automatisch die vorhergehende, obwohl
|
||
sie nicht nach jeder Query "\\r" eingegeben haben.
|
||
Das wird sp\o'a"'ter noch erkl\o'a"'rt.
|
||
.LP
|
||
Die Verwendung des "retrieve"-Kommandos erlaubt uns,
|
||
spezifische Queries \o'u"'ber Relationen zu schreiben.
|
||
Als Beispiel wollen wir \*(yy\ 6.3
|
||
veranlassen, nur "tname" als Dom\o'a"'ne aus der "teile"-
|
||
Relation auszugeben.
|
||
Geben sie das Kommando:
|
||
.DS L
|
||
|
||
* range of t is teile
|
||
* retrieve (t.tname)
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|tname |
|
||
|--------------------|
|
||
|Zentraleinheit |
|
||
|Hauptspeicher |
|
||
|Plattenspeicher |
|
||
|Magnetbandspeicher |
|
||
|Magnetbaender |
|
||
|Zeilendrucker |
|
||
|Zeilendruckerpapier |
|
||
|Terminals |
|
||
|Lochbandleser |
|
||
|Lochbandstanzer |
|
||
|Konsolpapier |
|
||
|Kartenleser |
|
||
|Kartenstanzer |
|
||
|--------------------|
|
||
13 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
.LP
|
||
Die Ausgabe beschr\o'a"'nkt sich auf die Dom\o'a"'ne
|
||
"tname" aus der Relation "teile".
|
||
Dazu ben\o'o"'tigten wir zwei Schritte.
|
||
Zuerst haben wir eine sogenannte "Tupel-Variable"
|
||
deklariert und ihren Bereich der Relation "teile" zugewiesen.
|
||
.DS L
|
||
|
||
range of t is teile
|
||
.DE
|
||
.LP
|
||
Damit ist gemeint, dass der Buchstabe "t" die Relation
|
||
"teile" repr\o'a"'sentiert.
|
||
Man kann sich das als eine Markierung
|
||
vorstellen, die die Relation "teile" eine Stufe
|
||
niedriger einordnet.
|
||
\*(yy\ 6.3 merkt sich die Verbindung, sodass,
|
||
wenn "t" einmal als Bereich \o'u"'ber "teile"
|
||
deklariert wurde, eine Wiederholung der Deklaration
|
||
nicht notwendig ist.
|
||
Das ist, wie wir sp\o'a"'ter sehen werden, \o'u"'blich,
|
||
falls wir mit mehr als einer Relation arbeiten.
|
||
.LP
|
||
Als n\o'a"'chstes benutzten wir das
|
||
"retrieve"-Kommando.
|
||
Seine Form ist
|
||
.DS L
|
||
|
||
retrieve ( listen sie hier, wonach sie suchen )
|
||
|
||
.DE
|
||
.LP
|
||
"t" referenziert durch sich selbst die Relation "teile".
|
||
"t.tname" referenziert die Dom\o'a"'ne "tname" der Relation
|
||
"teile", sozusagen:
|
||
.DS L
|
||
|
||
retrieve (t.tname)
|
||
|
||
.DE
|
||
meint die Recherche nach der Dom\o'a"'ne
|
||
"tname" der Relation "teile".
|
||
.LP
|
||
Versuchen wir
|
||
nach "tname" und "farbe" zu recherchieren:
|
||
.DS L
|
||
|
||
* retrieve t.tname, t.farbe
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
2500: syntax error on line 1
|
||
last symbol read was: .
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
.LP
|
||
Ungl\o'u"'cklicherweise haben wir einen Fehler gemacht.
|
||
\*(yy\ 6.3 teilt uns mit, dass es einen Syntax-Fehler
|
||
auf der ersten Zeile der Query gefunden hat.
|
||
"Syntax error" bedeutet, dass wir etwas eingegeben
|
||
haben, was \*(yy\ 6.3 nicht wiedererkennen bzw. interpretieren
|
||
kann.
|
||
Der Fehler trat auf Zeile 1 auf.
|
||
\*(yy\ 6.3 f\o'u"'hrt einen manchmal undeutlichen
|
||
Versuch zur Diagnose des Problems durch.
|
||
Sofern m\o'o"'glich, teilt uns \*(yy\ 6.3 mit,
|
||
was es gelesen hat, bevor es durcheinander kam.
|
||
.LP
|
||
In diesem Fall ist der Fehler der, dass die Liste der
|
||
Rechercheobjekte
|
||
(, die sogenannte "target_list",) in Klammern eingeschlossen
|
||
werden muss.
|
||
Die korrekte Query ist:
|
||
.DS L
|
||
|
||
* retrieve (t.tname, t.farbe)
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|tname |farbe |
|
||
|-----------------------------|
|
||
|Zentraleinheit |rosa |
|
||
|Hauptspeicher |grau |
|
||
|Plattenspeicher |schwarz |
|
||
|Magnetbandspeicher |schwarz |
|
||
|Magnetbaender |grau |
|
||
|Zeilendrucker |gelb |
|
||
|Zeilendruckerpapier |weiss |
|
||
|Terminals |blau |
|
||
|Lochbandleser |schwarz |
|
||
|Lochbandstanzer |schwarz |
|
||
|Konsolpapier |weiss |
|
||
|Kartenleser |grau |
|
||
|Kartenstanzer |grau |
|
||
|-----------------------------|
|
||
13 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
.LP
|
||
Sie k\o'o"'nnen durch Hinzuf\o'u"'gung einer
|
||
"Qualifikation" an die Query einschr\o'a"'nken,
|
||
welche Tupel ausgegeben werden sollen.
|
||
Beispielsweise, um die Namen und Farben
|
||
nur der Teile zu erhalten, die grau sind,
|
||
geben sie ein:
|
||
.DS L
|
||
* retrieve (t.tname, t.farbe)
|
||
* where t.farbe = "grau"
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|tname |farbe |
|
||
|-----------------------------|
|
||
|Hauptspeicher |grau |
|
||
|Magnetbaender |grau |
|
||
|Kartenleser |grau |
|
||
|Kartenstanzer |grau |
|
||
|-----------------------------|
|
||
4 tuples touched
|
||
|
||
ING-db:
|
||
*
|
||
|
||
.DE
|
||
Beachten sie, dass \*(yy\ 6.3 nur die Teile angibt, wo "t.farbe"
|
||
gleich "grau" ist.
|
||
Beachten sie auch, dass grau in Anf\o'u"'hrungsstrichen ("grau")
|
||
stehen muss.
|
||
Das ist notwendig.
|
||
Der einzige Weg, \*(yy\ 6.3 zur Erkennung von Zeichenketten zu
|
||
veranlassen (z.B. Worte), ist, sie in
|
||
Anf\o'u"'hrungsstriche einzuschliessen.
|
||
.LP
|
||
Was ist, wenn wir die Bezeichnungen der Teile wissen wollen,
|
||
die grau oder rosa sind?
|
||
Wir brauchen nur an die vorhergehende Query den
|
||
Ausdruck
|
||
.DS L
|
||
|
||
or t.farbe = "rosa"
|
||
|
||
.DE
|
||
anh\o'a"'ngen.
|
||
Erinnern sie sich, wie auch immer,
|
||
wenn die n\o'a"'chste Zeile eingegeben wurde,
|
||
beginnt \*(yy\ 6.3 eine neue Query und wird automatisch
|
||
den Arbeitsspeicher l\o'o"'schen.
|
||
Der Arbeitsspeicher kann nur
|
||
.ft B
|
||
gerettet
|
||
.ft R
|
||
werden, wenn die n\o'a"'chste Zeile mit einem solchen Kommando
|
||
wie "\\p" oder "\\g" beginnt.
|
||
(Es gibt noch andere M\o'o"'glichkeiten, wie wir
|
||
sp\o'a"'ter sehen werden.)
|
||
Wenn so ein Kommando eingegeben wird,
|
||
ist die vorhergehende Query gerettet und
|
||
anschliessend kann an diese Query angeh\o'a"'ngt werden.
|
||
.LP
|
||
Wir geben ein:
|
||
.DS L
|
||
|
||
* \ep
|
||
retrieve (t.tname, t.farbe)
|
||
where t.farbe = "grau"
|
||
ING-db:
|
||
*
|
||
|
||
.DE
|
||
.LP
|
||
Sie k\o'o"'nnen die vorhergehende Query sehen.
|
||
Jetzt geben sie ein:
|
||
.DS L
|
||
|
||
* or t.farbe = "rosa"
|
||
*
|
||
|
||
.DE
|
||
\*(yy\ 6.3 h\o'a"'ngt die letzte Zeile an das Ende der Query an.
|
||
Sie k\o'o"'nnen sich davon \o'u"'berzeugen, indem sie
|
||
den Arbeitsspeicher ausgeben:
|
||
.DS L
|
||
|
||
* \ep
|
||
retrieve (t.tname, t.farbe)
|
||
where t.farbe = "grau"
|
||
or t.farbe = "rosa"
|
||
ING-db:
|
||
*
|
||
|
||
.DE
|
||
Jetzt starten wir die Query:
|
||
.DS L
|
||
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|tname |farbe |
|
||
|-----------------------------|
|
||
|Zentraleinheit |rosa |
|
||
|Hauptspeicher |grau |
|
||
|Magnetbaender |grau |
|
||
|Kartenleser |grau |
|
||
|Kartenstanzer |grau |
|
||
|-----------------------------|
|
||
5 tuples touched
|
||
|
||
ING-db:
|
||
*
|
||
.DE
|
||
.LP
|
||
Die Regeln dazu, wann der Arbeitsspeicher gel\o'o"'scht
|
||
ist, m\o'o"'gen anfangs etwas verwirrend erscheinen.
|
||
Im Allgemeinen wird \*(yy\ 6.3 genau das tun,
|
||
was sie erwarten, ohne dass sie viel daran denken.
|
||
.LP
|
||
Wir haben die verwendeten Qualifikationen "or" und "=" gesehen.
|
||
Im Allgemeinen kann eine der folgenden verwendet werden:
|
||
|
||
.DS L
|
||
and
|
||
or
|
||
not
|
||
= (equal)
|
||
!= (not equal)
|
||
> (greater than)
|
||
>= (greater than or equal)
|
||
< (less than)
|
||
<= (less than or equal)
|
||
.DE
|
||
.LP
|
||
Die Wertigkeit bestimmt sich in der Reihenfolge,
|
||
wie die Qualifikationen angegeben sind (d.h. von links nach rechts).
|
||
Klammern k\o'o"'nnen verwendet werden,
|
||
um Zusammenh\o'a"'nge in der gew\o'u"'nschten
|
||
Reihenfolge zu gruppieren.
|
||
.LP
|
||
\*(yy\ 6.3 kann Berechnungen mit den, in der
|
||
Relation gespeicherten Daten ausf\o'u"'hren.
|
||
Beispielsweise beinhaltet die Relation
|
||
"teile" den Bestand und das Gewicht f\o'u"'r jedes
|
||
Tupel.
|
||
Wir m\o'o"'chten das Gesamtgewicht f\o'u"'r
|
||
jede Gruppe von Teilen wissen (,d.h. Gewicht multipliziert
|
||
mit Bestand).
|
||
.LP
|
||
Um die Bezeichnung, die Teile-Nummer und das
|
||
Gesamtgewicht f\o'u"'r jedes Teil zu erhalten,
|
||
geben wir ein:
|
||
.DS L
|
||
|
||
* retrieve (t.tname, t.tnum, t.menge * t.gewicht)
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
2500: syntax error on line 1
|
||
last symbol read was: *
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Ein anderer Fehler!
|
||
Das Problem besteht darin, dass nach Ausf\o'u"'hrung
|
||
einer Rechnung \*(yy\ 6.3 nicht weiss, wie es die entstandene
|
||
Dom\o'a"'ne bei der Ausgabe bezeichnen soll.
|
||
F\o'u"'r eine einfache Dom\o'a"'ne
|
||
nutzt \*(yy\ 6.3 den Dom\o'a"'nen-Namen als Titel
|
||
(\o'U"'berschrift in der Kopfzeile).
|
||
Wie auch immer, sie m\o'u"'ssen eine neue Dom\o'a"'ne
|
||
gr\o'u"'nden, um den Titel zu spezifizieren:
|
||
.DS L
|
||
|
||
tot = t.menge * t.gewicht
|
||
|
||
.DE
|
||
Die allgemeine Form ist:
|
||
.DS L
|
||
|
||
title = expression
|
||
|
||
.DE
|
||
Zum Beispiel:
|
||
.DS L
|
||
|
||
name = t.tname
|
||
berechnung = t.gewicht / 2000 * (t.menge + 2)
|
||
|
||
.DE
|
||
Wir wollen uns noch mit dem Fehler, der eine Korrektur
|
||
der Query erfordert, besch\o'a"'ftigen.
|
||
Solange die erste Zeile nach einer Query
|
||
nicht mit "\\p" oder "\\g" beginnt, wird
|
||
\*(yy\ 6.3 automatisch den Arbeitsspeicher l\o'o"'schen
|
||
und die vorhergehende Query ist f\o'u"'r
|
||
uns verloren.
|
||
.DS L
|
||
* retrieve (t.tname, t.tnum, tot=t.menge * t.gewicht)
|
||
\eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|tname |tnum |tot |
|
||
|----------------------------------|
|
||
|Zentraleinheit | 1| 10|
|
||
|Hauptspeicher | 2| 640|
|
||
|Plattenspeicher | 3| 1370|
|
||
|Magnetbandspeicher | 4| 1800|
|
||
|Magnetbaender | 5| 250|
|
||
|Zeilendrucker | 6| 1734|
|
||
|Zeilendruckerpapier | 7| 1425|
|
||
|Terminals | 8| 285|
|
||
|Lochbandleser | 13| 0|
|
||
|Lochbandstanzer | 14| 0|
|
||
|Konsolpapier | 9| 700|
|
||
|Kartenleser | 10| 0|
|
||
|Kartenstanzer | 11| 0|
|
||
|Hauptspeicher | 2| 640|
|
||
|Kartenleser | 10| 0|
|
||
|----------------------------------|
|
||
13 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Ausser der Multiplikation unterst\o'u"'tzt \*(yy\ 6.3
|
||
bspw. die Operatoren
|
||
.DS
|
||
+ Addition
|
||
- Subtraktion (und Bin\o'a"'rnegation)
|
||
/ Division
|
||
* Multiplikation
|
||
** Exponentation (z.B. 3**10)
|
||
abs Absolutwert (z.B. abs(p.qoh - 50) )
|
||
mod Modulo-Division (Divisionsrest)
|
||
.DE
|
||
und einige andere mehr.
|
||
\o'U"'berpr\o'u"'fen sie bitte im \*(yy\ 6.3-Referenz-Manual diese
|
||
kurze Darstellung und vervollst\o'a"'ndigen sie,
|
||
was unterst\o'u"'tzt wird.
|
||
.LP
|
||
Wenn wir anschliessend die Teile-Nummer 2 oder 10
|
||
ausw\o'a"'hlen wollen, dann k\o'o"'nnen wir die Qualifikation
|
||
.DS L
|
||
|
||
where t.tnum = 2 or t.tnum = 10
|
||
.DE
|
||
angeben.
|
||
.LP
|
||
.ft B
|
||
VORSICHT:
|
||
.ft R
|
||
Wenn wir gerade damit beginnen "where t.tnum .... "
|
||
einzugeben, wird \*(yy\ 6.3 das als Beginn einer neuen Query
|
||
verstehen und den Arbeitsspeicher
|
||
l\o'o"'schen.
|
||
Um das zu umgehen, k\o'o"'nnen sie "\\p" eingeben und ein
|
||
anschliessendes "append"-Kommando garantiert
|
||
("\\a" (append)), dass, was immer sie eingeben, dem Inhalt des
|
||
Arbeitsspeichers hinzugef\o'u"'gt wird.
|
||
Dieses Kommando wird nur ben\o'o"'tigt, nachdem
|
||
zwischenzeitlich eine Query zur Ausf\o'u"'hrung
|
||
angewiesen wurde.
|
||
Zum anderen werden Daten automatisch hinzugef\o'u"'gt.
|
||
Versuchen sie folgendes:
|
||
.DS L
|
||
|
||
* \ea
|
||
* where t.tnum = 2 or t.tnum = 10
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|tname |tnum |tot |
|
||
|----------------------------------|
|
||
|Hauptspeicher | 2| 640|
|
||
|Kartenleser | 10| 0|
|
||
|----------------------------------|
|
||
2 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Um alle Teile-Nummern gr\o'o"'sser als 2 und kleiner,
|
||
gleich 10 auszuw\o'a"'hlen, folgendes:
|
||
.DS L
|
||
|
||
* retrieve (t.tname, t.tnum, tot=t.menge * t.gewicht)
|
||
* where t.tnum > 2 and t.tnum <= 10
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|tname |tnum |tot |
|
||
|----------------------------------|
|
||
|Plattenspeicher | 3| 1370|
|
||
|Magnetbandspeicher | 4| 1800|
|
||
|Magnetbaender | 5| 250|
|
||
|Zeilendrucker | 6| 1734|
|
||
|Zeilendruckerpapier | 7| 1425|
|
||
|Terminals | 8| 285|
|
||
|Konsolpapier | 9| 700|
|
||
|Kartenleser | 10| 0|
|
||
|----------------------------------|
|
||
8 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
.LP
|
||
Nun wollen wir Unterst\o'u"'tzung, um die
|
||
vorhergehende Query so zu \o'a"'ndern, dass sie die
|
||
Ergebnisse der Teile-Nummern zwischen 5 und 10,
|
||
anstelle von 2 und 10 liefert.
|
||
Sie w\o'a"'ren sicher ver\o'a"'rgert, wenn
|
||
sie nur ein Zeichen \o'a"'ndern m\o'u"'ssten, sollen
|
||
aber daf\o'u"'r die ganze Query nocheinmal eingeben.
|
||
Deshalb gestattet
|
||
\*(yy\ 6.3 die Verwendung des \*(xx\-Texteditors,
|
||
um Korrekturen und/oder Hinzuf\o'u"'gungen
|
||
zu Ihrem Arbeitsspeicher vorzunehmen.
|
||
Jederzeit k\o'o"'nnen sie "\\e" eingeben,
|
||
der \*(yy\ 6.3-Monitor schreibt ihren Arbeitsspeicher auf ein
|
||
File und ruft das \*(xx\-Programm "ed".
|
||
Zum Beispiel:
|
||
.DS L
|
||
|
||
* \ee
|
||
>>ed
|
||
83
|
||
|
||
.DE
|
||
Die ">>ed"-Mitteilung sagt Ihnen, dass sie jetzt den
|
||
Editor nutzen.
|
||
Die Zahl 83 ist die Anzahl der Bytes in Ihrem Arbeitsspeicher.
|
||
.LP
|
||
Wir k\o'o"'nnen nun die Query editieren und
|
||
2 auf 5 \o'a"'ndern.
|
||
Die \*(xx\-Dokumentation
|
||
(Manual 1, "ed") beschreibt, wie der
|
||
Texteditor zu nutzen ist.
|
||
Aber wir wollen lieber etwas doppelt bringen und zeigen
|
||
einige Editor-Kommandos, um zu illustrieren,
|
||
wie zu editieren ist:
|
||
.DS L
|
||
|
||
1p
|
||
retrieve (t.tname,t.tnum,tot = t.menge * t.gewicht)
|
||
2p
|
||
where t.tnum > 2 and t.tnum <= 10
|
||
s/2/5/p
|
||
where t.tnum > 5 and t.tnum <= 10
|
||
w
|
||
83
|
||
q
|
||
*
|
||
|
||
.DE
|
||
Ganz kurz, was ereignet sich.
|
||
"1p" und "2p" gibt die Zeilen 1 und 2 aus.
|
||
"s/2/5/p" ersetzt 5 durch 2 auf der aktuellen Zeile
|
||
(Zeile 2) und gibt diese Zeile anschliessend aus.
|
||
"w" schreibt die Query zur\o'u"'ck in den \*(yy\ 6.3-Arbeitsspeicher.
|
||
.LP
|
||
Innerhalb des Editors k\o'o"'nnen sie alle "ed"-Kommandos,
|
||
ausser "e" (,es ver\o'a"'ndert den File-Namen) verwenden.
|
||
Wenn sie mit "quit" den Editor (q-Kommando) verlassen,
|
||
sind sie wieder zum Monitor zur\o'u"'ckgekehrt.
|
||
Beachten sie, dass vor einem "q"-Kommando ein
|
||
"w"-Kommando gegeben werden muss,
|
||
um den Arbeitsspeicher zur\o'u"'ckzuschreiben
|
||
(Aber keine Angst! Der Editor erinnert sie daran, wenn
|
||
sie es vergessen haben!).
|
||
.LP
|
||
Um sich zu vergewissern, dass die Query korrekt ist, und um
|
||
sie auszuf\o'u"'hren, geben sie ein:
|
||
.DS L
|
||
* \ep\eg
|
||
retrieve (t.tname,t.tnum,tot = t.menge * t.gewicht)
|
||
where t.tnum > 5 and t.tnum <= 10
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
|tname |tnum |tot |
|
||
|----------------------------------|
|
||
|Zeilendrucker | 6| 1734|
|
||
|Zeilendruckerpapier | 7| 1425|
|
||
|Terminals | 8| 285|
|
||
|Konsolpapier | 9| 700|
|
||
|Kartenleser | 10| 0|
|
||
|----------------------------------|
|
||
5 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
.LP
|
||
Wir nehmen an, dass ihr
|
||
Interesse, soweit es die Relation "teile" betrifft, ersch\o'o"'pft
|
||
ist. Sehen wir uns deshalb
|
||
eine neue Relation, genannt "lieferung" an.
|
||
Geben sie ein:
|
||
.DS L
|
||
|
||
* print lieferung
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
lieferung relation
|
||
|
||
|lnum |tnum |bnum |liefdat |menge |
|
||
|------------------------------------|
|
||
| 475| 1| 1001|73-12-31| 1|
|
||
| 475| 2| 1002|74-05-31| 32|
|
||
| 475| 3| 1001|73-12-31| 2|
|
||
| 475| 4| 1002|74-05-31| 1|
|
||
| 122| 7| 1003|75-02-01| 144|
|
||
| 122| 7| 1004|75-02-01| 48|
|
||
| 122| 9| 1004|75-02-01| 144|
|
||
| 440| 6| 1001|74-10-10| 2|
|
||
| 241| 4| 1001|73-12-31| 1|
|
||
| 62| 3| 1002|74-06-18| 3|
|
||
| 475| 2| 1001|73-12-31| 32|
|
||
| 475| 1| 1002|74-07-01| 1|
|
||
| 5| 4| 1003|74-11-15| 3|
|
||
| 5| 4| 1004|75-01-22| 6|
|
||
| 20| 5| 1001|75-01-10| 20|
|
||
| 20| 5| 1002|75-01-10| 75|
|
||
| 241| 1| 1005|75-06-01| 1|
|
||
| 241| 2| 1005|75-06-01| 32|
|
||
| 241| 3| 1005|75-06-01| 1|
|
||
| 67| 4| 1005|75-07-01| 1|
|
||
| 999| 10| 1006|76-01-01| 144|
|
||
| 241| 8| 1005|75-07-01| 1|
|
||
| 241| 9| 1005|75-07-01| 144|
|
||
|------------------------------------|
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Die "lieferung"-Relation beinhaltet "lnum" (, die
|
||
Lieferer-Nummer),
|
||
"tnum" (, die Teile-Nummer des gelieferten Teils),
|
||
"bnum" (, die Bestellnummer),
|
||
"liefdat" (, das Lieferdatum)
|
||
und "menge" (, die Liefermenge).
|
||
.LP
|
||
Um herauszufinden, welche Teile von der Lieferer-Nummer 122
|
||
geliefert werden, geben sie ein:
|
||
.DS L
|
||
|
||
* retrieve (l.tnum) where l.lnum = 122
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
2109: line 1, Variable 'l' not declared in RANGE statement
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Wir haben die Tupel-Variable "l"
|
||
(, d.h. l.tnum) verwendet, ohne \*(yy\ 6.3 mitzuteilen, was
|
||
"l" repr\o'a"'sentiert.
|
||
Wir haben die Bereichsdeklaration "range" vergessen.
|
||
Korrigieren wir die Query wie folgt:
|
||
.DS L
|
||
|
||
* range of l is lieferung
|
||
* retrieve (l.tnum) where l.lnum = 122
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
|tnum |
|
||
|------|
|
||
| 7|
|
||
| 7|
|
||
| 9|
|
||
|------|
|
||
3 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Die Lieferer-Nummer 122 liefert die Teile-Nummern 7, 7 und 9.
|
||
Beachten sie, dass 7 zweimal aufgelistet wurde.
|
||
Bei der Recherche nach Tupeln \o'u"'ber das Terminal ist es
|
||
effizienter f\o'u"'r \*(yy\ 6.3,
|
||
.ft B
|
||
nicht
|
||
.ft R
|
||
nach doppelten Tupeln suchen zu
|
||
m\o'u"'ssen.
|
||
\*(yy\ 6.3 ist in der Lage doppelte Tupel zu l\o'o"'schen.
|
||
Wir wollen darauf sp\o'a"'ter zur\o'u"'ckkommen.
|
||
.LP
|
||
Wir wissen jetzt, dass der Lieferer 122 die
|
||
Teile-Nummern 7 und 9 liefert.
|
||
Wenn sie diese Query nicht einige hundert
|
||
mal abarbeiten, wissen sie sicher nicht,
|
||
was mit den Teile-Nummern 7 und 9 gemeint ist.
|
||
Wir k\o'o"'nnen das einfach herausfinden,
|
||
wenn wir die Query
|
||
.DS L
|
||
|
||
* retrieve (t.tname) where t.tnum = 7 or
|
||
* t.tnum = 9
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|tname |
|
||
|--------------------|
|
||
|Zeilendruckerpapier |
|
||
|Konsolpapier |
|
||
|--------------------|
|
||
2 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
abarbeiten.
|
||
Nach zwei Queries wissen wir die Teile-Bezeichnung
|
||
der Teile, die der Lieferer 122 liefert.
|
||
Wir k\o'o"'nnen dasselbe in einer Query erreichen,
|
||
wenn wir fragen:
|
||
.DS L
|
||
|
||
* retrieve (t.tname) where t.tnum = l.tnum
|
||
* and l.lnum = 122
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
|tname |
|
||
|--------------------|
|
||
|Zeilendruckerpapier |
|
||
|Zeilendruckerpapier |
|
||
|Konsolpapier |
|
||
|--------------------|
|
||
3 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Beachten sie, dass "Zeilendruckerpapier" doppelt vorkommt.
|
||
Schauen sie sich schliesslich die Query an.
|
||
Sie bemerken, dass die Dom\o'a"'ne "tnum"
|
||
sowohl in der Relation
|
||
"teile", als auch in "lieferung" vorkommt.
|
||
Mit der Aussage "t.tnum = l.tnum" verbinden wir logisch
|
||
die beiden Relationen.
|
||
.LP
|
||
Um alle Lieferer, die die Zentraleinheit
|
||
liefern, zu finden,
|
||
folgende Unterst\o'u"'tzung.
|
||
Wir wissen, wie wir nach "l.lnum" recherchieren.
|
||
Wir m\o'o"'chten aber nur jene "l.lnum"'s wissen, wo die korrespondierende
|
||
"l.tnum" gleich der Teile-Nummer der Zentraleinheit
|
||
ist.
|
||
.LP
|
||
Wenn wir den "t.tname" finden, der gleich "Zentraleinheit"
|
||
ist, dann haben wir die korrekte Teile-Nummer "t.tnum".
|
||
Schliesslich m\o'o"'chten wir "l.tnum = t.tnum",
|
||
die Query lautet:
|
||
.DS L
|
||
|
||
* retrieve (l.lnum) where
|
||
* l.tnum = t.tnum and t.tname = "Zentraleinheit"
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|lnum |
|
||
|------|
|
||
| 475|
|
||
| 475|
|
||
| 241|
|
||
|------|
|
||
3 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Wir wollen die Relationen "teile" und "lieferung"
|
||
verlassen und etwas anderes probieren.
|
||
Zuerst k\o'o"'nnen wir feststellen, welche anderen
|
||
Relationen die Datenbank besitzt, wenn wir eingeben:
|
||
.DS L
|
||
|
||
* help \eg
|
||
I N G - d b . . .
|
||
help \eg
|
||
K1630 / EVK Olbernhau - k 1630 / DBA ing_db
|
||
DB nicht parallel verwendbar
|
||
keine QRYMOD-Unterstuetzung
|
||
Seitengroesse 1024 Byte
|
||
|
||
Relation Besitzer Typ
|
||
----------------------------------------------
|
||
attribute ing_db Systemkatalog
|
||
relation ing_db Systemkatalog
|
||
indexes ing_db Systemkatalog
|
||
integrities ing_db Systemkatalog
|
||
lager ing_db Systemkatalog
|
||
personal ing_db Nutzerkatalog
|
||
lieferant ing_db Systemkatalog
|
||
abt ing_db Systemkatalog
|
||
teile ing_db Nutzerkatalog
|
||
artikel ing_db Systemkatalog
|
||
protect ing_db Systemkatalog
|
||
lieferung ing_db Nutzerkatalog
|
||
tree ing_db Systemkatalog
|
||
----------------------------------------------
|
||
|
||
ING-db:
|
||
*
|
||
|
||
.DE
|
||
Schauen wir uns die Relation "personal" an.
|
||
Sofern wir nichts \o'u"'ber die Relation wissen,
|
||
k\o'o"'nnen wir das "help"-Kommando nutzen, um etwas
|
||
dar\o'u"'ber zu erfahren.
|
||
Geben sie ein:
|
||
.DS L
|
||
|
||
* help personal
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
relation: personal
|
||
---------
|
||
Besitzer: ing_db
|
||
Tupellaenge: 30
|
||
Verfallsdatum: Tue Apr 26 11:01:30 1988
|
||
Tupelanzahl: 25
|
||
Speicherstruktur: HEAP
|
||
Relationentyp: Nutzerrelation
|
||
|
||
Domaenenname Typ Laenge Schluessel.
|
||
----------------------------------------
|
||
num i 2
|
||
name c 20
|
||
gehalt i 2
|
||
leiter i 2
|
||
gebdat i 2
|
||
einstdat i 2
|
||
----------------------------------------
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Das "help"-Kommando listet \o'U"'bersichtsinformationen
|
||
zur Relation "personal" aus,
|
||
weiterhin zu jedem Attribut, seinem
|
||
Typ und seiner L\o'a"'nge.
|
||
.LP
|
||
\*(yy\ 6.3 unterst\o'u"'tzt drei Datentypen: Integerzahlen,
|
||
Gleitkommazahlen und Zeichenketten.
|
||
Zeichenketten-Dom\o'a"'nen k\o'o"'nnen von 1 bis 255 Zeichen
|
||
lang sein.
|
||
Integer-Dom\o'a"'nen k\o'o"'nnen 1, 2, oder 4 Bytes lang sein.
|
||
Das bedeutet, dass Integerzahlen einen Wertebereich von
|
||
127, \%32767 und \%2147483647 maximal annehmen k\o'o"'nnen.
|
||
Gleitkommazahlen k\o'o"'nnen entweder 4 oder 8 Bytes lang sein.
|
||
Beide erhalten einen Maximalwert von \o'u"'ber 10**38;
|
||
mit 7 oder 17 Ziffern genauer Abbildung.
|
||
.LP
|
||
Um alle Dom\o'a"'nen anzusehen, k\o'o"'nnen wir das "print"-Kommando
|
||
oder das "retrieve"-Kommando nutzen
|
||
und geben jede Dom\o'a"'ne in der "target_list" an.
|
||
\*(yy\ 6.3 verschafft uns einen Weg, mit wenig Arbeitsaufwand,
|
||
das zu realisieren.
|
||
Versuchen sie folgendes:
|
||
.DS L
|
||
|
||
* range of p is personal
|
||
* retrieve (p.all)
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|num |name |gehalt|leiter|gebdat|einstd|
|
||
|-------------------------------------------------------|
|
||
| 157|Schmidt, Petra | 1200| 199| 1940| 1960|
|
||
| 1110|Kayser, Helmut | 600| 33| 1952| 1973|
|
||
| 35|Loda, Dieter | 500| 32| 1952| 1974|
|
||
| 129|Thoms, Rolf | 1000| 199| 1941| 1962|
|
||
| 13|Wunsch, Peter-Paul | 900| 199| 1928| 1958|
|
||
| 215|Mueller, Ernst | 700| 10| 1950| 1971|
|
||
| 55|Malter, Juergen | 1200| 199| 1920| 1969|
|
||
| 26|Schneider, Peter | 1300| 199| 1930| 1970|
|
||
| 98|Weise, Juergen | 900| 199| 1935| 1969|
|
||
| 32|Heine, Rolf | 905| 199| 1929| 1967|
|
||
| 33|Ernst, Eva | 1010| 199| 1931| 1963|
|
||
| 199|Gruene, Peter | 1700| 0| 1920| 1952|
|
||
| 4901|Baum, Klaus | 837| 32| 1956| 1975|
|
||
| 843|Schmidt, Hermann | 1120| 26| 1936| 1956|
|
||
| 2398|Warnke, Peter | 788| 26| 1940| 1959|
|
||
| 1639|Maerz, Udo | 1116| 55| 1947| 1970|
|
||
| 5119|Mueller, Petra | 1362| 55| 1939| 1963|
|
||
| 37|Neumann, Inge | 1198| 26| 1950| 1974|
|
||
| 5219|Weber, Franz | 1337| 33| 1944| 1959|
|
||
| 1523|Zeidler, Fritz | 1686| 129| 1928| 1949|
|
||
| 430|Moser, Otto | 1567| 129| 1938| 1959|
|
||
| 994|Schulze, Ernst | 1564| 129| 1944| 1970|
|
||
| 1330|Fleischer, Karl | 877| 13| 1952| 1971|
|
||
| 10|Rose, Peter | 1590| 199| 1927| 1953|
|
||
| 11|Rose, Petra | 1206| 0| 1931| 1951|
|
||
|-------------------------------------------------------|
|
||
25 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
"all" ist ein Schl\o'u"'sselwort, das bei
|
||
\*(yy\ 6.3 angewendet wird, um alle Dom\o'a"'nen zu erhalten.
|
||
F\o'u"'r die Dom\o'a"'nen ist eine besondere Reihenfolge
|
||
nicht sichergestellt.
|
||
Die vorhergehende Query ist \o'a"'quivalent zu:
|
||
.DS L
|
||
|
||
range of p is personal
|
||
retrieve (p.num, p.name, p.gehalt, p.leiter
|
||
p.gebdat, p.einstdat)
|
||
|
||
.DE
|
||
Wir wollen nach dem Gehalt von Peter Wunsch recherchieren.
|
||
An diesem Punkt ist es g\o'u"'nstig,
|
||
\o'u"'ber Gross- und Kleinbuchstaben zu verf\o'u"'gen.
|
||
Wenn sie an einem Grossbuchstaben-Terminal arbeiten,
|
||
geben sie einen einfachen "\\" vor jenen Buchstaben, die
|
||
sie in Grossbuchstaben umwandeln wollen.
|
||
Damit m\o'u"'sste an einem Grossbuchstaben-Terminal
|
||
"\\WUNSCH, \\PETER" eingegeben werden.
|
||
Wenn sie an einem Gross-/Kleinbuchstaben-Terminal
|
||
arbeiten, benutzen sie die Umschalttaste (u.U. auch SHIFT)
|
||
um Grossbuchstaben zu schreiben.
|
||
.LP
|
||
Starten sie die Query:
|
||
.DS L
|
||
|
||
* retrieve (p.name,p.gehalt)
|
||
* where p.name = "Wunsch, Peter"
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
|name |gehalt|
|
||
|---------------------------|
|
||
|---------------------------|
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Das Ergebnis ist leer.
|
||
Es gibt keinen "p.name", der die Qualifikation erf\o'u"'llt.
|
||
Das befremdet, weil wir wissen, dass es einen Peter Wunsch gibt.
|
||
Jedoch weiss \*(yy\ 6.3 nicht, dass "Peter-Paul"
|
||
und "Peter" semantisch das Gleiche ist.
|
||
.LP
|
||
Um in dieser Situation die korrekte Antwort
|
||
zu erhalten, m\o'u"'ssen sie die speziellen
|
||
"pattern matching"-Zeichen (Vergleichsmuster),
|
||
die \*(yy\ 6.3 bereith\o'a"'lt, verwenden.
|
||
Ein solches Zeichen ist "*".
|
||
Es ist irgendeiner Zeichenkette von 0 bis mehreren Zeichen
|
||
ebenb\o'u"'rtig.
|
||
Versuchen sie es:
|
||
.DS L
|
||
|
||
* retrieve (p.name,p.gehalt)
|
||
* where p.name = "Wunsch, P*"
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
|name |gehalt|
|
||
|---------------------------|
|
||
|Wunsch, Peter-Paul | 900|
|
||
|---------------------------|
|
||
1 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
.LP
|
||
Probieren wir damit etwas anderes.
|
||
.DS L
|
||
|
||
* retrieve (p.name, p.gehalt) where p.name = "Rose, P*"
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |gehalt|
|
||
|---------------------------|
|
||
|Rose, Peter | 1590|
|
||
|Rose, Petra | 1206|
|
||
|---------------------------|
|
||
2 tuples touched
|
||
|
||
ING-db:
|
||
*
|
||
.DE
|
||
Im ersten Fall ersetzt "*" die Zeichenkette "eter" und
|
||
im zweiten Fall "etra".
|
||
.LP
|
||
Hier ein anderes Beispiel.
|
||
Finden sie die Geh\o'a"'lter der
|
||
Personen, deren Vorname "Peter" ist:
|
||
.DS L
|
||
|
||
* retrieve (p.name,p.gehalt)
|
||
* where p.name = "*, Peter*"
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |gehalt|
|
||
|---------------------------|
|
||
|Wunsch, Peter-Paul | 900|
|
||
|Schneider, Peter | 1300|
|
||
|Gruene, Peter | 1700|
|
||
|Warnke, Peter | 788|
|
||
|Rose, Peter | 1590|
|
||
|---------------------------|
|
||
5 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Beachten sie, wenn wir nach p.name = "*, Peter"
|
||
gefragt h\o'a"'tten, w\o'a"'re das 1. Tupel nicht
|
||
ausgew\o'a"'hlt worden.
|
||
Ebenso ignoriert
|
||
\*(yy\ 6.3 "blanks"
|
||
in irgendeinem Zeichenkettenvergleich,
|
||
egal ob sie "pattern matching" anwenden oder nicht.
|
||
Das bedeutet, dass die folgenden
|
||
Varianten alle das gleiche Ergebnis bringen:
|
||
.DS L
|
||
|
||
p.name = "Rose,Peter"
|
||
p.name = "Rose, Peter "
|
||
p.name = "R o s e,Peter"
|
||
|
||
.DE
|
||
Einzelne Zeichen oder Bereiche von Zeichen k\o'o"'nnen
|
||
in eckige Klammern ([]) eingeschlossen werden.
|
||
Zum Beispiel, finde alle Personen, deren Namen mit
|
||
"B" bis "F" beginnen:
|
||
.DS L
|
||
|
||
* retrieve (p.name,p.gehalt)
|
||
* where p.name = "[B-F]*"
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |gehalt|
|
||
|---------------------------|
|
||
|Ernst, Eva | 1010|
|
||
|Baum, Klaus | 837|
|
||
|Fleischer, Karl | 877|
|
||
|---------------------------|
|
||
3 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Beachten sie, dass die letzte Query auch auf einem
|
||
anderen Weg realisiert werden k\o'o"'nnte:
|
||
.DS L
|
||
|
||
* retrieve (p.name,p.gehalt)
|
||
* where p.name >"A*" and p.name <"G*"
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |gehalt|
|
||
|---------------------------|
|
||
|Ernst, Eva | 1010|
|
||
|Baum, Klaus | 837|
|
||
|Fleischer, Karl | 877|
|
||
|---------------------------|
|
||
3 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Die beiden Ergebnisse sind identisch;
|
||
jedoch ist der zweite Weg in der Ausf\o'u"'hrung
|
||
f\o'u"'r \*(yy\ 6.3 effizienter.
|
||
.LP
|
||
Es gibt drei Typen von "pattern matching"-Konstruktionen.
|
||
Alle drei Typen k\o'o"'nnen in einer Kombination f\o'u"'r
|
||
Zeichenketten-Vergleiche genutzt werden.
|
||
Das sind:
|
||
|
||
.IP * 5
|
||
\o'A"'quivalent zu einer beliebig langen Zeichenkette;
|
||
.IP ? 5
|
||
\o'A"'quivalent zu einem Zeichen (nicht "blank")
|
||
.IP [] 5
|
||
Kann irgendein Zeichen \o'u"'berdecken, das in
|
||
Klammern eingeschlossen ist.
|
||
Wenn zwei Zeichen durch Binde\%strich (-) getrennt werden,
|
||
dann wird jedes Zeichen, das zwischen
|
||
beiden in der alphabetischen Folge stehen w\o'u"'rde
|
||
\o'u"'berdeckt.
|
||
.RE
|
||
.LP
|
||
Die spezielle Bedeutung der "pattern matching"-Zeichen
|
||
kann durch die Kaschierung
|
||
mit "\\" aufgehoben werden.
|
||
Damit referenziert "\\*" nur das Zeichen
|
||
"*".
|
||
.LP
|
||
Wir wenden uns nun den Aggregat-Operatoren,
|
||
die \*(yy\ 6.3 unterst\o'u"'tzt, zu.
|
||
Sie bef\o'a"'higen den Nutzer, Berechnungen auf
|
||
Dom\o'a"'nen einer Relation vorzunehmen.
|
||
Zum Beispiel ist einer dieser Aggregat-Operatoren Durchschnitt (avg)
|
||
="average".
|
||
Um das durchschnittliche Gehalt f\o'u"'r alle
|
||
Angestellten zu berechnen, geben wir ein:
|
||
.DS L
|
||
|
||
* retrieve (dgehalt=avg(p.gehalt))
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
|dgehalt |
|
||
|----------|
|
||
| 1126.520|
|
||
|----------|
|
||
1 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Der Name "dgehalt"
|
||
ist willk\o'u"'rlich, aber notwendig;
|
||
\*(yy\ 6.3 ben\o'o"'tigt
|
||
.ft B
|
||
einen
|
||
.ft R
|
||
Namen
|
||
f\o'u"'r irgend\%einen Ausdruck in der "target_list"
|
||
(anders als f\o'u"'r eine einfache Dom\o'a"'ne).
|
||
.LP
|
||
Wir k\o'o"'nnen auch das niedrigste (Minimum) und h\o'o"'chste (Ma\%ximum)
|
||
Gehalt finden:
|
||
.DS L
|
||
|
||
* retrieve (mingeh=min(p.gehalt),maxgeh=max(p.gehalt))
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
|mingeh|maxgeh|
|
||
|-------------|
|
||
| 500| 1700|
|
||
|-------------|
|
||
1 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Wenn wir die Namen der Angestellten wissen wollen, die das
|
||
niedrigste und h\o'o"'chste Gehalt beziehen, dann
|
||
m\o'u"'sste die Query lauten:
|
||
.DS L
|
||
|
||
* retrieve (p.name, p.gehalt)
|
||
* where p.gehalt = min(p.gehalt) or p.gehalt = max(p.gehalt)
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |gehalt|
|
||
|---------------------------|
|
||
|Loda, Dieter | 500|
|
||
|Gruene, Peter | 1700|
|
||
|---------------------------|
|
||
2 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
\*(yy\ 6.3 unterst\o'u"'tzt folgende Aggregat-Operatoren:
|
||
.DS L
|
||
|
||
count Z\o'a"'hle Tupel
|
||
min Minimum der Dom\o'a"'ne
|
||
max Maximum der Dom\o'a"'ne
|
||
avg Berechne Durchschnitt
|
||
sum Summiere Tupel entsprechend Dom\o'a"'ne
|
||
any logischer Wert entsprechend Qualifikation
|
||
|
||
.DE
|
||
Wir wollen jetzt eine Query vorstellen, die je Angestelltem
|
||
das Durch\%schnittsgehalt \o'u"'ber alle Angestellten
|
||
auslistet:
|
||
.DS L
|
||
|
||
* retrieve (p.name,pergeh=avg(p.gehalt))
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |pergeh |
|
||
|-------------------------------|
|
||
|Schmidt, Petra | 1126.520|
|
||
|Kayser, Helmut | 1126.520|
|
||
|Loda, Dieter | 1126.520|
|
||
|Thoms, Rolf | 1126.520|
|
||
|Wunsch, Peter-Paul | 1126.520|
|
||
|Mueller, Ernst | 1126.520|
|
||
|Malter, Juergen | 1126.520|
|
||
|Schneider, Peter | 1126.520|
|
||
|Weise, Juergen | 1126.520|
|
||
|Heine, Rolf | 1126.520|
|
||
|Ernst, Eva | 1126.520|
|
||
|Gruene, Peter | 1126.520|
|
||
|Baum, Klaus | 1126.520|
|
||
|Schmidt, Hermann | 1126.520|
|
||
|Warnke, Peter | 1126.520|
|
||
|Maerz, Udo | 1126.520|
|
||
|Mueller, Petra | 1126.520|
|
||
|Neumann, Inge | 1126.520|
|
||
|Weber, Franz | 1126.520|
|
||
|Zeidler, Fritz | 1126.520|
|
||
|Moser, Otto | 1126.520|
|
||
|Schulze, Ernst | 1126.520|
|
||
|Fleischer, Karl | 1126.520|
|
||
|Rose, Peter | 1126.520|
|
||
|Rose, Petra | 1126.520|
|
||
|-------------------------------|
|
||
25 tuples touched
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Ein Aggregat-Operator erzeugt immer einen einfachen Wert.
|
||
Um die letzte Query auszuf\o'u"'hren, bildet
|
||
\*(yy\ 6.3 das Durch\%schnittsgehalt zun\o'a"'chst zu jedem
|
||
Namen ("p.name") ab.
|
||
.LP
|
||
Aggregat-Operatoren k\o'o"'nnen ihre eigene Qualifikation haben.
|
||
Zum Beispiel k\o'o"'nnen wir eine Liste \o'u"'ber alle
|
||
Angestellten herstellen und das Durchschnittsgehalt f\o'u"'r
|
||
alle Angestellten \o'u"'ber 50 (Jahre) berechnen
|
||
und eintragen:
|
||
.DS L
|
||
|
||
* retrieve (p.name,pergeh=
|
||
* avg(p.gehalt where 1985-p.gebdat > 50))
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |pergeh |
|
||
|-------------------------------|
|
||
|Schmidt, Petra | 1277.444|
|
||
|Kayser, Helmut | 1277.444|
|
||
|Loda, Dieter | 1277.444|
|
||
|Thoms, Rolf | 1277.444|
|
||
|Wunsch, Peter-Paul | 1277.444|
|
||
|Mueller, Ernst | 1277.444|
|
||
|Malter, Juergen | 1277.444|
|
||
|Schneider, Peter | 1277.444|
|
||
|Weise, Juergen | 1277.444|
|
||
|Heine, Rolf | 1277.444|
|
||
|Ernst, Eva | 1277.444|
|
||
|Gruene, Peter | 1277.444|
|
||
|Baum, Klaus | 1277.444|
|
||
|Schmidt, Hermann | 1277.444|
|
||
|Warnke, Peter | 1277.444|
|
||
|Maerz, Udo | 1277.444|
|
||
|Mueller, Petra | 1277.444|
|
||
|Neumann, Inge | 1277.444|
|
||
|Weber, Franz | 1277.444|
|
||
|Zeidler, Fritz | 1277.444|
|
||
|Moser, Otto | 1277.444|
|
||
|Schulze, Ernst | 1277.444|
|
||
|Fleischer, Karl | 1277.444|
|
||
|Rose, Peter | 1277.444|
|
||
|Rose, Petra | 1277.444|
|
||
|-------------------------------|
|
||
25 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Im Gegensatz zur vorhergehenden Query folgendes Beispiel.
|
||
Wir wollen die Namen derjenigen Angestellten \o'u"'ber f\o'u"'nfzig
|
||
suchen und das Durchschnittsgehalt f\o'u"'r alle berechnen.
|
||
.DS L
|
||
|
||
* retrieve (p.name,pergeh=avg(p.gehalt))
|
||
* where 1985-p.gebdat > 50
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |pergeh |
|
||
|-------------------------------|
|
||
|Wunsch, Peter-Paul | 1126.520|
|
||
|Malter, Juergen | 1126.520|
|
||
|Schneider, Peter | 1126.520|
|
||
|Heine, Rolf | 1126.520|
|
||
|Ernst, Eva | 1126.520|
|
||
|Gruene, Peter | 1126.520|
|
||
|Zeidler, Fritz | 1126.520|
|
||
|Rose, Peter | 1126.520|
|
||
|Rose, Petra | 1126.520|
|
||
|-------------------------------|
|
||
9 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Es gibt einen bedeutenden Unterschied zwischen den beiden
|
||
letzten Queries.
|
||
Der Aggregat-Operator ist vollst\o'a"'ndig in sich abgeschlossen.
|
||
Er wird nicht durch die Qualifikation der
|
||
Query als Ganzes beeinflusst.
|
||
.LP
|
||
Im ersten Fall wurde der Durchschnitt nur f\o'u"'r
|
||
die Angestellten \o'u"'ber f\o'u"'nfzig berechnet und
|
||
\o'u"'ber alle Angestellten durchsucht.
|
||
Im zweiten Fall jedoch, wurde der Durchschnitt f\o'u"'r alle
|
||
Angestellten berechnet, aber nur f\o'u"'r die Angestellten
|
||
\o'u"'ber f\o'u"'nfzig eingetragen.
|
||
.LP
|
||
Wenn wir eine Liste aller Angestellten \o'u"'ber 50 zusammen
|
||
mit dem durchschnittlichen Gehalt w\o'u"'nschen,
|
||
kombinieren wir die vorhergehenden zwei Queries zu einer.
|
||
Diese Query k\o'o"'nnte sein:
|
||
|
||
.DS L
|
||
* retrieve (p.name, pergeh=
|
||
* avg(p.gehalt where 1985 - p.gebdat > 50))
|
||
* where 1985 - p.gebdat > 50
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |pergeh |
|
||
|-------------------------------|
|
||
|Wunsch, Peter-Paul | 1277.444|
|
||
|Malter, Juergen | 1277.444|
|
||
|Schneider, Peter | 1277.444|
|
||
|Heine, Rolf | 1277.444|
|
||
|Ernst, Eva | 1277.444|
|
||
|Gruene, Peter | 1277.444|
|
||
|Zeidler, Fritz | 1277.444|
|
||
|Rose, Peter | 1277.444|
|
||
|Rose, Petra | 1277.444|
|
||
|-------------------------------|
|
||
9 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Es ist manchmal gebr\o'a"'uchlich, dass doppelte Werte gel\o'o"'scht
|
||
werden, bevor ein Aggregat-Operator ausgef\o'u"'hrt wird.
|
||
Wenn sie beispielsweise wissen m\o'o"'chten, wieviele Leiter
|
||
("leiter") es gibt, wird die
|
||
folgende Query die richtige Antwort geben:
|
||
|
||
.DS L
|
||
* retrieve (chefs = count(p.leiter))
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
|chefs |
|
||
|-------------|
|
||
| 25|
|
||
|-------------|
|
||
1 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Beachten sie, dass "count" mitteilt, wieviele Tupel es in
|
||
"personal" gibt.
|
||
Was wir wissen wollten, war,
|
||
wieviele Leiter ("p.leiter") es gibt.
|
||
.LP
|
||
\*(yy\ 6.3 stellt drei spezielle Formen von
|
||
Aggregat-Operatoren zur Verf\o'u"'gung.
|
||
|
||
.DS L
|
||
countu z\o'a"'hlt unikate (einmalig vorkommende)
|
||
Werte
|
||
avgu Durchschnitt \o'u"'ber unikate Werte
|
||
sumu summiert unikate Werte
|
||
.DE
|
||
.LP
|
||
Interessanterweise werden "minu", "maxu" und "anyu" nicht
|
||
ben\o'o"'tigt.
|
||
Ihre Werte sind die gleichen, unabh\o'a"'ngig davon, ob
|
||
doppelte Tupel vorkommen oder nicht.
|
||
.LP
|
||
Die korrekte Query, um die Anzahl der "leiter" zu finden, ist:
|
||
|
||
.DS L
|
||
* retrieve (chefs=countu(p.leiter))
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
|chefs |
|
||
|-------------|
|
||
| 9|
|
||
|-------------|
|
||
1 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Eine andere Erleichterung, die \*(yy\ 6.3 unterst\o'u"'tzt, sind die
|
||
sogenannten Aggregat-Funktionen.
|
||
Aggregat-Funktionen gruppieren Daten
|
||
in Kategorien und unterst\o'u"'tzen separate Zusammenfassungen
|
||
zu jeder Kategorie.
|
||
.LP
|
||
Was ist zum Beispiel, wenn
|
||
wir f\o'u"'r die Angestellten, die zum selben
|
||
Leiter geh\o'o"'ren, das Durchschnittsgehalt ermitteln wollen?
|
||
Die Query w\o'u"'rde sein:
|
||
.DS L
|
||
|
||
* retrieve (p.name,leiteravg=avg(p.gehalt by p.leiter))
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |leiteravg |
|
||
|-------------------------------|
|
||
|Mueller, Ernst | 700.000|
|
||
|Gruene, Peter | 1453.000|
|
||
|Rose, Petra | 1453.000|
|
||
|Loda, Dieter | 668.500|
|
||
|Baum, Klaus | 668.500|
|
||
|Kayser, Helmut | 968.500|
|
||
|Weber, Franz | 968.500|
|
||
|Fleischer, Karl | 877.000|
|
||
|Maerz, Udo | 1239.000|
|
||
|Mueller, Petra | 1239.000|
|
||
|Schmidt, Hermann | 1035.333|
|
||
|Warnke, Peter | 1035.333|
|
||
|Neumann, Inge | 1035.333|
|
||
|Schmidt, Petra | 1111.667|
|
||
|Thoms, Rolf | 1111.667|
|
||
|Wunsch, Peter-Paul | 1111.667|
|
||
|Malter, Juergen | 1111.667|
|
||
|Schneider, Peter | 1111.667|
|
||
|Weise, Juergen | 1111.667|
|
||
|Heine, Rolf | 1111.667|
|
||
|Ernst, Eva | 1111.667|
|
||
|Rose, Peter | 1111.667|
|
||
|Zeidler, Fritz | 1605.667|
|
||
|Moser, Otto | 1605.667|
|
||
|Schulze, Ernst | 1605.667|
|
||
|-------------------------------|
|
||
25 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Die erste Person ist allein und
|
||
ihr Einkommen betr\o'a"'gt 700.00 M.
|
||
Die n\o'a"'chsten zwei Personen haben den selben Leiter und
|
||
das Durchschnittseinkommen betr\o'a"'gt 1453.00 usw.
|
||
.LP
|
||
Noch einmal, wenn wir die gleiche Liste eben
|
||
f\o'u"'r jene Angestellten \o'u"'ber 50 sehen m\o'o"'chten:
|
||
.DS L
|
||
|
||
* retrieve (p.name,leiteravg=avg(p.gehalt by p.leiter))
|
||
* where 1985-p.gebdat > 50
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |leiteravg |
|
||
|-------------------------------|
|
||
|Gruene, Peter | 1453.000|
|
||
|Rose Petra | 1453.000|
|
||
|Wunsch, Peter-Paul | 1111.667|
|
||
|Malter, Juergen | 1111.667|
|
||
|Schneider, Peter | 1111.667|
|
||
|Heine, Rolf | 1111.667|
|
||
|Ernst, Eva | 1111.667|
|
||
|Rose, Peter | 1111.667|
|
||
|Zeidler, Fritz | 1605.667|
|
||
|-------------------------------|
|
||
9 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Aggregat-Funktionen (im Gegensatz zu Aggregat-Operatoren) sind
|
||
nicht vollst\o'a"'ndig in sich abgeschlossen.
|
||
Die Dom\o'a"'nen, auf die die Daten gruppiert sind
|
||
(, durch die sogenannte "by_list"), sind logisch
|
||
mit den restlichen Dom\o'a"'nen der Query
|
||
verkn\o'u"'pft.
|
||
.LP
|
||
In diesem letzten Beispiel referenziert "p.leiter" in
|
||
der "by_list" zu den selben Tupeln wie
|
||
"p.name" in der "target_list".
|
||
.LP
|
||
Wenn wir das Durchschnittsgehalt nach Leitern nur f\o'u"'r
|
||
die Leiter 33 und 199 berechnen wollen,
|
||
erg\o'a"'be sich diese Query:
|
||
.DS L
|
||
|
||
* retrieve (p.name,leiteravg=
|
||
* avg(p.gehalt by p.leiter))
|
||
* where p.leiter = 199 or p.leiter = 33
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |leiteravg |
|
||
|-------------------------------|
|
||
|Kayser, Helmut | 968.500|
|
||
|Weber, Franz | 968.500|
|
||
|Schmidt, Petra | 1111.667|
|
||
|Thoms, Rolf | 1111.667|
|
||
|Wunsch, Peter-Paul | 1111.667|
|
||
|Malter, Juergen | 1111.667|
|
||
|Schneider, Peter | 1111.667|
|
||
|Weise, Juergen | 1111.667|
|
||
|Heine, Rolf | 1111.667|
|
||
|Ernst, Eva | 1111.667|
|
||
|Rose, Peter | 1111.667|
|
||
|-------------------------------|
|
||
11 tuples touched
|
||
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Nehmen wir an, wir wollen herausfinden,
|
||
wie viele Personen bei jedem Leiter
|
||
arbeiten und weiterhin wollen wir nur
|
||
die Personen einbeziehen, die
|
||
bereits vor 1970 dort arbeiteten.
|
||
.DS L
|
||
|
||
* retrieve (p.leiter,mitarb=count(p.name by p.leiter where
|
||
* p.einstdat < 1970))
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
|leiter|mitarb |
|
||
|--------------------|
|
||
| 0| 2|
|
||
| 10| 0|
|
||
| 13| 0|
|
||
| 26| 2|
|
||
| 32| 0|
|
||
| 33| 2|
|
||
| 55| 1|
|
||
| 129| 2|
|
||
| 199| 8|
|
||
|--------------------|
|
||
9 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Beachten sie, dass die Leiter 32, 10 und 13 keine
|
||
Angestellten haben, die vor 1970
|
||
dort angefangen haben.
|
||
Jetzt nehmen wir an, dass wir das Durchschnittsgehalt
|
||
f\o'u"'r diese Angestellten wissen wollen.
|
||
\o'A"'ndern sie einfach "count" in "avg" und starten sie die Query.
|
||
.DS L
|
||
* retrieve (p.leiter,mitarb=avg(p.gehalt by p.leiter where
|
||
* p.einstdat < 1970))
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|leiter|mitarb |
|
||
|-----------------|
|
||
| 0| 1453.000|
|
||
| 10| 0.000|
|
||
| 13| 0.000|
|
||
| 26| 954.000|
|
||
| 32| 0.000|
|
||
| 33| 1337.000|
|
||
| 55| 1362.000|
|
||
| 129| 1626.500|
|
||
| 199| 1088.125|
|
||
|-----------------|
|
||
9 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Beachten sie, was \*(yy\ 6.3 f\o'u"'r die
|
||
Leiter 32, 10 und 13 macht.
|
||
Das Durchschnitsgehalt f\o'u"'r diese Angestellten
|
||
ist tats\o'a"'chlich nicht
|
||
definiert, weil es keine Angestellten gibt, die vor 1970
|
||
angefangen haben.
|
||
\*(yy\ 6.3 wandelt undefinierte Werte immer
|
||
in Null.
|
||
.LP
|
||
Wenn sie die Nullwerte von der Ausgabe entfernen wollen,
|
||
kann das durch Hinzuf\o'u"'gung einer Qualifikation
|
||
zur Query erfolgen.
|
||
Die folgende Query wird nur die Durchschnittsgeh\o'a"'lter
|
||
finden, die einen Wert gr\o'o"'sser Null haben.
|
||
.DS L
|
||
|
||
* retrieve (p.leiter,mitarb=avg(p.gehalt by p.leiter where
|
||
* p.einstdat < 1970))
|
||
* where avg(p.gehalt by p.leiter where p.einstdat < 1970) > 0
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|leiter|mitarb |
|
||
|-----------------|
|
||
| 0| 1453.000|
|
||
| 26| 954.000|
|
||
| 33| 1337.000|
|
||
| 55| 1362.000|
|
||
| 129| 1626.500|
|
||
| 199| 1088.125|
|
||
|-----------------|
|
||
6 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Bis jetzt haben wir die Rechercheergebnisse direkt auf dem Terminal
|
||
ausgegeben.
|
||
Sie k\o'o"'nnen die Ergebnisse auch in eine neue Relation
|
||
retten bzw. sichern.
|
||
Das wird realisiert, wenn sie sagen:
|
||
.DS L
|
||
|
||
retrieve into steigerung ( ... )
|
||
where . . .
|
||
|
||
.DE
|
||
Die Regeln sind genau die gleichen, als w\o'u"'rden sie \o'u"'ber
|
||
das Terminal recherchieren.
|
||
\*(yy\ 6.3 gr\o'u"'ndet die neue Relation mit den
|
||
korrekten Dom\o'a"'nen und gibt die Ergebnisse
|
||
der Query in diese Relation.
|
||
.LP
|
||
Als Beispiel gr\o'u"'nden
|
||
wir eine neue Relation "steigerung", die nur die Angestellten
|
||
enth\o'a"'lt, die mehr als 1000 M verdienen:
|
||
.DS L
|
||
|
||
* retrieve into steigerung (p.all)
|
||
* where p.gehalt > 1000
|
||
* print steigerung
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
Relation: steigerung
|
||
K 1630 \*(yy\ EVK Olbernhau - K1630
|
||
|
||
|num |name |gehalt|leiter|gebdat|einstd|
|
||
|-------------------------------------------------------|
|
||
| 10|Rose, Peter | 1590| 199| 1927| 1953|
|
||
| 11|Rose, Petra | 1206| 0| 1931| 1951|
|
||
| 26|Schneider, Peter | 1300| 199| 1930| 1970|
|
||
| 33|Ernst, Eva | 1010| 199| 1931| 1963|
|
||
| 37|Neumann, Inge | 1198| 26| 1950| 1974|
|
||
| 55|Malter, Juergen | 1200| 199| 1920| 1969|
|
||
| 157|Schmidt, Petra | 1200| 199| 1940| 1960|
|
||
| 199|Gruene, Peter | 1700| 0| 1920| 1952|
|
||
| 430|Moser, Otto | 1567| 129| 1938| 1959|
|
||
| 843|Schmidt, Hermann | 1120| 26| 1936| 1956|
|
||
| 994|Schulze, Ernst | 1564| 129| 1944| 1970|
|
||
| 1523|Zeidler, Fritz | 1686| 129| 1928| 1949|
|
||
| 1639|Maerz, Udo | 1116| 55| 1947| 1970|
|
||
| 5119|Mueller, Petra | 1362| 55| 1939| 1963|
|
||
| 5219|Weber, Franz | 1337| 33| 1944| 1959|
|
||
|-------------------------------------------------------|
|
||
15 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Durch ein "retrieve into" wird nichts gedruckt bzw. ausgegeben.
|
||
Wir haben ein "print"-Kommando eingef\o'u"'gt, um
|
||
die Ergebnisse zu sehen.
|
||
Die Relation, die durch ein "retrieve into" benannt wird,
|
||
darf vorher nicht existieren.
|
||
Wenn wir beispielsweise versuchen,
|
||
die selbe Query zu wiederholen:
|
||
.DS L
|
||
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
2135: line 1, You cannot duplicate the name of an
|
||
existing relation(steigerung)
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
.LP
|
||
Es gibt zwei spezielle Merkmale zu "retrieve into".
|
||
Erstens wird die Relation automatisch sortiert
|
||
und doppelte Tupel gel\o'o"'scht.
|
||
Zweitens wird die Relation Bestandteil der Datenbank
|
||
und sie werden ihr Eigent\o'u"'mer.
|
||
Wenn sie nicht wollen, dass sie erhalten bleibt, denken sie daran,
|
||
dass sie gel\o'o"'scht werden muss.
|
||
Der Ablauf zum L\o'o"'schen einer Relation wird
|
||
etwas sp\o'a"'ter erl\o'a"'utert.
|
||
.LP
|
||
Bisher haben wir nur Daten gesucht, aber niemals
|
||
welche ge\o'a"'ndert.
|
||
\*(yy\ 6.3 unterst\o'u"'tzt drei Aktualisierungskommandos:
|
||
"append", "replace" und "delete".
|
||
.LP
|
||
Beispielsweise wollen wir "Heinz Heinrich" zur
|
||
Liste der Angestellten auf "steigerung" hinzuf\o'u"'gen und ihm
|
||
ein Gehalt von 1000 M zuordnen:
|
||
.DS L
|
||
|
||
* append to steigerung(name = "Heinrich, Heinz",gehalt = 1000)
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
1 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Beachten sie, dass wir nur zwei Werte spezifizierten,
|
||
obwohl "steigerung" aus sechs Dom\o'a"'nen besteht.
|
||
Das ist sch\o'o"'n!
|
||
\*(yy\ 6.3 setzt automatisch numerische Dom\o'a"'nen
|
||
auf Null und Zeichenkettendom\o'a"'nen auf "blank",
|
||
wenn sie nicht spezifiziert wurden.
|
||
.LP
|
||
Beachten sie auch, dass \*(yy\ 6.3 nach der Query nichts
|
||
ausgibt.
|
||
Das trifft f\o'u"'r alle Aktualisierungskommandos zu.
|
||
.LP
|
||
Wir wollen jedem in "steigerung" 10% Gehaltszuschlag geben.
|
||
Um das zu tun, ersetzen wir "gehalt" durch das Produkt aus
|
||
1,1 mal Wert.
|
||
Geben sie die Query ein:
|
||
.DS L
|
||
|
||
* range of s is steigerung
|
||
* replace s(gehalt = s.gehalt * 1.1)
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
16 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
W\o'a"'hrend das "append"-Kommando erwartet, dass sie einen
|
||
Relationen-Name (d.h. "append to steigerung") angeben, erwartet das
|
||
"replace"- und "delete"-Kommando eine
|
||
Tupel-Variable.
|
||
Bemerken sie, dass das Kommando lautet:
|
||
.DS L
|
||
|
||
replace s ( . . . )
|
||
where . . .
|
||
|
||
und nicht:
|
||
|
||
replace steigerung ( . . . )
|
||
where . . .
|
||
|
||
.DE
|
||
Geben sie die Ergebnisse der beiden
|
||
letzten Aktualisierungen aus:
|
||
.DS L
|
||
|
||
* print steigerung
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
Relation: steigerung
|
||
|
||
|
||
|num |name |gehalt|leiter|gebdat|einstd|
|
||
|-------------------------------------------------------|
|
||
| 10|Rose, Peter | 1749| 199| 1927| 1953|
|
||
| 11|Rose, Petra | 1326| 0| 1931| 1951|
|
||
| 26|Schneider, Peter | 1430| 199| 1930| 1970|
|
||
| 33|Ernst, Eva | 1111| 199| 1931| 1963|
|
||
| 37|Neumann, Inge | 1317| 26| 1950| 1974|
|
||
| 55|Malter, Juergen | 1320| 199| 1920| 1969|
|
||
| 157|Schmidt, Petra | 1320| 199| 1940| 1960|
|
||
| 199|Gruene, Peter | 1870| 0| 1920| 1952|
|
||
| 430|Moser, Otto | 1723| 129| 1938| 1959|
|
||
| 843|Schmidt, Hermann | 1232| 26| 1936| 1956|
|
||
| 994|Schulze, Ernst | 1720| 129| 1944| 1970|
|
||
| 1523|Zeidler, Fritz | 1854| 129| 1928| 1949|
|
||
| 1639|Maerz, Udo | 1227| 55| 1947| 1970|
|
||
| 5119|Mueller, Petra | 1498| 55| 1939| 1963|
|
||
| 5219|Weber, Franz | 1470| 33| 1944| 1959|
|
||
| 0|Heinrich, Heinz | 1100| 0| 0| 0|
|
||
|-------------------------------------------------------|
|
||
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Nun wollen wir denjenigen, der am wenigsten verdient, entlassen:
|
||
.DS L
|
||
|
||
* delete s where s.gehalt = min(s.gehalt) \eg
|
||
I N G - d b . . .
|
||
|
||
1 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Beachten sie, dass das "delete"-Kommando eine
|
||
Tupel-Variable (d.h. "delete s") erwartet
|
||
und keinen Relationen-Name.
|
||
.LP
|
||
Was ist, wenn wir wissen wollen, wer mehr als
|
||
Otto Moser verdient? Mit Heinz Heinrich k\o'o"'nnen wir nicht
|
||
mehr arbeiten, den haben wir entlassen.
|
||
Die Query, die das erledigt, ist recht schwierig.
|
||
Zuerst ben\o'o"'tigen wir eine neue Tupel-Variable, genannt
|
||
"o", die auf auf dem Bereich "steigerung" liegt
|
||
und benutzt wird, um Otto zu referenzieren.
|
||
"o.name" muss auf "Moser, Otto" gesetzt werden.
|
||
Danach m\o'u"'ssen wir eine Tupel-Variable "s"
|
||
nutzen, die die gesamte Relation durchforscht.
|
||
Jedesmal, wenn wir "s.gehalt > o.gehalt"
|
||
finden, dann verdient "s.name" mehr als Otto.
|
||
.LP
|
||
Die vollst\o'a"'ndige Query ist:
|
||
.DS L
|
||
|
||
* range of o is steigerung
|
||
* retrieve (s.name, sgeh=s.gehalt,ottogeh=o.gehalt)
|
||
* where s.gehalt > o.gehalt
|
||
* and o.name = "Moser, Otto"
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|name |sgeh |ottoge|
|
||
|----------------------------------|
|
||
|Rose, Peter | 1749| 1723|
|
||
|Gruene, Peter | 1870| 1723|
|
||
|Zeidler, Fritz | 1854| 1723|
|
||
|----------------------------------|
|
||
3 tuples touched
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Wenn wir Otto Moser 50 M mehr geben wollen, als
|
||
irgendeinem anderen, dann muss die Query lauten:
|
||
.DS L
|
||
|
||
* replace s(gehalt = max(s.gehalt) + 50)
|
||
* where s.name = "Moser, Otto"
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Schliesslich wollen wir noch eine Relation,
|
||
f\o'u"'r die sie Eigent\o'u"'mer sind,
|
||
l\o'o"'schen-geben sie das Kommando:
|
||
.DS L
|
||
|
||
* destroy steigerung
|
||
* \eg
|
||
|
||
I N G - d b . . .
|
||
|
||
ING_db:
|
||
*
|
||
|
||
.DE
|
||
Wir sind jetzt fertig und verlassen \*(yy\ 6.3.
|
||
Das kann durch Eingabe eines
|
||
"end-of-file" (CONTROL_c)
|
||
oder g\o'u"'nstiger durch Verwendung des "\\q"-
|
||
Kommandos erreicht werden:
|
||
.DS L
|
||
|
||
* \eq
|
||
* ING-db Version 6.3/3 logout
|
||
K1630 / EVK Olbernhau - K1630
|
||
Wed May 4 19:58:00 1988
|
||
Auf Wiedersehen ing_db -- Kommen Sie bald wieder
|
||
.DE
|
||
.LP
|
||
Als "ing_db" wird immer der Nutzername eingetragen, ggfs.
|
||
aber eben auch ing_db.
|
||
|
||
|