Home - qdidactic.com
Didactica si proiecte didacticeBani si dezvoltarea cariereiStiinta  si proiecte tehniceIstorie si biografiiSanatate si medicinaDezvoltare personala
referate stiintaSa fii al doilea inseamna sa fii primul care pierde - Ayrton Senna





Aeronautica Comunicatii Drept Informatica Nutritie Sociologie
Tehnica mecanica

Baze de date


Qdidactic » stiinta & tehnica » informatica » baze de date
Programarea aplicatiilor de Baze de Date



Programarea aplicatiilor de Baze de Date


Programarea aplicatiilor de Baze de Date


Pentru programarea aplicatiilor de baze de date relationale se folosesc combinatii de limbaje de programare si biblioteci de programe, fiecare SGBD oferind diferite solutii, mai mult sau mai putin incadrate in standardele existente. In majoritatea cazurilor, SGBD-ul prelucreaza instructiuni (comenzi) SQL, dar acestea pot fi primite si prelucrate in cateva moduri distincte, in combinatie cu programe scrise in diferite alte limbaje.

Daca se considera arhitectura clasica a unui sistem de baze de date compus dintr-un server (care este chiar SGBD-ul) si un client (aplicatia de baze de date), atunci dezvoltarea aplicatiilor de baze de date implica prelucrari la nivel client si prelucrari la nivel server.



Partea server de programare a bazelor de date (server-side) permite stocarea chiar in baza de date a unor proceduri care pot fi apelate de programele client. Procedurile stocate in baza de date extind functionalitatea serverului (SGBD) si folosesc, de regula, limbaje procedurale care, la randul lor pot apela in diferite moduri comenzi SQL. Dintre limbajele procedurale, PL/SQL pentru produsele Oracle si Transact SQL pentru produsele Microsoft (SQL Server) sunt cele mai cunoscute.

Programele client de prelucrare a bazelor de date se pot dezvolta la randul lor in mai multe modalitati diferite, in functie de cerintele aplicatiei: se pot dezvolta ca aplicatii independente sau se pot integra cu un server Web, pot folosi sau nu biblioteci de componente software, etc.

In forma cea mai simpla, partea client de programare a bazelor de date (client-side) se poate dezvolta ca un program independent (stand-alone) folosind:

Limbajul SQL integrat.

Interfete de programare (API – Application Programming Interface).

In limbajul SQL integrat instructiunile SQL sunt integrate direct in codul programului sursa scris intr-un limbaj gazda (Ada, Pascal, Fortran, Cobol, Pascal, C, Pl/1). Controlul fluxului de operatii este realizat prin instructiuni ale limbajului gazda, iar operatiile cu baza de date sunt realizate prin comenzile SQL. Funizorii de SGBD-uri pun la dispozitia programatorilor doua categorii de limbaj SQL integrat: SQL integrat static si SQL integrat dinamic.

Limbajul SQL integrat static este cel mai simplu, dar ofera o slaba flexibilitate de utilizare. Instructiunile SQL care se pot executa sunt statice, adica etrebue sa fie cunoscut continutul lor de la inceput, inainte de compilarea si executia programului. Un precompilator transforma instructiunile SQL integrate in rutine de apel, iar dupa compilare si link-are programul va accesa baza de date si va executa diferite operatii pentru client, fixe si stabilite de la inceput.

Limbajul SQL dinamic permite realizarea unor programe de aplicatii de uz mai general, in care clientul poate cere anumite operatii cu baza de date in mod dinamic, in cursul executiei. Pentru o astfel de functionalitate, instructiunile SQL nu pot fi fixate (cunoscute) din faza de compilare si programul pregateste o instructiune pe care o transmite SGBD-ului.

Interfetele de programare a bazelor de date (API) reprezinta o tehnica alternativa fata de tehnica integrarii limbajului SQL si permite dezvoltarea aplicatiilor client intr-o maniera mult mai flexibila, mai usor de dezvoltat si de intretinut. Interfetele separa partea de program client de biblioteca de acces si, mai departe de programul din partea de server, iar aceasta separare ofera modularitate, stabilitate si independenta mai ridicata a aplicatiilor.

Ca interfete de programare a bazelor de date, exista atat interfete specifice, oferite de diferite SQBD-uri, dar exista si interfete cu un grad mare de generalitate, care pot fi folosite pentru mai muilte tipuri de SGBD-uri prin intermediul unor drivere, cum sunt interfetele ODBC (Open DataBase Connectivity) sau JDBC (Java DataBase Connectivity). In lucrarea de fata se vor studia interfete de programare pentru partea client a aplicatiilor de baze de date.


5.1. Interfata de programare MySQL C API


Interfata MySQL C-API este distribuita odata cu SGBD-ul sub forma unei biblioteci (libmysql) care permite accesul programelor C la serverul MySQL. Fisierele bibliotecii (fisierul de import libmysql.lib si fisierul bibliotecii dinamice libmysql.dll) se gasesc in directorul libdebug relativ la directorul de instalare al serverului mysql.

Pentru testarea interfetei C MySQL, in mediul de deyvoltare MSVC 6.0 se creeza un proiect de tipul Win32 Console Application (cu numele, de exemplu, MySQLC) in care se insereaza un fisier (MySQLC.cpp) care va contine programul.

Pentru utilizarea bibliotecii libmysql, trebuie ca fisierul header al bibliotecii sa fie inclus in program (#include <mysql.h>), biblioteca de import libmysql.lib sa fie link-ata cu programul sursa, iar biblioteca dinamica libmsql.dll sa fie copiata in directorul System (System32) al sistemului de operare Windows. In mediul MSVC, adaugarea bibliotecii de import se poate face fie prin comanda Project-Settings-Link. Numele bibliotecii de import (libmysql.lib) se inscrie in caseta de editare Object/Library Modules. Acest nume nu contine calea (directorul) in care se afla fisierul libmysql.lib, de aceea mai trebuie sa setam calea de incudere prin comanda Tools-Options. In pagina Directories se selecteaza mai intai optiunea Library Files in caseta combinata Show Directories for, dupa care se adauga directorul (calea) unde se afla biblioteca in lista Directories. De asemenea, trebuie sa fie setata calea (directorul) unde se afla fisierul header (mysql.h). Prin comanda Tools/Options, se selecteaza pagina Directories iar in caseta combinata Show Directories for se selecteaza optiunea Include files; dupa aceasta in caseta de editare Directories se adauga calea unde se afla fisierul header mysql.h.

Un program simplu de conectare la o baza de date Mysql, executia unei interogari si afisarea rezulatelor acesteia este prezentat mai jos:


Fisierul MySQLC.cpp

#include    <windows.h>


#include                              <stdio.h>

#include                              <string.h>

#include                              <mysql.h>

SETARI INITIALE -- SE POT MODIFICA

char host[] = 'localhost';

char user[] = 'user1';

char password[] = '1';

char baza[] = 'baza1';

char comanda[] = 'select * from ANGAJAT';


int main( int argc, char * argv[] )

if(!mysql_real_connect(mysql,host,user,password,baza,0,NULL,0))

if (mysql_query(mysql, comanda))

if (!(res = mysql_store_result(mysql)))

while((row = mysql_fetch_row(res)))

mysql_close(mysql);

return 0;


Clientul are la dispozitie o zona de comunicatie cu serverul, in care poate plasa instructiunile SQL si in care primeste liniile de raspuns de la server. Zona de comunicatie alocata initial este de 16 kBytes si ea poate creste automat atunci cand este necesar, pana la o valoare de maxim 16 Mbytes.

Principalele tipuri de date definite de biblioteca libmysql sunt:

MYSQL – o structura de date care este un identificator (handle) de conexiune la o baza de date MySQL;

MYSQL_RES – o structura care reprezinta rezultatul unei interogari care returneaza o multime de linii (SELECT, SHOW, DESCRIBE, EXPLAIN);

MYSQL_ROW - o structura de date care contine informatii despre o linie de date; ea este de fapt un sir de caractere de o anumita lungime (nu poate fi un sir de caractere terminat cu nul, deoarece o linie de date poate contine si date binare care pot avea octeti cu valoare zero).

MYSQL_FIELD – structura de date pentru stocarea unei coloane.

Pentru conectarea la o baza de date MySQL, se apeleaza mai intai functia mysql_init() care initializeaza un identificator (handle) de conexiune de tip MYSQL

MYSQL* mysql_init(MYSQL* mysql)

Daca argumentul transmis este NULL, atunci se initializeaza si se returneaza un nou handle de conexiune, care va fi eliberat prin apelul functiei mysql_close(MYSQL *mysql); altfel, se initializeaza handle-ul existent si se returneaza noua valoare a handle-ului. In ambele situatii, se returneaza NULL daca alocarea conexiunii a esuat. Dupa initializarea conexiunii se apeleaza functia de conectare la baza de date:

MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user,

const char *passwd, const char *db, unsigned int port,

const char *unix_socket, unsigned int client_flag);

Acestei functii i se transmit mai multe argumente: handle-ul conexiunii (mysql , numele host-ului (host), numele user-ului, (user), parola (passwd), numele bazei de date (db). Argumentul port reprezinta portul de conexiune (daca este diferit de valoarea implicita 3306 sau NULL daca are valoarea implicita); sirul de caractere unix_soket poate contine numele unui pipe, sau este NULL daca se foloseste conexiune TCP/IP; flag-ul client_flag stabileste tipul protocolului folosit de client. Daca conexiunea a reusit, functia returneaza handlerul conexiunii, identic cu primul argument transmis; daca conexiunea nu reuseste, functia returneaza NULL.

Dupa conectare reusita, clientul poate trimite serverului interogari apeland una din functiile:

int mysql_query(MYSQL *mysql, const char *query);

int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length);

Diferenta dintre cele 2 functii este aceea ca mysql_query() asteapta ca argument un sir de caractere terminat cu NULL, in timp ce functiei mysql_real_query() i se transmite un vector de caractere si lungimea acestuia (length). Rezultatul returnat de o interogare se regaseste intr-o structura de tip MYSQL_RES, al carui pointer este returnat de functia:

MYSQL_RES *mysql_store_result(MYSQL *mysql);

Numarul de coloane ale fiecarei linii dintr-un tabel rezultat se obtine prin apelul functiei:

unsigned int mysql_num_fields(MYSQL_RES *result);

Liniile rezultatului se pot extrage utilizand functia:

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

La executia programului se vor lista toate liniile tabelului ANGAJAT. Conectarea la alte baze de date sau executia altor comenzi SQL se poate face modificand in program constantele (sirurile) respective sau introducand interactiv datele care trebuie sa fie selectate.

Alte functii din interfata C MySQL se pot studia din manualul de prezentare al sistemului.


5.2. Interfata ODBC


Interfetele de programare a clientilor specifice fiecarui SGBD (asa cum este interfata C pentru MySQL) prezinta dezavantajul dependentei codului dezvoltat de SGBD-ul folosit la un moment dat; daca se schimba SQBD-ul, atunci se schimba intreaga interfata si tot programul trebuie sa fie rescris.

Tehnologia ODBC (Open Database Connectivity) ofera o interfata de acces la baze de date relationale independenta de SQBD-ul folosit. Aceasta independenta se obtine prin intermediul unor drivere, care sunt specifice fiecarui SGBD, in timp ce functiile de conectare si interogare a bazei de date folosite in programul aplicatie sunt aceleasi, definite de standardul ODBC (Figura 5.1.). Administratorul de drivere incarca drverul specific sursei de date folosite de aplicatie. O sursa de date stabileste un nume al bazei de date, impreuna cu alte informatii (tipul SGBD-ului, utilizatorul, etc.).

Pentru a folosi interfata ODBC, trebuie sa fie instalat driverul pentru SGBD-ul necesar. Unele drivere ODBC se instaleaza (daca se selecteaza optiunea respectiva) atunci cand se instaleaza unele sisteme de programe. De exemplu, driverele ODBC pentru baze de date Access, FoxPro se instaleza la instalarea pachetului Microsoft Office. Alte drivere ODBC se pot instala separat, daca avem kit-ul de instalare respectiv.

Pentru MySQL, la adresa de Internet www.mysql.com exista, pe langa fisierul de instalare a serverului MySQL, si un fisier (myodbc-2.50.39-nt.zip) care contine un kit de instalare al driver-ului ODBC pentru MySQL. Instalarea se face simplu, prin executia programului Setup.exe.

Pentru orice tip de SGBD pentru care este instalat un driver ODBC se poate defini o sursa de date care atribue un nume (si alte optiuni, depinzand de driverul instalat) unei baze de date de acel tip.

Pentru dezvoltarea unei aplicatii de baze de date cu interfata ODBC se parcurg urmatorii pasi

Se creaza mai intai baza de date dorita (sau se foloseste o baza de date existenta).

Se defineste sursa de date ODBC, corespunzatoare bazei de date.

Se dezvolta aplicatia client care va accesa baza de date ca sursa ODBC inregistrata.


5.2.1. Definirea surselor ODBC


Pentru inregistrarea unei baze de date ca sursa de date ODBC (Data Source Name - DSN) se foloseste administratorul ODBC in felul urmator:

In Control Panel, se selecteaza ODBC Data Sources;

In caseta de dialog  ODBC Data Source Administrator se selecteaza pagina System DSN. Apoi, in aceasta pagina se selecteaza comanda Add, pentru adaugarea unei noi surse de date.

In caseta de dialog Add Data Sources, se alege driverul ODBC corespunzator (Microsoft Access, SQL Server, MySQL, Oracle, etc.).

Din acest punct, inregistararea sursei de date depinde de tipul driverului de baze de date.

Pentru Microsoft Access, in campul Data Source Name din caseta de dialog ODBC Setup se scrie numele sursei (de exemplu INTREPRINDERE), iar in grupul Database, alegerea optiunii Select permite localizarea pe disc a fisierului INTREPRINDERE.mdb creat cu Microsoft Access.

Pentru MySQL, se completeaza mai multe informatii de configurare a sursei de date: Windows DNS Name (numele sursei, cu care va fi accesata din programul client); numele bazei de date, al utilizatorului, parola si portul (daca nu este portul implicit al serverului MySQL, 3306).


5.2.2. Dezvoltarea programului client ODBC


Programul client se creeza ca un proiect in MSVC 6.0, de tipul Win32 Console Application. Dupa crearea proiectului se insereaza un fisier al aplicatiei (WinODBC.cpp), cu continutul de mai jos:


// Fisierul WinODBC.cpp

#include <windows.h>

#include <stdio.h>

#include <string.h>

#include <sql.h>

#include <sqlext.h>

SETARI INITIALE --SE POT MODIFICA

#define ROW_LEN 2000

#define COL_LEN 50

char sursaDate[] = 'INTREPRINDERE';

char comanda[] = 'select * from Angajat';


int main (int argc, char** argv )

rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,

(SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

rc = SQLAllocHandle(SQL_HANDLE_DBC,henv, &hdbc);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

//Conectare la sursa de date

rc = SQLConnect(hdbc, (unsigned char*) sursaDate,

SQL_NTS, NULL, 0, NULL, 0);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

rc = SQLAllocHandle(SQL_HANDLE_STMT,hdbc, &hstmt);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

// Executie instructiune

rc = SQLExecDirect(hstmt, (unsigned char*) comanda, SQL_NTS);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

// Extragerea si afisarea coloanelor din fiecare linie

rc = SQLFetch(hstmt);

SQLNumResultCols(hstmt, &nr_cols);

while (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)

}

printf('%sn', row);

rc = SQLFetch(hstmt);

}

// Eliberare instructiune, deconectare, eliberare conexiune si mediu

SQLFreeStmt(hstmt, SQL_DROP);

SQLDisconnect(hdbc);

SQLFreeConnect(hdbc);

SQLFreeEnv(henv);

return 0;



In biblioteca ODBC sunt definite mai multe tipuri de date. Exista tipuri de date pentru numere (de exemplu SQLSMALLINT, care este un numar intreg pe 16 biti), pentru tipul returnat de functii (SQLRETURN) pentru tipuri de date pentru de identidficatori (handle) (SQLHANDLE). La randul lui, identificatorii SQLHANDLE pot avea mai forme:

HENV - identificator al mediului in care se vor desfasura operatiile cu sursa de date ODBC.

HDBC - identificator al unei conexiuni cu o sursa de date.

HINST - identificator al unei instructiuni SQL.

Intr-un program pentru interfata ODBC trebuie sa fie definiti astfel de identificatori (de mediu, de conectare si de instructiune) si fiecare identificator trebuie sa fie alocat, operatie care se efectueaza prin apelul functiei SQLAllocHandle():

SQLRETURN SQLAllocHandle(

SQLSMALLINT HandleType,

SQLHANDLE InputHandle,

SQLHANDLE *OutputHandlePtr);

Primul argument al acestei functii (HandleType) este o valoare care indica tipul identificatorului care se va aloca si poate lua una din valorile SQL_HANDLE_ENV, SQL_HANDLE_DBC sau SQL_HANDLE_STMT, pentru alocare a unui identificator de mediu, de conexiune sau de instructiune.

Cel de-al doilea argument al functiei este identificatorul de intrare (InputHandle) care trebuie sa fie NULL (pentru alocarea unui identificator de mediu), de tipul HENV (pentru alocarea unui identificator de conexiune) sau de tip HDBC (pentru alocarea unui identificator de instructiune).

Cel de-al treilea argument (OutputHandlePtr ) este un pointer care indica locul unde functia va depune identificatorul alocat.

Pentru un handle alocat corect, functia returneza unul din codurile SQL_SUCCESS sau SQL_SUCCESS_WITH_INFO. In caz de eroare, functia returneaza unul din codurile SQL_INVALID_ HANDLE sau SQL_ERROR

Mai intai se aloca un handle de mediu (henv), dupa care se seteaza atributele acestuia cu comanda SQLSetEnvAttr(). Dupa aceasta, in mediul ODBC definit, se aloca un identificator de conexiune (hdbc), si se incearca conectarea la sursa de date prin apelul functiei SQLConnect(). Daca conectarea reuseste, pentru conexiunea respectiva se aloca un identificator de instructiune (hstmt), dupa care pot fi executate instructiuni (comenzi) SQL, prin apelul functiei SQLExecDirect();

Liniile tabelului returnat la o comanda SQL SELECT se extrag cu comanda SQLFetch() si fiecare linie a tabelului rezultat contine acelasi numar de coloane, care se poate afla cu comanda SQLNumResultCols(). Dintr-o instructiune se extrag succesiv liniile, atata timp cat valoarea returnata de functia SQLFetch() este SQL_SUCCESS sau SQL_SUCCESS_WITH_INFO. Din fiecare linie se extrag apoi coloanele, cu comanda SQLGetData() si se afiseaza.


Exercitii


E5.1. Dezvoltati aplicatia de acees la bazele de date MySQL create in lucrarile precedente folosind interfata MySQL C-API. Se vor realiza doua versiuni, o versiune ca proiect Win32 Console Application si un proiect MFC (SDI sai MDI). In proiectul cu interfata grafica se vor prevedea comenzi de meniu care sa permita conectarea la diferite baze de date, dialoguri pentru introducerea dinamica a instructiunilor SQL.


E5.2. Dezvoltati aplicatia de acees la bazele de date MySQL si Access create in lucrarile precedente folosind interfata ODBC. Se vor realiza doua versiuni, o versiune ca proiect Win32 Console Application si un proiect MFC(SDI sai MDI). In proiectul cu interfata grafica se vor prevedea comenzi de meniu care sa permita conectarea la diferite baze de date, dialoguri pentru introducerea dinamica a instructiunilor SQL.



Contact |- ia legatura cu noi -| contact
Adauga document |- pune-ti documente online -| adauga-document
Termeni & conditii de utilizare |- politica de cookies si de confidentialitate -| termeni
Copyright © |- 2024 - Toate drepturile rezervate -| copyright