Berechnungen in UPDATE
Der neue Wert in SET muss nicht fest sein. Er kann berechnet werden, sogar aus den eigenen Werten der Zeile. Wenn der Shop den Preis aller Sportspiele um 5 € erhöht, muss er ihre Preise nicht kennen:
UPDATE spiele
SET preis = preis + 5
WHERE genre = 'Sport';Für jede Zeile, die WHERE findet, nimmt SQLite den aktuellen Preis, addiert 5 und speichert das Ergebnis als neuen Preis: Goal Rush steigt von 50 € auf 55 €, Ice Hockey Pro von 45 € auf 50 €. Du kannst jede Berechnung und jede Funktion verwenden, die du kennst, und wenn du mehrere Spalten änderst, kann jede ihre eigene haben: SET preis = preis - 10, altersfreigabe = 12. Alle Berechnungen verwenden die Werte, die die Zeile vor dem UPDATE hatte.
Nun ein Rabatt von 10 % auf die Actionspiele. Ihr neuer Preis ist 90 % des alten, also multiplizierst du ihn mit 0.9:
UPDATE spiele
SET preis = preis * 0.9
WHERE genre = 'Action';Error on line 1: cannot store REAL value in INTEGER column spiele.preisDie Tabellen von Pixel Shop sind STRICT: Jede Spalte nimmt nur Werte ihres Typs auf, und preis ist ein INTEGER, eine Ganzzahl. Shadow Ninja kostet 25 €, und 90 % davon sind 22.5, eine Dezimalzahl (REAL), die die Spalte nicht aufnehmen kann. Also lehnt die Datenbank die ganze Anweisung ab, und kein Spiel bekommt einen neuen Preis, nicht einmal Zombie Town, dessen neuer Preis ein glatter Wert von 27 € wäre. Eine Anweisung ändert entweder jede Zeile, die sie ändern soll, oder keine.
Die Lösung ist ROUND(), das du aus der Lektion über Funktionen kennst. ROUND(preis * 0.9) ergibt für Shadow Ninja 23.0. Das ist immer noch eine Dezimalzahl, aber eine ohne Nachkommastellen, und so eine Zahl passt in eine INTEGER-Spalte, wo sie als 23 gespeichert wird:
UPDATE spiele
SET preis = ROUND(preis * 0.9)
WHERE genre = 'Action';
SELECT titel, preis
FROM spiele
WHERE genre = 'Action';| titel | preis |
|---|---|
| Shadow Ninja | 23 |
| Star Pilots | 32 |
| Zombie Town | 27 |
| Robot Rebellion | 36 |
Ohne STRICT würde SQLite 22.5 trotzdem in der Spalte speichern, und andere Datenbanken wie PostgreSQL oder MySQL würden stillschweigend runden. Der Fehler ist besser: Du entscheidest, wie gerundet wird. Pass auch bei der Division auf: preis / 2 teilt zwei Ganzzahlen, also ergibt es, wie du weißt, eine Ganzzahl und lässt den Rest weg, ohne jeden Fehler (15 / 2 ist 7).
Manchmal brauchen verschiedene Zeilen verschiedene Änderungen. Ein UPDATE kann sie mit CASE vornehmen, das jeder Zeile ihren eigenen neuen Wert gibt. Hier werden die Puzzlespiele um 2 € teurer und die Rennspiele um 5 €:
UPDATE spiele
SET preis = CASE
WHEN genre = 'Puzzle' THEN preis + 2
ELSE preis + 5
END
WHERE genre IN ('Puzzle', 'Rennspiel');Typischer Fehler: ein CASE ohne ELSE. Für die Zeilen, die zu keinem WHEN passen, ergibt CASE den Wert NULL, also würden die Rennspiele ihre Preise verlieren. Hier lehnt die Datenbank das mit NOT NULL constraint failed: spiele.preis ab, aber in einer Spalte, die NULL erlaubt, würden die Werte stillschweigend verschwinden. Wenn eine Zeile ihren Wert behalten soll, schreibe ELSE preis.
So schreibst du es:
Anweisungen
- 1
Das
UPDATEim Editor soll den Strategiespielen 15 % Rabatt geben, aber die Datenbank lehnt es ab. Führe es aus, lies den Fehler und korrigiere dasUPDATE, sodass die neuen Preise auf ganze Euro gerundet werden. Zeige darunter den Titel und den Preis der Strategiespiele, sortiert nach dem Preis:titel preis Tiny Kingdoms 21 Castle Siege 26 Galaxy Trader 30 - 2
Auch die Adventures werden abverkauft: Die, die mehr als 15 € kosten, werden um 5 € billiger, die anderen um 3 €. Nimm unter der Abfrage beide Änderungen in einem
UPDATEmitCASEvor. - 3
Zeige danach den Titel und den Preis der Adventures, sortiert nach dem Titel:
titel preis Lost Temple 15 Mystery Manor 20 Ocean Deep 12