Když databáze řekne ne
V této lekci už databáze několikrát změnu odmítla. Takové chyby pocházejí z omezení (anglicky constraints): pravidel, která tabulka pro svá data stanoví. Databáze je kontroluje při každém INSERT a UPDATE (cizí klíče i při každém DELETE), a když by příkaz některé z nich porušil, odmítne celý příkaz a nic nezmění. Pravidla jsou součástí databáze, takže data chrání, ať je zapisuje kdokoli: web obchodu, aplikace skladu, nebo vy.
Toto jsou omezení obchodu Pixel Shop, každé s ukázkou své zprávy:
- NOT NULL (nesmí být prázdné): sloupec musí mít hodnotu. V Pixel Shopu smí zůstat prázdné jen datum vydání hry, město zákazníka, údaj o tom, kdo mu obchod doporučil, a komentář recenze. Hra bez věkové hranice skončí chybou
NOT NULL constraint failed: hry.vek_od. - UNIQUE (jedinečné): žádné dva řádky nesmějí mít ve sloupci stejnou hodnotu. Každý zákazník má svůj vlastní e-mail, takže druhý zákazník s
eva.novotna@mail.czdostane chybuUNIQUE constraint failed: zakaznici.email. Jedinečný je i primární klíč: ID, které už je obsazené, skončí chybouUNIQUE constraint failed: hry.id, a protože primární klíč recenze tvoří hra a zákazník dohromady, může každý zákazník ohodnotit každou hru jen jednou. - CHECK (kontrola): podmínka, kterou musí splnit každý řádek. V Pixel Shopu: hvězdičky od 1 do 5, počet kusů větší než 0 a stav
zaplacenonebovraceno. Zpráva podmínku ukáže:CHECK constraint failed: hvezdicky BETWEEN 1 AND 5. - FOREIGN KEY (cizí klíč): cizí klíč musí ukazovat na řádek, který existuje. Recenze od zákazníka 99 dostane chybu
FOREIGN KEY constraint failed, stejně jako mazání řádku, na který ukazují jiné řádky. Tato zpráva neříká, o který sloupec jde. - Typy: ve STRICT tabulkách smí sloupec
INTEGERobsahovat jen celá čísla a sloupecTEXTjen text. Text ve sloupci s čísly skončí chyboucannot store TEXT value in INTEGER column recenze.hvezdicky. Celé číslo v apostrofech, třeba'5', se bez problémů změní na číslo 5, ale'pět'nebo4.5databáze odmítne.
Když přidáváte několik řádků najednou a jeden z nich pravidlo poruší, nedostane se do tabulky žádný:
INSERT INTO recenze (hra_id, zakaznik_id, hvezdicky)
VALUES
(4, 4, 5),
(14, 2, 6);Error on line 1: CHECK constraint failed: hvezdicky BETWEEN 1 AND 5První recenze je v pořádku, ale druhá má 6 hvězdiček, takže databáze odmítne celý příkaz a nepřidá ani tu první.
Když příkaz poruší víc pravidel najednou, databáze ohlásí jedno z nich. Opravte ho, spusťte příkaz znovu a možná dostanete další. Tabulka a sloupec ve zprávě vám řeknou, kde hledat. A odkud se pravidla berou? Každá tabulka je má ve své definici, v příkazu CREATE TABLE, který ji vytvořil. V příští lekci budete psát vlastní tabulky i s jejich omezeními.
Typická chyba: chybu obejít, místo abyste opravili data. Když nový zákazník dostane chybu UNIQUE constraint failed: zakaznici.email, řešením není měnit v e-mailu písmenka, dokud ho databáze nepřijme. Zákazník už možná v tabulce je, nebo je e-mail špatně. Omezení našlo skutečný problém, tak zjistěte jaký.
Jak psát:
Pokyny
INSERT v editoru má přidat novou zákaznici, Lucii Malou, ale databáze ho odmítá. Spusťte ho, přečtěte si chybu, opravte INSERT a spusťte ho znovu, dokud nebude fungovat: má dvě chyby. Lucie se registrovala 2026-01-12 a e-mail v INSERT patří Evě Novotné; Luciin vlastní je lucie.mala@mail.cz. Dotaz pod ním ji pak ukáže:
| id | jmeno | mesto | registrace | |
|---|---|---|---|---|
| 15 | Lucie Malá | lucie.mala@mail.cz | Ostrava | 2026-01-12 |
Lucie zadává svou první objednávku. Její INSERT v editoru ještě není a také má chyby. Zkopírujte ho na konec souboru pod dotaz, spusťte soubor a opravujte INSERT, dokud ho databáze nepřijme. Objednávka je Luciina a je zaplacená:
INSERT INTO objednavky (zakaznik_id, datum, stav)
VALUES (51, '2026-01-12', 'nova');Pak ukažte ID, zákazníka, datum a stav Luciiných objednávek:
| id | zakaznik_id | datum | stav |
|---|---|---|---|
| 31 | 15 | 2026-01-12 | zaplaceno |
A položka objednávky: jeden kus Moon Farm (hra 3) za 499 Kč. Zkopírujte i tento INSERT na konec souboru a opravte jeho chyby:
INSERT INTO polozky (objednavka_id, hra_id, pocet, cena)
VALUES (31, 3, 0, '499 Kč');Pak ukažte všechny sloupce položek objednávky 31:
| objednavka_id | hra_id | pocet | cena |
|---|---|---|---|
| 31 | 3 | 1 | 499 |
Začněte programovat zdarma
7/9