Document

Werbung
Daten modifizieren –
INSERT, UPDATE und DELETE
jetzt lerne ich
KAPITEL 3
Ihre Datenbestände können Sie jetzt nach allen Regeln der Kunst abfragen.
Für den Teil der Datenbankbenutzer, die an reinen Auskunftssystemen arbeiten, dürfte damit der Fall bereits erledigt sein. Die Pflege der Daten, d.h. das
Einfügen neuer, Überarbeiten vorhandener und Löschen nicht mehr benötigter Daten übernimmt oftmals eine zentrale Stelle mit entsprechendem Personal und einem Datenbankadministrator, der sich um die Wartung der Datenbank kümmert. Wenn Sie aber zum Kreis derjenigen gehören, die den
Datenbestand auf dem Laufenden halten müssen, wenn Sie Datenbankanwendungen programmieren oder wenn Sie Administrator und Benutzer in
Personalunion sind, müssen Sie auch wissen, wie sich neue Daten in die
Datenbank einfügen und vorhandene Daten bearbeiten bzw. löschen lassen.
Dieses Kapitel erläutert die dafür verfügbaren SQL-Anweisungen und zeigt
außerdem, wie Sie die auf der Begleit-CD enthaltenen Beispieldaten in die
Datenbank cd einlesen.
Mit der Anweisung INSERT (Einfügen) nehmen Sie neue Datensätze in eine
Tabelle auf, UPDATE (Aktualisieren) dient zum Bearbeiten vorhandener Datensätze und schließlich lassen sich mit DELETE (Löschen) Datensätze aus der
Datenbank entfernen. Diese Anweisungen gehören zur Kategorie der Datenmanipulationssprache (Data Manipulation Language, DML) von SQL.
Bei den Anweisungen UPDATE und DELETE treffen Sie wieder auf die Klauseln,
die Ihnen von der SELECT-Anweisung aus Kapitel 2 her bekannt sind. Der letzte Abschnitt dieses Kapitels streift kurz die Anweisungen zum Masseneinfügen, mit denen sich Datensätze aus Dateien mit nur einer einzigen Anweisung
auf einen Schlag in eine Tabelle übertragen lassen.
73
3 Daten modifizieren – INSERT, UPDATE und DELETE
jetzt lerne ich
1
Die Anweisungen in diesem Kapitel beziehen sich auf die Datenbank cd.
Wenn Sie das Datenbanksystem neu gestartet haben, führen Sie als Erstes
die Anweisung
USE cd
aus, um cd zur aktuellen Datenbank zu machen, wie es Kapitel 1 erläutert
hat.
3.1
Daten einfügen – INSERT
Bevor Sie Daten abrufen, bearbeiten oder löschen können, müssen Sie die
Datenbank zuerst einmal »bestücken«, sprich mit Daten füllen. Mit der Anweisung INSERT lassen sich einzelne oder alle Felder eines Datensatzes in eine Tabelle einfügen:
Beispiel 3.1 INSERT INTO cddata (artist, id)
VALUES ('Donovan', '45376816')
Diese Anweisung fügt einen neuen Datensatz in die Tabelle cddata ein und
schreibt die Werte Donovan und 45376816 in die Spalten artist bzw. id.
Die Anweisung INSERT arbeitet datensatzweise, man kann weder mehrere
Datensätze auf einmal einfügen, noch mit mehreren INSERT-Anweisungen
nacheinander einzelne Felder desselben Datensatzes füllen. Fehlende Felder
ersetzt das Datenbanksystem entweder durch festgelegte Standardwerte oder
durch einen speziellen Wert, der einen unbekannten Inhalt kennzeichnet –
mehr dazu gleich.
3.1.1
Vollständige Werteliste einfügen
Die einfachste Form der Anweisung INSERT sieht wie folgt aus:
Syntax:
INSERT [INTO] Tabellenname VALUES(Werteliste)
Wie der Abschnitt »Syntaxdarstellungen lesen« in Kapitel 2 erläutert hat, ist
das in eckigen Klammern stehende Schlüsselwort INTO optional. Mit Tabellenname spezifizieren Sie die Zieltabelle, in die der Datensatz einzufügen ist.
Nach dem Schlüsselwort VALUES geben Sie die einzufügenden Werte – jeweils
durch Komma getrennt – an. Diese Syntaxform der INSERT-Anweisung verlangt, dass Sie alle Spalten der Zieltabelle in der Werteliste aufführen und dabei auch die Reihenfolge beachten müssen, wie sie die Tabellendefinition vorschreibt. Da die Tabelle cddata der Datenbank cd aus 15 Spalten besteht,
müssen Sie auch 15 Werte bereitstellen.
74
Daten einfügen – INSERT
In Kapitel 5 erfahren Sie, wie eine Tabellendefinition aufgebaut ist.
Als Beispiel nehmen wir eine CD mit der ID 45376816 von Donovan. Die
CD enthält 20 Titel, die in der Tabelle cddata jeweils einen Datensatz mit 15
Feldern ergeben. Einen vollständigen Titeleintrag fügen Sie mit folgender Anweisung ein:
INSERT INTO cddata VALUES('45376816','Donovan',
'The very best of Donovan','0',4250787,20,'Pop',
'CD','',1,'','Sunshine Superman',275027,'','')
jetzt lerne ich
1
Beispiel 3.2
In dieser Anweisung fällt auf, dass einige Felder lediglich aus zwei einfachen
Anführungszeichen bestehen. Wenn Sie für ein Feld keinen Wert bereitstellen, muss dieses Feld dennoch in der Werteliste erscheinen, was durch die beiden Anführungszeichen und das Komma symbolisiert wird.
Die Anweisung ist aufgrund ihrer Länge zu breit für eine gedruckte Buchseite und wurde deshalb auf drei Zeilen umbrochen. Genauso können Sie auch
bei der Eingabe der Anweisung verfahren. Es ist sogar möglich, mitten in einer Zeichenfolge auf eine neue Zeile zu wechseln. Beispielsweise ist folgende Eingabe zulässig (wenn auch wenig sinnvoll):
1
INSERT INTO cddata VALUES('45376816','Dono
van',
'The very best of Donovan','0',4250787,20,'Pop',
'CD','',1,'','Sunshine Superman'
,275027,'','')
Manchmal ist es nicht nötig oder möglich, für alle Felder Werte anzugeben.
Wenn Sie aber in einer Anweisung wie
INSERT INTO cddata VALUES ('Wert1', 'Wert2', 'Wert3')
Beispiel 3.3
lediglich drei statt 15 Werte angeben, erhalten Sie in MySQL die Fehlermeldung:
ERROR 1136: Column count doesn't match value count at row 1
SQL Server zeigt folgende Meldung an:
Meldung 213, Ebene 16, Status 4, Server SER, Zeile 1
INSERT-Fehler: Spaltenname oder Anzahl der übergebenen Werte entspricht nicht
der Tabellendefinition.
Beide Meldungen sagen das Gleiche aus – es fehlen Spaltenwerte. Weil die
obige Anweisung nichts über die Spalten aussagt, ermittelt INSERT die Anzahl
der Spalten aus der Tabellendefinition, die im Datenbanksystem gespeichert
ist.
75
3 Daten modifizieren – INSERT, UPDATE und DELETE
jetzt lerne ich
3.1.2
Einzelne Werte einfügen
Wenn man nicht alle Werte bereitstellen möchte, kann man die optionale
Spaltenliste spezifizieren. Nur für die hier genannten Spalten sind Werte in
der Anweisung erforderlich. Die ergänzte Syntax der INSERT-Anweisung lautet:
Syntax:
INSERT [INTO] Tabellenname [(Spaltenliste)]
{[DEFAULT] VALUES | VALUES (Wert[,...n]) | Auswahlanweisung }
Die Reihenfolge der Spalten in der Spaltenliste muss nicht mit der Reihenfolge der Spalten in der Tabellendefinition übereinstimmen. Die Werte in der
Werteliste müssen aber in der Reihenfolge erscheinen, wie sie durch die
Spaltenliste vorgegeben ist:
Beispiel 3.4 INSERT INTO cddata (artist, id)
VALUES ('Donovan', '45376816')
Diese Anweisung stellt für den neu einzufügenden Datensatz lediglich zwei der
15 möglichen Werte bereit. Was passiert mit den übrigen Feldern im Datensatz? Rufen Sie dazu außer id und artist noch einige andere Spalten ab:
Beispiel 3.5 SELECT id, artist, category, title, tracknum FROM cddata
WHERE id = 45376816
+----------+---------+----------+--------------------------+----------+
| id
| artist | category | title
| tracknum |
+----------+---------+----------+--------------------------+----------+
| 45376816 | Donovan | Pop
| The very best of Donovan |
1 |
| 45376816 | Donovan | NULL
| NULL
|
NULL |
+----------+---------+----------+--------------------------+----------+
2 rows in set (0.00 sec)
Der erste Datensatz stammt noch aus dem Beispiel des letzten Abschnitts, bei
dem alle 15 Felder bereitgestellt wurden. Für den zweiten Datensatz haben
wir in der obigen Anweisung nur die Felder id und artist angegeben. Diese
beiden Werte stehen in den richtigen Spalten, die übrigen Spalten enthalten
den Eintrag NULL.
NULL ist in jeder Hinsicht ein besonderer Wert. Wenn Sie beispielsweise die
WHERE-Klausel in der SELECT-Anweisung wie folgt ergänzen
Beispiel 3.6 SELECT id, artist, category, title, tracknum FROM cddata
WHERE id = 45376816 AND tracknum <> 1
erhalten Sie nicht etwa den erwähnten zweiten Datensatz, der in der Spalte
tracknum den Eintrag NULL enthält (was zweifellos ungleich 1 ist), sondern gar
keinen Datensatz zurück! Der folgende Abschnitt erläutert, warum das so ist.
76
Daten einfügen – INSERT
jetzt lerne ich
Für nicht angegebene Werte kann man anstelle von NULL auch so genannte
Standardwerte einfügen lassen, die in der Anweisung zum Erstellen der Tabelle festgelegt werden. Mehr dazu erfahren Sie in Kapitel 5. In der INSERTAnweisung legen Sie mit der Klausel DEFAULT VALUES (die allerdings in MySQL
nicht implementiert ist) fest, dass in alle Spalten die entsprechenden Standardwerte eingetragen werden:
INSERT INTO cddata
DEFAULT VALUES
Beispiel 3.7
Wie die obige Syntaxdarstellung gezeigt hat, kann man entweder DEFAULT
VALUES, das Schlüsselwort VALUES mit einer Werteliste oder eine Auswahlanweisung angeben. Deshalb ist es mit DEFAULT VALUES nicht möglich, nur
einige Werte zu spezifizieren und für die übrigen Werte die Standardwerte
bereitstellen zu lassen.
Gemäß der in Kapitel 2 im Abschnitt »Syntaxdarstellungen lesen« erläuterten
Konventionen stehen die geschweiften Klammern um eine Gruppe von Elementen (hier: DEFAULT VALUES, VALUES und Auswahlanweisung), von denen
eines obligatorisch ist – und zwar nur eines und nicht mehrere.
1
Wenn ein Wert nicht angegeben ist, muss das Datenbanksystem einen Standardwert bereitstellen können, was aber nicht immer ohne weiteres möglich
ist. Wie bereits erwähnt, erhalten nicht spezifizierte Spalten den Wert NULL zugewiesen. Wenn aber die betreffende Spalte keine NULL-Werte zulässt und die
Spalte weder einen Standardwert noch einen Datentyp aufweist, der einen
Wert automatisch zuweist, schlägt die INSERT-Anweisung fehl.
Mehr zur NULL-Zulässigkeit erfahren Sie in Kapitel 5 beim Thema Tabellendefinition.
3.1.3
Reihenfolge der Spalten
Im relationalen Datenbankmodell (siehe Kapitel 5) ist die Reihenfolge der Zeilen und Spalten einer Tabelle nicht relevant und lässt sich per SQL jederzeit
ändern. Wenn Sie mit der INSERT-Anweisung alle Spaltenwerte für einen Datensatz einfügen, ohne die Spalten zu spezifizieren, besteht die Gefahr, dass
Werte nach Änderungen der Datenbankstruktur in falschen Spalten landen.
Deshalb empfiehlt es sich, die Spaltennamen explizit in der Spaltenliste der
INSERT-Anweisung aufzuführen.
77
3 Daten modifizieren – INSERT, UPDATE und DELETE
jetzt lerne ich
3.1.4
Wahrheitswerte und der besondere Wert NULL
Wer schon mit anderen Programmiersprachen zu tun hatte, kennt Wahrheitswerte als Ergebnis logischer Ausdrücke: TRUE (wahr), wenn die formulierte Bedingung zutrifft, und FALSE (falsch), wenn die Bedingung nicht erfüllt ist. Es
sind also nur zwei mögliche Werte definiert. Anders in SQL: Neben den hier
ebenfalls verwendeten Werten TRUE und FALSE gibt es noch einen dritten Zustand des Ergebnisses: UNKNOWN (unbekannt). Mit diesem Wert kommen Sie
immer dann in Berührung, wenn Tabellenspalten keine Daten enthalten. SQL
sieht für solche Spalten den besonderen Wert NULL vor. Das ist kein Wert, den
man »anfassen« kann, es handelt sich weder um die Zahl 0 noch um eine leere
Zeichenfolge – denn das sind schon wieder konkrete Werte.
Der Wert NULL wird Spalten zugewiesen, wenn beim Einfügen kein Wert explizit angegeben wird. Im ersten Beispiel der INSERT-Anweisung mit vollständiger Werteliste wurden fehlende Werte durch '', symbolisiert. Was macht
SQL mit solchen Werten? Erweitern Sie dazu die zuletzt verwendete INSERTAnweisung um zwei zusätzliche Spalten, eine Zeichenfolgenspalte (category)
und eine Zahlenspalte (tracknum):
Beispiel 3.8 INSERT INTO cddata (artist, id, category, tracknum)
VALUES ('Donovan', '45376816','','');
Rufen Sie wieder die entsprechenden Datensätze ab:
Beispiel 3.9 SELECT id, artist, category, title, tracknum FROM cddata
WHERE id = 45376816
+----------+---------+----------+--------------------------+----------+
| id
| artist | category | title
| tracknum |
+----------+---------+----------+--------------------------+----------+
| 45376816 | Donovan | Pop
| The very best of Donovan |
1 |
| 45376816 | Donovan | NULL
| NULL
|
NULL |
| 45376816 | Donovan |
| NULL
|
0 |
+----------+---------+----------+--------------------------+----------+
3 rows in set (0.01 sec)
Interessant ist jetzt der dritte Datensatz: Für category und tracknum hat
MySQL eine leere Zeichenfolge bzw. den Zahlenwert 0 eingesetzt, weil diese
beiden Spalten in der Spaltenliste aufgeführt sind und mit '' in der Werteliste
jeweils ein definierter Wert angegeben wurde. In der Spalte title steht dagegen wieder die NULL, weil diese Spalte in der INSERT-Anweisung nicht explizit
benannt wurde. Mit dem Wert NULL bringt SQL sozusagen zum Ausdruck: »Ich
weiß nicht, was soll es bedeuten.«
Im Gegensatz zu anderen Programmiersprachen sind TRUE und FALSE in SQL
lediglich ein Ausdrucksmittel, um den logischen Wert verbal zu beschreiben.
Dagegen kann man den Wert NULL in Ausdrücken verwenden. Die arithmeti-
78
Daten einfügen – INSERT
jetzt lerne ich
schen Vergleichsoperatoren liefern aber bei Vergleichen, an denen mindestens ein NULL-Wert beteiligt ist, das Ergebnis NULL zurück. Der Zustand UNKNOWN
ist gleichbedeutend mit dem Wert NULL. Zum Beispiel führt die Anweisung
mysql> SELECT 1 > NULL;
Beispiel 3.10
zum Ergebnis:
+----------+
| 1 > null |
+----------+
|
NULL |
+----------+
1 row in set (0.00 sec)
In dieser Anweisung dient SELECT lediglich dazu, das Ergebnis des nachfolgenden Ausdrucks auszugeben (siehe den Abschnitt »SELECT ohne FROM«
in Kapitel 2).
1
Für Vergleiche mit NULL-Werten ist der Operator IS NULL vorgesehen:
SELECT id, artist, category, title, tracknum FROM cddata
WHERE id = 45376816 AND tracknum IS NULL
Beispiel 3.11
+----------+---------+----------+-------+----------+
| id
| artist | category | title | tracknum |
+----------+---------+----------+-------+----------+
| 45376816 | Donovan | NULL
| NULL |
NULL |
+----------+---------+----------+-------+----------+
1 row in set (0.01 sec)
Die logische Umkehrung des Vergleichs erfolgt mit IS NOT NULL:
SELECT id, artist, category, title, tracknum FROM cddata
WHERE id = 45376816 AND tracknum IS NOT NULL
Beispiel 3.12
+----------+---------+----------+--------------------------+----------+
| id
| artist | category | title
| tracknum |
+----------+---------+----------+--------------------------+----------+
| 45376816 | Donovan | Pop
| The very best of Donovan |
1 |
| 45376816 | Donovan |
| NULL
|
0 |
+----------+---------+----------+--------------------------+----------+
2 rows in set (0.03 sec)
Tests mit Vergleichsoperatoren auf Spalten, die NULL-Werte enthalten, liefern
NULL als Ergebnis, während Tests mit dem Operator IS auf Spalten, die NULLWerte enthalten, logisch wahr (TRUE) oder falsch (FALSE) liefern.
79
3 Daten modifizieren – INSERT, UPDATE und DELETE
jetzt lerne ich
1
In SQL Server kann man über die Einstellung ANSI_NULLS festlegen, wie
NULL-Werte in Vergleichen behandelt werden. Ist ANSI_NULLS auf ON gestellt,
liefern Vergleiche mit NULL-Werten nicht das Ergebnis TRUE oder FALSE, sondern UNKNOWN. Dieses Verhalten entspricht dem ANSI-Standard.
MySQL erlaubt es, das Ergebnis eines logischen Vergleichs als numerischen
Wert aufzufassen und weiterzuverarbeiten:
Beispiel 3.13 mysql> SELECT 5 + (3 IS NOT NULL);
+---------------------+
| 5 + (3 is not null) |
+---------------------+
|
6 |
+---------------------+
1 row in set (0.00 sec)
Der Ausdruck 3 IS NOT NULL liefert das Ergebnis TRUE, das MySQL mit dem
numerischen Wert 1 beschreibt. Der resultierende Ausdruck 5 + (1) ergibt
dann das dargestellte Ergebnis 6.
Mit SQL Server kann man solche Spielchen nicht treiben. Führt man hier die
gleiche Anweisung aus, erhält man eine Fehlermeldung.
3.1.5
Daten aus einer anderen Tabelle einfügen
Nehmen wir an, Sie beziehen Ihre Daten aus einer Quelle, deren Format
noch nicht dem Ihrer Datenbanktabellen entspricht. Entweder lassen Sie die
Daten im Vorfeld aufbereiten, d.h. durch die Clientanwendung, die auf die
Datenbank zugreift, oder Sie lesen die Daten zunächst in eine Hilfstabelle ein,
um sie dann später in den richtigen Formaten auf die endgültigen Zieltabellen
zu verteilen. Die Beispiele im Buch verwenden natürlich den zweiten Ansatz,
um die Möglichkeiten von SQL zu demonstrieren.
Um die Daten aus der Hilfstabelle in die endgültige Zieltabelle zu übertragen,
kann man die INSERT-Anweisung durch eine Auswahlanweisung (d.h. eine
SELECT-Anweisung) ergänzen. Diese Auswahlanweisung holt die gewünschten
Daten aus der Hilfstabelle und die eigentliche INSERT-Anweisung fügt sie in die
jeweiligen Zielspalten ein.
In Kapitel 5 erstellen Sie eine neue Datenbank av, in die Sie die Datensätze
der Datenbank cd übernehmen. Dort finden Sie auch ein Beispiel für die Konstruktion INSERT ... SELECT. Der folgende Steckbrief für die INSERT-Anweisung enthält bereits eine einfache Version.
80
Daten einfügen – INSERT
jetzt lerne ich
Steckbrief: INSERT
Fügt einen neuen Datensatz in eine Tabelle ein.
Beispiele:
(1) INSERT INTO cddata (id, artist, title) VALUES (1234, 'Santana',
'Jingo')
(2) INSERT INTO cddata VALUES('45376816','Donovan',
'The very best of Donovan','0',4250787,20,'Pop',
'CD','',1,'','Sunshine Superman',275027,'','')
(3) INSERT INTO cddata DEFAULT VALUES
(4) INSERT av.cddata SELECT * FROM cd.cddata
(1) Fügt einen neuen Datensatz in die Tabelle cddata ein. Die Felder id, artist und title erhalten die Werte »1234«, »Santana« bzw. »Jingo«; in
die nicht spezifizierten Spalten der Tabelle cddata schreibt das Datenbanksystem Standardwerte (falls für die jeweilige Spalte spezifiziert) oder
NULL.
(2) Fügt einen neuen Datensatz in die Tabelle cddata ein, wobei für jede
Spalte ein Wert anzugeben ist.
(3) Fügt einen neuen Datensatz in die Tabelle cddata ein. In die einzelnen
Spalten werden die Standardwerte eingetragen, die in der Definition der
Tabelle cddata festgelegt sind.
(4) Fügt in die Tabelle cddata der Datenbank av alle Datensätze ein, die mit
der Auswahlanweisung SELECT * FROM ... aus der Tabelle cddata der
Datenbank cd übernommen werden.
Syntax:
INSERT [INTO] {Tabellenname | Sichtname}
[(Spaltenliste)]
{[DEFAULT] VALUES | VALUES (Wert[,...]) | Auswahlanweisung}
Argumente:
– INTO: Schlüsselwort, das in den meisten Implementierungen von Datenbank-Managementsystemen optional ist.
– Tabellenname, Sichtname: Bezeichnet die Tabelle bzw. Sicht, in die der
neue Datensatz einzufügen ist.
– Spaltenliste: Eine optionale Liste der Spalten, für die Werte in der Anweisung angegeben werden. Fehlt die Spaltenliste, muss man Werte für
alle Spalten bereitstellen.
81
3 Daten modifizieren – INSERT, UPDATE und DELETE
jetzt lerne ich
– [DEFAULT] VALUES: Legt fest, dass das Datenbanksystem für alle Spalten
Standardwerte eintragen soll.
– Wert: Für jede in Spaltenliste aufgeführte Spalte bzw. für alle Spalten der
in die jeweilige Spalte einzutragende Wert.
3.2
Daten modifizieren – UPDATE
Die Anweisung UPDATE erlaubt es, gezielt Spaltenwerte einer Tabelle zu ändern. Während INSERT einfach nur einen neuen Datensatz in die Tabelle einfügt, erfüllt die Anweisung UPDATE zwei Aufgaben:
쐽 Suchen der Datensätze, die den spezifizierten Kriterien entsprechen
쐽 Ändern der in der Anweisung angegebenen Werte in den gefundenen
Datensätzen
Wenn Sie in einer INSERT-Anweisung nicht alle Felder eines Datensatzes spezifiziert haben, können Sie die noch fehlenden Felder desselben Datensatzes
nicht im Nachhinein mit einer weiteren INSERT-Anweisung ergänzen. Wie sollte SQL auch den richtigen Datensatz aus der Menge der bereits gespeicherten
finden? Eine FROM-Klausel kennt die INSERT-Anweisung nicht. Ist nun das Unternehmen »Einfügen weiterer Werte in denselben Datensatz« gescheitert?
Natürlich nicht. Änderungen an einem bestehenden Datensatz kann man
über die UPDATE-Anweisung vornehmen.
Die Syntax der Anweisung UPDATE lautet:
UPDATE Tabellenname
SET {Spaltenname | Variablenname} = {DEFAULT | Ausdruck} [,...n]
WHERE Bedingungen
Hier finden Sie auch die WHERE-Klausel, mit der Sie die zu ändernden Datensätze herausfiltern können. Ohne WHERE-Klausel wirkt die UPDATE-Anweisung
auf alle Datensätze der Tabelle.
3.2.1
Werte ändern – SET
Das bestimmende Element der UPDATE-Anweisung ist die SET-Klausel. Was
sich hinter Spaltenname verbirgt, haben Sie sicherlich schon selbst erraten:
Hier spezifizieren Sie die Spalte, die mit dem in Ausdruck angegebenen Wert
zu ändern ist. Im einfachsten Fall weisen Sie der Spalte einen neuen Wert zu,
d.h. überschreiben gegebenenfalls einen schon vorhandenen Wert.
Die Spalte comment ist in allen Datensätzen der Beispieldatenbank leer und
bietet sich für Experimente an. Die folgende Anweisung setzt diese Spalte zunächst für alle CDs auf die Zeichenfolge »Eigene Sammlung«:
82
Daten modifizieren – UPDATE
UPDATE cddata
SET comment = 'Eigene Sammlung'
jetzt lerne ich
Beispiel 3.14
Rufen Sie die Datensätze zur Kontrolle ab:
SELECT id, comment FROM cddata
Beispiel 3.15
+----------+-----------------+
| id
| comment
|
+----------+-----------------+
| 667454 | Eigene Sammlung |
| 667454 | Eigene Sammlung |
| 667454 | Eigene Sammlung |
...
| 49639765 | Eigene Sammlung |
| 49639765 | Eigene Sammlung |
| 49639765 | Eigene Sammlung |
+----------+-----------------+
470 rows in set (0.00 sec)
Die für UPDATE in diesem Kapitel angegebenen Beispiele gehen wieder von
der Installationsversion der Datenbank cd mit 470 Datensätzen aus.
1
Der Ausdruck kann auch die zu aktualisierende Spalte selbst enthalten. Nehmen wir einmal an, Sie möchten die bislang in Millisekunden angegebene
Spielzeit der CDs in Anzahl der Sekunden ausdrücken. Dazu sind die Spalten
totallength und tracklength jeweils durch 1000 zu dividieren. Da sich diese
Operation auf alle Datensätze bezieht, kann die WHERE-Klausel entfallen. Die
UPDATE-Anweisung sieht dann folgendermaßen aus:
UPDATE cddata
SET
totallength = totallength / 1000,
tracklength = tracklength / 1000
Beispiel 3.16
+----------+-------------+-------------+
| id
| totallength | tracklength |
+----------+-------------+-------------+
| 667454 |
648 |
201 |
| 667454 |
648 |
240 |
| 667454 |
648 |
208 |
| 1335934 |
919 |
211 |
...
| 49639765 |
4418 |
233 |
| 49639765 |
4418 |
226 |
| 49639765 |
4418 |
122 |
| 49639765 |
4418 |
342 |
+----------+-------------+-------------+
470 rows in set (0.00 sec)
83
3 Daten modifizieren – INSERT, UPDATE und DELETE
jetzt lerne ich
1
Wie eingangs erwähnt, kann man die Ausführung der UPDATE-Anweisung in
Teile gliedern. Dabei entspricht der erste Teil einer SELECT-Anweisung. Um
sicher zu sein, dass UPDATE auch die richtigen Datensätze aktualisiert, empfiehlt es sich in der Testphase, zur Kontrolle zunächst eine SELECT-Anweisung mit der gleichen WHERE-Bedingung wie in der geplanten UPDATE-Anweisung auszuführen. Damit erhält man alle Datensätze zurück, die letztlich von
der UPDATE-Anweisung beeinflusst werden.
3.2.2
UPDATE mit WHERE-Klausel
Abgesehen von Fällen, wie sie der letzte Abschnitt an einem Beispiel gezeigt
hat, ändert man Datensätze normalerweise nicht im Rundumschlag, sondern
abhängig von bestimmten Kriterien. Die Syntax der UPDATE-Anweisung sieht
deshalb eine WHERE-Klausel vor, in der Sie genau wie bei SELECT bestimmte Bedingungen formulieren können.
Angenommen, Sie haben die Spielzeiten mit der obigen Anweisung durch
1000 dividiert und anschließend neue Datensätze eingefügt. Die Spalten
totallength und tracklength der neuen Datensätze enthalten aber wieder die
Zeiten in Millisekunden. Wenn Sie die einfache UPDATE-Anweisung noch einmal ausführen, werden die bereits durch 1000 dividierten Werte noch einmal
durch 1000 geteilt.
Als Kriterium, ob die Zeiten in einem Datensatz durch 1000 zu teilen sind,
kann man die Gesamtspielzeit (totallength) heranziehen. In den Beispieldatensätzen bewegen sich diese Werte zwischen 648454 und 4747987 Millisekunden. Durch 1000 geteilt ergeben sich Werte zwischen 648 und 4748.
Wenn also in der Spalte totallength ein Wert größer als 4748 steht, muss es
sich um einen neu eingefügten Datensatz handeln, dessen Zeiten anzupassen
sind. Um auf der sicheren Seite zu sein, wählen wir 20000 als Grenzwert und
schreiben die UPDATE-Anweisung wie folgt:
Beispiel 3.17 UPDATE cddata
SET
totallength = totallength / 1000,
tracklength = tracklength / 1000
WHERE totallength > 20000
Diese Anweisung aktualisiert die Spalten totallength und tracklength eines
Datensatzes nur dann, wenn der Wert in totallength größer als 20000 ist
und damit auf einen neuen Datensatz hinweist.
1
84
SQL Server erlaubt in der UPDATE-Anweisung eine FROM-Klausel. Damit ist es
möglich, Spalten aus verschiedenen Tabellen in der Bedingung zu verknüpfen. Kapitel 7 geht näher auf das Thema Verknüpfungen ein. Ebenfalls in
diesem Kapitel geht es um Unterabfragen in der WHERE-Klausel einer UPDATEAnweisung.
Daten löschen – DELETE
jetzt lerne ich
Steckbrief: UPDATE
Modifiziert festgelegte Spaltenwerte bereits vorhandener Datensätze in einer Tabelle oder Sicht.
Beispiele:
(1) UPDATE cddata SET id = '0000' WHERE title LIKE '%xxx%'
(2) UPDATE cddata
SET
totallength = totallength / 1000,
tracklength = tracklength / 1000
WHERE totallength > 20000
(1) Setzt den Wert der Spalte id auf die Zeichenfolge »0000« für alle Datensätze, die in der Spalte title an einer beliebigen Stelle die Zeichenfolge
»xxx« enthalten.
(2) Teilt alle Werte in den Spalten totallength und tracklength durch
1000 für alle Datensätze, die in der Spalte totallength einen Wert größer als 20000 aufweisen.
Syntax:
UPDATE Tabellenname
SET {Spaltenname | Variablenname} = {DEFAULT | Ausdruck} [,...n]
WHERE Bedingungen
Argumente:
– Tabellenname: Gibt die Tabelle an, in der Spaltenwerte zu modifizieren
sind.
– Spaltenname: Bezeichnet die Spalte, deren Werte zu modifizieren sind.
– Variablenname: Eine bereits deklarierte Variable, der das Ergebnis von
Ausdruck zugewiesen wird.
– Ausdruck: Ein einzelner Wert von einer Variablen, einem Literalwert, einem Ausdruck oder einer Unterabfrage.
– Bedingungen: Gibt die Bedingungen an, denen die zu aktualisierenden
Datensätze genügen müssen.
3.3
Daten löschen – DELETE
Die letzte Anweisung der Datenmanipulationssprache hat die einfachste Syntax, aber die radikalste Wirkung: DELETE löscht Datensätze.
Die Syntax ist überschaubar:
DELETE [FROM] Tabellenname [WHERE Bedingungen]
85
jetzt lerne ich
3 Daten modifizieren – INSERT, UPDATE und DELETE
Das Schlüsselwort FROM ist optional; in Tabellenname geben Sie die Tabelle
an, aus der die Datensätze zu löschen sind. Wenn Sie die WHERE-Klausel vergessen, löscht SQL gnadenlos sämtliche Datensätze in der Tabelle. Die Tabelle an sich bleibt zwar erhalten, doch ihr Inhalt landet im Nirwana. In Kapitel
5 lernen Sie mit TRUNCATE TABLE eine Anweisung kennen, die das Gleiche
noch schneller erledigt.
Sinnvoll ist DELETE also nur zusammen mit der WHERE-Klausel, um einzelne
Datensätze zu löschen, die beispielsweise veraltet oder infolge einer Aktualisierung ungültig geworden sind.
Wenn Sie die weiter oben mit INSERT eingefügten Titel wieder löschen möchten, führen Sie folgende Anweisung aus:
Beispiel 3.18 DELETE FROM cddata
WHERE id = 45376816
Das Ergebnis ist genauso unspektakulär wie die DELETE-Anweisung selbst:
Query OK, 1 row affected (0.28 sec)
Falls Sie mehrere Datensätze für die CD mit der ID 45376816 eingefügt haben, erscheinen entsprechend mehr Spalten in der Meldung.
2
Überlegen Sie genau, welche Auswirkung die DELETE-Anweisung auf die Tabelle hat und haben könnte. Im Beispiel ist die WHERE-Bedingung mit der
Spalte id formuliert, die eindeutige Werte enthält. Wenn Sie als Bedingung
WHERE artist like '%donovan%'
angeben, löschen Sie zwar in der hier verwendeten Beispieltabelle nur die
Datensätze, die Sie zuletzt mit den weiter oben vorgestellten INSERT-Anweisungen in die Datenbank eingefügt haben (weil es keine anderen DonovanTitel in der Datenbank gibt), bei einer größeren Sammlung können aber
durchaus mehrere CDs betroffen sein.
Der Abschnitt zur UPDATE-Anweisung hat bereits darauf hingewiesen, dass es
gerade in der Testphase sinnvoll ist, zunächst eine SELECT-Anweisung mit
identischer WHERE-Klausel auszuführen und erst nach positivem Befund die
DELETE-Anweisung auszulösen. Eine hundertprozentige Sicherheit gegen
Überraschungen bietet das zwar nicht, weil auch Datensätze hinzukommen
können, die Sie mit der SELECT-Anweisung für den aktuellen Datenbestand
noch nicht »erwischt« haben, doch sind Ihre Sinne auf jeden Fall sensibilisiert, wenn Sie feststellen mussten, dass die zweite Version auch andere CDs
betreffen kann, während die erste Version mit eindeutiger ID in der WHEREKlausel sicher ist.
86
Daten importieren
Auch für die DELETE-Anweisung bietet SQL Server eine FROM-Klausel (nicht
zu verwechseln mit dem optionalen Schlüsselwort FROM unmittelbar nach
DELETE, um Spalten aus verschiedenen Tabellen in der Bedingungsklausel zu
verknüpfen). Mehr dazu finden Sie in Kapitel 7.
jetzt lerne ich
1
Steckbrief: DELETE
Löscht Datensätze aus einer Tabelle oder Sicht.
Beispiel:
DELETE FROM cddata
WHERE id = '123456'
Löscht aus der Tabelle cddata alle Datensätze, die in der Spalte id den Wert
'123456' enthalten.
Syntax:
DELETE [FROM] {Tabellenname | Sichtname}
WHERE Bedingungen
Argumente:
– FROM: Im SQL99-Standard und SQL Server optionales Schlüsselwort.
– Tabellenname oder Sichtname: Die Tabelle bzw. die Sicht, aus der die
Datensätze zu löschen sind.
– Bedingungen: Gibt die Bedingungen an, die die zu löschenden Datensätze erfüllen müssen.
3.4
Daten importieren
Normalerweise – d.h. mit den im ANSI-Standard definierten Anweisungen –
können Sie jeweils nur einen einzelnen Datensatz in eine Tabelle einfügen
(sieht man einmal davon ab, dass sich mit INSERT auch mehrere Datensätze
von einer Tabelle in eine andere übertragen lassen). Für jeden einzufügenden
Datensatz müssen Sie eine INSERT-Anweisung erzeugen und ausführen. Bei
einer kleinen Beispieldatenbank fällt dieser Aufwand kaum ins Gewicht.
Wenn Sie aber Tausende oder Millionen Datensätze aus externen Quellen einlesen möchten, ist die einfache INSERT-Anweisung umständlich und verschlingt ziemlich viel Zeit, da alle bisher vorgestellten Anweisungen protokolliert werden. Das Datenbanksystem führt sozusagen Buch darüber, was alles
mit der Datenbank passiert, um im Falle eines Absturzes die protokollierten
Operationen erneut ausführen und die Datenbank in den Zustand vor dem
Absturz wiederherstellen zu können.
87
jetzt lerne ich
3 Daten modifizieren – INSERT, UPDATE und DELETE
Wenn aber die Daten ohnehin in einer externen Quelle vorliegen, könnte
man selbst bei einem Absturz der Datenbank erneut auf diese Daten zugreifen
und sie noch einmal einlesen. Nach der nächsten Komplettsicherung der
Datenbank kann man dann auch die Quelldaten löschen. Wozu also der Aufwand, jeden einzelnen Datensatz beim Einfügen zu protokollieren?
Genau für diesen Zweck bieten fast alle Datenbanksysteme Anweisungen für
so genannte Massenoperationen. Diese werden zwar nicht protokolliert, laufen aber ungleich schneller ab. Auch wenn der ANSI-Standard solche Anweisungen nicht vorsieht, sollten Sie sie kennen, weil sich damit das Einfügen
großer Datenmengen effizienter realisieren lässt: MySQL stellt die Anweisung
LOAD DATA INFILE bereit, in SQL Server heißt die vergleichbare Anweisung
BULK INSERT.
Dieser Abschnitt erläutert, wie die Daten für die Beispieldatenbank cd mit diesen Anweisungen erzeugt wurden.
Damit sich Massenoperationen ausführen lassen, brauchen Sie eine geeignete Datenquelle, in der die Daten im benötigten Format vorliegen. Die aus der
Datenbank von http://www.cdarchiv.de abgerufenen Daten wurden zunächst
als Textdatei gespeichert und dann mithilfe eines kleinen Visual Basic-Programms zeilenweise in die Datei cddata.txt übernommen. Diese Textdatei
hat folgenden Inhalt (Ausschnitt):
667454왘Sixpence None The Richer왘Kiss me왘0왘648454왘3왘Rock/Pop왘Maxi
CD왘왘1왘왘Kiss me (Radio Remix)왘201094왘왘왘
667454왘Sixpence None The Richer왘Kiss me왘0왘648454왘3왘Rock/Pop왘Maxi
CD왘왘2왘왘Sad but true (Previously unreleased)왘239641왘왘왘
667454왘Sixpence None The Richer왘Kiss me왘0왘648454왘3왘Rock/Pop왘Maxi
CD왘왘3왘왘Kiss me (Live in Hollywood)왘207721왘왘왘
1335934왘Marque왘One to make her happy왘0왘919054왘4왘Rock/Pop왘Maxi
CD왘왘1왘왘One to make her happy (Radio Edit)왘211294왘왘왘
Wenn Sie die Datei cddata.txt in einem Editor öffnen, sieht sie etwas anders
aus als hier dargestellt. Zur Verdeutlichung steht im obigen Ausschnitt das Zeichen 왘 anstelle des Tabulatorzeichens, das in einem Editor nicht als Zeichen
an sich sichtbar ist.
Jeder Datensatz stellt die Werte für einen Titeleintrag in der Datenbank cd
dar. Das Tabulatorzeichen trennt die einzelnen Felder eines Datensatzes.
Wenn ein Feld keine Daten enthält, schließt sich gleich das Tabulatorzeichen
als Trennzeichen zum nächsten Feld an. Eine Zeile wird durch das Zeichen für
Neue Zeile beendet; der nächste Titeleintrag beginnt damit am Anfang der
nächsten Zeile.
88
Daten importieren
jetzt lerne ich
Dieses Format – Trennung der einzelnen Felder durch Tabulatorzeichen, Zeilenabschluss durch Zeichen für neue Zeile – ist gleichzeitig das Standardformat, das die im Buch verwendeten Datenbanksysteme und auch andere Systeme als Format für die Übernahme von Textdaten in programmeigene
Datenformate verwenden.
3.4.1
Daten importieren – MySQL
Die MySQL-Anweisung LOAD DATA INFILE bietet die Möglichkeit, Daten aus
einer (Text-) Datei in eine Tabelle zu importieren:
LOAD DATA INFILE "C:/JLISQL/Data/CDData.txt"
INTO TABLE cddata;
Beispiel 3.19
In dieser Form verwendet die Anweisung Standardwerte für die Zeichen, mit
denen die einzelnen Felder in der Textdatei voneinander getrennt sind (Tabulatoren zwischen den Feldern, Zeichen für neue Zeile am Ende der Zeile).
Wenn Sie in der Textdatei andere Trennzeichen verwenden, können Sie das
in der LOAD DATA INFILE-Anweisung wie folgt spezifizieren:
LOAD DATA INFILE "C:/JLISQL/Data/CDIntro.txt"
INTO TABLE cddata
FIELDS
TERMINATED BY ','
ENCLOSED BY '"';
Beispiel 3.20
Das Schlüsselwort FIELDS leitet die Spezifikation für die Feldtrennzeichen ein.
Die Klausel TERMINATED BY gibt das Trennzeichen zwischen den einzelnen Feldern an (im Beispiel ein Komma). Mit ENCLOSED BY können Sie festlegen, in
welche Begrenzer Zeichenfolgen eingeschlossen sind. Wenn die zu importierende Zeichenfolge ein Feldtrennzeichen (im Beispiel das Komma) enthält,
würde dieses als Trennzeichen zwischen zwei Feldern interpretiert, was verständlicherweise zu Fehlern führt. In so einem Fall umschließt man die Zeichenfolge meistens mit Anführungszeichen. Die Importanweisung ignoriert
dann die zwischen dem ersten und zweiten Anführungszeichen in der Zeichenfolge enthaltenen Trennzeichen.
Wenn die importierten Datensätze nicht für alle Felder einen Wert enthalten,
schreibt MySQL in die leeren Spalten den Wert '' (eine leere Zeichenfolge).
Falls Sie den Wert NULL in leere Spalten eintragen möchten, müssen Sie das
in der Textdatei mit \N kennzeichnen.
89
3 Daten modifizieren – INSERT, UPDATE und DELETE
jetzt lerne ich
3.4.2
Daten importieren – SQL Server
Die zu LOAD DATA INFILE vergleichbare Anweisung in SQL Server heißt BULK
INSERT.
Beispiel 3.21 BULK INSERT cddata
FROM "C:\JLISQL\Data\CDDataS.txt"
Als Standardtrennzeichen verwendet SQL Server genau wie MySQL das
Tabulatorzeichen (\t) und als Zeilenabschlusszeichen das Zeichen für neue
Zeile (\n). Um andere Zeichen zu spezifizieren, leiten Sie mit dem Schlüsselwort WITH einen Block für optionale Werte ein (vergleichbar mit FIELDS in der
MySQL-Anweisung LOAD DATA INFILE). Das Feldtrennzeichen legen Sie mit
FIELDTERMINATOR und das Zeilenabschlusszeichen mit ROWTERMINATOR fest. Eine
Option analog zu ENCLOSED BY von MySQL ist in BULK INSERT nicht verfügbar.
Standardmäßig gilt das Anführungszeichen.
Die folgende Anweisung legt das Komma als Feldtrennzeichen fest; für die übrigen Optionen gelten die Standardwerte:
Beispiel 3.22 BULK INSERT cddata
FROM "C:\JLISQL\Data\CDDataS.txt"
WITH (
FIELDTERMINATOR=','
)
Die Anweisung BULK INSERT kennt noch eine ganze Reihe weiterer Optionen,
auf die wir aber im Rahmen dieser Einführung nicht eingehen und auf die
Dokumentation zu SQL Server verweisen.
1
Beispiel 3.23
SQL Server bietet mit bcp (bulk copy program) ein Kommandozeilenwerkzeug, das es nicht nur erlaubt, Datensätze in eine Datenbank zu importieren,
sondern auch aus einer Datenbank zu exportieren. Die Formate für das Importieren bzw. Exportieren lassen sich mit unzähligen Schaltern auf der Befehlszeile sowie über eine Formatdatei steuern.
bcp CD..CDData in CDData.csv -t, -Spro -T
Gerade diese vielfältigen Möglichkeiten sind es aber auch, die bcp zur Glaubensfrage werden lassen. Es ist oftmals nicht ganz einfach, die richtige Kombination von Parametern für einen bestimmten Anwendungsfall zu finden.
Probleme tauchen vor allem bei Datumswerten, Zeichenfolgen mit Feldtrennzeichen und der Konvertierung von Datentypen auf.
Das Programm bcp stammt noch aus den Anfangstagen von SQL Server.
Inzwischen steht mit den Data Transformation Services (DTS) ein grafisch
orientiertes und äußerst flexibles Werkzeug zur Verfügung, mit dem sich unter anderem Daten aus heterogenen Quellen importieren und auch wieder
exportieren lassen.
90
Zusammenfassung
3.5
jetzt lerne ich
Zusammenfassung
Dieses Kapitel hat die Anweisungen INSERT, UPDATE und DELETE behandelt, die
zur Kategorie der Datenmanipulationssprache (DML) von SQL gehören.
INSERT fügt jeweils einen neuen Datensatz ein. Man kann entweder alle oder
ausgewählte Werte bereitstellen. Für nicht spezifizierte Spalten setzt das
Datenbanksystem automatisch Standardwerte ein. Je nachdem, wie die Anweisung formuliert ist, handelt es sich dabei um den besonderen Wert NULL für
unbekannte Daten bzw. 0 für Zahlenspalten und die leere Zeichenfolge für
Zeichenspalten. Man kann aber auch eigene Standardwerte in der Tabellendefinition festlegen (siehe Kapitel 5). Die Anweisung UPDATE erlaubt es, einen
oder mehrere Werte in bereits vorhandenen Datensätzen zu ändern. In der
WHERE-Klausel der UPDATE-Anweisung legt man die Kriterien fest, für welche
Datensätze die Änderungen wirksam werden. Die Anweisung DELETE löscht
vollständige Datensätze aus einer Tabelle. Dabei ist besonders auf die richtige
Formulierung der WHERE-Klausel zu achten, damit nicht versehentlich die falschen oder zu viele Datensätze gelöscht werden.
Schließlich ist dieses Kapitel kurz auf die Anweisungen zum Masseneinfügen
eingegangen, die zwar nicht im ANSI-Standard vorgesehen, aber in vielen
Datenbanksystemen realisiert sind. In MySQL handelt es sich um die Anweisung LOAD DATA INFILE, SQL Server stellt die Anweisung BULK INSERT bereit.
3.6
Kontrollfragen
1. Muss man eine längere SQL-Anweisung auf ein und derselben Zeile eingeben oder kann man sie auf mehrere Zeilen aufteilen?
2. Wenn man einen Datensatz mit INSERT einfügt und nur bestimmte Spaltenwerte bereitstellt, kann man dann mit der Klausel DEFAULT VALUES erreichen, dass die übrigen Spalten Standardwerte erhalten?
3. Kann man mit zwei unmittelbar nacheinander ausgeführten INSERT-Anweisungen in der ersten Anweisung z.B. zwei Werte und in der zweiten
Anweisung nochmals drei Werte in denselben neuen Datensatz einfügen?
4. Müssen die Spalten in der Spaltenliste einer INSERT-Anweisung in der Reihenfolge erscheinen, wie sie durch die Tabellendefinition festgelegt ist?
5. Wie lässt sich in einer INSERT-Anweisung erreichen, dass eine bestimmte
Spalte den Wert NULL erhält?
6. Kann man sich auf die Aussage »der boolesche Wert TRUE wird durch 1
dargestellt, der boolesche Wert FALSE durch 0« in jedem Fall verlassen?
91
3 Daten modifizieren – INSERT, UPDATE und DELETE
jetzt lerne ich
7. Gehört die WHERE-Klausel zu den obligatorischen Elementen einer UPDATEAnweisung?
8. Erlaubt die DELETE-Anweisung, einzelne Spalten einer Tabelle zu löschen?
3.7
Übungen
1. Schreiben Sie INSERT-Anweisungen, um die Titel der im Kapitel bereits erwähnten Donovan-CD in die Tabelle cddata einzufügen. Die Daten für diese CD finden Sie im Verzeichnis \JLISQL\Data in der Datei Donovan.txt.
Hinweis: Die Felder der einzelnen Datensätze sind durch Tabulatoren
getrennt. Wenn Sie die Datei in Ihrem Editor öffnen und unter einem anderen Namen wie zum Beispiel Donovan.sql speichern (um die Datei
Donovan.txt unverändert für Übung 2 verfügbar zu haben), brauchen Sie
nur noch die erforderlichen SQL-Elemente für die einzelnen INSERT-Anweisungen vor bzw. hinter die Datensätze zu schreiben und das Format
der Datensätze anzupassen (z.B. Tabulatoren durch Kommas ersetzen und
Anführungszeichen ergänzen). Beschränken Sie sich auf zwei oder drei
Datensätze und löschen Sie die anderen. Die Datei Donovan.sql können
Sie dann ausführen, wie es Kapitel 1 für die Installationsskripts beschrieben hat.
2. Schreiben Sie für das von Ihnen verwendete Datenbank-Managementsystem eine Anweisung zum Masseneinfügen, um alle Datensätze der Datei
Donovan.txt (siehe Übung 1) in die Tabelle cddata der Datenbank cd einzulesen.
3. Schreiben Sie eine UPDATE-Anweisung, um die in Millisekunden angegebenen Zeitwerte in Minuten umzuwandeln. Formulieren Sie die Anweisung
so, dass Sie sie mehrfach ausführen können, ohne dass bereits geänderte
Werte noch einmal geändert werden.
4. Löschen Sie die in den Übungen 1 bzw. 2 eingefügten Datensätze aus der
Tabelle cddata. Vergewissern Sie sich, dass die Tabelle wieder 470 Datensätze (wie nach der Installation) enthält.
92
Herunterladen