řízení transakcí 2-3 hodiny

Podobné dokumenty
PL/SQL. Jazyk SQL je jazykem deklarativním, který neobsahuje procedurální příkazy jako jsou cykly, podmínky, procedury, funkce, atd.

Text úlohy. Systémový katalog (DICTIONARY):

2. blok část B Základní syntaxe příkazů SELECT, INSERT, UPDATE, DELETE

6. blok část B Vnořené dotazy

6. blok část C Množinové operátory

Návrh a tvorba WWW stránek 1/14. PHP a databáze

4. lekce Přístup k databázi z vyššího programovacího jazyka

Dotazovací jazyk SQL a PL/SQL. 8. Přednáška

Informační systémy 2008/2009. Radim Farana. Obsah. Jazyk SQL

PRŮBĚHOVÝ TEST Z PŘEDNÁŠEK

4. blok část A Logické operátory

Databázové systémy II. KIV/DB2 LS 2007/2008. Zadání semestrální práce

Stored Procedures & Database Triggers, Tiskové sestavy v Oracle Reports

Kurz Databáze. Obsah. Dotazy. Zpracování dat. Doc. Ing. Radim Farana, CSc.

Databázové systémy Cvičení 5.2

8 Třídy, objekty, metody, předávání argumentů metod

DATABÁZOVÉ A INFORMAČNÍ SYSTÉMY

Databázové systémy. - SQL * definice dat * aktualizace * pohledy. Tomáš Skopal

Embedded SQL v C/C++ úvod. Administrace Oracle Kateřina Opočenská

6 Příkazy řízení toku

Distanční opora předmětu: Databázové systémy Tématický blok č. 8: Transact SQL Autor: RNDr. Jan Lánský, Ph.D.

7. Integrita a bezpečnost dat v DBS

7. Integrita a bezpečnost dat v DBS

Informační systémy 2008/2009. Radim Farana. Obsah. Dotazy přes více tabulek

InnoDB transakce, cizí klíče, neumí fulltext (a nebo už ano?) CSV v textovém souboru ve formátu hodnot oddělených čárkou

Databáze I. 5. přednáška. Helena Palovská

DATABÁZOVÉ A INFORMAČNÍ SYSTÉMY

KIV/ZIS cvičení 5. Tomáš Potužák

10. Architektura klient/server a třívrstvá architektura

10. Architektura klient/server a třívrstvá architektura

Databázové systémy a SQL

Databázové systémy I

Databáze I. Přednáška 4

Kód v databázi. RNDr. Ondřej Zýka

Jazyk PL/SQL Úvod, blok

5. blok Souhrnné a skupinové dotazy

Jaký je rozdíl v definicicíh VARCHAR2(20 BYTE) a VARCHAR2(20 CHAR):

Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost rozhraním a výjimkám.

Databáze I. Přednáška 7

FIREBIRD relační databázový systém. Tomáš Svoboda

Úvod do databázových systémů

13. blok Práce s XML dokumenty v databázi Oracle

Západočeská univerzita v Plzni Katedra informatiky a výpočetní techniky. 9. června krovacek@students.zcu.cz

Administrace Oracle. Práva a role, audit

Databázové systémy I

KAPITOLA 4. SQL a PL/SQL

Tematický celek Proměnné. Proměnné slouží k dočasnému uchovávání hodnot během provádění aplikace Deklarace proměnných

Oracle XML DB. Tomáš Nykodým

Ukázka knihy z internetového knihkupectví

PG 9.5 novinky ve vývoji aplikací

12. blok Pokročilé konstrukce SQL dotazů - část II

Uložené procedury Úvod ulehčit správu zabezpečení rychleji

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

2-3 hodiny. Při studiu tohoto bloku se předpokládá, že čtenář je obeznámen s jazykem SQL a zná základy jazyka PL/SQL.

Deklarativní IO shrnutí minulé přednášky

KIV/ZIS cvičení 6. Tomáš Potužák

Fakulta elektrotechniky a informatiky Databázové systémy 2. Leden 2010 souhrn. Červené dobře (nejspíš), modré možná

Úvod do databázových systémů

Verzování a publikace dat na webu za pomoci PostgreSQL

B0M33BDT Technologie pro velká data. Supercvičení SQL, Python, Linux

Virtual private database. Antonín Steinhauser

Databázové systémy. Cvičení 6: SQL

Jazyk SQL 3 - DML, DDL, TCL, DCL

PHP a Large Objecty v PostgreSQL

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

SII - Informatika. 1. Atribut relace, jehož hodnota jednoznačně určuje prvek v jiné relaci, se nazývá:

SQL - trigger, Databázové modelování

5. POČÍTAČOVÉ CVIČENÍ

Obsah. Kapitola 1. Kapitola 2. Kapitola 3. Kapitola 4. Úvod 11. Stručný úvod do relačních databází 13. Platforma 10g 23

8.2 Používání a tvorba databází

17. července :51 z moravec@yahoo.com

Sada 1 - PHP. 14. Úvod do jazyka SQL

Embedded SQL v C/C++ III - pole, struktury. Jindřich Vodrážka

Univerzita Pardubice. Fakulta elektrotechniky a informatiky SEMESTRÁLNÍ PRÁCE PRO PŘEDMĚT IDAS2

Z. Kotala, P. Toman: Java ( Obsah )

Algoritmizace a programování

Vzorové příklady SQL. Tabulka: Kniha CREATE TABLE kniha (id INTEGER, název VARCHAR(50), PRIMARY KEY (id))

Informační systémy 2008/2009. Radim Farana. Obsah. Skripty a dávky. Nastavení aktuální databáze. USE DatabaseName

RNDr. Michal Kopecký, Ph.D. Department of Software Engineering, Faculty of Mathematics and Physics, Charles University in Prague

Kapitola 4: SQL. Základní struktura

Tento blok je věnován vytváření uživatelských balíků funkcí v jazyce PL/SQL a použití systémových balíků. 2-3 hodiny

Internetová filmová databáze IFDB

Programování v jazyce JavaScript

DSL manuál. Ing. Jan Hranáč. 27. října V této kapitole je stručný průvodce k tvorbě v systému DrdSim a (v

POSTUP PRO VYTVOŘENÍ STRUKTUR PRO UKLÁDÁNÍ RDF DAT V ORACLE

6. SQL složitější dotazy, QBE

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

Marian Kamenický. Syntea software group a.s. marian.kamenicky. MFFUK Praha 2012/13

Maturitní otázky z předmětu PROGRAMOVÁNÍ

Základní přehled SQL příkazů

Zápisování dat do databáze

Databázové systémy a SQL

Popis souboru pro generování reportů *.report

Co se stane po jeho vykonání? Vyberte libovolný počet možných odpovědí. Správná nemusí být žádná, ale také mohou být správné všechny.

2. blok část A Jazyk SQL, datové typy

Databáze II. 2. přednáška. Helena Palovská

Databáze SQL SELECT. David Hoksza

Assembler - 5.část. poslední změna této stránky: Zpět

Databáze. Velmi stručný a zjednodušený úvod do problematiky databází pro programátory v Pythonu. Bedřich Košata

MAXScript výukový kurz

Transkript:

7. blok - část A Jazyk PL/SQL - zpracování chyb, řízení transakcí Studijní cíl Tento blok je věnován ošetření chyb a řízení transakcí v kódu PL/SQL. Doba nutná k nastudování 2-3 hodiny Průvodce studiem Při studiu tohoto bloku se předpokládá, že čtenář je obeznámen s jazykem SQL, je schopen napsat jednoduchý program v libovolném programovacím jazyce a zná základy jazyka PL/SQL. 1. Zpracovávání chyb Dobře napsané programy musí být schopny správně zpracovávat chyby a umět se z nich vzpamatovat. V PL/SQL se s chybami pracuje pomocí výjimek a zachytávání výjimek. Výjimky je možné navázat na chyby Oracle nebo je možné si definovat vlastní uživatelsky definované chyby. V následujícím textu se seznámíme se syntaxí pro práci s výjimkami a s pravidly pro šíření výjimek. Výjimky v PL/SQL se podobají výjimkám v jazyce Java. Ale na rozdíl od výjimek v jazyce Java nejsou výjimky v PL/SQL objekty a nemají definovány žádné metody. V PL/SQL se mohou objevit 2 typy chyb: chyby při překladu, které hlásí překladač a které je nezbytné opravit, aby mohl být předkompilován a chyby za běhu programu, které zpracovávají zachytávače výjimek. Jestliže doje k chybě za běhu programu, je vyvolána výjimka. Provádění kódu (řízení běhu programu) poté přejde do části zachytávače výjimek, která je oddělena od zbytku programu. Toto oddělení má kromě vlastního zpřehlednění kódu také tu výhodu, že zde budou zachycenyy všechny chyby. Program tedy nebude pokračovat dál od příkazu, který způsobil chybu, ale vždy přejde do zachytávače výjimek a poté do libovolného vnějšího bloku. Existují 2 typy výjimek: předdefinované a uživatelsky definované. 1

Předdefinované výjimky Oracle má mnoho předdefinovaných výjimek, které odpovídají běžným chybám, viz následující tabulka: Výjimka Oracle chyba Hodnota SQLCODE Vyvolána je: ACCESS_INTO_NULL 06530 COLLECTION_IS_NULL 06531 CURSOR_ALREADY _OPEN DUP_VAL_ON_INDEX INVALID_CURSOR INVALID_NUMBER LOGIN_DENIED NO_DATA_FOUND NOT_LOGGED_ON 06511 00001 01001 01722 01017 01403 01012-6530 Přiřazení hodnoty k atributu neinicializovaného (null) objektu. -6531 Použití jiné sběrné metody (collection method) než EXISTS na neinicializovanou (atomicky null) vnořenou tabulku nebo pole (varray) nebo přiřazení hodnoty do položek neinicializované vnořené tabulky nebo pole -6511 Snaha o otevření již jednou otevřeného kurzoru (cursor), před opětovným otevřením musíte kurzor nejdříve zavřít, kurzorový FOR cyklus otevírá kurzor automaticky, takže jej nelze uvnitř cyklu opět otevřít. -1 Snaha o uložení totožné (již existující) hodnoty do sloupce, který je označen jako unique index - index specifických hodnot. -1001 Nepovolená operace s kurzorem (cursor), například zavření neotevřeného kurzoru. -1722 Selhání převodu mezi řetězcem znaků a číslem v příkazu SQL z toho důvodu, že řetězec neobsahuje platné číslo. V procedurálním příkazu je vyvolána výjimka VALUE_ERROR. -1017 Snaha nalogovat se na Oracle server s neplatným jménem (username) a/nebo heslem (password). +100 Pokud příkaz SELECT INTO nevrátí žádné řádky nebo se odkazujete na smazaný prvek vnořené tabulky nebo neinicializovaný prvek index-by tabulky. Od příkazu FETCH se případně dá očekávat navrácení prázdného řádku (no rows) a v tomto případě výjimka není vyvolána. SQL kolektivní (group) funkce jako AVG a SUM vracejí vždy hodnotu nebo null. Proto také příkaz SELECT INTO volající group funkci nikdy nevyvolá výjimku NO_DATA_FOUND. -1012 Pokud se PL/SQL program pokouší provést databázovou operaci bez předchozího připojení k serveru Oracle. 2

PROGRAM_ERROR 06501 ROWTYPE_MISMATCH 06504 STORAGE_ERROR SUBSCRIPT_BEYOND _COUNT SUBSCRIPT_OUTSIDE _LIMIT TIMEOUT_ON _RESOURCE TOO_MANY_ROWS VALUE_ERROR ZERO_DIVIDE 06500 06533 06532 00051 01422 06502 01476-6501 Vnitřní problém (internal problem) při běhu programu. -6504 Hlavní (host) a PL/SQL kurzorová proměnná vyžádaná dosazením mají nekompatibilní návratové typy. Například, když přenecháte otevřený host kurzor uloženému podprogramu, pak návratové typy aktuálních a formálních parametrů musí být kompatibilní. -6500 PL/SQL vyčerpalo paměť, nebo je paměť poškozená. -6533 Odkaz na prvek vnořené tabulky (nested table) či pole (varray) s číslem indexu větším než je počet dostupných prvků. -6532 Odkaz na prvek vnořené tabulky (nested table) či pole (varray) s číslem indexu, který je mimo povolený rozsah (např. -1). -51 Vypršel čas (time-out), během kterého Oracle čeká na prostředky (resource). -1422 Příkaz SELECT INTO vrací více než jeden řádek. -6502 Chyba aritmetická, převodní, zkrácení nebo omezení velikosti. Například, když dosadíte hodnotu ze sloupce do znakové proměnné a tato hodnota je delší než nedeklarovaná délka proměnné. V procedurálních příkazech je výjimka vyvolána, pokud selže převod mezi řetězcem a číslem (v SQL je to výjimka INVALID_NUMBER). -1476 Dělení nulou. Příklad: DECLARE v_jmeno ucitel..jmeno%type; v_id ucitel..id%type; SELECT jmeno, Id INTO v_jmeno, v_id FROM ucitel WHERE Id=2; DBMS_OUTPUT.PUT_LINE('Jméno: ' v_jmeno); DBMS_OUTPUT.PUT_LINE('Id: ' v_id); EXCEPTION -- ošetření výjimky při nenalezení dat WHEN NO_DATA_FOUND THEN 3

DBMS_OUTPUT.PUT_LINE('Data nenalezena'); -- ošetření výjimky při nalezení více řádků WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.PUT_LINE('Mnoho řádků'); Uživatelsky definované výjimky V PL/SQL má uživatel možnost nadefinovat si vlastní výjimky. Tyto výjimky se deklarují v deklarační části, vyvolávají se v exekuční části příkazem RAISE a zpracovávají se v oblasti výjimek. Deklarace výjimky začíná jejím jménem následovaným klíčovým slovem EXCEPTION. Pro vlastní výjimky je SQLCODE rovno 1 a SQLERRM vrací Text User-Defined Exception. Syntaxe DECLARE <název výjimky> EXCEPTION; <příkazy>; RAISE <název výjimky>; EXCEPTION WHEN <název výjimky> THEN <příkazy>; Příklad deklarace a vyvolání výjimky pojmenované PRILIS_MNOHO_TRPASLIKU: : DECLARE PRILIS_MNOHO_TRPASLIKU EXCEPTION; v_pocet_trpasliku NUMBER; select count(*) INTO v_pocet_trpasliku FROM trpaslici; IF v_pocet_trpasliku > 7 THEN RAISE PRILIS_MNOHO_TRPASLIKU; END IF; EXCEPTION WHEN PRILIS_MNOHO_TRPASLIKU THEN DBMS_OUTPUT.PUT_LINE('Trpaslíků může být max. 7!' '); 4

Použití raise_application_error Balíček DBMS_STANDARD dodávaný spolu s Oracle poskytuje jazykové prostředky, které mohou vašim aplikacím napomoci při spolupráci s Oracle. Například procedura raise_application_error umožňuje zveřejnit uživatelsky definované chybové hlášky z uložených podprogramů (stored subprograms). Touto cestou můžete své aplikaci oznamovat chyby a vyhnout se vracení neošetřených chyb. Příkaz raise_application_error má následující syntax: RAISE_APPLICATION_ERROR(error_number, message[, {TRUE FALSE}]); kde error_number je záporné celé číslo (integer) v rozsahu -20000.. -20999 a message je řetězec maximální délky 2048 bytů. Jestliže je třetí nepovinný parameter TRUE, chyba je uložena do zásobníku, pokud je FALSE (default), chyba nahradí všechny dosud uložené chyby. Aplikace může volat raise_application_error pouze ze spustitelného uloženého podprogramu. Je-li zavolána, raise_application_error ukončí podprogram a vrátí uživatelsky definovanou chybu (číslo chyby) a zprávu aplikaci. Číslo chyby a zpráva pak může být odchytnuta stejně jako každá jiná Oracle chyba. V následujícím příkladu je zavolána procedura raise_application_error, pokud není uvedena mzda u daného zaměstnance, v opačném případě provede navýšení mzdy: DECLARE v_mzda NUMBER; v_id NUMBER := 1; SELECT mzda INTO v_mzda FROM zamestnanci WHERE zam_id = v_id; IF v_mzda IS NULL THEN raise_application_error(-20101, 'Mzda neuvedena'); ELSE UPDATE zamestnanci SET mzda = p_mzda * 1,05 WHERE zam_id = v_id; END IF; Volající modul obdrží výjimku, kterou může zpracovat pomocí funkcí na zpracování chyb (error-reporting functions) SQLCODE a SQLERRM v handleru OTHERS. 5

Zachytávání výjimek Jakmile dojde k výjimce, přechází tok programu v daném bloku do oblasti výjimek. Tato oblast se skládá ze zachytávačů pro některé (WHEN <název výjimky>) nebo všechny ostatní (OTHERS). Za klauzulí THEN je uveden kód, který se v daném případě provede. Všeobecná syntaxe pro zpracování výjimek: EXCEPTION [WHEN <název výjimky1> THEN <příkazy>; [WHEN <název výjimky2> OR <název výjimky3> THEN <příkazy>; [OTHERS THEN <příkazy> >;] Zachytávač ostatních výjimek (OTHERS) zachytí všechny výjimky neošetřené v klauzuli WHEN. Klauzule WHEN OTHERS zachytí všechny výjimky. Je vhodné mít tento univerzální zachytávač na nejvyšší úrovni programu (nejvyšším bloku), protože poté z programu neunikne řádná výjimka. Jinak hrozí, že se chyba bude šířit do vnějšího prostředí. Když je vyvolána výjimka v exekuční oblasti bloku, postupuje řízení běhu programu podle následujících pravidel: 1. Jestliže má aktuální blok pro danou výjimku zachytávač, spustí jej a blok dokončí jako úspěšný. Řízení pak přechází do vnějšího bloku. 2. Jestliže neexistuje pro danou výjimku v daném bloku zachytávač, dojde k přenosu chyby do vnějšího (bloku). Pro tento blok se provede krok 1 - pokud existuje zachytávač pro danou výjimku, jinak se opakuje přenos do dalšího vnějšího bloku. 3. Jestliže vnější blok neexistuje, výjimka se dostane do volajícího prostředí. Pokud je vyvolána výjimka v deklarační oblasti při přiřazování, přechází výjimka ihned do vnějšího bloku. Pokud je vyvolána výjimka v zachytávači výjimek, přechází opět řízení ihned do vnějšího bloku. Neboli platí, že v danou chvíli může být aktivní pouze jediná výjimka. 6

Příklad 1: Po vyvolání výjimky A je tato zachycena ve vnitřním bloku a program pokračuje dalším příkazem ve vnějším bloku. Příklad 2: Po vyvolání výjimky A není tato zachycena vnitřním bloku a výjimka je propagována vnějšího bloku, kde je v sekci výjimek zachycena. ve do Příklad 3: Po vyvolání výjimky A není tato zachycena ve vnitřním bloku a výjimka je propagována do vnějšího bloku, bohužel ani zde není tato výjimka zachycena. Další vnější programový blok již neexistuje a PL/SQL proto propaguje výjimku do volajícího prostředí. 7

V zachytávači výjimek lze ke zjištění informací o chybě použít funkcí SQLCODE a SQLERRM (číslo chyby a chybová zpráva). Pro vnitřní výjimky SQLCODE vrací číslo chyby (Oracle error number), které je záporné (tedy kromě výjimky no data found, kdy SQLCODE vrací +100). Funkce SQLERRM vrací příslušnou chybovou zprávu (začínající kódem dané chyby). Pro uživatelské výjimky (user-defined exceptions) vrací fce SQLCODE +1 a SQLERRM vrací 'User-Defined Exception' Příklad: DECLARE v_vysledek NUMBER(9,2); v_vysledek := 5/0; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(' Chyba '); DBMS_OUTPUT.PUT_LINE('Kód chyby:' SQLCODE); DBMS_OUTPUT.PUT_LINE('Popis chyby:' SQLERRM); Při práci s výjimkami mohou vzniknout následující potřeby: 1) pokračování po vyvolání výjimky v provádění příkazů v rámci daného bloku - tuto potřebu ošetříme vložením dalšího (vnitřního) bloku do daného bloku a výjimku zpracujeme v rámci tohoto nově vloženého bloku. 2) použití vyhledávací proměnné - pokud v rámci bloku existuje více příkazů, které mohou vyvolat stejnou výjimku, je vhodné použít pomocnou proměnnou pro uložení označení příkazu, který se bude následně provádět. V zachytávači pak můžeme s hodnotou této proměnné pracovat, například ji logovat spolu s informací o vyskytnuvší se chybě. 3) opakování transakce - pokud chcete po vyvolání výjimky namísto přerušení transakce tuto transakci zopakovat, je potřeba transakci uzavřít do jednoho vnitřního bloku a poté umístit tento vnitřní blok do cyklu. Před započetím transakce je potřeba označit záchranný bod (savepoint). Pokud je transakce úspěšná, přijmete ji a opustíte cyklus. Pokud však selže, kontrola je předána zachytávači výjimek tohoto vnitřního bloku, kde odrolujete k savepointu a pokusíte se napravit problém. Program poté bude pokračovat dalším cyklem. Je však vhodné, aby cyklus měl jen konečný počet pokusů a bylo možné program ukončit. 8

2. Řízení transakcí v PL/SQL Z jedné z předchozích lekcí již znáte, že transakce zajišťují konzistentnost databáze a jejich vlastnosti označované zkratkou ACIT chrání transakční data před narušením. Víme, jak se chovají transakce v jazyce SQL, a zajímá nás, jak to bude v případě, kdy operace DML budou s daty pracovat uprostřed bloků PL/SQL. Pokud váš program selže uprostřed transakce, Oracle detekuje chybu a vrátí transakci - odroluje na začátek. Proto je databáze obnovena do původního stavu automaticky. Řízení transakcí se zajišťuje pomocí příkazů COMMIT, ROLLBACK, SAVEPOINT a SET TRANSACTION. COMMIT je trvalé potvrzení změn databáze provedených během aktuální transakce. ROLLBACK ukončí aktuální transakci a zruší všechny změny provedené od začátku transakce. SAVEPOINT označí aktuální bod zpracování transakce. Používá se pro odrolování transakce k bodu návratu příkazem ROLLBACK TO <bod návratu>. SET TRANSAKCE nastaví transakční vlastnosti - například úroveň izolace. Autonomní transakce Autonomní transakce probíhají samostatně - tj. bez transakčního dohledu z nadřízené transakce. To znamená, že jestliže v rámci autonomní nebo hlavní transakce použijeme potvrzení nebo odrolování, druhou transakci to neovlivní. Autonomní transakce se používají například pro zápis do protokolu událostí, který si sami chceme vytvářet. To nám umožní monitorovat aktivitu bez ohledu na její výsledek (tím mějme na mysli hlavní transakci), a opačně, úspěch či selhání zápisu do protokolu (pracuje v autonomní transakci) nemá vliv na hlavní transakci. Pro vytvoření autonomní transakce se použije direktiva (pragma) AUTONOMOUS_TRANSACTION, která se umístí do deklarační oblasti bloku. Autonomní kód můžeme použít ve funkcích, procedurách, spouštích, balíčcích a objektových typech. Chování si můžeme vysvětlit na následujícím příkladu. CREATE TABLE at_test ( id NUMBER NOT NULL, popis VARCHAR2( (50) NOT NULL ); INSERT INTO at_test (id, INSERT INTO at_test (id, popis) VALUES (1, 'Popis pro 1'); popis) VALUES (2, 'Popis pro 1'); Příkaz SELECT * FROM at_test; vrátí 2 řádky. 9

Nyní vložíme 8 řádků s použitím kódu s autonomní transakcí: DECLARE PRAGMA AUTONOMOUS_TRANSACTION; FOR i IN 3.. 10 LOOP INSERT INTO at_test (id, popis) VALUES (i, 'Popis pro ' i); END LOOP; COMMIT; Jak vidíme, celá autonomní transakce byla potvrzena příkazem COMMIT. Pokud nyní provedeme příkaz ROLLBACK; Dotaz SELECT * FROM at_test; vrátí 8 řádků. Příkaz ROLLBACK je tedy aplikován pouze na řádky vložené z hlavní transakce, ale na řádky vložené autonomní transakcí nemá vliv. Druhý příklad ukazuje způsob zalogování chyby do tabulky error_logs, která bude použita jako protokol událostí. Nejdříve vytvoříme tuto tabulkuu a sekvenci pro generování m hodnot primárního klíče: CREATE TABLE error_logs ( id NUMBER(10) NOT NULL, log_timestamp TIMESTAMP NOT NULL, error_message VARCHAR2(4000), CONSTRAINT error_logs_pk PRIMARY KEY (id) ); CREATE SEQUENCE error_logs_seq; Dále vytvoříme proceduru pro zalogování chyby jako autonomní transakci: CREATE OR REPLACE PROCEDURE log_errors (p_error_message IN VARCHAR2) AS PRAGMA AUTONOMOUS_TRANSACTION; INSERT INTO error_logs (id, log_timestamp, error_message) VALUES (error_logs_seq.nextval, SYSTIMESTAMP, p_error_message); COMMIT; 10

Nyní provedeme kód PL/SQL, který vyvolá chybu, která je zachycena a uložena. -- Platný příkaz INSERT INTO at_test (id, description) VALUES (998, 'Description for 998'); -- Vynutit neplatný INSERT INSERT INTO at_test (id, description) VALUES (999, NULL); EXCEPTION WHEN OTHERS THEN log_errors (p_error_message => SQLERRM); ROLLBACK; Po vykonání kódu dostaneme hlášku: completed. PL/SQL procedure successfully Existenci dat v tabulce at_test zjistíme příkazem: SELECT * FROM at_test WHERE id >= 998; Odpovědí bude: no rows selected Podíváme se na obsah tabulky error_logs příkazem SELECT * FROM error_logs; Získáme výsledek: ID LOG_TIMESTAMP ERROR_MESSAGE ---- -------------------------------- ---------------------------------- 1 28-FEB-2012 11:10:10.107625 01400: cannot insert NULL into ("SCHEMANAME"."AT_TEST"."DESCRIPTION") Opět vidíme, že ROLLBACK hlavní transakce nezpůsobil změny v potvrzené autonomní transakci. Výjimky a transakce Vyvolání výjimky ani konec bloku neukončují transakci. Jedině v případě, kdy neošetřená výjimka je v bloku nejvyšší úrovně, která se rozšíří do volajícího prostředí, server automaticky transakci odvolá. 11

Pojmy k zapamatování Příkazy a funkce: PL/SQL, výjimky, zachytávač, řízení transakcí, EXCEPTION, RAISE, COMMIT, SAVEPOINT, ROLLBACK Problém: řízení toku programu při vyvolání chyby, zachycení výjimky Shrnutí V této lekci jste se seznámili s detekcí a zpracováním chyb v kódu PL/SQL. Velké množství chyb je předdefinováno systémem, ale můžeme vytvářet i uživatelsky definované chyby a tyto programově vyvolat. Důležitou částí je pak pochopení pravidel pro šíření výjimek (není-li výjimka zachycena v lokálním bloku, šíří se do bloku vnějšího, a pokud není zachycena ani v bloku nejvyšší úrovně, je ošetřena ve volajícím prostředí). Další část dokumentu se věnovala transakčnímu zpracování. Z hlediska transakčního zpracování je důležité zejména neopomenout příkazy pro řízení transakcí u těch programových kódů, které budouu realizovat DML příkazy. Otázky na procvičení 1. Jak se pracuje s uživatelsky definovanými výjimkami? 2. Popište zachytávání a šíření chyb mezi bloky PL/SQL. 3. K čemu slouží funkce SQLCODE a SQLERRM? 4. Jakým způsobem zajistit, aby po výskytu chyby zůstal běh programu v daném modulu? 5. Jak probíhá zpracování transakcí v modulech PL/SQL? Odkazy a další studijní prameny http://www.oracle-base.com/articles/misc/autonomoustransactions.php http://www.techonthenet.com/oracle (syntaxe příkazů SQL jazyka a funkcí) http://www.oracle.com/ /technetwork/database/enterpriseedition/documentation (dokumentace k databázové platformě Oracle) http://www.penguin.cz/ /noviny/?id=chip/index (seriál Databáze standardu SQL z časopisu CHIP) Odkazy a další studijní prameny LACKO, L. Oracle, správa, programování a použití databázového systému. Praha: Computer Press, 2007. ISBN 80-251-1490-2. URMAN, S., HARDMAN, R., MCLAUGHLIN, M. Oracle - programování v PL/SQL. Computer Press, 2008. ISBN 978-80-251-1870-2 12