Upload
renate
View
126
Download
4
Embed Size (px)
DESCRIPTION
Programovanie DB aplikácií. Embedded SQL Z. Ondrejčíková. Čo potrebujeme. Interaktívne načítanie parametrov SQL príkazu zo vstupu Testovanie dat Spracovávanie výstupu SELECTu procedurálny alebo objektový jazyk. Príklad- Školský informačný systém. Student (ids, meno, rocnik, obor) - PowerPoint PPT Presentation
Citation preview
Programovanie DB aplikácií
Embedded SQL
Z. Ondrejčíková
Čo potrebujeme
• Interaktívne načítanie parametrov SQL príkazu zo vstupu
• Testovanie dat• Spracovávanie výstupu SELECTu
• procedurálny alebo objektový jazyk
Príklad- Školský informačný systém
Student (ids, meno, rocnik, obor)
Ucitel (idu, meno, katedra)
Predmet (idp, nazov, idu)
Zapisany (ids, idp)
Príklad - SIS
• Vlož do tabuľky Predmet predmet zadaný premennými: predmet_, idp_, idu_
• V klasickom SQL nemôžeme vkladať vopred neznáme hodnoty
• Riešením je embedded SQL
Syntax Pro*C/C++
• Hostiteľským jazykom je C/C++• Každý SQL dotaz začína EXEC SQL a končí
bodkočiarkou (;)• EXEC SQL funguje ako direktiva preprocesoru• Hostiteľské premenné sa môžu používať aj vnútri SQL
dotazu – píše sa pred nich dvojbodka
Pripojenie sa k databáze
• EXEC SQL CONNECT meno/heslo• EXEC SQL CONNECT meno IDENTIFIED BY heslo
Odpojenie
• S uložením zmien: EXEC SQL COMMIT WORK RELEASE
• Bez uloženia zmien : EXEC SQL ROLLBACK WORK RELEASE
Include
• Sqlca.h – sql communicative area (informácie o prevedení SQL dotazov; chyby, varovania...)
• EXEC SQL INCLUDE sqlca;• #include<sqlca.h>
Deklaratívne vs. výkonné SQL dotazy
• Deklaratívne nič nevykonávajú
• Môžu sa v programe nachádzať všade tam, kde sa môžu nachádzať deklarácie v C
• Musia predchádzať výkonným
• Výkonné priamo pracujú s DB
• Vždy po ich prevedení by sa mala previesť kontrola, či prebehli bez chýb
Reakcia na chyby
• EXEC SQL WHENEVER podmienka akcia• podmienka = NOT FOUND | SQLERROR |
SQLWARNING
• akcia = do meno_funkcie() | break | continue | goto label
Reakcia na chyby
• EXEC SQL WHENEVER popisuje, ako sa má reagovať na nejaký druh chyby
• Platí na všetky príkazy, ktoré sú pozične za ním, až do nasledujúceho „whenever“ s tou istou podmienkou
Príklad 1
• Vložiť do tabuľky Predmet predmet určený premennými predmet_, idp_, idUcitel_
#include <sqlca.h>
#include <stdio.h>
Príklad 1
int main () { /* deklaracia premennych */ EXEC SQL BEGIN DECLARE SECTION; int idp_ = 1; int idUcitel_ = 11; char predmet_ [20] = “Matematika”; EXEC SQL END DECLARE SECTION; /* osetrenie chyb */ EXEC SQL WHENEVER SQLERROR do printf (“Chyba”); EXEC SQL CONNECT “scott/tiger”; if (sqlca.sqlcode == 0) { EXEC SQL INSERT INTO Predmet (idp, nazov, idu) VALUES (:idp_, :predmet_, :idUcitel_); } EXEC SQL COMMIT WORK RELEASE;}
Poznámky
• Jednoriadkové komentáre musia byť uvedené /*...*/, nesmú sa používať komentáre //...
• sqlca je štruktura obsahujúca niekoľko komponent, ktoré nám pomáhajú zistiť ako prebehol SQL dotaz
• Všetky komponenty a ich popis nájdete na: http://rfhs8012.fh-regensburg.de/~oracle/proc/ch12.html#ERR
Poznámky
• sqlca.sqlcode má hodnotu nula, ak posledný sql dotaz prebehol správne
• Hostiteľské premenné sa môžu volať aj rovnakým menom ako tabuľky, názvy atributov tabuliek a iné identifikátory SQL dotazov (sú uvedené s : na zaciatku)
• Konvencia – premenné označujúce data ekvivalentné atributom sa zvyknú nazývať rovnako ako atribut s „_“ na konci
Príklad 2
• Zisti meno študenta s identifikačným číslom 1.
EXEC SQL BEGIN DECLARE SECTION;
char meno[20];
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT meno
INTO :meno;
FROM Student
WHERE Student.ids=1;
Použitie premenných v embedded SQL
• Ako vstupné premenné pre dotaz SQL: INSERT, UPDATE, DELETE• Ako výstup dotazu SQL (kam sa má výstup uložiť) : SELECT
Práca s poľami
• Doteraz sme pracovali vždy s jedným záznamom tabuľky (vkládanie jedného záznamu, vyberanie jedného záznamu)
• Väčšinou viac záznamov• Zjednodušenie práce : polia
Príklad 3
• Vlož do tabuľky Zapisany hodnoty z polí idp_, ids_. Tzn. V poli idp_ máme uložené čísla predmetov a v poli ids_ čísla študentov v odpovedajúcom si poradí.
/* polia uz predpokladame naplnene */EXEC SQL INSERT INTO Zapisany (idp, ids) VALUES (:idp_, :ids_);
• Tento príkaz urobí to isté ako nasledujúci:
/* riadiaca premenna i musi byt deklarovana v ramci declare section */for (i=0; i< MAX; i++) { EXEC SQL INSERT INTO Zapisany (idp, ids) VALUES (:idp_[i], :ids_[i]);}
SELECT INTO pole
• Väčšinou je výsledkom SELECTu viac ako jeden riadok• Príklad :
EXEC SQL BEGIN DECLARE SECTION;
int ids[20];
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT ids
INTO :ids
FROM Student;
• Vloží do poľa ids ident. čísla všetkých študentov
Problém
• Predchádzajúci príklad bude fungovať iba v prípade, že výsledkom SELECTu nebude viac ako 20 riadkov
• Pre viac ako 20 riadkov sa do poľa ids dostane iba prvých 20 riadkov
• Riešenie : SELECT zanoríme do cyklu (ak ešte nie sú spracované všetky riadky, pokračuj)
• Problém : Každý priechod cyklom sa do poľa dostane vždy tých istých prvých 20 riadkov
Kurzory
• Sú to akési ukazatele aktuálneho riadku
• Správne riešenie predchádzajúceho príkladu:
EXEC SQL DECLARE c CURSOR FOR
SELECT ids
FROM Student;
EXEC SQL OPEN c;
EXEC SQL WHENEVER NOT FOUND do break; for (;;) { EXEC SQL FETCH c INTO :ids;
/* ... spracovanie ids... */
}
Poznámky
• DECLARE CURSOR je čisto deklaratívny príkaz, nič nevykonáva, označuje daný príkaz (v našom prípade SELECT) a pomenováva ho
• Až OPEN CURSOR je výkonným príkazom; pri jeho zavolaní sa vykoná príkaz definovaný kurzorom c
• Príkaz WHENEVER spôsobí opustenie cyklu vo chvíli, kedy sme spracovali všetky riadky a nie je nájdený žiaden ďalší
• Príkaz FETCH postupne do premennej ids načíta toľko riadkov z výstupu SELECTu, koľko je možné (v našom prípade 20) a normálne nasleduje spracovanie týchto riadkov
Pokračovanie
Nadvädzujú referáty– Dynamic SQL– Transakčné spracovanie