Aplikativni SQL - poincare.matf.bg.ac.rspoincare.matf.bg.ac.rs/~gordana/SQLC.pdf · Aplikativni SQL...

Post on 01-Jul-2018

285 views 3 download

transcript

Aplikativni SQL

Aplikativni SQL

• Interaktivni SQL

• Aplikativni SQL

– Statički SQL

– Dinamički SQL

• Druge mogućnosti ugradnje blokova za komunikaciju sa SUBP

u program.

• U slučaju sistema DB2, te mogućnosti su

– direktni pozivi DB2 funkcija (Call Level Interface – CLI)

– upotreba ODBC standarda (Open Database Connectivity) –

dinamički

– zapamćene procedure

ODBC

• ODBC: standardizovanje interfejsa korisnika i međusistema (prema

SUBP), nezavisno od SUBP kome će međusistem proslediti korisnički

zahtev.

• Nemoguće je koristiti specifičnosti pojedinog sistema (u ovom

slučaju DB2), a svi upiti upućeni sistemu DB2 preko ODBC-a

izvršavaju se dinamički.

CLI

• Direktni pozivi DB2 funkcija (CLI-sistem) su specifični za DB2 sistem i

koriste sve njegove mogućnosti (kao i aplikativni SQL), mada su

maksimalno usaglašeni sa ODBC pristupom

• CLI je alternativa aplikativnom dinamičkom SQL-u

• DB2 CLI aplikacija ne mora ni da se prekompilira ni da se povezuje

sa bazom; ona koristi standardni skup funkcija za izvršenje SQL

iskaza u vreme izvršenja programa.

• DB2 CLI aplikacija postaje ”prenosivija” u odnosu na aplikaciju u

aplikativnom SQL-u (bar kada su razne DB2 platforme u pitanju)

• osnovna prednost aplikativnog SQL-a u tome što može da koristi

statički SQL i što je u značajnoj meri standardizovan pa se može

koristiti (u manjoj ili većoj meri) i među različitim SUBP-

platformama.

CLI

• Aplikacije koriste CLI pozive funkcija u vreme izvršavanja da se

povežu sa bazama podataka, izvrše SQL iskaze i pretraže

informacije o podacima i statusu

• Primeri DB2 CLI funkcija:

• SQLConnect() – uspostavlja konekciju sa ciljnom bazom

podataka

• SQLPrepare()

• SQLExecute()

• SQLExecDirect()

• SQLRowCount()

• SQLDisconnect ()

• SQLPrimaryKeys () ...

CLI / primerSQLRETURN SQLConnect (

SQLHDBC ConnectionHandle, /* hdbc */

SQLCHAR * ServerName, /* szDSN */

SQLSMALLINT NameLength1, /* cbDSN */

SQLCHAR * UserName, /* szUID */

SQLSMALLINT NameLength2, /* cbUID */

SQLCHAR * Authentication, /* szAuthStr */

SQLSMALLINT NameLength3); /* cbAuthStr */

CLI / primer

CLI / primer

/* From the CLI sample utilcli.c */

/* ... */

/* connect to the database */

printf( "\nConnecting to %s ...\n", dbAlias ) ;

sqlrc = SQLConnect( *pHdbc, (SQLCHAR *)dbAlias, SQL_NTS, (SQLCHAR

*)user, SQL_NTS, (SQLCHAR *)pswd, SQL_NTS );

HANDLE_CHECK( SQL_HANDLE_DBC, *pHdbc, sqlrc, pHenv, pHdbc ) ;

printf( "Connected to %s.\n", dbAlias ) ;

return(0);

}

Zapamćena procedura (stored

procedure)• U slučaju da aplikacija zahteva prednosti oba mehanizma (DB2 CLI i

aplikativnog SQL-a), moguće je koristiti statički SQL unutar DB2 CLI

aplikacije kreiranjem zapamćenih procedura napisanih na statičkom

SQL-u.

• Zapamćena procedura se poziva iz DB2 CLI aplikacije i izvršava se na

serveru.

• Jednom napisanu zapamćenu proceduru može da pozove bilo koja

DB2 CLI ili ODBC aplikacija.

• Aplikacija može biti projektovana tako da se izvršava u dva dela –

jedan na klijentu a drugi na serveru.

• Zapamćene procedure imaju niz prednosti, od smanjenja mrežnog

saobraćaja pri prenosu podataka do koncepta učaurenja koji

povećava bezbednost podataka.

Zapamćena procedura (stored

procedure)• Zapamćena procedura (engl. stored procedure) je programski blok

koji se poziva iz aplikacije na klijentu a izvršava se na serveru baza

podataka.

• Piše se u odgovarajućim proširenjima SQL-a, kao što je, na primer,

Oracle PL/SQL ili C-Java/SQL u DB2, kompilira i pamti u biblioteci

odgovarajućeg SUBP.

• Deo logike aplikacije prenosi se sa klijenta na server, i povećava

funkcionalnost servera.

• Najčešći razlog za korišćenje zapamćenih procedura je intenzivna

obrada podataka iz baze podataka, koja proizvodi malu količinu

rezultujućih podataka, ili

• činjenica da je skup operacija (koje se izdvajaju u zapamćenu

proceduru) zajednički za više aplikacija.

Aplikativni (ugnježdeni) SQL

• Matični (host) jezik – C, Java, ...

• Princip dualnosti

• Slogovno / skupovni odnos: kursor

• Jednočlani rezultat: INTO linija u SELECT iskazu

• 1. prefix EXEC SQL...

• 2. EXEC SQL BEGIN DECLARE SECTION

...

EXEC SQL END DECLARE SECTION

Aplikativni (ugnježdeni) SQL

3. Obraćanju matičnoj promenljivoj u okviru SQL iskaza prethodi

dvotačka, koja razlikuje tu promenljivu od imena atributa SQL-a

EXEC SQL SELECT NASLOV, OBLAST

INTO :KNJIGA, :OBLAST

FROM K

WHERE K_SIF = :DATI_K_SIF

Indikatorska promenljiva

EXEC SQL SELECT NASLOV, OBLAST

INTO :KNJIGA, :OBLAST:O1

FROM K

WHERE K_SIF = :DATI_ K_ SIF

Aplikativni (ugnježdeni) SQL

4. Program sa izvršnim SQL iskazima komunicira sa DB2 preko

memorijskog prostora koji se zove SQL prostor za komunikaciju

(engl. SQL Communication Area, SQLCA).

• SQLCA je struktura koja se ažurira posle izvršenja svakog SQL

iskaza.

• Najčešće korišćena promenljiva SQLCA strukture je SQLCODE.

• Indikator uspešnosti: 0, <0, >0 (100)

• Uključenje u program: EXEC SQL INCLUDE SQLCA

• Pre prvog izvršnog SQL iskaza

Aplikativni (ugnježdeni) SQL

5. Provera statusa izvršavanja (SQLCODE)

Direktiva

EXEC SQL WHENEVER uslov akcija

Uslov:

• NOT FOUND (nije nađen – drugi zapis za SQLCODE = 100),

• SQLERROR (indikator greške – drugi zapis za SQLCODE < 0) ili

• SQLWARNING (indikator upozorenja – drugi zapis za SQLCODE > 0

AND SQLCODE <> 100);

Akcija:

• CONTINUE – program nastavlja sa izvršenjem ili

• GOTO obeležje – skok na deo programa u kome se nastavlja obrada,

npr. izveštavanje o uzroku nastalog uslova.

Aplikativni (ugnježdeni) SQL

Na primer,

EXEC SQL WHENEVER SQLERROR CONTINUE

SQLCA sadrži još i:

• SQLSTATE tipa CHAR[5] (slično promenljivoj SQLCODE)

(npr. prva dva karaktera ’01’ promenljive SQLSTATE predstavljaju grupu

kodova – upozorenja)

• Niz celih brojeva SQLERRD[6] koji se odnosi na razne vrste

informacija o nastaloj grešci ili rezultatu izvršavanja SQL iskaza,

• Skup CHAR(1) promenljivih SQLWARN0 – SQLWARN10 koje sadrže

informacije o uzroku upozorenja.

Aplikativni (ugnježdeni) SQL

• Neki od ovih elemenata SQLCA strukture:

• SQLERRD[3] sadrži broj vrsta obrađenih (unetih, ažuriranih ili izbrisanih)

izvršavanjem poslednjeg INSERT, UPDATE ili DELETE iskaza

• SQLERRD[5] sadrži ukupan broj izbrisanih, unetih ili ažuriranih vrsta,

direktno ili indirektno, izvršavanjem odgovarajućeg iskaza;

• SQLwarn0 sadrži ’W’ ako bar jedna od preostalih SQLwarni promenljivih

sadrži upozorenje (’W’);

• Npr. SQLWARNING u direktivi WHENEVER:

disjunkcija uslova (SQLCODE >0 AND SQLCODE <>100 )

OR SQLWARN0 = ’W’;

• SQLWARN1 sadrži ’W’ ako je pri dodeli promenljivoj matičnog jezika

odesečena vrednost kolone tipa niske znakova (CHAR(m));

• SQLWARN2 sadrži ’W’ ako je došlo do eliminacije NULL vrednosti pri

primeni agregatne funkcije.

Aplikativni (ugnježdeni) SQL: rad sa

kursorima• Deklarisanje

EXEC SQL DECLARE X CURSOR FOR

SELECT I_SIF, NAZIV, STATUS

FROM I

WHERE DRZAVA = :Y

Za čitanje:

FOR FETCH ONLY (FOR READ ONLY)

(može i u specifičnom poretku: ORDER BY)

Za ažuriranje liste kolona rezultata

FOR UPDATE OF lista-kolona

Aplikativni (ugnježdeni) SQL: rad sa

kursorima• Ne može se ažurirati ako:

• DISTINCT opciju u spoljašnjoj SELECT liniji;

• skupovnu (UNION, INTERSECT, EXCEPT) operaciju osim UNION

• ALL;

• agregatnu funkciju u spoljašnjoj SELECT liniji;

• GROUP BY ili HAVING liniju u spoljašnjem SELECT iskazu;

• ORDER BY liniju;

• podupit nad istom tabelom;

• dve ili više tabela u FROM liniji

• tabelu-pogled (u FROM liniji) koja se ne može ažurirati;

• FOR FETCH ONLY (FOR READ ONLY) opciju.

Aplikativni (ugnježdeni) SQL: rad sa

kursorima• Otvaranje i dohvatanje:

EXEC SQL OPEN X; /* otvaranje kursora */

WHILE (SQLCODE == 0) /* ima još vrsta i FETCH se uspešno izvršava */

{ EXEC SQL FETCH X INTO :I_SIF, :NAZIV, :STATUS;

/* "uzimanje" sledece vrste */

...

}

EXEC SQL CLOSE X

EXEC SQL FETCH X INTO :I_SIF, :NAZIV, :STATUS:IND;

Aplikativni (ugnježdeni) SQL: rad sa

kursorima• Ažuriranje:

EXEC SQL UPDATE I

SET STATUS = STATUS + :POVECANJE

WHERE CURRENT OF X

Aplikativni (ugnježdeni) SQL:

primerPovećanje statusa (za 10%) svim izdavačima koji su izdali knjigu sa šifrom koja

se nalazi u programskoj promenljivoj “knjiga”, može se izraziti programskom

strukturom sledećeg oblika:

#include <stdio.h>

#include <stdlib.h>

EXEC SQL INCLUDE SQLCA;

EXEC SQL BEGIN DECLARE SECTION;

char knjiga[5];

char i[6];

char naziv[20];

short status;

char drzava[20];

short n_ind, s_ind, d_ind;

EXEC SQL END DECLARE SECTION;

Aplikativni (ugnježdeni) SQL:

primerVoid greska(char *poruka)

{...

printf("SQL greska, SQLCODE = %i, %s\n ", SQLCODE, poruka);

EXEC SQL ROLLBACK;

exit(0);

}

Aplikativni (ugnježdeni) SQL:

primer{EXEC SQL CONNECT to izdavastvo;

if (SQLCODE <> 0) greska(" pri otvaranju konekcije");

EXEC SQL DECLARE Z CURSOR FOR

SELECT I_SIF, NAZIV, STATUS, DRZAVA

FROM I

WHERE EXISTS

(SELECT *

FROM KI

WHERE KI.I_SIF = I.I_SIF AND KI.K_SIF = :knjiga)

FOR UPDATE OF STATUS

EXEC SQL WHENEVER NOT FOUND CONTINUE;

EXEC SQL WHENEVER SQLERROR CONTINUE;

EXEC SQL WHENEVER SQLWARNING CONTINUE;

...

Aplikativni (ugnježdeni) SQL:

primerEXEC SQL OPEN Z;

if (SQLCODE <> 0) greska(" pri otvaranju kursora Z");

EXEC SQL FETCH Z INTO :i, :naziv:n_ind, :status:s_ind, :drzava:d_ind;

if (SQLCODE == 100)

greska(" nema izdavaca koji su izdali datu knjigu");

if (SQLCODE <>0)

greska(" pri prvom uzimanju vrste o trazenom izdavacu");

while(SQLCODE <> 100)

{

printf("naziv izdavaca je %s", naziv);

EXEC SQL UPDATE I

SET STATUS = STATUS * 1.1

WHERE CURRENT OF Z;

Aplikativni (ugnježdeni) SQL:

primerIf ((SQLCODE <> 0))

greska(" pri azuriranju tekuceg izdavaca");

EXEC SQL FETCH Z INTO :i, :naziv:n_ind, :status:s_ind, :drzava:d_ind;

if ((SQLCODE <> 0) && (SQLCODE <> 100))

greska(" pri uzimanju (FETCH) sledeceg izdavaca");

}

EXEC SQL CLOSE Z;

if (SQLCODE <> 0) greska(" pri zatvaranju kursora Z");

EXEC SQL COMMIT;

if (SQLCODE <> 0) greska(" pri operaciji COMMIT");

EXEC SQL CONNECT RESET;

if (SQLCODE <> 0) greska(" pri zatvaranju konekcije");

}

Dinamički SQL

• U statičkom SQL-u iskaz je poznat u vreme pisanja (prekompilacije)

programa

• Statički SQL iskaz u pretkompilaciji se zamenjuje fiksiranim

(poznatim) CLI pozivom

• U dinamičkom SQL-u iskaz je poznat tek u vreme izvršavanja

programa

• Iskaz je vrednost matične promenljive tipa niske znakova

• Vredost matične promenljive (pa i SQL iskaza) može da se menja u

toku izvršavanja programa

• Nad dinamičkim SQL iskazom potrebno je primeniti statički

PREPARE iskaz i zatim statički EXECUTE iskaz

• EXEC SQL PREPARE S1 FROM :V1

• EXEC SQL EXECUTE S1

Dinamički SQL

• Mogu da se pripreme i izvrše izvršni iskazi, na primer:

• ALTER, COMMIT, CREATE, DELETE, DROP, INSERT, ROLLBACK,

SELECT, SET, UPDATE,...

• statički iskaz EXECUTE IMMEDIATE

• Na primer, vrednost matične promenljive V1 jeste niska

znakova “DELETE FROM KI WHERE K_SIF = ’k1’ ”,

• iskaz

• EXEC SQL EXECUTE IMMEDIATE :V1

Dinamički SQL

• Matične promenljive:

• Primer: Neka je vrednost matične promenljive V1 niska

znakova “INSERT INTO K VALUES (?, ?, ?)”

• Posle izvršenja iskaza

• EXEC SQL PREPARE K_INSERT FROM :V1

• Izvršava se i iskaz

• EXEC SQL EXECUTE K_INSERT USING :KSIFRA, :KNASLOV,

:KOBLAST

Dinamički SQL

• Ne mogu dinamički da se izvrše:

CLOSE

DECLARE

EXECUTE

EXECUTE IMMEDIATE

FETCH

OPEN

PREPARE

WHENEVER

Dinamički SQL

• Dinamički pripremljen SELECT iskaz može da se izvrši

korišćenjem kursora:

• 1. priprema iskaza

• 2. deklarisanje kursora nad imenom iskaza

• 3. otvaranje kursora

• 4. uzimanje vrsta iz rezultujuće tabele

• 5. zatvaranje kursora

Dinamički SQL: primer

• Neka program pretražuje šifre knjiga i šifre izdavača iz tabele

KI, dinamičkim izvršavanjem SELECT iskaza oblika

SELECT K_SIF, I_SIF

FROM KI

WHERE ...

(iskaz se čita sa terminala, a korisnik zadaje uslov u WHERE liniji)

Dinamički SQL: primer

EXEC SQL PREPARE ISKAZ FROM :KI_NISKA;

...

EXEC SQL DECLARE C1 CURSOR FOR ISKAZ;

...

EXEC SQL OPEN C1;

WHILE ...

{ ...

EXEC SQL FETCH C1 INTO :K BR, :I BR;

...

}

...

EXEC SQL CLOSE C1;

Dinamički SQL

Dinamički SQL nudi potpunu fleksibilnost

programiranja.