SQL (syntaxe a sémantika příkazů; vestavěné funkce, triggery, uložené procedury, příkazy pro definici dat; transakční zpracování; atomické operace; optimalizace dotazů)
Jazyk SQL obsahuje i vestavěné funkce, mezi ně patří především tzv. agregační funkce, ale dále do nich patří např. funkce pro práci s řetězci (SUBSTRING
, LOWER
atd.), pro zjištění aktuálního data a času atd. Množina dostupných funkcí je hodně závislá na zvoleném DBMS, kterým může být Oracle, Postgresql, SQL Server atd.
COUNT
– počet záznamů ve vrácené množině. Aplikuje-li se ve formě „COUNT(*)“, tak je vrácen počet všech záznamů; pokud je aplikován ve tvaru „COUNT(nazev_sloupce)
“, tak je vrácen počet záznamů, které nemají ve sloupci „nazev_sloupce“ hodnotu NULL
. AVG
– průměr dané hodnoty ve všech záznamech. SUM
– součet všech hodnot daného sloupce. MIN, MAX
– minimální, resp. maximální, hodnota daného sloupce v záznamech. Příklady
Počet všech produktů, které splňují podmínku, že ID
je větší než 1
SELECT COUNT(*) FROM [Products] WHERE nRowID > 1
Počet všech produktů, které mají vyplněný popis (tj. není NULL
)
SELECT COUNT(sDescription) FROM [Products]
Průměrná mzda zaměstnanců
SELECT AVG(mSalary) FROM [Zamestnanci]
Počet kusů všech produktů
SELECT SUM(nCount) FROM [Products]
Minimální a maximální mzda zaměstnanců
SELECT MIN(mSalary), MAX(mSalary) FROM [Employees]
Přetypování řetězce na celé číslo
CAST ('987' AS INT)
Definuje sadu příkazů, které lze použít pro vytváření, úpravu a odstraňování objektů v databázi. Nejčastěji spravovanými objekty jsou: tabulky, pohledy, procedury, funkce.
CREATE
– vytvoření objektu. ALTER
– úprava. V případě změny tabulky se může jednat o přidání/úpravu/odstranění sloupce, změny datového typu sloupce, změny relace a jiných integritních omezení. Příklad přidání sloupce do tabulky: ALTER TABLE [Nazev_Tabulky] ADD COLUMN [sValue3] Boolean
. DROP
– odstranění. Příklad odstranění procedury: DROP PROCEDURE [Procedura1]
. Příklady
Vytvoření tabulky
CREATE TABLE [Nazev_Tabulky] (nRowID Int PRIMARY KEY, sValue1 Varchar, sValue2 Varchar)
Vytvoření tabulky s tím, že je vynuceno zadání hodnoty pro název produktu
CREATE TABLE [Products] (nProductID Int PRIMARY KEY, sName NOT NULL)
Vytvoření tabulky s popisy produktů, které navazují na tabulku s produkty vytvořenou výše
CREATE TABLE [ProductDescriptions] (nProductID Int PRIMARY KEY, sDescription Varchar, CONSTRAINT vazbaProdukt FOREIGN KEY (nProductID) REFERENCES [Products] (nProductID))
Vytvoření tabulky s kontrolou, že je hodnota rodného čísla unikátní pro každého studenta (UNIQUE
)
CREATE TABLE [Students] (nStudentID Int PRIMARY KEY, sBirthNumber Varchar UNIQUE)
Vytvoření tabulky s kontrolou, že je hodnota platu vždy kladná hodnota (CHECK)
CREATE TABLE [Employees] (nEmployeeID Int PRIMARY KEY, sName Varchar, mSalary Decimal, CONSTRAINT plat CHECK (mSalary > 0))
Vytvoření tabulky s výchozí hodnotou na sloupci (DEFAULT)
CREATE TABLE [Nazev_Tabulky] (nRowID Int PRIMARY KEY, sValue1 Varchar, sValue2 Varchar DEFAULT 'výchozí hodnota')
Množina příkazů, které se využívají pro výběr, vkládání, úpravu a mazání dat v tabulkách.
INSERT
– vloží záznam do právě jedné tabulky. UPDATE
– upraví libovolný počet záznamů v právě jedné tabulce. DELETE
– odstraní libovolný počet záznamů z právě jedné tabulky. SELECT
– vybírá data z databáze, umožňuje výběr, agregaci a řazení dat. (odpovídá operaci projekce v relační algebře)
DISTINCT
– slouží k eliminaci duplikátů ve výsledku dotazu (ALL duplikáty ponechává) WHERE
– odpovídá operaci selekce v relační algebře FROM
– odpovídá kartézskému součinu z relační algebry ORDER BY
– uspořádá výpis sestupně (DESC) či vzestupně (ASC) GROUP BY
– umožňuje aplikovat souhrnné funkce, klauzule HAVING se aplikuje až po vytvoření skupin JOIN
– spojí dvě relace a vrátí jednu relaci, hlavní typy spojení: vnitřní, vnější
Příklady
Vložení produktu do tabulky
INSERT INTO [Products] (nProductID, sName) VALUES (1, „Produkt cislo 1“)
Úprava produktu
UPDATE [Products] SET sName = „Novy nazev produktu 1“ WHERE [nProductID] = 1
Odstranění všech produktů
DELETE FROM [Products]
Výběr všech produktů včetně jejich popisu
SELECT prod.nProductID, prod.sName, prod.sDescription
FROM [Products] AS prod
INNER JOIN [ProductDescriptions] prodDesc ON prod.nProductID = prodDesc.nProductID
Výběr všech produktů bez ohledu na to, mají vyplněný popis či nikoliv
SELECT prod.nProductID, prod.sName, prod.sDescription
FROM [Products] AS prod
LEFT OUTER JOIN [ProductDescriptions] prodDesc ON prod.nProductID = prodDesc.nProductID
Výběr skladů seřazených podle jejich naplnění sestupně
Předpokládejme tabulku se stavy produktů ve skladě: CREATE TABLE [ProductsInStores] (nStoreID INT, nProductID INT, nAmount INT, PRIMARY KEY (nStoreID, nProductID))
pak dotaz může vypadat následovně: SELECT nStoreID, SUM(nAmount)
FROM [ProductsInStores]
GROUP BY [nStoreID]
ORDER BY SUM(nAmount) DESC
Zpravidla se jedná o příkazy, které slouží k řízení transakcí, nastavení práv a jiné.
BEGIN
– spustí transakci s uvedeným názvem, který není povinný. Často se ještě uvádí úroveň izolace, která je použitá během zpracování příkazů kvůli předejití konkurenčním operacím. Příklad: BEGIN TRAN [MyTran1]
.
BEGIN
. Na toto je potřeba si dávat pozor, protože pokud provedené změny manuálně nepotvrdíte příkazem COMMIT
, neprojeví se. Databázový systém po nějakém specifikovaném timeoutu transakci zruší a změny se zahodí.
COMMIT
– potvrdí transakci. Příklad: COMMIT TRAN [MyTran1]
ROLLBACK
– vrátí provedené změny. Může se rušit jak celá transakce, tak její část od určitého bodu až po chvíli, kdy je ROLLBACK
volán (viz. SAVE
). Příklad: ROLLBACK TRAN [MyTran1]
SAVE
– tento příkaz není součástí standardu, ale většina db systémů jej podporuje. Ukládá stav transakce, do něhož je možné se vrátit, pokud není žádoucí vracet úplně celou transakci. Příklad: SAVE TRAN [MyCheckpoint1]
. Definice dle Wikipedie:
Atomická operace znamená, že její vykonání je nedělitelné – buď proběhne zcela úspěšně, nebo zcela neúspěšně. Atomickými operacemi jsou například: „vlož jeden záznam“, „zobraz jeden záznam“, apod.
Oproti tomu, vykonání neatomické operace je dělitelné: dojde-li při vykonávání příkazu k chybě, operace, které již byly vykonány, nebudou vráceny zpět. To se týká například operací, které mají vliv na větší množství řádků.
Příklad atomické a neatomické operace:
Vložení jednoho záznamu do tabulky
INSERT INTO [Products] (nProductID, sName) VALUES (1, „Muj produkt 1“)
Vložení více záznamů do tabulky překopírováním z jiné tabulky
INSERT INTO [Products] (nProductID, sName)
SELECT nProductID, sName FROM [Products2]
Je posloupnost operací (DML příkazů), které převedou datové schéma z jednoho konzistentního stavu do druhého.
O transakci platí, že je ACID:
Každá transakce má určitou úroveň izolace. Pokud se při vytvoření nespecifikuje, použije se výchozí úroveň.
Více transakcí může být spouštěno současně. Výhody jsou:
Nevýhody:
Neboli uváznutí, označuje stav, kdy transakce A čeká na prostředky, které drží transakce B a transakce B čeká na prostředky, které má uvolnit transakce A. Vždy se reší zaříznutím jedné z transakcí, nelze čistě vyřešit a je nutné jim předcházet.
Neopakovatelné čtení označuje stav, kdy si jedna transakce přečetla záznam, provedla nějaké příkazy a pak si tento záznam přečetla znovu a už měl jiné hodnoty.
Fantom označuje data, která na první pohled „záhadně“ unikají aktualizacím.
Jsou databázové objekty, které neobsahují data, ale programy, které se nad daty v databázi mají vykonávat. Mají své parametry a lokální proměnné, které nejsou zvenku vidět.
Uložená procedura je uložená (rozuměj: uložená v databázi). To znamená, že se k ní lze chovat stejně jako ke každému jinému objektu databáze (indexu, pohledu, triggeru apod.). Lze jí založit, upravovat a smazat pomocí příkazů dotazovacího jazyka databáze.
Pro psaní uložených procedur je obvykle používán specifický jazyk konkrétní databáze, který je rozšířením jejího dotazovacího jazyka. V případě Oraclu to je procedurální jazyk PL/SQL, u SQL Serveru se jedná o T-SQL.
Jedná se o uloženou sadu SQL příkazů, kterou lze parametrizovat. Má návratový typ a často se požaduje, aby byly deterministické. V praxi se to projevuje tak, že nesmí obsahovat prvky nedeterminismu jako například aktuální datum a čas atp.
Funkce je objekt jako každý jiný, takže ji lze spravovat pomocí jazyka DDL.
V databázi specifikuje činnosti, které se mají provést v případě definované události nad databázovou tabulkou. Definovanou událostí může být například vložení nebo smazání dat. Často slouží pro složitější kontrolu integrity dat.
Triggery jako takové jsou definovány ve většině moderních databázových systémů, ovšem mírně se liší v sémantice svého provedení.
Klíčové rozdíly jsou zejména v:
Syntax (databáze Oracle):
CREATE [OR REPLACE] TRIGGER jmeno {BEFORE | AFTER | INSTEAD OF}
udalost [FOR EACH ROW] [WHEN (podminka)]
blok
UPDATE
, DELETE
nebo INSERT
, případně jejich kombinace (zpravidla oddělené klíčovým slovem OR) BEFORE
triggery jsou spouštěny před provedením události, AFTER
triggery až po provedení události FOR EACH ROW
) INSERTING, UPDATING, DELETING
3) Robin Hood osobně používal tento Trigger
CREATE TRIGGER uprav_platy BEFORE UPDATE OF plat ON people FOR EACH ROW BEGIN IF (:NEW.plat>30000) THEN :NEW.plat:=28000; END IF; /* prilis by se namlsali */ IF (:NEW.plat<12000) THEN :NEW.plat:=15000; END IF; /* a chudym pridame */ END;
Existuje celá řada způsobů, jakými lze ovlivnit rychlost zpracování dotazu, níže je seznam těch základních.
SELECT * FROM [Products]
“ vybere všechny sloupce z tabulky, které možná ani nepotřebujeme, ale přinese také zpomalení z toho důvodu, že systém si musí nejdříve vytáhnout seznam sloupců z definice tabulky, aby je mohl zobrazit. Navíc takový dotaz není odolný proti změnám schématu tabulky. LIKE
– Obecně není vhodné operátor používat ve tvaru LIKE '%Karel%', v tom případě musí databáze projít všechny zbývající výskyty. To při omezení vhodnou podmínkou nemusí vadit. Tvar LIKE 'Karel%' je naprosto v pořádku a indexy v tomto případě fungují, stejně tak tvar bez procent. Většina dnešních nástrojů nabízí možnost zobrazení plánu provedení dotazů, který velice usnadní jejich ladění.
LIKE
je výběrový operátor používaný na řetězce, který může obsahovat tzv. wildcards.
Příklad výběru zaměstnanců, jejichž příjmení začíná na „Eich“
SELECT * FROM [Employees] WHERE sLastName LIKE 'Eich%
'
Pohled je databázový objekt, který uživateli poskytuje data ve stejné podobě jako tabulka. Na rozdíl od tabulky, kde jsou data přímo uložena, obsahuje pohled pouze předpis, jakým způsobem mají být data získána z tabulek a jiných pohledů.
Takto se nazývá speciální varianta pohledů, u nichž jsou výsledky volání ukládány. Rozdíl oproti normálním pohledům je ten, že při opakovaném volání přináší znatelné urychlení a navíc je možné v nich upravovat data. Podmínkou úpravy je to, že v pohledu musí být vybrány všechny sloupce primárního klíče tabulky, jejíž data aktualizujeme. Zpravidla se aktualizují pohledy nad jednou tabulkou, aby byly úpravy průhledné a nedocházelo k nechtěným změnám. Tuto možnost podporuje například Oracle, SQL Server už nikoliv.
Příklady
Vytvoření pohledu pro výběr produktů včetně jejich popisu
CREATE VIEW [View_Product] AS
SELECT prod.nProductID, prod.sName, prod.sDescription
FROM [Products] AS prod
INNER JOIN [ProductDescriptions] prodDesc ON prod.nProductID = prodDesc.nProductID
Moderní databázové systémy většinou umožňují integraci klasických programovacích jazyků do procedur, funkcí a triggerů, takže tímto způsobem je možné s výhodou využít například C++ nebo Javu tam, kde je SQL slabé.
Existují 4 druhy úrovní izolace dle standardu:
Petr Koutný, ICQ: 223-009-182. Nemám patent na rozum, takže klidně něco upravte, pokud vám to přijde nesmyslný
Otázku si přečetl pan RNDr. Vlastislav Dohnal a rámcově prošel. Jeho podněty pro doplnění textu, opravy nesrovnalostí a odstranění matoucích či k otázce se nevztahujících textů byly do otázky zaneseny. Tato kontrola je jen rámcová, stále se může stát, že v otázce zůstala zapomenutá chybka či nesrovnalost, vyučující za toto nenese odpovědnost, berte tuto rámcovou kontrolu jako formu pomoci od vyučujících pro studenty.