Uložené procedury Úvod Uložená procedura (rutina) je sada příkazů SQL, které jsou uložené na databázovém serveru a vykonává se tak, že je zavolána prostřednictvím dotazu názvem, který jim byl přiřazen (je to určitá obdoba funkce).
Výhody Uložené procedury můžou podstatným způsobem ulehčit správu databázových aplikací. Pokud máme např. server, který ukládá a zpracovává data a pokud bude využívat uložených procedur, mohou se shodným způsobem vůči databázi chovat klienti pocházející z nejrůznějšího prostředí - desktopová aplikace napsaná v Javě, webový klient v PHP nebo třeba vzdálený server, který s tím "naším" komunikuje. Jestliže je potřeba uloženou proceduru upravit (nebo opravit), může se to udělat na jednom místě a tato změna je ihned použitelný pro všechny aplikace, které s databází komunikují. Dalším významným rysem uložených procedur je to, že přispívají k zabezpečení serveru. Procedury mohou být v databázových systémech nastaveny tak, že je smí spouštět pouze uživatel s oprávněním a procedury mohou samy kontrolovat počet, typ, velikost a některé jiné charakteristiky parametrů, jež jsou jim posílány. To je v praxi velmi významné, protože to umožňuje vyhnout se fenoménu SQL injection. Nejdůležitějším argumentem pro nasazení uložených procedur na server bývá to, že jsou obecně schopny běžet rychleji, než kdyby se příslušný kód vykonával příkaz po příkazu z klientské aplikace. Důvodem je fakt, že uložené procedury jsou na serveru zkompilovány. (zkompilováním je myšleno, že server si pro uloženou proceduru vytvoří a spravuje tzv. prováděcí plán, díky kterému je subsystém serveru zvaný optimalizátor obvykle schopen najít nejrychlejší způsob, jak uloženou proceduru provést, a potom tento způsob opakovaně používat při jednotlivých voláních této uložené procedury).
Nevýhody
Vyšší spotřeba prostředků – kromě hlavního účelu databáze, kterým je ukládat data a udržovat relace mezi nimi, musí také vykonávat kód, který by jinak vykonala aplikace. Menší zdatnost - i přes bohatou výbavu jazykové konstrukce SQL, nenabízí takové možnosti jako plnohodnotný jazyk. Horší udržovatelnost rutin – psaní kódu a ladění rutin je obtížnější, než psaní funkcí v PHP Obtížnější přenositelnost – rutiny často používají syntaxi, která je specifická pro určitou danou databázi
1
Uložené procedury a MySQL MySQL umožňuje tvorbu uložených procedur od verze 5.0. Každá uložená procedura je v MySQL ukládána s konkrétní databází. Při odstranění databáze se smažou i definice uložených procedur. Uložené procedury podporují vykonávání SQL příkazů SELECT, INSERT, UPDATE a DELETE. Uložené procedury se obecně vytvářejí příkazem CREATE PROCEDURE proceduere_name [(seznam parametrů)] Když se vytváří uložené procedury z několika příkazů, musí se příkazy umístit do bloku BEGIN/END (příkazy jsou zakončeny středníkem).
Př.1) V MySQL 5 vytvoříme následující tabulku: create table software (id int, nazev varchar(50));
s následující sadou dat: insert into software (id, nazev) values (1, 'Firefox'); insert into software (id, nazev) values (2, 'Mozilla'); insert into software (id, nazev) values (3, 'Chrome');
Uloženou proceduru, která vrátí všechny záznamy z této tabulky lze vytvořit pomocí kódu: create procedure VratSoftware() begin select * from software; end //
V phpmyadmin je nutné zvolit jiný oddělovač než středník (;) dole v okně pro SQL dotazy (např. //) viz obrázek vpravo. a vytvořenou proceduru zavolat pomocí příkazu: call VratSoftware();
Uvedenou proceduru lze napsat i pomocí řádkového klienta, ikdyž tělo procedury obsahuje středník (odřádkování by v takovém případě způsobilo odeslání neúplné definice, příkaz by skončil chybou a procedura by nebyla vytvořena). V řádkovém klientovi lze změnit sekvenci znaků ukončujících příkaz za něco jiného než je středník. Lze to provést následujícím způsobem: delimiter // Obdobně by se příklad zapsal pomocí klienta mysql: mysql>DELIMITER // mysql>create procedure VratSoftware() –>select * from software; –>// mysql>DELIMITER ; mysql>call VratSoftware();
2
Parametry uložených procedur Podobně jako funkce v programovacích jazycích, mohou i uložené procedury v MySQL přebírat vstupní parametry i vracet parametry zpět volajícímu.U každého parametru musí být deklarován název, datový typ, a zda se bude parametr používat pro předání informace dovnitř procedury, nebo pro předání informace z procedury zpět volajícímu, nebo zda bude zastávat obě činnosti. Pro deklaraci datových typů slouží stejné typy, které podporuje MySQL. Pro deklaraci účelu parametru se používá: IN – pro předávání informací do procedury OUT – pro předávání informací z procedury zpět volajícímu INOUT – mohou předávat informace do procedury, jejich hodnota se může změnit a pak znovu používat vně procedury U všech parametrů deklarovaných jako OUT a INOUT se musí uvést jako prefix jejich názvu symbol @, když je volána uložená procedura, aby mohl být parametr znovu volán vně procedury. Ukázka možného zápisu procedury s parametry: create procedure vrat_data (IN produkt char(8), OUT pocet int) … tělo příkazu …
proceduru lze poté zavolat: call vrat_obsah („ABC12345“, @pocet);
a k parametru počet se poté dá přistoupit: select @pocet;
Př.2) Pokud bychom chtěli vrátit jen jeden jediný řádek, který bude vybraný například podle identifikátoru, lze to provést např. takto: create procedure vratradek (radek int) begin select * from software where id = radek; end //
zavoláním příkazu call vratradek(2); poté získáme druhý řádek tabulky software.
3
Deklarace a nastavování proměnných V uložených procedurách se často potřebují lokální proměnné. Na rozdíl od PHP se musí deklarovat před jejich prvním použití a specifikovat jejich typ. Proměnná se deklaruje pomocí příkazu DECLARE. Deklarace musí být uvnitř bloku BEGIN/END. Např.: DECLARE plat decimal(8,2);
Hodnota proměnné se nastavuje příkazem SET. Např.: SET cislo = 155;
Proměnné je také možno nastavit příkazem SELECT … INTO. Např.: DECLARE prom INT; SELECT sloupec INTO prom FROM tabulka WHERE id=“10“;
Prosměná však bude mít lokální obor vzhledem k bloku BEGIN/END, ve kterém byla deklarována (v jedné rutině může být i více bloků BEGIN/END). Pokud je potřeba proměnnou používat i vně procedury, musela by se předat jako proměnná typu OUT.
Př.3) create procedure vrathodnotu(OUT hodnota INT) begin select 45 INTO hodnota; end // CALL vrathodnotu(@hodnota); SELECT @hodnota;
Procedura vrátí výsledek 45 a s hodnotou můžeme dále pracovat i vně procedury.
Podmínky Mnohem širší uplatnění uložených procedur však souvisí s faktem, že mohou obsahovat určitou logiku - podmínky, cykly, lokální proměnné a tak dále. Syntaxe uložených procedur nabízí dvě konstrukce: IF-ELSEIF-ELSE a CASE. Příklad zápisu konstrukce IF-ELSEIF-ELSE: IF rok < 5 THEN set bonus = celkem * 1.05; ELSEIF rok >=5 AND rok < 10 THEN set bonus = celkem * 1.06; ELSEIF rok >=10 THEN set bonus = celkem * 1.07; END IF
4
Příklad zápisu konstrukce CASE: CASE WHEN stát=“ČR“ THEN set tel = “+420”; WHEN stát=“SR“ THEN set tel = “+421”; END CASE
Cykly Syntaxe uložených procedur nabízí také konstrukci cyklů. Cyklus se může skládat z příkazů LOOP, ITERATE a LEAVE, nebo REPEAT, UNTIL a WHILE. Příklad zápisu: název_návěští: LOOP příkazy … podmínky … LEAVE název_návěští; ITERATE název_návěští; END LOOP název_návěští;
// začátek cyklu // vyskočí z bloku cyklu // skočí na začátek cyklu // konec cyklu
Cyklus REPEAT se velmi podobná konstrukci DO-WHILE z PHP (podmínka se vyhodnocuje na konci). Příklad zápisu: REPEAT příkazy … UNTIL podmínka END REPEAT;
// začátek cyklu // testování podmínky // konec cyklu
Poslední možností je použití cyklu WHILE. Použití a zápis je obdobný jako v jiných programovacích jazycích. Příklad zápisu: WHILE podmínka DO příkazy … END WHILE;
// začátek cyklu a testování podmínky // konec cyklu
Odstranění uložené procedury K odstranění uložené procedury slouží příkaz DROP. Zápis syntaxe: DROP PROCEDURE název_procedury; DROP PROCEDURE procedure IF EXISTS "název_procedury";
Prohlížení stavu procedury Někdy je potřeba zjistit, kdo konkrétní rutinu vytvořil, kdy byla vytvořena, kdy byla modifikována, nebo ke které databázi se vztahuje. K tomu slouží příkaz SHOW STATUS. Zápis syntaxe: SHOW PROCEDURE STATUS LIKE "název_procedury";
Prohlížení syntaxe procedury Pokud se potřebujeme podívat na zápis uložené procedury, můžeme použít příkaz SHOW CREATE. Zápis syntaxe: SHOW CREATE PROCEDURE název_databáze.název_procedury;
5
Příklad Vytvořte si jednoduchou uloženou proceduru, pomocí které budete vypisovat jméno a příjmení z tabulky president, seřazené podle příjemní. Poté vytvořte skript v PHP a tuto proceduru zavolejte. Příklad k vyzkoušení http://djlj.mujblog.info/mysql/ulozene-procedury-v-mysql
Použité materiály: http://www.linuxsoft.cz/article.php?id_article=1003 http://www.linuxsoft.cz/article.php?id_article=1009 Velká kniha PHP a MySQL 5, W. Jason Gilmore
6