Základy embedded SQL a použití kurzorů
Autor: Pavel Petrek
Seminář: Administrace Oracle
Shrnutí
- Cíl: propojení jazyka SQL s vyšším programovacím jazykem.
- Překlad programu (V Oracle Pro*C s příponou .pc)
- Nástrojem, který je součástí databázového systému, prekompilujeme kombinovaný zdrojový kód (např. C,SQL) na čistý jazyk (např. C).
- Překladačem vybraného jazyka přeložíme získaný zdrojový kód.
- Oba kroky obsaženy v připraveném skriptu v učebně "pcc".
- Syntaxe: EXEC SQL uvozuje každý příkaz, který je zpracováván databázovým prekompilátorem. Příkaz končí středníkem.
- SQL a direktiva #include: Obsahuje-li header "EXEC SQL" příkazy, includujeme pomocí EXEC SQL INCLUDE file.h;
- Zdrojový kód by měl obsahovat #include sqlca.h.
- Hostitelské proměnné: Určeny pro komunikaci databáze s prostředím programu. Deklarace takových proměnných začíná (resp. končí) EXEC SQL BEGIN DECLARE SECTION (... END DECLARE SECTION)
- Povolené typy
- char, char[n], int, short, long, float, double, VARCHAR[n]
- Použití proměnné v SQL uvozeno dvojtečkou, jinak je považována za databázové pole.
- Indikátorové proměnné: jsou hostitelské proměnné (typu short) následující v SQL příkazu za jinou proměnnou. Může obsahovat následující hodnoty:
- 0: Proměnná koretně naplněna.
- -1: Vkládaná hodnota je NULL, proměnná má neurčitý obsah.
- -2: Vkládaná hodnota je větší než proměnná a není možné určit skutečnou velikost.
- >0: Vkládaná hodnota je větší než proměnná, skutečná velikost je hodnota indikátoru.
- Při použití v INSERT / UPDATE jsou relevantní pouze hodnoty -1 a 0.
Ukázka použití hostitelských proměnných
EXEC SQL BEGIN DECLARE SECTION;
char mujtext[20 + 1];
short i_mujtext;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL SELECT pole FROM tabulka INTO :mujtext :i_mujtext WHERE druhepole = 15;
if (i_mujtext == -1) printf("NULL"); else printf(mujtext);
Připojení k databázi
- Připojení: EXEC SQL CONNECT :user IDENTIFIED BY :password ...
- :user : Uživatelské jméno pro připojení.
- :password : Heslo k uživatelskému jménu.
- Odpojení s commitem změn: EXEC SQL COMMIT WORK RELEASE
- Odpojení s rollbackem: EXEC SQL ROLLBACK WORK RELEASE
Ukázka použití CONNECT a INSERT pole
EXEC SQL BEGIN DECLARE SECTION;
char user[20 + 1];
char pwd[20 + 1];
float insval[50];
EXEC SQL END DECLARE SECTION;
strcpy(user,"novak");
strcpy(pwd,"krokodyl");
EXEC SQL CONNECT :user IDENTIFIED BY :pwd;
...
EXEC SQL INSERT INTO tabulka (mojepole) VALUES (:insval);
EXEC SQL COMMIT WORK RELEASE;
Kurzory
- Definujeme jako prostředek pro zpracování víceřádkových výsledků SQL dotazu
- Kurzor je pojmenovaný, můžeme mít několik různých kurzorů otevřených najednou.
Deklarace kurzoru
- Syntaxe: EXEC SQL DECLARE curs_name CURSOR FOR SELECT ....
- curs_name: Pojmenování kurzoru.
- SELECT ...: Dotaz pro který se kurzor připraví.
Otevření / zavření kurzoru
- Syntaxe: EXEC SQL OPEN curs_name; / EXEC SQL CLOSE curs_name;
- curs_name: Jméno deklarovaného kurzoru. Jméno není uváděno s dvojtečkou, nejedná se o proměnnou, ale o identifikátor pro SQL prekompilátor.
Vyzvednutí záznamu a posun kurzoru
- Syntaxe: EXEC SQL FETCH curs_name INTO :variable1, :variable2 :i_variable2;
- curs_name: Jméno otevřeného kurzoru.
- :variable1 : Hostitelské proměnné pro vyzvednutá data.
- :i_variable2 : Indikátorová proměnná.
Ošetření varování, chyb, jiných akcí - příkaz WHENEVER
- Příkaz WHENEVER nastaví od daného místa prekompilace způsob ošetřování varování, chyb a nepřítomnosti záznamu.
- Syntaxe: EXEC SQL WHENEVER cond solution;
- cond:
- NOT FOUND: Je-li odpověď na FETCH nebo SELECT žádná položka, je vygenerována akce solution.
- SQLERROR: Skončí-li jakákoliv akce SQL EXEC chybou, je provedeno solution.
- SQLWARNING: Skončí-li jakákoliv akce SQL EXEC varováním, je provedeno solution.
- solution:
- CONTINUE: Program pokračuje následujícím příkazem.
- GOTO label: Program skočí na zadaný label.
- STOP: Program se ukončí.
- DO routine: Program zavolá funkci routine.
- DO BREAK: Zavolá break pro opuštění cyklu.
- DO CONTINUE: Zavolá continue pro pokračování dalšího kroku cyklu.
Ukázka použití KURZORU a ošetření posledního řádku
EXEC SQL BEGIN DECLARE SECTION;
int cislo;
short i_cislo;
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE mujkurzor CURSOR FOR
SELECT pole FROM tabulka WHERE druhepole > 20;
EXEC SQL OPEN mujkurzor;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH mujkurzor INTO :cislo :i_cislo;
if (i_cislo == -1) printf("NULL\n"); else printf("Hodnota %i\n",cislo);
}
EXEC SQL CLOSE mujkurzor;
Zdroje