VOICE-Homepage: http://de.os2voice.org |
Juni 2004
Inhaltsverzeichnis
|
Von Wolfgang Draxler © Juni 2004 |
Heute werden wir uns die SQL-Befehle »Update« und »Delete« genauer anschauen.
Aber bevor wir mit diesen beiden Befehlen beginnen, gibt es noch eine kleine Ergänzung zum SQL-Befehl »select«. Denn wenn Sie sich den Aufbau im letzten Teil noch einmal anschauen, werden Sie bemerken, daß ich die »order by«-Klausel nicht erwähnt habe. Dies hole ich natürlich jetzt nach.
Die »order by«-Klausel sortiert die Datensätze nach den angegebenen Felder. Dabei kann man die Sortierreihenfolge jedes einzelnen Feldes mittels »asc« (ascending = aufsteigend) und »desc« (descending = absteigend) angeben. Wenn Sie »asc« bzw. »desc« nicht angeben, dann ist die Sortierreihenfolge immer aufsteigend (also »asc«).
Als erstes werden wir den Befehl ohne »order by« aufrufen.
mysql> select * from land; +---------+-------------------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------------------+---------+ | A | Österreich | +43 | | D | Deutschland | +49 | | CH | Schweiz | +41 | | GB | Großbritannien | +44 | | USA | United States of America| +1 | | I | Italien | +39 | | H | Ungarn | +36 | | NL | Niederlande | NULL | | L | Luxemburg | NULL | | B | Belgien | NULL | +---------+-------------------------+---------+ 10 rows in set (0.07 sec)
Und nun mit der ersten »Order«-Klausel:
mysql> select * from land order by kurzbez; +---------+-------------------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------------------+---------+ | A | Österreich | +43 | | B | Belgien | NULL | | CH | Schweiz | +41 | | D | Deutschland | +49 | | GB | Großbritannien | +44 | | H | Ungarn | +36 | | I | Italien | +39 | | L | Luxemburg | NULL | | NL | Niederlande | NULL | | USA | United States of America| +1 | +---------+-------------------------+---------+ 10 rows in set (0.06 sec)
Wie man sieht, werden die Datensätze nun nach der Kurzbezeichnung aufsteigend sortiert. Man kann den Befehl natürlich auch folgendermaßen angeben:
mysql> select * from land order by kurzbez asc;
Wenn Sie die umgekehrte Reihenfolge haben wollen, dann sieht das ganze so aus:
mysql> select * from land order by kurzbez desc; +---------+-------------------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------------------+---------+ | USA | United States of America| +1 | | NL | Niederlande | NULL | | L | Luxemburg | NULL | | I | Italien | +39 | | H | Ungarn | +36 | | GB | Großbritannien | +44 | | D | Deutschland | +49 | | CH | Schweiz | +41 | | B | Belgien | NULL | | A | Österreich | +43 | +---------+-------------------------+---------+ 10 rows in set (0.00 sec)
Wie schon besprochen kann man auch mehrere Felder angeben und bei jedem Feld die Sortierreihenfolge selber bestimmen. Beispielsweise so:
mysql> select * from land order by bezeichnung asc, kurzbez desc; +---------+-------------------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------------------+---------+ | B | Belgien | NULL | | D | Deutschland | +49 | | GB | Großbritannien | +44 | | I | Italien | +39 | | L | Luxemburg | NULL | | NL | Niederlande | NULL | | A | Österreich | +43 | | CH | Schweiz | +41 | | H | Ungarn | +36 | | USA | United States of America| +1 | +---------+-------------------------+---------+ 10 rows in set (0.00 sec)
(Der Befehl ist nicht gerade schön, aber mir ist keine sinnvolle Kombination eingefallen
Für »schreibfaule«: man kann statt der Feldnamen auch die Spaltennummer des Ergebnisses angeben, dann sieht der Befehl folgendermaßen aus:
mysql> select * from land order by 2 asc, 1 desc; +---------+-------------------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------------------+---------+ | B | Belgien | NULL | | D | Deutschland | +49 | | GB | Großbritannien | +44 | | I | Italien | +39 | | L | Luxemburg | NULL | | NL | Niederlande | NULL | | A | Österreich | +43 | | CH | Schweiz | +41 | | H | Ungarn | +36 | | USA | United States of America| +1 | +---------+-------------------------+---------+ 10 rows in set (0.01 sec)
Nur sehr schön ist das nicht. Außerdem ist es nicht sehr leserlich (überhaupt durch den Stern-Platzhalter). Zudem könnten sich bei späterer Änderung der Struktur der Tabelle Sortierfehler einschleichen. Deswegen sollte man die Feldnamen unbedingt angeben. Das sähe in diesem Fall folgendermaßen aus:
mysql> select kurzbez, bezeichnung, vorwahl from land order by 2 asc, 1 desc;
Natürlich läßt sich die »Where«-Bedingung mit der »Order by«-Klausel kombinieren, z.B. so:
mysql> select * from land where vorwahl is null order by kurzbez; +---------+-------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------+---------+ | B | Belgien | NULL | | L | Luxemburg | NULL | | NL | Niederlande | NULL | +---------+-------------+---------+ 3 rows in set (0.01 sec)
MySQL - und auch andere SQL-Server - verarbeiten zuerst die Bedingungen, und erst zum Schluß wird das Ergebnis nach den Angaben der »order by«-Klausel sortiert.
Nun werden wir auf die anderen beiden Befehle eingehen, auch wenn ich den Befehl »select« noch nicht vollständig erläutert habe. Denn es fehlen noch die »Gruppier«-Klauseln, Verschachtelungen von Tabellen und die Verknüpfungen von verschiedenen Tabellen. Nur mit dieser einen Tabelle bzw. mit diesen Daten gibt es keine vernünftigen Beispiele dazu. Wenn es notwendig sein sollte, werde ich zu einem späteren Zeitpunkt darauf eingehen.
Der prinzipiell Aufbau des »update«-Befehls ist:
update <Tabelle> set <Feld> = <Wert>, [<Feld> = <Wert>, ...] [where <Bedingung>]
Es sieht komplizierter aus, als es in Wirklichkeit ist. Man gibt an, um welche Tabelle es sich handelt und welche Felder geändert werden sollen (der »set«-Teil«). Die »where«-Bedingung besagt nur, um welche Sätze es sich handelt. Gibt man diese nicht an, so werden alle Sätze geändert. Deswegen sollte man immer darauf achten, eine sinnvolle »where«-Bedingung anzugeben. Ansonsten kann das Ergebnis ganz anders aussehen, als man es sich vorgestellt hat, und die Korrektur kann sehr viel Zeit in Anspruch nehmen.
Nun werden wir gleich ein Beispiel ausprobieren:
mysql> update land set vorwahl="+32" where kurzbez="B"; Query OK, 1 row affected (0.01 sec) Datensätze gefunden: 1 Geändert: 1 Warnungen: 0
Der Befehl macht nichts anderes als die Vorwahl von Belgien von NULL auf »+32« zu ändern. Um dies zu überprüfen, führen wir folgenden Select-Befehl aus:
mysql> select * from land where kurzbez = "B"; +---------+-------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------+---------+ | B | Belgien | +32 | +---------+-------------+---------+ 1 row in set (0.00 sec)
Wie Sie sehen können, hat es auch geklappt.
Der Server geht dabei folgendermaßen vor:
Ermittlung der benötigen Tabellen
Ausführen der Where-Bedingung und eine interne Ergebnisliste erstellen
Aus dieser Liste die Sätze einlesen
Die angegeben Felder ändern
Um diese Vorgehensweise noch besser aufzuzeigen, schauen wir uns folgendes Beispiel an:
mysql> select * from land where vorwahl is null; +---------+-------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------+---------+ | NL | Niederlande | NULL | | L | Luxemburg | NULL | +---------+-------------+---------+
Wie man sieht, haben die Niederlande und Luxemburg keine Vorwahl. Jetzt werden wir bei diesen
beiden Länder den Text gleichzeitig in »K.A.« (heißt »Keine
Angabe«) ändern. Dazu verwenden wir die »where«-Bedingung des
»Select«-Befehls (also »where vorwahl is null«
) und bauen
diese in den »update«-Befehl ein. Dadurch entsteht folgender Befehl:
mysql> update land -> set vorwahl = 'K.A.' -> where vorwahl is null; Query OK, 2 rows affected (0.01 sec) Datensätze gefunden: 2 Geändert: 2 Warnungen: 0
Und als Beweis rufen wir wieder den »Select«-Befehl auf.
mysql> select * from land where vorwahl is null; Empty set (0.03 sec)
Das Ergebnis - oder besser gesagt, das fehlende Ergebnis - ist nun korrekt, denn es gibt jetzt kein Land, daß bei der Vorwahl keinen Wert (also nicht null) hat. Um dies zu untermauern, führen wir folgenden Befehl aus:
mysql> select * from land; +---------+-------------------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------------------+---------+ | A | Österreich | +43 | | D | Deutschland | +49 | | CH | Schweiz | +41 | | GB | Großbritannien | +44 | | USA | United States of America| +1 | | I | Italien | +39 | | H | Ungarn | +36 | | NL | Niederlande | K.A. | | L | Luxemburg | K.A. | | B | Belgien | +32 | +---------+-------------------------+---------+ 10 rows in set (0.00 sec)
Wie Sie nun sehen können, hat jedes Land einen Wert, und bei genauerem Hinsehen werden Sie sicherlich bemerken, daß die Niederlande und Luxemburg den Wert »K.A.« haben.
Nun werden wir bei diesen beiden Ländern das Feld »vorwahl« mit den korrekten Werten befüllen, und zwar mit:
mysql> update land -> set vorwahl="+352" -> where kurzbez="L"; Query OK, 1 row affected (0.02 sec) Datensätze gefunden: 1 Geändert: 1 Warnungen: 0
mysql> update land -> set vorwahl="+31" -> where kurzbez="NL"; Query OK, 1 row affected (0.02 sec) Datensätze gefunden: 1 Geändert: 1 Warnungen: 0
Nun ist das Ergebnis:
mysql> select * from land; +---------+-------------------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------------------+---------+ | A | Österreich | +43 | | D | Deutschland | +49 | | CH | Schweiz | +41 | | GB | Großbritannien | +44 | | USA | United States of America| +1 | | I | Italien | +39 | | H | Ungarn | +36 | | NL | Niederlande | +31 | | L | Luxemburg | +352 | | B | Belgien | +32 | +---------+-------------------------+---------+ 10 rows in set (0.00 sec)
Es lassen sich auch mehrere Felder in einem »Update«-Befehl ändern. (Dies bezieht sich natürlich auf alle gefunden Datensätze.) Dies geschieht im »Set«-Teil, und die Felder werden dabei durch ein Komma getrennt.
Als Beispiel:
mysql> update land -> set kurzbez="Oe", bezeichnung="OESTERREICH", vorwahl="K.A." -> where kurzbez="A"; Query OK, 1 row affected (0.02 sec) Datensätze gefunden: 1 Geändert: 1 Warnungen: 0
Dann wäre das Ergebnis:
mysql> select * from land; +---------+-------------------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------------------+---------+ | Oe | OESTERREICH | K.A. | | D | Deutschland | +49 | | CH | Schweiz | +41 | | GB | Großbritannien | +44 | | USA | United States of America| +1 | | I | Italien | +39 | | H | Ungarn | +36 | | NL | Niederlande | +31 | | L | Luxemburg | +352 | | B | Belgien | +32 | +---------+-------------------------+---------+ 10 rows in set (0.00 sec)
Um wieder alles in Ordnung zu bringen, führen wir folgenden Befehl aus:
mysql> update land -> set kurzbez="A", Bezeichnung ="Österreich", vorwahl="+43" -> where kurzbez = "Oe"; Query OK, 1 row affected (0.00 sec) Datensätze gefunden: 1 Geändert: 1 Warnungen: 0
mysql> select * from land; +---------+-------------------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------------------+---------+ | A | Österreich | +43 | | D | Deutschland | +49 | | CH | Schweiz | +41 | | GB | Großbritannien | +44 | | USA | United States of America| +1 | | I | Italien | +39 | | H | Ungarn | +36 | | NL | Niederlande | +31 | | L | Luxemburg | +352 | | B | Belgien | +32 | +---------+-------------------------+---------+ 10 rows in set (0.00 sec)
Gott sei Dank, die Welt sieht wieder in Ordnung aus.
Nun werden wir uns noch mit dem »Delete«-Befehl befassen.
Dieser Befehl löscht Datensätze aus einer Tabelle. Der Aufbau ist relativ einfach:
delete from <Tabelle> [where <Bedingung>]
Man kann auch eine Gruppe von Datensätzen oder auch alle Datensätze löschen. Dies hängt wie beim Select-Befehl bzw. Update-Befehl von der Where-Bedingung ab. Läßt man die Where-Bedingungen weg, so löscht MySQL alle Datensätze aus der angegebenen Tabelle. Deswegen sollten Sie unbedingt (wie auch beim Update-Befehl) darauf achten, wie Sie mit der Where-Bedingung umgehen.
Als Beispiel werden wir das Land Österreich löschen (und danach wieder anlegen).
mysql> delete from land where kurzbez='A'; Query OK, 1 row affected (0.03 sec)
Nun werden wir uns anschauen, ob das Land wirklich gelöscht wurde.
mysql> select * from land; +---------+-------------------------+---------+ | kurzbez | bezeichnung | vorwahl | +---------+-------------------------+---------+ | D | Deutschland | +49 | | CH | Schweiz | +41 | | GB | Großbritannien | +44 | | USA | United States of America| +1 | | I | Italien | +39 | | H | Ungarn | +36 | | NL | Niederlande | +31 | | L | Luxemburg | +352 | | B | Belgien | +32 | +---------+-------------------------+---------+ 9 rows in set (0.00 sec)
Siehe da, es ist wirklich gelöscht worden, und auch die Anzahl der Sätze hat sich um 1 verringert.
Nun werden wir wieder den Satz anlegen.
mysql> insert into land values ('A', 'Österreich', '+43'); Query OK, 1 row affected (0.02 sec)
So, jetzt sind wieder alle Sätze in der Tabelle vorhanden.
Damit beende ich auch diesen Artikel, und im nächsten werden wir mit einem kleinen REXX-Programm starten, daß diese Tabelle einliest.
Daten und Quellen:
|
Artikelverzeichnis
editor@os2voice.org
< Vorherige Seite | Inhaltsverzeichnis | Nächste Seite >
VOICE-Homepage: http://de.os2voice.org