Výpočty v UPDATE

Nová hodnota v SET nemusí být pevně daná. Může se vypočítat, a to i z hodnot samotného řádku. Když obchod zdraží všechny sportovní hry o 100 Kč, nemusí znát jejich ceny:

UPDATE hry
SET cena = cena + 100
WHERE zanr = 'Sportovní';

U každého řádku, který WHERE najde, vezme SQLite jeho současnou cenu, přičte 100 a výsledek uloží jako novou cenu: cena Goal Rush stoupne z 1299 Kč na 1399 Kč a Ice Hockey Pro z 1199 Kč na 1299 Kč. Použít můžete jakýkoli výpočet a jakoukoli funkci, kterou znáte, a když měníte několik sloupců, každý může mít svůj vlastní: SET cena = cena - 200, vek_od = 12. Všechny výpočty pracují s hodnotami, které měl řádek před UPDATE.

Teď sleva 10 % na akční hry. Nová cena je 90 % té staré, takže ji vynásobíte 0.9 (v SQL se desetinná místa oddělují tečkou):

UPDATE hry
SET cena = cena * 0.9
WHERE zanr = 'Akční';
Error on line 1: cannot store REAL value in INTEGER column hry.cena

Tabulky obchodu Pixel Shop jsou STRICT (přísné): každý sloupec smí obsahovat jen hodnoty svého typu a cena je INTEGER, celé číslo. Shadow Ninja stojí 649 Kč a 90 % z toho je 584,1, desetinné číslo (REAL), které do sloupce uložit nejde – to je to „cannot store“ v chybě. Databáze proto odmítne celý příkaz a žádná hra novou cenu nedostane. Příkaz buď změní všechny řádky, které má, nebo žádný.

Pomůže ROUND(), kterou znáte z lekce o funkcích. ROUND(cena * 0.9) dá pro Shadow Ninja 584.0. To je pořád desetinné číslo, ale za desetinnou tečkou má jen nulu, a takové číslo se do sloupce INTEGER vejde a uloží se jako 584:

UPDATE hry
SET cena = ROUND(cena * 0.9)
WHERE zanr = 'Akční';

SELECT nazev, cena
FROM hry
WHERE zanr = 'Akční';
nazevcena
Shadow Ninja584
Star Pilots809
Zombie Town719
Robot Rebellion899

Bez STRICT by SQLite do sloupce uložilo 584,1 tak jako tak a jiné databáze, třeba PostgreSQL nebo MySQL, by číslo potichu zaokrouhlily. Chyba je lepší: o zaokrouhlení rozhodnete vy. Pozor i na dělení: cena / 2 dělí dvě celá čísla, takže dá, jak víte, celé číslo a zbytek bez jakékoli chyby zahodí (399 / 2 je 199).

Někdy potřebují různé řádky různé změny. Jeden UPDATE je zvládne s výrazem CASE, který každému řádku dá jeho vlastní novou hodnotu. Tady logické hry zdraží o 50 Kč a závodní o 100 Kč:

UPDATE hry
SET cena = CASE
        WHEN zanr = 'Logická' THEN cena + 50
        ELSE cena + 100
    END
WHERE zanr IN ('Logická', 'Závodní');

Typická chyba: CASE bez ELSE. Pro řádky, které nesplní žádné WHEN, dá CASE hodnotu NULL, a závodní hry by tak o cenu přišly. Tady to databáze odmítne chybou NOT NULL constraint failed: hry.cena, ale ve sloupci, který NULL povoluje, by hodnoty potichu zmizely. Když si má řádek svou hodnotu ponechat, napište ELSE cena.

Pokyny

UPDATE v editoru má zlevnit strategie o 15 %, ale databáze ho odmítá. Spusťte ho, přečtěte si chybu a opravte UPDATE tak, aby se nové ceny zaokrouhlily na celé koruny. Pod něj ukažte název a cenu strategií, seřazené podle ceny:

nazevcena
Tiny Kingdoms552
Castle Siege679
Galaxy Trader764

Výprodej mají i adventury: ty, které stojí víc než 400 Kč, zlevní o 100 Kč, ostatní o 50 Kč. Pod dotaz napište obě změny jedním příkazem UPDATE s CASE.

Pak ukažte název a cenu adventur, seřazené podle názvu:

nazevcena
Lost Temple399
Mystery Manor549
Ocean Deep349

Začněte programovat zdarma

Registrací souhlasíte s provozními podmínkami a zásadami ochrany osobních údajů.

Nebo se registrujte pomocí:

4/9