Procedurální rozšíření Transact SQL Michal Kopecký Výběr ze slajdů k 3. přednášce předmětu Databázové Aplikace (DBI026) na MFF UK
DBI026 -DB Aplikace - MFF UK 2 Procedurální rozšíření SQL proč jej používat Ve standardním SQL server obdrží a vyhodnotí vždy jednotlivý příkaz. V daném případě se odešle 2n paketů na server a 2n paketů zpět. for (;;) { FETCH; if (…) break; if (…) INSERT …; else UPDATE …; }; n x
DBI026 -DB Aplikace - MFF UK 3 Procedurální rozšíření SQL proč jej používat Pomocí procedurálního rozšíření je možné na server odeslat a zpracovat rozsáhlejší kus kódu včetně řízení toku V daném případě se odešle 1 paket na server a 1 paket zpět. LOOP FETCH; EXIT WHEN (…); IF (…) THEN INSERT …; ELSE UPDATE …; END LOOP; 1 1
DBI026 -DB Aplikace - MFF UK 4 Procedurální rozšíření SQL proč jej používat Šetření komunikačního kanálu –Menší množství odesílaných povelů v jednom povelu je vetší množství příkazů –Podstatně menší objem přenesených dat Data se zpracují na serveru bez přenosu na klienta –Odlehčení klienta Možnost ukládat a vykonávat kód na serveru Kód na serveru může být používán všemi klientskými aplikacemi
DBI026 -DB Aplikace - MFF UK 5 Procedurální rozšíření SQL použití Rozšíření možností serveru o další uživatelské funkce a procedury Zvýšená ochrana integrity dat –Triggery –Zapouzdření povolených manipulací s daty do procedur a funkcí Aplikace nemusí mít práva pro přímý přístup k tabulkám
DBI026 -DB Aplikace - MFF UK 6 Procedurální rozšíření SQL problémy Podstatně menší přenositelnost než v případě definic tabulek a příkazů pro manipulaci s daty (INSERT, UPDATE, DELETE) Standardizováno poprvé v SQL-99 –Řada proprietárních řešení v jednotlivých implementacích serverů –Navzájem nekompatibilní
DBI026 -DB Aplikace - MFF UK 7 Struktura Bloky kódu s pevnou strukturou Příkazy ukončené středníkem [DECLARE deklarace] BEGIN výkonná část [EXCEPTION ošetření výjimek] END; Posloupnosti příkazů Nemusí být ukončeny středníkem DECLARE sekce je chápána jako příkaz BEGIN … END také
DBI026 -DB Aplikace - MFF UK 8 Struktura DECLARE podil NUMBER; BEGIN SELECT citatel/jmenovatel INTO podil FROM Zlomky WHERE citatel=123; IF podil > 0 THEN UPDATE Zlomky SET Vysledek=Podil WHERE citatel=123; END IF; END; FLOAT = citatel/jmenovatel FROM Zlomky WHERE citatel=123 > 0 UPDATE Zlomky SET Vysledek WHERE citatel=123
DBI026 -DB Aplikace - MFF UK 9 Deklarace proměnných jméno [CONSTANT] typ [:= výraz]; Základní typy –Standardní –BOOLEAN obsahující TRUE, FALSE, [AS] typ
DBI026 -DB Aplikace - MFF UK 10 Příkazy Prázdný příkaz NULL; Přiřazovací příkaz prom := výraz; SQL příkaz UPDATE Emp SET Sal = Sal*1.05; DELETE FROM Emp WHERE EmpNo=1; Přiřazovací příkaz = výraz SQL příkaz UPDATE Emp SET Sal = Sal*1.05; DELETE FROM Emp WHERE EmpNo=1
DBI026 -DB Aplikace - MFF UK 11 Příkazy SELECT, vracející právě jednu řádku SELECT výr 1 [, …] INTO prom 1 [, …] FROM … WHERE …; SELECT, vracející právě jednu řádku 1 = výr 1 [, …] FROM … WHERE …;
DBI026 -DB Aplikace - MFF UK 12 T-SQL procedury CREATE PROCEDURE jmproc [; číslo] [deklarace_parametru [, …]] [WITH RECOMPILE] AS příkazy [;] –Deklarace typ [= výraz] [OUT[PUT]] –OUT[PUT] parametr je výstupní –číslo umožňuje vytvoření více verzí stejné procedury –Volání procedury EXEC[UTE] jmproc [výraz [, …]] –Parametry se předávají podle pořadí EXEC[UTE] jmproc [, …]] –Parametry se předávají podle jména
DBI026 -DB Aplikace - MFF UK 13 T-SQL procedury CREATE PROCEDURE INTEGER = NULL AS UPDATE Emp SET Sal Comm WHERE EXEC = = 15500; GO EXEC UpdEmpSal 4321, 14000, 500; GO
DBI026 -DB Aplikace - MFF UK 14 T-SQL funkce CREATE FUNCTION jmfunc [(deklarace_parametru [, …])] RETURNS typ [AS] BEGIN … RETURN výraz; END [;] –Volání funkce shodné se standardní funkcí Závorky musí být i v případě fce bez parametrů SELECT jmfunc ([výraz [, …]]) FROM …; –Parametry se předávají podle pořadí SELECT jmfunc [, …]]) FROM …; –Parametry se předávají podle jména
DBI026 -DB Aplikace - MFF UK 15 T-SQL funkce CREATE FUNCTION Polynom2 FLOAT = FLOAT = FLOAT = 0 ) RETURNS FLOAT AS BEGIN RETURN END; GO SELECT -- 2*x, x=1, tj *x+5, x=2, tj. 11 SELECT Polynom2(2, 1, 1, 1); -- x2+x+1, x=2, tj. 7
DBI026 -DB Aplikace - MFF UK 16 T-SQL funkce vracející tabulku CREATE FUNCTION jmfunc [(deklarace_parametru [, …])] RETURNS TABLE [AS] RETURN [(] SELECT …[)] –Použití jako pohled (tentokrát i s parametry) SELECT * FROM jmfunc ([výraz [, …]]);
DBI026 -DB Aplikace - MFF UK 17 T-SQL funkce vracející tabulku CREATE FUNCTION jmfunc [(deklarace_parametru [, …])] TABLE (def. tabulky) [AS] BEGIN tělo, vkládající data do RETURN END [;] –Použití jako pohled (tentokrát i s parametry) SELECT * FROM jmfunc ([výraz [, …]]);
DBI026 -DB Aplikace - MFF UK 18 Řídící příkazy - IF IF podmínka THEN příkazy IF [ELSIF podmínka THEN příkazy ELSIF1 [ELSIF podmínka THEN příkazy ELSIF2 …]] [ELSE příkazy ELSE ] END IF; Podmínka, vyhodnocená jako NULL je považována za nesplněnou IF podmínka příkaz IF | blok IF [ELSE příkaz ELSE | blok ELSE ] Podmínka, vyhodnocená jako NULL je považována za nesplněnou
DBI026 -DB Aplikace - MFF UK 19 Řídící příkazy - WHILE WHILE podmínka LOOP … [EXIT WHEN podmínka] … END LOOP; While-cyklus s možným výskokem uprostřed WHILE podmínka příkaz WHILE | blok WHILE BREAK ukončí cyklus CONTINUE ukončí iteraci
DBI026 -DB Aplikace - MFF UK 20 SELECT příkazy – T-SQL SELECT [, …] FROM … WHERE …; Musí vracet právě jednu řádku, jinak výjimka VARCHAR(30) = = EName FROM EMP WHERE EmpNo=1
DBI026 -DB Aplikace - MFF UK 21 Víceřádkový SELECT – T-SQL Víceřádkové SELECT příkazy bez INTO lze zpracovat jedině pomocí kurzorů Po každém FETCH je nutné zkontrolovat –0 … v pořádku –-1 … za koncem kurzoru –-2 … řádka chybí DECLARE C CURSOR FOR SELECT * FROM EMP; OPEN C; FETCH NEXT FROM C; WHILE BEGIN … FETCH NEXT FROM C; END; CLOSE C; DEALLOCATE C;
DBI026 -DB Aplikace - MFF UK 22 Kurzory Deklarace –C [SCROLL] CURSOR FOR SELECT …; Získání dat –FETCH {NEXT | PRIOR | ABSOLUTE n | RELATIVE n | LAST | FIRST} FROM C [, …]] –Pokud kurzor není deklarovaný s klíčovým slovem SCROLL, je možné použít jen NEXT
DBI026 -DB Aplikace - MFF UK 23 Výjimky Slouží k ošetření výjimečných stavů při vykonávání SQL příkazů K výjimkám dochází velmi často Je nutné je korektně obsloužit
DBI026 -DB Aplikace - MFF UK 24 Výjimky Typy výjimek –Určené k ošetření na serveru či v klientské aplikaci Standardní pojmenované výjimky –Generované serverem, mají přidělené jméno Standardní nepojmenované výjimky –Generované serverem, nemají přidělené jméno –Určené k ošetření na serveru Uživatelské vnitřní výjimky –Definované uživatelem, mají jméno, nemají popis –Určené k ošetření v klientské aplikaci Uživatelské aplikační výjimky –Definované uživatelem, nemají jméno, mají popis
DBI026 -DB Aplikace - MFF UK 25 Výjimky – T-SQL BEGIN TRY příkaz END TRY BEGIN CATCH příkaz END CATCH Funkce pro identifikaci chyb –ERROR_NUMBER() –ERROR_SEVERITY() –ERROR_STATE() –ERROR_PROCEDURE() –ERROR_LINE() –ERROR_MESSAGE()
DBI026 -DB Aplikace - MFF UK 26 Výjimky – T-SQL BEGIN TRY příkaz END TRY BEGIN CATCH příkaz END CATCH Zachyceny nejsou –Varování s ERROR_SEVERITY<=10 –Chyby s ERROR_SEVERITY>20 pokud zastavují vykonávání pro session O úroveň výše zachyceny –Kompilační chyby
DBI026 -DB Aplikace - MFF UK 27 Výjimky – T-SQL BEGIN TRY SELECT 1/0; -- zero divide … END TRY BEGIN CATCH SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_SEVERITY() AS ErrorSeverity, ERROR_STATE() AS ErrorState, ERROR_PROCEDURE() AS ErrorProcedure, ERROR_LINE() AS ErrorLine, ERROR_MESSAGE() AS ErrorMessage; END CATCH; GO
DBI026 -DB Aplikace - MFF UK 28 Uživatelské aplikační výjimky Generování –RAISERROR({ msg_id -- číslo výjimky, >= | msg_str -- text výjimky -- text výjimky v proměnné }, severity, state, argument [, …]) Jednotlivé zprávy lze předpřipravit pomocí sp_addmessage a poté se odkazovat jen pomocí msg_id msg_str může obsahovat odkazy na parametry, podobně jako C-funkce printf, hodnoty předány v argumentech Severity je závažnost chyby pouze skup. sysadmin