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.cz dostane chybu UNIQUE constraint failed: zakaznici.email. Jedinečný je i primární klíč: ID, které už je obsazené, skončí chybou UNIQUE 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 zaplaceno nebo vraceno. 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 INTEGER obsahovat jen celá čísla a sloupec TEXT jen text. Text ve sloupci s čísly skončí chybou cannot 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' nebo 4.5 databá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 5

První 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ý.

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:

idjmenoemailmestoregistrace
15Lucie Malálucie.mala@mail.czOstrava2026-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:

idzakaznik_iddatumstav
31152026-01-12zaplaceno

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_idhra_idpocetcena
3131499

Začněte programovat zdarma

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

Nebo se registrujte pomocí:

7/9