# Structured Query Language - dotazovací jazyk pro relační SŘBD - ISO standard jazyka SQL - ISO/EIC 9075 - 1986, 1989, **1992**, 1999, 2003, 2006, 2008, 2011, 2016, 2019, 2023 - komponenty: - DDL - Data Definition Language - DML - Data Manipulation Language - DCL - Data Control Language - TCL - Transaction Control Language **Vlastnosti a použití SQL** - neprocedurální deklarativní jazyk - vychází z jazyka SEQEL - slouží k vytvoření databáze a struktury relací (tabulek) - uživatelé jazyka - administrátor (DBA) - management - vývojář aplikace - koncový uživatel **Základní příkazy** - DDL - `CREATE TABLE`, `ALTER TABLE`, `DROP TABLE` - `CREATE VIEW`, `DROP VIEW` - `CREATE INDEX`, `DROP INDEX` - DML - `SELECT` - `INSERT`, `UPDATE`, `DELETE` - DCL a TCL - `GRANT`, `REVOKE` - `COMMIT`, `ROLLBACK` **Jak psát příkazy** - každý příkaz musí začínat na nové řádce - může být zapsán na více řádek - SQL rozlišuje - rezervovaná slova - nejsou case-sensitive - názvy objektů - mohou být case-sensitive - rezervovaná slova nesmí být dělená do více řádků - každý příkaz SQL musí být zakončen středníkem - řetězce v příkazu musí být uzavřeny v apostrofech ## DML **Příkaz SELECT** - příkaz `SELECT` nebo jeho části jsou součástí jiných příkazů - zjednodušená syntaxe ```sql SELECT [DISTINCT] {* | [sloupec_vyraz [[AS] alias] [,...]} FROM tabulka [alias] [,...] [WHERE podmínka] [GROUP BY seznam_neagregovaných_sloupců_výrazů] [HAVING podmínka] [ORDER BY seznam_řazených_sloupců_výrazů]; ``` **Agregované funkce** - `COUNT(sloupec)` - počet neprázdných hodnot sloupce - `SUM(sloupec)` - součet neprázdných hodnot sloupce - `AVG(sloupec)` - aritmetický průměr neprázdných hodnot sloupce - `MIN(sloupec)` - minimální hodnota sloupce - `MAX(sloupec)` - maximální hodnota sloupce **Vložení záznamu do tabulky** - jedním příkazem `INSERT` lze vložit jen jeden záznam do jedné tabulky - registrace čtenáře Jana Nováka ```sql INSERT INTO Čtenář (Č_čt, Jméno) VALUES (123, 'Jan Novák'); ``` **Změna záznamů tabulky** - jedním příkazem `UPDATE` lze modifikovat hodnoty několika záznamů jedné tabulky - uložení adresy čtenáři č. 123 ```sql UPDATE Čtenář SET Adresa = 'Univerzitní 8, Plzeň' WHERE Č_čt = 123; ``` **Zrušení záznamu tabulky** - jedním příkazem `DELETE` lze zrušit více záznamů jedné tabulky - zrušení (smazání) všech rezervací čtenáře č. 123 ```sql DELETE FROM Rezervace WHERE Č_čt = 123; ``` ## DDL **Identifikátory** - názvy tabulek, pohledů, sloupců a dalších databázových objektů - názvy objektů jsou u mnoha SŘBD case-sensitive - max. velikost 128 znaků - povoleny malá a velká písmena, cifry a podtržítko - musí začít písmenem - nesmí obsahovat diakritická znaménka a bílé znaky **Vybrané datové typy** + textové znaky a řetězce - `CHARACTER`, `CHARACTER VARYING` - přesné matematické výpočty - `NUMERIC`, `DECIMAL`, `INTEGER` - přibližné matematické výpočty - `FLOAT`, `REAL`, `DOUBLE PRECISION` + datum a čas + `DATE`, `TIME`, `TIMESTAMP` + rozsáhlé objekty + `BINARY LARGE OBJECT`, `CHARACTER LARGE OBJECT` **Definice tabulky** - příkazem `CREATE TABLE` vytváříme tabulku, ve které - definujeme její jméno - zavedeme alespoň jeden sloupec (a jeho datový typ) - můžeme a nemusíme definovat - výchozí hodnotu, nepojmenovaná integritní omezení - můžeme zavést pojmenovaná integritní omezení vázané s tabulkou - seznam sloupců a integritních omezení je oddělován čárkou a uzavřen v závorce ```sql CREATE TABLE Kluby ( Id_klubu NUMERIC PRIMARY KEY, Název CHARACTER VARYING(30) NOT NULL, Založen DATE ); ``` **Logické vs. fyzické datové typy** | logický | SŘBD Oracle | SŘBD MariaDB | | ---- | ---- | ---- | | CHARACTER | CHAR | CHAR | | CHARACTER VARYING | VARCHAR2 | VARCHAR | | NUMERIC | NUMBER | NUMBER | | DECIMAL | NUMBER | DECIMAL | | INTEGER | NUMBER | INT | | FLOAT | NUMBER | FLOAT | | REAL, DOUBLE PRECISION | NUMBER | DOUBLE | | DATE, TIME | DATE | DATE, TIME, TIMESTAMP | | TIMESTAMP | DATE | TIMESTAMP | | BINARY LARGE OBJECT | BLOB | BLOB | | CHARACTER LARGE OBJECT | CLOB | TEXT | **Nepojmenovaná integritní omezení** - každý sloupec může zahrnout tato integritní omezení - `NOT NULL` - vyžadovaná hodnota - `UNIQUE` - unikátní - `PRIMARY KEY` - primární klíč - `CHECK` - omezení podmínkou **Pojmenovaná integritní omezení** - začínají klíčovým slovem `CONSTRAINT` následovaného názvem omezení - poté jedna z uvedených možností nahoře (kromě `NOT NULL`) - zápis pokračuje seznamem sloupců tabulky, pro které je omezení definováno - některá omezení mají další konstrukce v zápise **Primární klíč** - maximálně jeden pro tabulku - nepojmenovaná varianta - `id_klubu NUMBER PRIMARY KEY` - pojmenovaná varianta - `CONSTRAINT kluby_pk PRIMARY KEY (id_klubu)` - umožňuje složený PK **Alternativní klíč** - nepojmenovaná varianta - `nazev VARCHAR2(30) NOT NULL UNIQUE` - pojmenovaná varianta - `CONSTRAINT nazev_un UNIQUE (nazev)` **Cizí klíč** - pouze pojmenovaná varianta ```sql CONSTRAINT exemplar_fk1 FOREIGN KEY (isbn) REFERENCES kniha (isbn) ``` - možno doplnit o reakci na rušení/aktualizaci prvku v nadřízené tabulce ```sql ON DELETE NO ACTION ON DELETE RESTRICT ON DELETE SET NULL ON DELETE CASCADE ON UPDATE NO ACTION ON UPDATE RESTRICT ON UPDATE SET NULL ON UPDATE CASCADE ``` - příklad ```sql CONSTRAINT exemplar_fk1 FOREIGN KEY (isbn) REFERENCES kniha (isbn) ON DELETE NO ACTION ON UPDATE NO ACTION ``` **Výběrová podmínka** (`CHECK`) - stanovení hodnot sloupce výčtem nebo podmínkou - nepojmenovaná varianta ```sql ... semestr CHAR(2) NOT NULL CHECK (semestr IN ('ZS', 'LS')) ... kladne_cislo NUMBER CHECK (kladne_cislo > 0) ... ``` - pojmenovaná varianta ```sql CONSTRAINT ruzne_tymy CHECK (id_domaci <> id_hoste) ``` **Kompletní vytvoření tabulky** ```sql CREATE TABLE zapas ( id_zapasu NUMBER PRIMARY KEY, misto VARCHAR2(100) NOT NULL, datum_cas DATE, id_domaci NUMBER, id_hoste NUMBER, goly_domaci NUMBER DEFAULT 0, goly_hoste NUMBER DEFAULT 0, CONSTRAINT zapas_fk1 FOREIGN KEY (id_domaci) REFERENCES kluby(id_klubu), CONSTRAINT zapas_fk2 FOREIGN KEY (id_hoste) REFERENCES kluby(id_klubu), CONSTRAINT ruzne_tymy CHECK (id_domaci <> id_hoste) ); ``` **Modifikace tabulky** - provádí se příkazem `ALTER TABLE` - lze měnit - název, sloupec, integritní omezení - lze přidat/zrušit sloupce - ideálně u prázdné tabulky - lze přidat nebo zrušit více sloupců jedním příkazem - lze přidat/zrušit pojmenovaná integritní omezení - jen jedno jedním příkazem **Indexy** - datová struktura - logické uspořádání prvků relace podle hodnot vybraných sloupců - má za úkol zrychlit operaci `SELECT` nad danou tabulkou - zpomaluje operace `INSERT`, `UPDATE` a `DELETE` - index je tvořen pro jeden nebo skupinu sloupců - index může být - unikátní (automaticky pro integritní omezení) - dovoluje opakování hodnot (ručně tvořené, např. pro cizí klíče) ```sql -- Unikátní index CREATE UNIQUE INDEX kluby_pk_idx ON kluby (id_klubu); -- Index dovolující opakovat hodnoty CREATE INDEX zapas_fk1_idx ON zapas (id_domaci); -- Zrušení indexu DROP INDEX kluby_pk_idx; DROP INDEX zapas_fk1_idx; -- zruší je i DROP TABLE ``` **Databázový pohled** - virtuální relace, která fyzicky neexistuje - poskytuje výsledek jedné nebo více relačních operací - definice spojena s příkazem `SELECT` - přiděluje příkazu `SELECT` jméno, pod kterým je uložen v databázi - datová struktura výhradně ke čtení - výjimkou jsou aktualizovatelné pohledy - čtenáři a jejich výpůjčky ```sql CREATE VIEW vypujcky_ctenare AS SELECT c.jmeno, v.inv_c FROM ctenar c, vypujcka v WHERE c.id_ctenar = v.id_ctenar; ``` - statistika tabulky exemplář ```sql CREATE VIEW statistika (zeme, pocet, soucet) SELECT zeme_vydani, COUNT(inv_c), SUM(cena) FROM exemplar GROUP BY zeme_vydani; ``` - zrušení: `DROP VIEW vypujcky_ctenare;` - pohled se může stát nevalidním, pokud bude smazána tabulka či pohled, který je jím používán ## DCL **Role a oprávnění** - DB administrátor může uživateli udělit - systémovou roli, např. `CONNECT`, `RESOURCE` - systémové oprávnění, např. `UNLIMITED TABLESPACE` - uživatel databáze může jinému uživateli udělit - uživatelskou roli - oprávnění k přístupu k jeho databázovému objektu - oprávnění předávat přidělený přístup dalším - role je množinou systémových nebo objektových oprávnění + vybraná objektová oprávnění - `ALL PRIVILEGES` - `CREATE`, `ALTER`, `DROP` - `INSERT`, `UPDATE`, `DELETE`, `SELECT` **Přidělení přístupu k objektům** - příkazem `GRANT` je možné přidělit jednomu či více uživatelům - jednu či více rolí - jedno nebo více systémových oprávnění - jedno nebo více oprávnění k jednomu DB objektu - konstrukcí `IDENTIFIED BY` je možné nastavit heslo k přístupu - konstrukcí `WITH ADMIN OPTION` možnost předávat přidělené systémové oprávnění dalším uživatelům - konstrukcí `WITH GRANT OPTION` možnost předávat přidělené objektové oprávnění dalším uživatelům ```sql GRANT UNLIMITED TABLESPACE TO zima; GRANT SELECT ON osoby TO PUBLIC; GRANT INSERT, UPDATE, DELETE ON osoby TO rychlik WITH GRANT OPTION; ``` **Odebrání přístupu** - příkazem `REVOKE` lze odebrat jednomu nebo více uživatelům - jednu či více rolí - jedno nebo více systémových oprávnění - jedno nebo více oprávnění k jednomu DB objektu - vždy možné odebrat - ty role a oprávnění, která byla přidělena - těm uživatelům, kterým byla přidělena ```sql REVOKE UNLIMITED TABLESPACE FROM zima; REVOKE SELECT ON osoby FROM PUBLIC; REVOKE INSERT, UPDATE, DELETE ON osoby FROM rychlik; ```