# 12 • Jazyk SQL

## 1. Historie a charakteristika

- **Původ:** Vyvinuto firmou **IBM**
- **Název:** Původně **SEQUEL** (Structured English QUEry Language), ale kvůli ochranné známce zkráceno na SQL.
- **Účel:** Slouží výhradně ke komunikaci s relačními databázemi. Je to tzv. **deklarativní jazyk** – říkáme „CO“ chceme (např. *dej mi seznam studentů*), nestaráme se „JAK“ to počítač na disku najde.
- **Design (dva směry):**
    1. **Pro lidi:** Snaha o jednoduchou angličtinu, aby se to dalo číst jako věta (`SELECT * FROM users WHERE age > 18`)
    2. **Pro počítač:** Jednoznačná syntaxe a pořadí příkazů = snadný **parsing** (počítač vždy přesně ví, co má udělat)

### Standardizace vs. Realita

- První standard byl **SQL-86** (ANSI).
- **Problém:** Každý výrobce databází (Oracle, Microsoft, PostgreSQL) si standard trochu upravil a přidal vlastní funkce. Vznikly tak **dialekty**:
    - Microsoft SQL Server
    - *Oracle SQL*
    - *pgSQL* (PostgreSQL)

---

## 2. Rozdělení příkazů

### A. DDL (Data Definition Language) – Definice dat

Příkazy, které mění **strukturu** databáze (schéma), ne samotná data uvnitř.

- `CREATE`: Vytvoří nový objekt (tabulku, databázi, pohled).
- `ALTER`: Upraví existující objekt (přidá sloupec do tabulky).
- `DROP`: Smaže objekt nenávratně i s daty (zruší tabulku).
- `TRUNCATE`: Smaže všechna data v tabulce, ale strukturu (hlavičku) nechá. Je to rychlejší než DELETE.

### B. DML (Data Manipulation Language) – Manipulace s daty

Příkazy pro práci s obsahem tabulek (řádky)

- `SELECT`: Vybere data (někdy se vyčleňuje jako DQL – Query Language)
- `INSERT`: Vloží nová data
- `UPDATE`: Aktualizuje existující data
- `DELETE`: Smaže konkrétní data (řádky)

### C. DCL (Data Control Language) – Řízení přístupu

Příkazy pro práva a bezpečnost

- `GRANT`: Udělí oprávnění (např. uživatel smí jen číst)
- `REVOKE`: Odebere oprávnění

### D. TCL (Transaction Control Language) – Řízení transakcí

Zajišťuje integritu operací (všechno nebo nic)

- `COMMIT`: Potvrdí změny (uloží je natrvalo)
- `ROLLBACK`: Vrátí změny zpět (pokud se něco pokazilo)

---

## 3. Databázové objekty a Integrita

Co všechno v databázi vlastně "leží" a jak to hlídáme.

### Objekty (co tvoříme přes CREATE)

1. **Tabulka (Table):** Základní úložiště dat (řádky a sloupce).
2. **Pohled (View):** Virtuální tabulka. Je to uložený SQL dotaz, který se tváří jako tabulka. Užitečné pro bezpečnost (skryjeme citlivé sloupce).
3. **Index:** Datová struktura (často B-strom), která urychluje vyhledávání (funguje jako rejstřík v knize).
4. **Sekvence (Sequence/Auto_increment):** Generátor čísel, typicky pro primární klíče (1, 2, 3...).
5. **Uložené procedury (Stored Procedures):** Kusy kódu/funkce uložené přímo v databázi.

### Integritní omezení (Constraints)

Pravidla, která hlídají kvalitu dat při vkládání/úpravě.

- `PRIMARY KEY` (PK): Jednoznačný identifikátor řádku (musí být unikátní a nesmí být prázdný).
- `FOREIGN KEY` (FK): Odkaz na PK jiné tabulky (vazby).
- `UNIQUE`: Hodnoty ve sloupci se nesmí opakovat (např. email, rodné číslo), ale může být NULL (pokud není zároveň PK).
- `NOT NULL`: Sloupec nesmí být prázdný.
- `CHECK`: Podmínka, kterou data musí splnit (např. `cena > 0`).

---

## 4. Konkrétní příkazy (Syntaxe)

### SELECT (Výběr dat)

Nejpoužívanější příkaz. Má pevné pořadí klauzulí:

1. `SELECT`: Co chci zobrazit (sloupce, funkce).
2. `FROM`: Odkud (tabulka).
3. `JOIN`: Připojení dalších tabulek (vazby).
4. `WHERE`: Filtrace řádků (podmínka, např. `vek > 18`).
5. `GROUP BY`: Seskupení řádků (např. "počet studentů **podle tříd**").
6. `HAVING`: Filtrace skupin (podmínka pro GROUP BY, např. "jen třídy, kde je víc než 20 lidí").
7. `ORDER BY`: Řazení výsledků (`ASC` vzestupně, `DESC` sestupně).

### INSERT (Vložení)

SQL

`INSERT INTO studenti (jmeno, prijmeni, trida)
VALUES ('Jan', 'Novák', '4.B');`

### UPDATE (Úprava)

**Pozor:** Vždy používat `WHERE`, jinak přepíšeš celou tabulku!

SQL

`UPDATE studenti
SET trida = '4.C'
WHERE id = 5;`

### DELETE (Smazání)

**Pozor:** Zase nutné `WHERE`, jinak smažeš všechna data (jako TRUNCATE, ale pomaleji).

SQL

`DELETE FROM studenti
WHERE znamka = 5;`