Cap.4 Limbaje şi biblioteci de programare a aplicaţiilor de baze de date

Size: px
Start display at page:

Download "Cap.4 Limbaje şi biblioteci de programare a aplicaţiilor de baze de date"

Transcription

1 CAPITOLUL 4 LIMBAJE ŞI BIBLIOTECI DE PROGRAMARE A APLICAŢIILOR DE BAZE DE DATE Sistemele de gestiune a bazelor de date relaţionale prelucrează instrucţiuni (comenzi) SQL. Limbajul SQL este un limbaj neprocedural, care permite definirea datelor şi operaţii de manipulare a acestora, dar nu prevede instrucţiuni de control al ordinii de execuţie a operaţiilor. De aceea, pentru realizarea aplicaţiilor de baze de date au fost dezvoltate o multitudine de limbaje şi biblioteci de programare: limbaje procedurale de extensie a limbajului SQL, limbajul SQL integrat, biblioteci de funcţii sau de clase pentru comunicarea cu bazele de date. Un limbaj procedural (procedural language) este o extensie a limbajului SQL şi permite combinarea instrucţiunilor SQL cu instrucţiunile de control al ordinii de execuţie. Astfel de limbaje sunt folosite în principal în cadrul sistemelor de gestiune, pentru stocarea unor proceduri de calcul, dar există şi posibilitatea ca programele de aplicaţii să transmită SGBD blocuri (loturi) de instrucţiuni într-un limbaj procedural. Pentru dezvoltarea programelor de aplicaţii de baze de date se pot aborda două tehnologii diferite, limbajul SQL integrat într-un limbaj de nivel înalt sau interfeţe de programare a aplicaţiilor. În limbajul SQL integrat (Embeded SQL), instrucţiunile limbajului SQL sunt incluse direct în codul programului sursă scris într-un limbaj gazdă de nivel înalt (Ada, PL/1, Pascal, Fortran, Cobol, C). Controlul fluxului de operaţii este realizat prin instrucţiunile limbajului gazdă, iar operaţiile cu baza de date sunt realizate prin instrucţiuni SQL. 95

2 Interfeţele de programare a aplicaţiilor (Application Programming Interface - API), sunt dezvoltate ca biblioteci de funcţii sau de clase, iar programele de aplicaţie folosesc apelul funcţiilor prevăzute de interfaţa respectivă pentru a comunica cu serverul bazei de date Limbaje procedurale de extensie a limbajului SQL Limbajele procedurale asigură controlul ordinii de execuţie (bucle while, instrucţiuni condiţionale if etc.) şi de asemenea, oferă suport de creare a cursoarelor, a procedurilor stocate, a funcţiilor definite de utilizator şi a declanşatorilor (triggere). Un cursor (cursor) este o structură care permite memorarea (folosind un buffer în memorie), a unei mulţimi de linii returnate ca rezultat, de o instrucţiune de interogare. Programele de aplicaţii nu pot prelucra deodată toate liniile rezultatului şi folosesc cursoare pentru extragerea individuală a unei linii (sau a unui grup de linii) din mulţimea de linii rezultat. În fiecare moment, într-un cursor există o poziţie curentă (linie curentă) în mulţimea de linii rezultat. La fiecare operaţie de extragere, se citesc una sau mai multe linii relativ la poziţia curentă a cursorului, iar această poziţie se actualizează conform modului de parcurgere (înainte sau înapoi). Cursoarele se pot crea atât la nivelul limbajului SQL2 sau a extensiilor procedurale ale acestuia, cât şi prin intermediul limbajului SQL integrat (Embedded SQL) sau a bibliotecilor şi interfeţelor de programare a aplicaţiilor de baze de date (de exemplu, interfeţele ODBC şi JDBC). O procedură stocată (stored procedure) este o procedură care implementează o parte din algoritmii de calcul ai aplicaţiilor şi este memorată în baza de date la fel ca şi alte obiecte ale bazei de date. Procedurile stocate sunt compilate şi optimizate de sistemul de gestiune o singură dată, atunci când 96

3 sunt folosite prima oară şi ramân memorate în server pentru oricâte apeluri ulterioare. O funcţie definită de utilizator (user-defined function), este o funcţie memorată în baza de date, la fel ca o procedură stocată; diferenţa între acestea este că o funcţie returnează întotdeauna o valoare şi poate fi folosită direct în expresii, pe câtă vreme o procedură stocată poate să nu returneze nici o valoare. Un trigger este o procedură stocată cu o funcţionare specială, care se declanşează automat atunci când se efectuează o operaţie de actualizare a unei relaţii. Prin triggere se pot specifica şi impune procedural constrângerile explicite, cum sunt dependenţele de date care nu sunt determinate de chei ale relaţiilor. De asemenea, triggerele mai sunt folosite şi pentru generarea automată a unor valori care rezultă din valori ale altor atribute, precum şi pentru jurnalizarea transparentă a evenimentelor sau culegerea de date statistice în legatură cu accesarea relaţiilor. Majoritatea sistemelor de gestiune sunt prevazute cu cel puţin un limbaj procedural, cele mai cunoscute fiind: PL/SQL pentru sistemele de gestiune Oracle, Transact-SQL pentru sistemele de gestiune Microsoft SQL Server, PL/PGSQL şi PL/Pearl pentru sistemul de gestiune PostgreSQL etc Limbajul Transact SQL Programele Transact-SQL pot fi executate ca proceduri memorate în cadrul bazei de date sau ca loturi (batchs) de instrucţiuni transmise sistemului prin intermediul unei aplicaţii sau a unui program utilitar de acces interactiv la baza de date. Programele utilitare de acces interactiv din distribuţia SQL Server sunt isql sau osql (la nivel de linie de comandă) şi SQL Query Analizer (care oferă şi o interfaţă grafică). De asemenea, numeroase operaţii de definire a tabelelor şi a altor 97

4 caracteristici ale bazelor de date se pot face din consola de administrare (Enterprise Manager) a sistemului SQL Server Elementele de bază ale limbajului Transact-SQL Loturi de prelucrare. Un lot (batch) constă dintr-o secvenţă de instrucţiuni Transact-SQL terminată cu comanda GO. Există mai multe reguli de grupare a instrucţiunilor în loturi. De exemplu: orice instrucţiune CREATE trebuie să fie prima în lot; de aceea nu pot fi grupate în acelaşi lot instrucţiunile CREATE TABLE, CREATE VIEW, CREATE TRIGGER, CREATE RULE etc. Variabile locale. În limbajul Transact-SQL pot fi folosite variabile locale pentru memorarea unor valori care pot fi testate sau modificate (ca în orice alt limbaj), în plus, asigură transferul datelor către şi de la tabelele bazei de date. Variabilele locale au ca domeniu de definiţie lotul, procedura sau blocul în care au fost declarate. O variabilă locală se declară folosind instrucţiunea DECLARE care specifică un identificator (un nume care trebuie să înceapă cu şi tipul variabilei. Sintaxa de declarare arată astfel: tip_date Limbajul Transact-SQL suportă toate tipurile de date prevăzute în standardul SQL2, în plus, permite definirea de către utilizator a unor noi tipuri de date. Iniţializarea variabilelor locale se poate face printr-o comandă SELECT, cu următoarea sintaxă: = expresie Instrucţiuni SQL. Limbajul Transact-SQL suportă toate instrucţiunile SQL, cu unele modificări de sintaxă, astfel încât să poată fi folosite în combinaţie cu variabilele locale ale programului. De exemplu, forma modificată a instrucţiunii 98

5 SELECT, prin care se asignează variabile locale cu valori ale unor atribute selectate, este: = = = coln FROM lista_tabele WHERE conditie O astfel de instrucţiune este utilă pentru interogările care returnează o singură linie, deoarece variabilele locale sunt setate cu valorile coloanelor primei linii a rezultatului, iar valorile din celelalte linii se pierd (nemaifiind loc unde să fie memorate). Atunci când o interogare returnează o mulţime de linii se poate folosi un cursor, aşa cum va fi prezentat în continuare. Instrucţiuni de control a ordinii de execuţie. Ordinea de execuţie a instrucţiunilor unui lot sau a unei proceduri stocate este controlată prin următoarele instrucţiuni de control: BEGIN...END IF...ELSE WAITFOR BREAK GOTO RETURN WHILE CONTINUE Semnificaţia acestor instrucţiuni este cea generală, cunoscută din alte limbaje de programare, cu anumite particularităţi. Instrucţiunile de control nu pot depăşi graniţele unei lot de execuţie sau a unei proceduri stocate Cursoare Transact SQL În limbajul Transact-SQL se pot defini cursoare cu următoarea instrucţiune: DECLARE nume_cursor CURSOR [optiuni] FOR instructiune_select Există mai multe opţiuni care se pot seta şi care definesc tipul cursorului. Semnificaţia acestor opţiuni este descrisă în manualul sistemului (Books Online), iar în programul care urmează este dat un exemplu de creare şi utilizare a unui cursor Transact-SQL. La deschiderea unui cursor (prin comanda OPEN) se execută interogarea respectivă (instrucţiunea SELECT) şi 99

6 rezultatul (mulţimea de linii) se încarcă în cursor. După încărcarea cursorului, se pot extrage liniile prin operaţii de extragere cu instrucţiunea FETCH, a cărei sintaxă simplificată arată astfel: FETCH [[NEXT PRIOR FIRST LAST RELATIVE n ABSOLUTE n] ] Clauza INTO permite extragerea valorilor unei linii în variabilele locale. Asocierea dintre variabilele locale şi coloanele cursorului este implicit poziţională: valoarea din prima coloană se înscrie în prima variabilă (@var1), valoarea din a doua coloană se înscrie în variabila a doua (@var2) etc. Ordinea coloanelor cursorului este ordinea coloanelor din instrucţiunea SELECT asociată cursorului. Pentru testarea stării unui cursor se apelează funcţia care raportează starea ultimei instrucţiuni FETCH executate pentru conexiunea curentă la server. Valoarea returnată este 0, dacă extragerea a fost efectuată cu succes, 1, dacă a survenit o eroare şi 2, dacă nu mai sunt date în mulţimea de linii rezultat. După terminarea operaţiilor asupra datelor cursorului, acesta se închide cu comanda CLOSE, iar instrucţiunea DEALLOCATE şterge structurile de date ale cursorului şi eliberează memoria. Programul următor foloseşte un cursor pentru a afişa numele şi prenumele angajaţilor al căror identificator (IdAngajat) are valori cuprinse între 1 şi numărul maxim de linii ale tabelului respectiv (tabelul ANGAJATI). 100

7 La deschiderea cursorului (cursor_angajati), acesta se încarcă cu toate liniile tabelului ANGAJATI. Aceste linii sunt extrase una cîte una, cu câte o comandă FETCH, care înscrie valorile atributelor din linia curentă a cursorului în variabilele locale (@id_angajat,@nume,@prenume). Pentru fiecare linie extrasă se testează valoarea atributului IdAngajat (reţinută în variabila şi se tipăresc datele (identificator, nume, prenume) din acele linii care au acest atribut mai mic sau egal cu numărul total de linii ale tabelului (nr_linii) Limbajul PL/SQL Limbajul PL/SQL este limbajul procedural al sistemelor de gestiune a bazelor de date Oracle, care a fost introdus pentru prima oară în versiunea Oracle 6.0 în 1991 şi a fost dezvoltat continuu şi folosit intens, inclusiv în cele mai recente versiuni, Oracle9i şi Oracle 10g Elementele de bază ale limbajului PL/SQL Blocuri PL/SQL. Unitatea de programare PL/SQL este blocul, care oferă posibilitatea de dezvoltare modulară a 101

8 programelor. Există patru tipuri de blocuri: blocuri anonime, proceduri stocate, triggere şi funcţii definite de utilizator. Blocurile anonime pot fi executate imediat, de obicei dintr-un program utilitar interactiv, cum este SQL*Plus şi nu sunt memorate în baza de date. Acestea sunt echivalente loturilor de prelucrare din Transact-SQL. Celelalte blocuri (procedurile stocate, triggerele şi funcţiile definite de utilizator) sunt memorate în baza de date. Un bloc anonim PL/SQL este compus din mai multe secţiuni şi are următoarea structură: În prima secţiune (opţională) se declară variabilele locale ale blocului folosind instrucţiunea DECLARE. Fiecare variabilă se declară printr-un nume, urmat de tipul de date şi de caracterul de încheiere (punct şi virgulă). Opţional, orice variabilă poate fi iniţializată la declarare folosind operatorul de asignare (:=) sau poate avea o valoare implicită, stabilită folosind cuvântul cheie DEFAULT. Tipurile de date care pot fi folosite în limbajul PL/SQL sunt tipurile Oracle SQL, ca number, varchar2, char etc. Tot în această secţiune se pot declara cursoare, cu o sintaxă care va fi prezentată ulterior. Secţiunea principală a unui bloc PL/SQL este compusă din instrucţiuni executabile încadrate de instrucţiunile BEGIN...END. Dintre instrucţiunile executabile, o parte sunt chiar instrucţiuni SQL de manipulare a datelor, cu o sintaxă modificată, astfel încât să poată fi folosite în combinaţie cu variabile locale ale programului. Alte instrucţiuni sunt instrucţiuni de control a execuţiei programului. În partea finală a acestei secţiuni se plasează (opţional) şi rutinele de tratare a excepţiilor. Instrucţiuni SQL. Limbajul PL/SQL nu admite decât instructiuni SQL de manipulare a datelor. Dintre acestea, 102

9 instrucţiunea SELECT se poate folosi sub următoarea formă generală: SELECT lista_coloane INTO lista_variabile FROM lista_tabele [WHERE conditie] [optiuni] Deşi clauza WHERE este opţională, ea este necesară pentru a se asigura că rezultatul are o singură linie, iar valorile din coloanele selectate sunt atribuite (prin corespondenţă poziţională) variabilelor din lista de variabile introdusă după cuvântul cheie INTO. Instrucţiunea SELECT prezentată în continuare asignează variabilelor m_nume şi m_prenume valorile atributelor (coloanelor) Nume şi Prenume din linia care are valoarea cheii primare IdAngajat egală cu variabila locală id_angajat: SELECT Nume,Prenume INTO m_nume, m_prenume FROM ANGAJATI WHERE IdAngajat = id_angajat; Instrucţiunile SQL INSERT şi UPDATE se pot integra cu uşurinţă în limbajul PL/SQL şi pot folosi variabile locale pentru asignarea valorilor atributelor. De exemplu: id_sngajat:= 2; m_nume:= Ionescu ; m_prenume:= Ion ; INSERT INTO ANGAJATI (IdAngajat,Nume,Prenume) VALUES (id_angajat,m_nume,m_prenume); m_adresa := Bacau UPDATE ANGAJATI SET Adresa = m_adresa WHERE IdAngajat = id_angajat; O precauţie specială trebuie să fie luată de programatori pentru a evita ca variabilele locale şi coloanele din tabele să aibă aceleaşi nume, deoarece astfel de situaţii sunt admise ca 103

10 legale de către compilatorul PL/SQL, dar produc rezultate ambigue. Instrucţiuni de control al execuţiei. Ca şi în alte limbaje procedurale, ordinea de execuţie a instrucţiunilor unui program PL/SQL poate fi controlată prin mai multe instrucţiuni de control: IF conditie THEN...[ELSE...] END IF; CASE FOR conditie LOOP WHILE conditie LOOP LOOP... EXIT WHEN... conditie Semnificaţia acestor instrucţiuni este asemănătoare cu cea din limbajele de programare cunoscute, cu unele aspecte mai deosebite care vor fi prezentate pe scurt în continuare. În toate aceste instrucţiuni condiţia care se testează este o expresie care se evaluează la o valoare de tip Boolean (TRUE sau FALSE). Instrucţiunea IF...THEN permite execuţia condiţionată a unor instrucţiuni. Dacă condiţia este TRUE, se execută toate instrucţiunile dintre cuvintele cheie THEN şi ELSE sau între THEN şi END IF. Clauza ELSE este opţională şi ea este urmată de instrucţiunile care trebuie să fie executate dacă valoarea condiţiei este FALSE: IF x > 100 THEN x := 100; ELSE y := x; END IF; Instrucţiunile FOR...LOOP, WHILE...LOOP şi LOOP...WHEN se folosesc pentru execuţia repetată a unui grup de instrucţiuni. De exemplu, instrucţiunea FOR...LOOP poate fi folosită pentru execuţia repetată a grupului de instrucţiuni cuprins între cuvintele cheie LOOP şi END LOOP atâta timp cât contorul (care este o variabilă de tip întreg, locală acestei construcţii şi declarată automat) este cuprins între două valori (minimă şi 104

11 maximă); la fiecare iteraţie contorul este incrementat automat cu 1 (sau decrementat cu 1, dacă este introdusă opţiunea REVERSE). Această instrucţiune are sintaxa: FOR contor IN [REVERSE] valoare_minima.. valoare_maxima LOOP instructiuni; END LOOP; Instructiunea LOOP crează o bucla infinită din care se poate ieşi cu instrucţiunea EXIT, care poate fi invocată fie întrun bloc de condiţie IF, fie cu clauza WHEN. Forma generală a instrucţiunii LOOP este: LOOP instructiuni [IF conditie THEN EXIT EXIT WHEN conditie] ; instructiuni; END LOOP Tratarea excepţiilor. Partea finală (opţională) a unui bloc PL/SQL este secţiunea EXCEPTION care conţine una sau mai multe rutine de tratare a excepţiilor. Tratarea excepţiilor în limbajul PL/SQL este asemănătoare cu cea din limbajele C++ şi Java: atunci când apare o condiţie de eroare, execuţia normală a programului se opreşte şi controlul este pasat rutinei (handler) de tratare a excepţiei. Ca şi în C++ (şi spre deosebire de Java), tratarea excepţiilor este opţională în PL/SQL Cursoare PL/SQL În limbajul PL/SQL un cursor se declară în secţiunea DECLARE a unui bloc. Forma cea mai simplă a instrucţiunii de declarare a unui cursor este: CURSOR nume_cursor IS instructiune_select; Extragerea liniilor cursorului se realizează cu instrucţiunea: FETCH nume_cursor INTO lista_variabile; 105

12 Ca exemplu, în programul următor se defineşte un cursor PL/SQL cu o funcţionare asemănătoare programului precedent (afişează numele şi prenumele angajaţilor care au identificatorul (cuprins între 1 şi numărul total de linii ale tabelului ANGAJATI). Pentru aflarea stării unui cursor se testează atributul acestuia %FOUND, care este setat după fiecare operaţie de FETCH, la valoarea TRUE, dacă a fost extrasă o linie şi cu valoarea FALSE dacă nu s-a putut extrage nici o linie. Alternativ, se poate folosi atributul %NOTFOUND, care are valoarea TRUE atunci când operaţiunea FETCH a eşuat Interfeţe de programare a aplicaţiilor de baze de date Interfeţele de programare a aplicaţiilor (API) reprezintă cea mai cunoscută tehnică de dezvoltare a aplicaţiilor de baze de date, fiind mult mai utilizată decât tehnica de programare în limbajul SQL integrat, deoarece programele rezultate sunt mai flexibile şi mai uşor de dezvoltat şi de întreţinut. Ca interfeţe de programare a bazelor de date, există atât interfeţe specifice, oferite de diferite SGBD, cât şi interfeţe cu un grad mare de 106

13 generalitate, care pot fi folosite pentru mai multe tipuri de SGBD, cum sunt interfeţele ODBC (Open DataBase Connectivity ) sau JDBC (Java DataBase Connectivity ) Interfaţa ODBC Tehnologia ODBC (Open DataBase Connectivity) oferă o interfaţă de acces la baze de date relaţionale independentă de SGBD folosit. Această independenţă se obţine prin intermediul unor drivere, care sunt specifice fiecărui SGBD, în timp ce funcţiile de conectare şi interogare a bazei de date folosite în programul aplicaţie sunt aceleaşi, definite de standardul ODBC. Administratorul de drivere încarcă driverul specific sursei de date folosite de aplicaţie. O sursă de date stabileşte un nume al bazei de date, împreună cu alte informaţii (tipul SGBD, utilizatorul etc.). Pentru a folosi interfaţa ODBC, trebuie să fie instalat driverul pentru SGBD necesar. Unele drivere ODBC se instalează (dacă se selectează opţiunea respectivă) atunci când se instalează unele sisteme de programe, iar altele trebuie să fie instalate separat. Pentru orice tip de SGBD pentru care este instalat un driver ODBC se poate defini o sursă de date care atribuie un nume (alte opţiuni, depinzând de driverul instalat) unei baze de date de acel tip. Pentru dezvoltarea unei aplicaţii de baze de date cu interfaţa ODBC se parcurg următorii paşi: Se crează mai întâi baza de date dorită (sau se foloseşte o bază de date existentă). Se defineşte sursa de date ODBC, corespunzătoare bazei de date. Se dezvoltă aplicaţia client care va accesa baza de date ca sursă ODBC înregistrată. 107

14 Definirea surselor ODBC Pentru înregistrarea unei baze de date ca sursă de date ODBC (Data Source Name - DSN) se foloseşte administratorul ODBC în felul urmator: În Control Panel, se selectează comanda Data Sources (ODBC) din grupul de comenzi Administrative Tools. În caseta de dialog ODBC Data Source Administrator se selectează pagina System DSN. În această pagină se selectează comanda Add, pentru adăugarea unei noi surse de date. În caseta de dialog Add Data Sources, se alege driverul ODBC corespunzător (Microsoft Access, SQL Server, MySQL, Oracle etc.). Din acest punct, înregistararea sursei de date depinde de tipul driverului de baze de date. Pentru Oracle, se selectează tipul driverului Oracle in OraHome 92 şi se stabileşte numele sursei. Pentru serviciul de nume (TNS Service Name) se introduce denumirea acestuia aşa cum a fost stabilit la instalarea serverului şi acest serviciu trebuie să fie specificat în client. Dacă instalarea a fost făcută corect, atunci în fişierul tnsnames.ora din client (ora92\tnsnames.ora) trebuie să existe o intrare care conţine exact datele serviciului de nume afişate de programul Net Manager din server. Serviciul de nume are denumirea server...windowsnt.tech.pub.ro şi se conectează la serviciu l Oracle (server12.tech.pub.ro) pe portul... Dacă, la definirea sursei ODBC pentru Oracle testul de conexiune eşuează, atunci se poate adăuga manual această intrare în fişierul tnsnames.ora. La definirea sursei se stabileşte de asemenea şi numele utilizatorului (user ID). Pentru sistemul SQL Server la definirea unei surse de date ODBC se precizează numele serverului, modul de autentificare, contul utilizator şi parola acestuia. 108

15 Pentru Microsoft Access, în câmpul Data Source Name din caseta de dialog ODBC Setup se scrie numele sursei (de exemplu IntreprindereAccess), iar în grupul Database, alegerea opţiunii Select permite localizarea pe disc a fişierului INTREPRINDERE.mdb creat cu Microsoft Access. Pentru MySQL, se completează mai multe informaţii de configurare a sursei de date: Windows DNS Name (numele sursei, prin care va fi accesată din programul client); numele bazei de date, al utilizatorului, parola şi portul (dacă nu este portul implicit al serverului MySQL, 3306). Numele surselor de date se vor stabili diferit pentru fiecare utilizator şi pentru fiecare sistem de gestiune în parte. De exemplu, dacă utilizatorii au conturile user1, user2 etc, atunci se pot crea sursele de date ODBC cu numele: User1Oracle, User1SQLServer, User1MySQL, User2Oracle, User2SQLServer, User2MySQL etc. Dacă utilizatorul sistemului de operare Windows are drepturi restricţionate atunci sursele ODBC trebuie să fie create din alt utilizator cu drepturi de Administrator Dezvoltarea programului client ODBC În biblioteca ODBC sunt definite mai multe tipuri de date. Există tipuri de date pentru numere (de exemplu SQLSMALLINT, care este un număr întreg pe 16 biţi), pentru tipul returnat de funcţii (SQLRETURN) pentru tipuri de date pentru identificatori (handle) (SQLHANDLE). La rândul lui, identificatorii SQLHANDLE pot avea mai multe forme: HENV - identificator al mediului în care se desfăşoară operaţiile cu sursa de date ODBC. HDBC - identificator al unei conexiuni cu o sursă de date. HINST - identificator al unei instructiuni SQL. 109

16 Într-un program pentru interfaţa ODBC trebuie să fie definiţi astfel de identificatori (de mediu, de conectare şi de instrucţiune) şi fiecare identificator trebuie să fie alocat, operaţie care se efectuează prin apelul funcţiei SQLAllocHandle(): SQLRETURN SQLAllocHandle( SQLSMALLINT HandleType, SQLHANDLE InputHandle,SQLHANDLE *OutputHandlePtr); Primul argument al acestei funcţii (HandleType) este o valoare care indică tipul identificatorului care se va aloca şi poate lua una din valorile SQL_HANDLE_ENV, SQL_HANDLE_DBC sau SQL_HANDLE_STMT, pentru alocarea unui identificator de mediu, de conexiune sau de instrucţiune. Cel de-al doilea argument al funcţiei este identificatorul de intrare (InputHandle) care trebuie să 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 instrucţiune). Cel de al treilea argument (OutputHandlePtr) este un pointer care indică locul unde funcţia va depune identificatorul alocat. Pentru un identificator (handle ) alocat corect, funcţia returnează unul din codurile SQL_SUCCESS sau SQL_SUCCESS_WITH_INFO. În caz de eroare, funcţia returnează unul din codurile SQL_INVALID_HANDLE sau SQL_ERROR. Mai întâi se alocă un identificator (handle ) de mediu (henv) şi apoi se setează atributele acestuia cu comanda SQLSetEnvAttr(). După aceasta, în mediul ODBC definit, se alocă un identificator de conexiune (hdbc) şi se încearcă conectarea la sursa de date prin apelul funcţiei SQLConnect(). Dacă conectarea reuşeşte, pentru conexiunea respectivă se alocă un identificator de instrucţiune 110

17 (hstmt), după care pot fi executate instrucţiuni (comenzi) SQL. O instrucţiune SQL se construieşte ca un şir de caractere care conţine o comandă SQL şi parametrii acesteia. Interfaţa ODBC oferă două moduri de construire a instrucţiunilor SQL: instrucţiuni SQL statice, care sunt cunoscute la compilare, sunt codate în programul executabil şi execută întotdeauna aceleaşi operaţii şi instrucţiuni SQL dinamice, care se construiesc în timpul execuţiei programului şi conţin date care nu sunt cunoscute la compilare. După ce au fost construite într-una din aceste două forme, instrucţiunile SQL sunt transmise ca argumente unor funcţii ODBC care le execută şi returnează rezultatul (dacă există). Instrucţiunile SQL statice pot fi executate direct, folosind funcţia SQLExecDirect(), sau pot fi mai întâi pregatite cu funcţia SQLPrepare() şi apoi executate, posibil de mai multe ori, cu funcţia SQLExecute(). În general, este mai eficient ca o instrucţiune SQL să fie mai întâi pregătită şi apoi executată, dacă instrucţiunea respectivă se execută de mai multe ori. Prototipurile funcţiilor de execuţie a instrucţiunilor SQL statice sunt: SQLRETURN SQLExecDirect(SQLHSTMT hstmt, SQLCHAR *StatementText,SQLINTEGER TextLength); SQLRETURN SQLPrepare(SQLHSTMT hstmt, SQLCHAR *StatementText,SQLINTEGER TextLength); SQLRETURN SQLExecute(SQLHSTMT hstmt); Funcţiile SQLExecDirect() şi SQLPrepare() au ca parametri identificatorul instrucţiunii ODBC (hstmt), variabila (şir de caractere) care conţine instrucţiunea SQL ce trebuie să fie executată sau pregătită (StatementText) şi lungimea acestui şir de caractere (TextLength), care poate lua şi valoarea SQL_NTS, pentru şirurile de caractere terminate 111

18 cu NULL. Funcţia SQLExecute() are un singur parametru, un handle al instrucţiunii ODBC (hstmt). În Programul 4.12 se pot remarca cele două moduri de execuţie a instrucţiunilor SQL statice. Prima instrucţiune (UPDATE) este executată folosind funcţia SQLExecDirect(); cea de -a doua instrucţiune (SELECT) este pregătită cu funcţia SQLPrepare() şi apoi executată cu funcţia SQLExecute(). Acest program este un proiect MSVC 6.0, de tipul Win32 Console Application şi permite conectarea la o sursă de date ODBC cu un nume dat. Pentru conectarea la o sursă de date 112

19 MS Access este suficient numele sursei; pentru conectarea la surse Oracle, SQL Server sau MySQL mai este necesar numele unui cont şi parola de conectare. De asemenea, pentru SQL Server trebuie ca baza de date a sursei ODBC să fie baza de date implicită a acelui cont. Programul asigură executarea diferitelor instrucţiuni SQL, iar pentru o instrucţiune SELECT care returnează o mulţime de linii, se extrag liniile cu funcţia SQLFetch() şi se afişează valoarea fiecărui atribut al fiecărei linii folosind funcţia SQLGetData(). În această situaţie, mulţimea de linii rezultat returnate reprezintă un cursor, care este creat implicit de driverul ODBC. De aceea, în aplicaţiile ODBC, foarte rar se definesc în mod explicit cursoare (deşi este posibil acest lucru) şi se folosesc cursoarele implicite create de driver Dezvoltarea aplicaţiilor de baze de date folosind biblioteca MFC Biblioteca MFC (Microsoft Foundation Class) face parte din sistemul de dezvoltare MSVC (Microsoft Visual C++) si este o bibliotecă C++ de dezvoltare a aplicaţiilor în sistemele de operare Windows. Interfaţa ODBC este o interfaţă de funcţii C (deci nu este orientată pe obiecte), iar biblioteca MFC oferă o extensie obiect-orientată a interfeţei ODBC. Biblioteca MFC încapsulează funcţiile ODBC, grupându-le în mai multe clase prin care se realizează operaţiile de comunicaţie cu baza de date într-un mod mai structurat şi mai simplu. Folosind interfaţa ODBC şi clasele MFC ODBC, poate fi accesată orice sursă de date, locală sau la distanţă, pentru care s-a definit o sursă ODBC. În această lucrare se va dezvolta o aplicaţie de acces la o bază de date folosind interfaţa ODBC prin intermediul bibliotecii MFC. Aplicaţia se referă la baza de date INTREPRINDERE care a fost înregistrată ca sursă ODBC cu numele 113

20 Intreprindere. Aplicaţia MFC de baze de date se va crea în trei paşi de dezvoltare: Crearea unei aplicaţii minimale cu suport pentru baze de date. Adăugarea unei interogări parametrizate. Extinderea intefeţei pentru adăugarea, actualizarea şi ştergerea înregistrărilor Crearea unei aplicaţii minimale cu suport pentru baze de date Clasele MFC care se folosesc în aplicaţiile de baze de date prin interfaţa ODBC sunt: CDatabase, CRecordset, CRecordView. Clasa CDatabase specifică conexiunea la o bază de date prin intermediul numelui DSN al acesteia, înregistrat în ODBC. Un obiect de tip CRecordset reprezintă un set de înregistrări selectate dintr-o sursă de date. Obiectul de tipul CRecordset conţine o selecţie a înregistrărilor dintr-unul sau mai multe tabele ale bazei de date, proiectate pe una sau mai multe coloane. Obiectul vedere asociat acestor înregistrări (de tip CRecordView) corespunde unei vederi care este un formular şi permite înglobarea controalelor de editare sau de afişare. Un astfel de obiect are atasată o resursă de tip dialog, care permite afişarea / editarea câmpurilor unui set de înregistrări. Un obiect de tip CRecordView este asociat atât cu un obiect de tip CRecordset cât şi cu resursa de dialog asociată. Clasa CRecordset oferă suport pentru navigarea prin seturile de înregistrări, folosind comenzile Move First, Move Next, Move Previous si Move Last, utilizând un cursor, care este actualizat în mod corespunzător de aceste comenzi. Când este modificată valoarea cursorului şi se trece la 114

21 altă înregistrare, valoarea din câmpul corespunzator este actualizată automat. La crearea unei aplicaţii se va specifica o sursă de date ODBC şi un tabel din baza de date corespunzatoare. AppWizard va crea o pereche de clase: o clasă pentru setul de înregistrări şi o clasă vedere pentru vizualizarea acestora, în următorii paşi: Se crează un proiect SDI numit Angajati. În caseta de dialog AppWizard-Step2 se selectează opţiunea Database View Without File Suport; se apelează Data Source; în caseta de dialog Database Options se selectează ODBC, iar din listă se selectează Intreprindere; în caseta de dialog Select Database Tables se selectează tabelul ANGAJATI. După ce AppWizard a creat proiectul Angajati, se poate folosi ClassView pentru a vedea o reprezentare grafică a claselor şi a componentelor acestora, create de AppWizard în mod implicit. De asemenea, cu ClassWizard se pot vedea legăturile create de AppWizard între variabilele membru şi câmpurile tabelului ANGAJATI. Clasa pentru setul de înregistrări CAangajatiSet. AppWizard a legat toate coloanele tabelului Angajaţi de variabilele membru ale clasei CAngajatiSet. Acestea se numesc "variabile membru corespunzătoare câmpurilor" (field data members). AppWizard le denumeşte în mod automat, pe baza numelor coloanelor din tabelul ANGAJATI. De asemenea, AppWizard atribuie tipul corect de date C++ sau MFC pentru aceste variabile membru, în funcţie de tipul coloanei. Clasa vedere CAngajatiView. Funcţia membru a clasei de baza CRecordView:OnInitialUpdate()deschide baza de date dacă aceasta nu era deja deschisă, apoi deschide setul de înregistrări şi iniţializează formularul, apelând funcţia CFormView::OnInitialUpdate(). 115

22 Clasa document CAngajatiDoc. În alte tipuri de aplicaţii, documentul păstrează datele şi le stochează într-un fişier pe disc prin serializare. Într-o aplicaţie pentru baze de date, datele sunt stocate în baza de date, iar utilizatorul le vede ca înregistrări. O astfel de aplicaţie nu are nevoie de un fişier de stocare. Prin urmare, un document al unei aplicaţii pentru baze de date nu este folosit ca suport pentru serializare. Rolul clasei document în aplicaţia SA este acela de a păstra setul de înregistrări: class CAngajatiDoc : public Cdocument{ public: CAngajatiSet m_angajatiset;... } Obiectul de tip set de înregistrari m_angajatiset, este înglobat în obiectul document. De aceea, obiectul set de înregistrări este construit şi eliminat automat odată cu obiectul document. Clasa document poate păstra un număr oricât de mare de obiecte de tip set de înregistrări. Alegerea opţiunii Database without file support (baza de date fără suport pentru fişiere) face ca în meniul File să nu mai existe comenzile New, Open, Save sau Save as. Pe lânga aceste clase, AppWizard a creat şi o resursă de tip dialog, numită IDD_ANGAJATI_FORM, pe care clasa CAngajatiView, derivată din CRecordView, o foloseşte pentru a afişa controalele de editare sau de afişare a datelor. Deoarece CRecordView este derivată din CFormView, zona client a unei vederi din clasa CRecordView este ocupată de o resursă de dialog. Se configurează această resursă de dialog adaugând şapte controale de editare corespunzatoare coloanelor tabelului ANGAJATI: IdAngajat,Nume,Prenume,..Salariu,IdSectie şi controalele statice corespunzătoare. O regulă des folosită la proiectarea interfeţelor cu utilizatorul a aplicaţiilor pentru baze de date este aceea de a nu i se permite utilizatorului să modifice câmpurile care fac parte din cheia primară sau dintr-o cheie 116

23 străină, pentru a nu viola constrângerile implicite ale bazei de date şi de aceea se protejează la scriere controalele de editare Id şi IdComp, selectându-se caseta de validare Read Only din pagina Styles a ferestrei de proprietăţi. În mod normal, se foloseşte ClassWizard pentru a lega controalele dintr-o casetă de dialog (sau dintr-un formular) de variabilele membru ale clasei derivate din CDialog (sau CFormView). Totuşi, în cazul clasei CRecordView, nu se leagă controalele formularului de datele membru ale acestei clase, ci de datele membru ale clasei pentru setul de înregistrări. Clasa derivată din CRecordView, în acest caz CAngajatiView, are o variabilă membru numită m_pset care este un pointer la CAngajatiSet, clasa pentru setul de înregistrări a aplicaţiei. Legăturile ce pornesc de la controalele formularului ajung, prin intermediul variabilei m_pset, la variabilele membru corespunzătoare ale clasei CAngajatiSet. În fereastra editorului de resurse dialog, ţinând tasta Ctrl apăsată, executarea unui dublu-clic pe un controlul de editare conduce la apariţia casetei de dialog AddMember Variable din ClassWizard, propunându-vă un nume în câmpul Member Variable Name. Din caseta combobox se poate alege numele coloanei dorite. Se repetă această operaţie pentru fiecare din celelalte controale de editare ale formularului. La execuţia aplicaţiei se deschide setul de înregistrări de tip CAngajatiSet, care va selecta înregistrările din tabelul ANGAJATI al bazei de date INTREPRINDERE. Prima înregistrare devine cea curentă. Formularul aplicaţiei afişează în controale valorile din înregistrarea curentă. Meniul Record conţine comenzile First Record, Previous Record, Next Record si Last Record, cărora le corespund butoane din bara cu instrumente, care pot fi folosite 117

24 pentru parcurgerea liniilor tabelului ANGAJATI (conţinute în obiectul din obiectul CAngajatiSet) Crearea unei interogari parametrizate Deşi cu AppWizard se crează iniţial o aplicaţie care are numai o clasă CRecordset şi o clasă vedere CRecordView, ulterior se poate folosi ClassWizard pentru a adăuga mai multe astfel de clase. Diferite clase vedere pot "vedea" acelaşi set de înregistrări şi invers, mai multe seturi de înregistrări pot fi "văzute" de aceeaşi clasă vedere, dintre care unul singur este setul primar de înregistrări. Pasul al doilea al aplicaţiei (Step 2) ilustrează folosirea a două seturi de înregistrări într-o singură vedere, pentru realizarea unei interogări parametrizate. Se va adaugă un obiect set de înregistrări pentru tabelul SECTII, care va fi folosit pentru completarea unei liste din care să se poată selecta o anumită secţie. Astfel, clasa CAngajatiView va avea o asociere cu obiectul CAngajatiSet (vederea va afişa o înregistrare din CAngajatiSet), în timp ce lista secţiilor este asociată celui de-al doilea set de înregistrări, CSectiiSet. În clasa CAngajatiSet vor fi selectaţi numai acei angajaţi care aparţin unei anumite secţii, în loc să fie selectaţi toţi angajaţii, ai tuturor secţiilor. Interogarea corespunzătoare acestei funcţionări este: SELECT IdSectie,Nume,Prenume,Salariul FROM SECTII, ANGAJATI WHERE SECTII.IdSectie=ANGAJATI.IdAngajat AND SECTII.Nume = nume_selectat; Pentru a obţine această funcţionare se renunţă la controlul de editare IdSectie (şi la controlul static corespunzător) şi se adaugă o casetă combo-box cu numele Sectii, care va fi completată cu toate numele secţiilor existente în intreprinderea 118

25 respectivă. Când utilizatorul selectează un nume de secţie în casetă, se caută identificatorul acestuia (IdSectie) în tabelul SECTII şi va fi reinterogat tabelul ANGAJATI pentru a selecta numai angajaţii din secţia aleasă. Operaţiile care se vor efectua pentru a realiza această funcţionare sunt următoarele: a) Crearea unei clase pentru setul de înregistrări din tabelul SECTII. Aplicaţia are deja o clasă pentru setul de înregistrări din tabelul ANGAJATI, care completează controalele de editare ale vederii CAngajatiView cu informaţii despre un angajat. Se va adăuga o nouă clasă pentru setul de înregistrări din tabelul SECTII, care va fi utilizată pentru a completa lista tuturor secţiilor intreprinderii. Cu ClassWizard se crează o nouă clasă CSectiiSet derivată din clasa de bază CRecordSet. Se deselectează caseta de validare Add to Component Gallery. În caseta de dialog Database Options, din lista ODBC se selectează INTREPRINDERE. În caseta de dialog SelectDatabase Tables se selectează tabelul SECTII. Astfel s-a conectat numele tabelului SECTII la clasa CSectiiSet. b) Înglobarea obiectului set de înregistrări în obiectul document. În fişierul AngajatiDoc.h se adaugă un obiect de tip CSectiiSet (public: CsectiiSet m_sectiiset;) De asemenea, se adaugă directiva #include "SectiiSet.h" în fişierele AngajatiDoc.cpp, Angajati.cpp şi în AngajatiView.cpp înainte de directiva #include AngajatiDoc.h. c) Înlocuirea controlului de editare IdSectii cu caseta combo-box Sectii. În resursa dialog IDD_ANGAJATI_FORM se şterge controlul de editare IdSectie şi se adaugă în locul lui o casetă combo-box, pentru care se alege în lista Type din pagina de proprietăţi Styles opţiunea DropList. În clasa CAngajatiView se 119

26 adaugă variabila membru m_ctrlsectie de categorie Control care se asociază cu caseta combo-box. d) Înscrierea în caseta combo-box a listei numelor secţiilor. Locul cel mai potrivit pentru înscrierea în caseta combo-box a listei numelor secţiilor este funcţia virtuală redefinită OnInitialUpdate() din clasa CangajatiView. Vederea completează lista din casetă în cadrul procesului său de iniţializare. Pentru aceasta, în funcţia OnInitialUpdate() se construieşte şi se deschide obiectul set de înregistrări CSectiiSet, se şterge conţinutul curent al casetei, se introduce fiecare nume de compozitor în listă, se fixează selecţia curentă la primul nume din listă (în ordinea sortării). Codul care se adaugă prin procedura următoare completează caseta şi totodată, filtrează, parametrizează şi sortează setul de înregistrări: f) Introducerea filtrului parametrizat. Filtrele unui set de înregistrări determină submulţimea de înregistrări selectate dintr-un tabel sau dintr-o interogare. Acestea folosesc parametri, reprezentaţi prin semnul "?", în loc de valori literale atribuite la compilare. Aplicaţia reselectează sau "reinteroghează" înregistrările din tabelul ANGAJATI, ori de 120

27 câte ori utilizatorul selectează un alt nume de secţie din caseta combinată. O modalitate de reinterogare a setului de înregistrări este "parametrizarea" filtrului, adică apelarea funcţiei Requery() cu o nouă valoare a parametrului filtrului. Pentru aceasta se adaugă în clasa CAngjatiSet o variabilă membru pentru parametrul (CString m_idsectieparam;) şi se iniţializează această variabilă şi numărul de parametri în constructorul clasei CAngajatiSet: m_nparams=1; m_idsectiiparam=0; De asemenea, se completează funcţia DoFieldExchange()cu următoarele linii de cod pentru a identifica parametrul m_stridcompparam: pfx->setfieldtype(cfieldexchange::param); RFX_Long(pFX,"IDSectiiParam",m_IDSectiiPar am); Funcţia DoFieldExchange()recunoaşte două tipuri de câmpuri: coloane şi parametri. Apelând funcţia SetFieldType()membru al clasei CFieldExchange, ea afla ce tip de câmp (câmpuri) urmează în apelul (apelurile) funcţiei RFX. Semnul "?" din specificaţia filtrului parametrizat, indică locul unde va fi substituită valoarea parametrului la rulare. Pentru a furniza valoarea parametrului la rulare se atribuie această valoare variabilei membru parametru a setului de înregistrări în metoda OnInitialUpdate() a clasei CangajatiSet. m_pset->m_strfilter = "IdSectie =?"; m_pset->m_idsectieparam = m_psectiiset- >m_idsectie; În felul acesta, valoarea parametrului va fi prima valoare a câmpului IdSectii găsită în setul de înregistrări CSectiiSet. 121

28 Atât AppWizard, cât şi ClassWizard implementează clasele derivate din CRecordSet astfel încât obiectul set de înregistrări să aibă ca variabilă membru un pointer la obiectul baza de date, de tip CDatabase, prin intermediul căruia să fie conectat la sursa de date. Implementarea implicită a funcţiei CRecordView:: OnInitialUpdate()apelează indirect funcţia: CString CAngajatiSet::GetDefaultConnect(){ return _T("ODBC;DSN=Intreprindere"); } Cadrul-aplicaţie transmite acest "şir de caractere de conectare" funcţiei CDatabase::Open()pentru obiectul de tip CDatabase creat de cadrul-aplicaţie la implementarea funcţiei CRecordSet::Open(). Dacă aplicaţia are două sau mai multe seturi de înregistrări, fiecare dintre acestea va crea în mod implicit şi va deschide propriul obiect de tip CDatabase. Dacă mai multe seturi de înregistrări au acces la aceeaşi sursă de date, atunci este mai eficient ca ele să folosească în comun obiectul de tip CDatabase. O modalitate de a permite mai multor seturi de înregistrări să folosească în comun acelaşi obiect CDatabase este atribuirea ca parametru funcţiei Open(), pentru celelalte seturi de înregistrări, valoarea variabilei membru m_pdatabase a primului obiect: m_pset->m_pdatabase=pdoc- >m_sectiiset.m_pdatabase; CRecordView::OnInitialUpdate(); Dacă funcţia CRecordset::Open() află că variabila membru m_pdatabase este deja alocată, refoloseşte obiectul de tip CDatabase care este deschis. Înregistrările din tabelul SECTII au fost sortate după coloana Nume: pdoc->m_sectiiset.m_strsort = "Nume"; 122

29 Pentru o anumită secţie, înregistrările din CAngajatiSet sunt sortate după atributul Nume: m_pset->m_strsort = "Nume"; g) Reinterogarea bazei de date. De fiecare dată când utilizatorul selectează un alt nume de compozitor din caseta combinată, aplicaţia trebuie să reinterogheze obiectul set de înregistrări CAngajatiSet pentru a-i împrospăta înregistrările. Selectând un nume de secţie, utilizatorul va vedea numai înregistrările reprezentând angajaţii secţiei respective. CAngajaiSet conţine înregistrările pentru secţia selectată anterior. Reinterogarea îi actualizează înregistrările, în conformitate cu noul nume de secţie ales, folosind valorile curente ale şirurilor de caractere pentru filtrare şi sortare. Când utilizatorul selectează un nume de secţie din caseta combinată, vederea de tip CangajatiView primeşte mesajul de notificare CBN_SELENDOK. Apoi, vederea foloseşte funcţia de tratare a acestui mesaj pentru a reselecta înregistrările corespunzătoare numelui de secţie selectat, transmiţând ca parametru identificatorul secţiei respective. Implementarea funcţiei de tratare a mesajului CBN_SELENDOK este: 123

30 Codul adăugat reselectează înregistrările din baza de date în obiectul set de înregistrări, în funcţie de valoarea parametrului m_idsectiiparam. Această valoare reprezintă identificatorul compozitorului al cărui nume a fost selectat în caseta combinată. Funcţia GetLBText(), membru al clasei CComboBox, încarcă în cel de-al doilea parametru textul curent selectat în control. Astfel, variabila va primi ca valoare numele secţiei curent selectate. Apoi se caută în setul de înregistrări CAngajatiSet identificatorul compozitorului cu numele respectiv, pentru a-i atribui valoarea parametrului m_idsectiiparam. Dacă după reinterogarea obiectului CAngajatiSet reiese că pentru secţia curent selectată nu există nici un angajat, setul de înregistrari este iniţializat cu valoarea Null, cu excepţia câmpului IdSectie, care va fi iniţializat cu identificatorul secţiei respective. După compilarea şi rularea aplicaţiei, se poate folosi interfaţa cu utilizatorul pentru a naviga printre angajaţii din secţia al cărei nume a fost selectat în caseta combinată. Dacă se aleg alte nume de secţii, se vor obţine informaţiile stocate în baza de date despre angajaţii lor. La execuţia aplicaţiei în această versiune (Step 2) se va afişa o fereastră ca în Fig Fig Fereastra de afisare a aplicatiei Angajati (Step 2). 124

31 Extinderea interfeţei pentru adăugarea, actualizarea şi ştergerea înregistrărilor În acest ultim pas al aplicaţiei (Step 3), se va extinde interfaţa cu utilizatorul prin adăugarea a trei noi comenzi în meniul Record: Comanda Adauga, pregăteşte o înregistrare vidă în care utilizatorul va introduce datele. Acestea sunt salvate când utilizatorul trece la altă înregistrare, folosind o comandă de meniu sau un buton din bara cu instrumente pentru navigarea printre înregistrări. În acest fel, se puteau salva şi până acum modificările aduse unei înregistrări. În plus, utilizatorul poate să salveze noua înregistrare, alegând din nou comanda Adauga. Comanda Renunta, abandonează o operaţiune de adăugare sau de editare a unei înregistrări aflate în curs de desfăşurare. Totodată, readuce înregistrarea modificată la starea ei iniţială sau revine la înregistrarea afişată înainte de alegerea comenzii Adauga. Comanda Sterge, şterge o înregistrare. Cele trei articole se adaugă în meniul Record. Fiecare dintre articolele nou adaugate are nevoie de o funcţie de tratare în clasa CAngajatiView. Deoarece resursa meniu a aplicaţiei este asociată cu clasa CMaimFrame, trebuie stabilită o asociere între identificatorii articolelor de meniu şi clasa CAngajatiView. În operaţiunile de adăugare, editare şi ştergere a înregistrărilor, clasa CrecordView actualizează în mod automat înregistrarea curentă atunci când utilizatorul trece la altă înregistrare. Clasa CRecordView modifică în trei paşi o înregistrare în obiectul set de înregistrări asociat, atunci când utilizatorul trece la altă înregistrare: Pregăteşte înregistrarea curentă pentru a fi actualizată, apelând funcţia membru Edit() a clasei pentru setul de înregistrări. 125

32 Apelează funcţia membru UpdateData() pentru clasa vedere a aplicaţiei, derivată din CFormView, funcţie care modifică valorile variabilelor membru ale obiectului set de înregistrări, de obicei prin obţinerea noilor valori de la controalele formularului. Apelează funcţia membru Update() a clasei pentru seturi de înregistrări pentru a actualiza efectiv sursa de date cu valorile modificate. Implementarea comenzii Adauga. În implementarea descrisă, utilizatorul va putea adăuga numai angajaţi ai secţiilor existente în tabelul SECTII. Selectând comanda Adauga, se intră în modul Adaugare, atribuindu-se variabilei m_bseadauga valoarea TRUE; când utilizatorul trece la altă înregistrare se iese din modul Adaugare. Pentru implementarea funcţiei de tratare a comenzii Adauga, în fişierul AngajatiView.h se declară o variabilă protected:bool m_bseadauga care se iniţializează în constructorul clasei CAngajatiView cu valoarea FALSE. Se construieşte funcţia de tratare astfel: void CAcgajatiView::OnRecordAdauga(){ if(m_bseadauga) OnMove(ID_RECORD_FIRST); CString str = m_pset->m_idsectie; m_pset->addnew(); // Se pregateste o noua inregistrare. m_pset->setfieldnull(&(m_pset- >m_idsectie),false); m_pset->m_idsectie=str; m_bseadauga=true; UpdateData(FALSE); } Datele stocate în baza de date se actualizează, prin adăugarea noii înregistrări, atunci când utilizatorul trece la o altă înregistrare. Tot atunci se iese şi din modul Adaugare. 126

33 Această funcţionalitate se realizează prin redefinirea funcţiei membru OnMove() a clasei CRecordView: Dacă aplicaţia este în modul Adaugare, se încearcă adăugarea noii înregistrări la baza de date, înainte de a se trece la altă înregistrare. Dacă datele introduse încalcă vreo regulă de validare sau de integritate impusă tabelului respectiv în baza de date, atunci se afişează mesajul de eroare corespunzator. Variabila membru m_idsectie ia valoarea corespunzătoare secţiei selectate (în timpul adăugării, caseta cu numele de secţii este folosită pentru introducere). În final, se iese din modul Adaugare şi se apelează OnSelendokSectii() care va reinteroga baza de date. Atunci când aplicaţia este în modul Adaugare şi utilizatorul alege o comandă de navigare (de exemplu, MoveNext), ca urmare a reinterogării sursei de date în metoda OnSelendokSectii(), se ajunge întotdeauna la prima înregistrare. La pasul doi al aplicaţiei, atunci când utilizatorul alegea numele unei secţii, funcţia de tratare OnSelendokSectii()reinteroghează obiectul set de 127

34 înregistrări CAngajatiSet pentru a găsi toţi angajaţii aflaţi în întreprindere aparţinând secţiei respective. Pentru funcţia de adăugare de înregistrări, operaţiile legate de reinterogare sunt executate numai dacă aplicaţia nu este în modul Adaugare, aşa cum se vede în funcţia de tratare OnSelendokSectii(). Implementarea comenzii Sterge. Ca raspuns la comanda Sterge, se şterge înregistrarea curentă, apelându-se funcţia membru Delete() a obiectului set de înregistrări asociat: void CAngajatiView::OnRecordSterge(){ if(m_bseadauga){ OnRecordRenunta(); return; } TRY{m_pSet->Delete(); } CATCH(CDBException,e) { AfxMessageBox(e->m_strError); return; } END_CATCH; m_pset->movenext(); if(m_pset->iseof()) m_pset->movefirst(); if(m_pset->isbof()) m_pset->setfieldnull(null); UpdateData(FALSE); } Dacă programul este în modul Adaugare, se apelează OnRecordRenunta(). Altfel, se apelează funcţia membru Delete() şi dacă această funcţie lansează o excepţie (de exemplu, nu se poate şterge o înregistrare datorită regulilor de integritate la nivelul tabelului respectiv), erorile sunt raportate utilizatorului. Variabila membru m_strerror a clasei CDBException este pregatită de driverul ODBC pentru eroarea respectivă. Apoi, se trece la înregistrarea următoare. Dacă înregistrarea ştearsă era ultima din setul de înregistrări, în ordinea sortării, atunci ne întoarcem la înregistrarea care a 128

35 devenit ultima în urma operaţiunii de ştergere. Dacă înregistrarea ştearsă a fost ultima şi acum nu mai există înregistrări, câmpurile setului de înregistrări vor primi valoarea Null. Implementarea comenzii Renunta. Comanda Renunta anulează modul Adaugare, în cazul în care utilizatorul a ales anterior comanda Adauga sau nu ia în considerare modificările aduse înregistrării curente, dacă utilizatorul a încercat să editeze valorile din câmpul formularului: void CAngajati::OnRecordRenunta() { if(m_bseadauga){ m_pset->move(afx_move_refresh); m_bseadauga=false; OnSelendokComplist(); return; } UpdateData(FALSE); } Dacă utilizatorul se răzgândeşte şi nu mai vrea să adauge noua înregistrare, aplicaţia iese din modul Adaugare apelând funcţia Move(), membru al clasei CRecordSet. Când se apelează funcţia AddNew() pentru a începe operaţiunea de adăugare, cadrul-aplicaţie păstrează o copie a valorilor curente ale variabilelor setului de înregistrări, înainte de a permite utilizatorului să introducă noi valori în controalele formularului. Apelul funcţiei Move(), ca mai sus, anulează operaţiunea de adăugare, refăcând înregistrarea care era curentă înainte de a alege comanda Adauga. După ieşirea din modul Adaugare se va apela OnSelendokComplist()pentru a reinteroga baza de date, în cazul în care în timpul adăugării a fost selectat un alt compozitor. Acest exemplu s-a axat pe modul de definire a interogărilor în aplicaţiile MFC-ODBC, considerând un singur formular de interfaţă, care este chiar fereastra vedere a aplicaţiei (din clasa derivată din CRecordView). Bibllioteca MFC oferă şi alte posibilităţi de 129

36 dezvoltare a aplicaţiilor şi interfeţelor cu bazele de date, prin combinarea mai multor seturi de rezultate (obiecte CResultset) în aceeaşi vedere (formular) al unei aplicaţii SDI (Single Document Interface) sau folosind ferestrele descendent în aplicaţii MDI (Multiple Document Interface) Crearea formularelor care afişează mai multe seturi de rezultate Dezvoltarea unei aplicaţii care afişează mai multe seturi de rezultate în aceeaşi fereastră se poate urmări în exemplul din directorul..\aplicatii\capitol4\mfc\\sa\step1. Această aplicaţie cu numele SA este de tip SDI şi foloseşte baza de date INTREPRINDERE (dezvoltată într-una din lucrările precedente), pentru care s-a definit o sursă de date ODBC. Clasa interogării de bază (clasa CSASet derivată din clasa CresultSet) se asociază, pe de o parte, cu toate tabelele care intervin în interogare (în cazul acesta, tabelele ANGAJATI şi SECTII) iar pe de altă parte, cu clasa vedere (formular) CSAView, derivată din clasa CRecordView. În formular (clasa vedere - CSAView) se plasează controalele de selecţie şi afişare a datelor, care corespund variabilelor membre ale clasei CSASet asociate coloanelor (atributelor) tabelelor asociate (Fig. 4.2). Pentru a realiza anumite interogări(de exemplu, afişarea angajaţilor unei secţii date prin numele acesteia) se introduc parametri de interogare şi de cele mai multe ori, sunt necesare şi alte seturi de rezultate, separate pe tabele, din care se extrag valorile parametrilor. 130

37 Fig Afişarea mai multor seturi de rezultate în acelaşi formular. În exemplul prezentat, în panoul din stânga se afişează rezultatul interogării: SELECT IDAngajati, ANGAJATI.Nume,Prenume,Salariu,IdSectie FROM ANGAJATI, SECTII WHERE ANGAJATI.IDSectie = SECTII.IdSectie AND SECTII.Nume = parametru Pentru realizarea filtrului parametrizat este necesară crearea setului de rezultate de citire a tuturor liniilor tabelului SECTII, pentru care s-a adăugat clasa CSectiiSet, asociată cu tabelul SECTII. În clasa document se înglobează, pe lângă setul de înregistrări propriu şi un obiect instanţă al setului de înregistrări pentru filtrul parametrizat: class CSADoc : public CDocument { public: CSASet m_saset; CSectiiSet m_sectiiset;... }; 131

38 Iniţializarea casetei combo-box din care se selectează parametrul interogării este realizată în funcţia OnInitialUpdate() a clasei CSAView astfel: Crearea mai multor formulare într-o aplicaţie SDI O altă posibilitate de afişare a datelor într-o aplicaţie SDI este de a crea mai multe clase vedere (formulare) şi de a sigura comutarea între acestea. Tot în proiectul de mai sus se poate urmări şi acest mod de afişare. Pentru aceasta se creează câte o clasă de vizualizare derivată din clasa CRecordView pentru fiecare interogare (set de rezultate) şi fiecărei vederi i se atribuie un identificator. În acest exemplu s-au creat clasele CangajatiView (asociată cu clasa CAngajatiSet) şi o clasă CSectiiView (asociată cu clasa CsectiiSet existentă), pe lângă clasa iniţială a proiectului CSAView. Se adaugă un 132

39 articol în meniul principal (articolul Forms) căreia i se adaugă trei comenzi care permit selectarea formularului: (Angajati, Sectii,SectiiAngajati). Aceste comenzi sunt tratate în clasa CMainFrame şi produc schimbarea formularului afişat prin apelul unei funcţii de comutare (CMainFrame::SwitchToForm), al cărui cod poate fi studiat în exemplul propus Crearea mai multor formulare într-o aplicaţie MDI Este posibilă crearea şi afişarea mai multor formulare întro aplicaţie MDI, dacă se definesc mai multe template-uri de documente şi fiecare template este asociat unei vederi (formular) diferit. Un astfel de exemplu este aplicaţia MDI cu numele SA, din directorul \Aplicatii\Capitol4\MFC\SA\Step2 şi foloseşte tabelele SECTII, ANGAJATI, PROIECTE. Pentru o astfel de afişare se crează mai multe clase vedere (derivate din clasa CRecordView), fiecare clasă asociată cu o clasa set de rezultate derivate din clasa CRecordSet, care, la rândul ei se asociază cu unul sau mai multe tabele din baza de date. În exemplul descris s-au creat clasele de interogare (set de rezultate) CSASet, CSectiiSet şi CProiecteSet, asociate cu tabelele ANGAJATI, SECTII, respectiv PROIECTE, pe de o parte şi cu clasele vedere CSAView, CSectiiView şi CProiecteView, pe de altă parte. După aceasta, în funcţia InitInstance a clasei aplicaţiei (CSAApp) se creeză (manual, generatorul Wizard nu oferă această funcţionalitate) mai multe template-uri de document astfel: 133

40 Comutarea între vederi se realizează din meniul File (din meniul principal) în care se înlocuiesc comenzile New, Open etc. cu comenzile corespunzătoare vederilor care se vor afişa (Angajati,Sectii,Proiecte) şi fiecare funcţie de tratare a unei astfel de comenzi apelează o funcţie de comutare (OpenSpecifiedTemplate) care se poate studia din acest exemplu şi folosi ulterior. #define ANGAJATI 0 #define SECTII 1 #define PROIECTE 2 #define NR_FORMS 3 void CSAApp::OnFileAngajati() { OpenSpecifiedTemplate( ANGAJATI); } Ferestrele vedere create pot fi afişate şi selectate succesiv, şi reprezintă formulare multiple într-o singură aplicaţie de baze de date (Fig. 4.3). 134

41 Fig Crearea mai multor formulare într-o aplicaţie MDI. La rândul lor, formularele pot conţine nu numai interogări simple (ca cele de mai sus) ci şi interogări complexe, parametrizate şi comenzi de inserare, ştergere, actualizare, obţinându-se astfel interfeţe grafice versatile de acces la bazele de date Dezvoltarea aplicaţiilor de baze de date în tehnologia.net Pentru dezvoltarea aplicaţiilor de baze de date, tehnologia.net oferă interfaţa ADO.NET (Access Data Object) ca parte integrantă a bibliotecii.net Framework Class Library (FCL) care permite accesul la baze de date atât în aplicaţii locale cât şi în aplicaţii distribuite în Internet. Pentru accesul la bazele de date, ADO.NET foloseşte un modul software de interconectare numit driver (data provider). In prezent ADO.NET suportă trei tipuri de drivere (data providers): SQL Server.NET provider, care permite interfaţarea directă cu baze de date SQL Server, începând cu versiunea 7.0 şi continuând cu versiunile ulterioare (2000, 2003, 2005). OLE DB.NET provider, care permite interfaţarea cu baze de date care suportă interfaţa OLE DB, cum sunt Access, Oracle. Se poate folosi şi pentru SQL Server, în orice versiune. 135

42 ODBC.NET provider, care permite interfaţarea cu baze de date care suportă interfaţa ODBC. Orice interacţiune cu o bază de date în ADO.NET necesită crearea unui obiect de conexiune care reprezintă conexiunea fizică la baza de date şi este o instanţă a clasei SqlConnection (pentru SQL Server.NET provider), a clasei OleDbConnection (pentru OLE DB.NET provider) sau a clasei PdbcConnection (pentru ODBC.NET provider). Instrucţiunea SQL (SELECT, INSERT, UPDATE sau DELETE) care se transmite bazei de date se defineşte printr-un şir de comandă, care este conţinut într-un obiect de comandă. Un obiect de comandă, care este o instanţă a uneia din clasele SqlCommand, OleDbCommand sau OdbcCommand (în funcţie de providerul folosit) încapsulează o conexiune la baza de date şi un şir de comandă. Folosind un obiect de comandă, se pot executa atât instrucţiuni SQL de definire a datelor (INSERT,DELETE,UPDATE) prin apelul metodei ExecuteNonQuery()cât şi instrucţiuni de interogare, prin apelul metodei ExecuteReader(). Rezultatul unei instrucţiuni de interogare se obţine într-un obiect DataReader, instanţă a uneia din clasele SqlDataReader, OleDbData-Reader sau OdbcDataReader (în funcţie de providerul folosit), care încapsulează mulţimea de linii rezultat al interogării, cu posibilitatea de parcurgere înainte, linie cu linie. Interogarea bazei de date se mai poate face şi prin intermediul unui obiect DataSet, care este o instanţă a clasei DataSet şi reprezintă o copie în memorie a unor date dintr-o bază de date (mulţimi de linii). Liniile memorate într-un obiect DataSet pot fi extrase direct (nu prin parcurgere linie cu linie) iar modificările efectuate în DataSet sunt propagate în baza de date. 136

43 În continuare se va studia interogarea unei baze de date folosind un obiect DataReader şi interogarea prin intermediul unui obiect DataSet Interogarea bazei de date folosind un obiect DataReader In exemplul de mai jos (Program4_15.cs) se crează o conexiune la baza de date pubs din distribuţia SQL Server (Samples) executată local (localhost), cu mod de autentificare SQL, pentru utilizatorul sa cu parola data. În acest mod este bine să fie stabilită (sau modificată) parola contului sa şi să fie editată înregistrarea serverului cu comanda Edit SQL Server Registration Properties din meniul contextual care se deschide la apăsarea butonului dreapta al mouse-ului atunci când este selectat numele instanţei serverului. În fereastra care se deschide (Registered SQL Server Properties) se selectează opţiunile Use SQL Server Authentication şi Always prompt for login name and password. Pentru această conexiune creează mai întâi o comandă de inserare de date (obiectul cmd, instanţă a clasei SqlCommand) şi se execută inserarea prin apelul metodei ExecuteNonQuery()a acestui obiect. Pentru interogare se creează o nouă comandă (folosind aceeaşi referinţă cmd) care conţine o instrucţiune SQL de interogare şi se apelează metoda ExecuteReader() a obiectului de comandă. Rezultatul returnat de o interogare este o mulţime de linii (record set) memorată într-un obiect DataReader instanţă a clasei SqlDataReader. Liniile dintr-un astfel de obiect pot fi parcurse folosind metoda Read() care returnează false atunci când s-au parcurs toate liniile. Valoarea unui câmp (atribut) dintr-o linie se obţine prin indexarea (cu indexul dat prin numele atributului sau numeric, în ordinea coloanelor, începând cu valoarea 0) obiectului DataReader. 137

44 După citirea şi afişarea liniilor tabelului titles, se şterge linia introdusă folosind o comandă de ştergere (instrucţiunea SQL delete); pentru a executa această nouă comandă este necesar să fie mai întâi închis obiectul DataReader (prin apelul metodei Close()), altfel se obţine o eroare de execuţie.acest program poate fi creat cu un editor oarecare şi compilat cu compilatorul C# (csc) sau poate fi generat ca proiect C# Console Application în Visual Studio.NET. La execuţia acestui program sunt listate toate titlurile de cărţi existente în tabelul titles din baza de date pubs în momentul execuţiei, împreună cu cheile lor primare, aşa cum se vede mai jos. 138

45 Fig Rezultatul execuţiei aplicaţiei Program4_ Interogarea unei baze de date folosind un obiect DataSet Interogarea unui baze de date folosind clasa SqlDataReader este eficientă, dar setul de linii obţinut nu poate fi parcurs decât secvenţial şi este read-only. Nu se poate face, de exemplu, revenirea la linia precedentă şi nu se poate modifica o linie şi aceasta să fie apoi scrisă înapoi în baza de date. Pentru astfel de operaţii ADO.NET oferă o clasă mai puternică şi anume clasa DataSet, care reprezintă o submulţime de tabele ale bazei de date la care se conectează utilizatorul (Fig. 4.5). Datele din aceste tabele sunt încărcate în obiectul DataSet, obiectul se deconectează de la sursa de date, iar utilizatorul poate manipula datele din acest obiect. Periodic obiectul DataSet se reconectează la baza de date, pentru actualizarea bazei de date conform modificărilor efectuate de utilizator în obiectul DataSet şi a obiectului DataSet cu modificările efectuate de alţi utilizatori în baza de date. Clasa DataSet are proprietatea Tables care returnează o colecţie (DataTable-Collection) de obiecte DataTable, fiecare reprezentând un tabel din baza de date şi 139

46 proprietatea Relations care returnează o colecţie (DataRelationCollection) de obiecte DataRelation, fiecare reprezentând o asociere între două tabele ale bazei de date realizată prin intermediul unor obiecte DataColumn. Se reaminteşte că în CLS (Common Language Specification) o proprietate este o interfaţă de tip public a unei clase care conţine metodele de citire-scriere (get şi set) ale unui atribut de tip private. În acest mod, utilizatorii clasei accesează mai simplu atributul respectiv (ca şi cum acesta ar fi public), respectându-se încapsularea şi ascunderea datelor. Clasa DataTable are următoarele proprietăţi: Columns: reprezintă un obiect DataColumnCollection, care constă dintr-o colecţie de obiecte DataColumn, fiecare reprezentând o coloană dintr-un tabel. Rows: reprezintă un obiect DataRowCollection, care constă dintr-o colecţie de obiecte DataRow, fiecare reprezentând o linie dintr-un tabel. Constraints: reprezintă un obiect ConstraintCollection, care constă dintr-o colecţie de obiecte Constraint, fiecare reprezentând o constrângere în baza de date. Din păcate, aceste denumiri stabilite de dezvoltatorii Microsoft nu prea corespund terminologiei corecte din domeniul bazelor de date: clasa DataRelation reprezintă o asociere (relationship) nu o relaţie aşa cum ar sugera numele ei; o relaţie (relation) se reprezintă prin clasa DataTable. Bineînţeles, aceste denumiri nu pot fi schimbate şi trebuie să fie folosite aşa cum sunt. 140

47 Fig Diagrama UML (partiala) a claselor ADO.NET Clasa DataAdapter asigură o intermediere între baza de date şi program. Un obiect DataAdapter permite transferul datelor între obiectul DataSet şi baza de date, încapsulând şirul de comandă (instrucţiunea) SQL şi conexiunea la baza de date Între clasa DataAdapter şi clasa DataSet există o dependenţă de utilizare. Exemplul următor realizează aceeaşi funcţionare ca şi exemplul precedent, folosind un obiect DataSet: se realizează o conexiune la baza de date pubs, se înscrie o linie în tabelul titles, apoi se listează toate valorile atributelor title_id şi title ale tuturor liniilor din tabelul titles; în final se şterge linia nou introdusă. 141

48 Acest program poate fi creat, ca şi programul precedent, cu un editor oarecare şi compilat cu compilatorul C# (csc) sau poate fi generat ca proiect C# Console Application în Visual Studio.NET. La execuţia acestui program se obţine o listă a titlurilor de cărţi şi a cheilor primare ale acestora din tabelul titles din 142

49 baza de date pubs din distribuţia SQL Server, la fel ca şi în exemplul precedent. Toate operaţiile cu baza de date se desfăşoară prin intermediul obiectului DataSet(dataset1) care este populat cu mulţimea de linii rezultat al interogării definite prin şirul de comandă (cmdstring); şirul de comandă şi conexiunea la baza de date sunt încapsulate în obiectul DataAdapter, iar popularea obiectului DataSet se face prin metoda Fill() a adaptorului. Datele rezultate din interogare se extrag din obiectul DataSet, folosind proprietatea Tables a acestuia, indexată cu numele tabelului sau cu un index numeric începând cu 0; în mod similar, din tabel se extrag liniile folosind proprietatea Rows a tabelului: DataTable table = dataset1.tables["titles"]; foreach (DataRow row in table.rows) Console.WriteLine ("{0} {1}",row[0],row["title"]); Tot obiectul DataSet poate fi folosit şi pentru operaţii de actualizare a bazei de date, folosind metoda corespunzătoare ( Add(), Delete() etc.) Afişarea datelor din tabele folosind un obiect DataGrid Modelul ADO.NET oferă suport şi pentru dezvoltarea interfeţei grafice cu utilizatorul, prin posibilitatea de asociere a unor mulţimi de linii (DataSet) cu controale de afişare a datelor. În forma cea mai simplă, un obiect DataGrid se asociază cu un obiect DataSet şi afişează datele stocate de acesta. Un exemplu simplu în limbajul C# de acces la o bază de date folosind clase ADO şi un control DataGrid necesită, 143

50 într-adevăr, un număr incredibil de mic de linii de program (Program4_16). În acest exemplu se creează un formular Windows (Windows Form) cu un obiect DataGrid (cu referinţa notată datagrid1) care va fi populat cu informaţii citite din tabelul Customers al bazei de date Northwind, care face parte din setul de exemple ce se livrează cu sistemul SQL Server. De asemenea, sistemul de dezvoltare.net SDK (si VS.NET) conţine o versiune independentă de server de baze de date desktop cunoscut sub numele Microsoft SQL Server 2000 Desktop Engine (MDSE 2000) care poate fi folosit pentru testări în locul serverului SQL Server şi conţine baza de date Northwind. Listingul de mai jos este puţin simplificat (detaliile de implementare a metodelor InitializeComponent() şi Dispose()de iniţializare şi de ştergere a datelor). Pentru crearea aplicaţiei de acces la baza de date Northwind, se creează mai întâi un obiect DataAdapter (cu numele dataadapter1), căruia i se pasează ca argumente la construcţie un şir de caractere de conectare (conn) şi un şir de caractere de comandă (cmdstring): SqlDataAdapter dataadapter1 = new SqlDataAdapter(cmd, conn); Şirul conn transmite serverului SQL Server datele de conectare (numele utilizatorului, parola şi numele bazei de date), iar şirul comanda transmite bazei de date instrucţiunea SQL de interogare. 144

51 Aceste şiruri se definesc astfel: string conn = "server = localhost;uid = sa; + pwd = parola ;database = northwind"; string cmd = "Select * from Customers"; Datele din tabele se încarcă în obiectul DataSet prin apelul metodei Fill() a obiectului: dataadapter1: DataSet dataset1 = new DataSet(); dataadapter1.fill(dataset1,"customers"); Afişarea liniilor rezultat al interogării definite se poate face în obiectul DataGrid dacă se specifică asocierea acestuia cu obiectul DataSet: datagrid1.datasource = dataset1.tables["customers"].defaultview; 145

52 La execuţia acestui program se obţine lista liniilor din tabelul Customers al bazei de date Northwind, aşa cum se vede în figura de mai jos. Visual Studio.NET oferă suport complet de creare şi conectare a obiectelor DataSet şi DataGrid, astfel încât majoritatea liniilor de cod prezentate mai sus pot fi generate vizual, prin editarea proprietăţilor formularului şi a controalelor folosite, modalităţi care vor fi prezentate în continuare. Fig Rezultatul executiei aplicatiei Program4_ Crearea vizuală a aplicaţiilor de baze de date în Visual Studio.NET În sistemul de dezvoltare Visual Studio.NET se pot crea în mod vizual (prin selectarea din bare de instrumente) atât obiectele de comunicaţie cu baza de date (conexiuni, comenzi, adapter, set de date), controalele grafice de afişare a datelor: liste de afisare (ListView), tablouri de afişare (DataGrid) cât şi conexiunile dintre acestea. În continuare sunt prezentate câteva exemple semnificative de creare a aplicaţiilor de baze de date folosind proiectarea vizuală oferită de VS.NET. A. Interogarea bazei de date printr-un obiect DataReader şi afişarea rezultatelor folosind un obiect ListView Acest exemplu este o aplicaţie Windows creată în Visual Studio.NET, care creează o conexiune la o bază de date 146

53 Northwind, execută o comandă SQL de interogare, iar rezultatul îl afişează într-un control ListView. Mai întâi se creează un proiect Visual C# Windows Application, care conţine un formular (clasa Form1). Se pot modifica diferite caracteristici ale formularului selectând formularul (prin click pe formular în modul Design Form1.cs[Design]). La selecţia formularului, în fereastra Properties se poate seta titlul formularului editând proprietatea Text, în care introducem, de exemplu, textul Crearea unui DataReader in VS.NET. Etapele următoare de creare a aplicaţiei sunt: 1. Crearea obiectului de conexiune SqlConnection. Un obiect SqlConnection se creează prin selectarea în pagina Data a ferestrei de instrumente Toolbox a obiectului SqlConnection şi tragerea lui în fereastra formularului. După această operaţie, sub formular este afişat obiectul creat (cu numele implicit sqlconnection1), care este considerat un obiect nevizual (nu apare afişat în formular), dar poate fi totuşi proiectat folosind instrumentele Visual Studio. La selectarea obiectului sqlconnection1 proprietăţile lui se afisează în fereastra Properties. Pentru editarea proprietăţii ConnectionString (care specifică detaliile de conectare la baza de date) fie se editează direct şirul de conectare (la fel ca în aplicaţiile precedente), fie se acţionează cu click pe acest câmp şi se selecteză opţiunea New Connection din lista de opţiuni afişată, care generează fereastra de dialog Data Link Properties. În pagina Provider a acestei ferestre se selectează opţiunea Microsoft OLE DB Provider for SQL Server şi se trece (cu butonul de comandă Next) la pagina următoare (Connection). În această pagină (reprezentată în figura de mai jos) se pot seta mai mulţi parametri: (1) Serverul de baze de date (se poate selecta dintr-o listă sau se poate introduce numele serverului; pentru serverul local se introduce localhost); 147

54 (2) Modul de conectare (log on) la server; pentru opţiunea Use a specific user name and password se poate folosi userul sa; (3) Selectarea bazei de date pe server (s-a selectat baza de date Nortwind). După aceste setări se poate testa conexiunea la baza de date (cu butonul de comandă Test Connection) şi dacă acest test reuşeşte se afişează mesajul Test connection succeeded şi se 148

55 poate continua dezvoltarea aplicaţiei. Câteva din opţiunile setate se pot urmări în figura de mai sus. La închiderea (cu butonul OK) a ferestrei de dialog Data Link Properties, se lansează fereastra de dialog de conectare (login) la baza de date (aşa cum se vede în figura de mai sus) şi se introduce parola pentru conectare la server. Şirul de comandă creat astfel ca proprietate a obiectului sqlconnect1, se poate vedea în fereastra de proprietăţi, iar codul generat îl găsim în metoda InitializeComponent() a clasei Form1, care este afişat în fereastra de editare dacă formularul (clasa Form1) este selectat în modul View Code din meniul contextual care se obţine prin click dreapta pe numele fişierului (Form1.cs) în fereastra Solution Explorer. Ceea ce s-a obţinut arată astfel: this.sqlconnection1.connectionstring = "workstation id=felix;packet size=4096;user id=sa; data source=localhost;persist " + "security info=false;initial catalog=northwind"; Acest şir nu este suficient şi trebuie completat cu parola (pwd=parola;) altfel nu se va realiza conexiunea dorită. Se poate folosi şi un şir de conectare mai simplu, asemănător celui folosit în exemplul precedent: 2. Crearea obiectului de comandă SqlCommand. Obiectul de comandă se creează prin selectarea oţiunii SqlCommand din pagina Data a ferestrei de instrumente Toolbox şi tragerea acesteia în formular. Obiectul care se creează (cu numele implicit sqlcommand1) este afişat sub formular şi dacă este selectat, proprietăţile lui se afişează în fereastra Properties. Pentru acest obiect, importante sunt proprietăţile Connection şi CommandText. Se selectează proprietatea Connection şi se selectează opţiunea sqlconnection1. Apoi se selectează proprietatea CommandText pentru definirea instrucţiunii SQL 149

56 (ca un şir de caractere). Se acţionează butonul de urmărire ( ) şi se obţine un formular de creare a interogărilor (Query Builder) în care se pot introduce unul sau mai multe tabele, vederi (views) sau funcţii. Se introduce tabelul Customers şi apoi se selectează ca ieşiri (Output) acele atribute ale tabelului care trebuie să fie citite din baza de date (aşa cum se vede în figura de mai jos). 3. Crearea obiectului de citire SqlDataReader şi a controlului de afişare ListView. Obiectul ListView se selectează în pagina Windows Forms a ferestrei de instrumente ToolBox şi se trage în formular. Dimensiunile acestei liste se pot ajusta prin tragerea cu mouse-ul a ferestrei respective. Operatia de interogare a bazei de date o vom face la încărcarea formularului, prin tratarea evenimentului Load a acestuia. Pentru aceasta se efectuează dublu-click pe formular (în afara listei de afişare ListView) şi generatorul de cod creează un handler de eveniment (metoda Form1_Load) pe 150

57 care îl înregistrează pentru evenimentul Load a clasei Form1. Acest handler se completează astfel: private void Form1_Load(object sender, System.EventArgs e){ sqlconnection1.open(); System.Data.SqlClient.SqlDataReader reader = sqlcommand1.executereader(); while (reader.read()){ listview1.items.add(reader["customerid"].tostr ing()); listview1.items.add(reader["companyname"].tost ring()); listview1.items.add(reader["contactname"].tost ring()); } reader.close(); sqlconnection1.close(); } 4. Crearea obiectului DataReader. Obiectul de citire SqlDataReader nu se poate crea vizual, ci se obţine prin execuţia metodei ExecuteReader() a obiectului sqlcommand1, aşa cum se vede în codul de mai sus. La execuţia programului se obţine lista clienţilor firmei Northwind, afişată într-un control ListView, aşa cum se vede în imaginea de mai jos. 151

58 B. Interogarea bazei de date printr-un obiect DataSet şi afişarea rezultatelor folosind un obiect DataGrid Acest exemplu este o aplicaţie Windows asemănătoare exemplului precedent, cu deosebirea că datele se citesc printrun obiect DataSet şi se afişează într-un control DatataGrid. Primele etape de creare a proiectului în Visual Studio.NET, inclusiv etapele de creare a obiectului conexiune sqlconnection1 şi a obiectului de comandă sqlcommand1, sunt identice cu cele de la exemplul precedent. De asemenea, este necesară setarea proprietăţii Connexion a obiectului sqlcommand1 cu valoarea sqlconnexion1. Etapele următoare sunt date în continuare. 1. Crearea obiectului SqlDataAdapter se realizează vizual prin selectarea acestuia în pagina Data a ferestrei Toolbox şi tragere în formular. La introducerea adaptorului în formular se iniţiază un generator de configurare (Data Adapter Configuration Wizard) cu mai multe ferestre de dialog. În prima fereastră se setează conexiunea, selectând conexiunea la baza de date Nortwind, de pe staţia (host) locală şi utilizatorul dbo (în exemplul utilizat: FELIX.Nortwind.dbo). În a doua pagină a generatorului se selectează opţiunea Use SQL statement, din cele trei opţiuni posibile (Use SQL statement, Create new stored procedure, Use existing stored procedure). În pagina următoare de dialog se introduce direct instrucţiunea SQL dorită (SELECT * FROM Customers) sau se generează această instrucţiune folosind QueryBuilder, la fel ca în exemplul precedent. Aceste proprietăţi se pot reconfigura dacă se selectează link-ul Configure Data Adapter, afişat la sfârşitul listei de proprietăţi a obiectului dataadapter1. După crearea obiectului sqldataadapter1, se selectează acest obiect şi se setează proprietatea 152

59 SelectCommand selectând valoarea sqlcommand1 din lista de comenzi afişate. 2. Crearea obiectului DataSet. Obiectul DataSet care va fi folosit pentru interogarea bazei de date se poate crea selectând link-ul Generate Dataset afişat sub lista de proprietăţi a obiectului dataadapter1. La selectarea acestui link se afişează o fereastră de dialog intitulată Generate Dataset, în care se selectează (cu opţiunea New) crearea unui noi clase DataSet1 căreia i se adaugă tabelul Customers din baza de date. Obiectul dataset11 creat este o instanţă a clasei DataSet1 şi este afişat sub formular, alături de celelalte obiecte nevizuale (sqlconnect1, sqlcommand1, sqldataadapter1). După această etapă fereastra VS arată ca în imaginea de mai jos. Obiectul dataset11 creat, este instanţă a unei clase create de generatorul de cod (Wizard) VS.NET, numită DataSet1, derivată din clasa DataSet şi corespunzând datelor selectate pentru acest obiect (tabelul Customers). 153

60 Această clasă este definită printr-o schema XML, generată de Wizard şi conţinută în fişierul DataSet1.xsd care se vede în fereastra Solution Explorer. Schema XML a unui DataSet poate fi afişată în modul Design (selectând opţiunea Open din meniul derulant care se afişează cu click dreapta pe fişierul DataSet1.xsd din fereastra Solution Explorer) sau în mod text, dacă se selectează opţiunea View in Browser. În modul Design, se afişează schema XML corespunzătoare clasei DataSet1 sub forma unui tabel (al liniilor rezultat al interogării), iar în modul View in Browser, se afişează schema corespunzătoare, ca document XML. Clasa DataSet1 (din care se instanţiază obiectul dataset11) este generată în fişierul DataSet1.cs, care poate fi deschis dacă se selectează modul Show All Files (în fereastra Solution Explorer) şi apoi se expandează grupul de fişiere marcat DataSet1.xsd. Clasa DataSet1 este derivată din clasa DataSet: public class DataSet1 : DataSet {...} 3. Interogarea bazei de date se face în metoda Form1_Load(), care este un handler de evenimente înregistrat pentru evenimentul Load al formularului Form1. Se completează această metodă astfel: private void Form1_Load(object sender, System.EventArgs e){ sqlconnection1.open(); sqldataadapter1.fill(dataset11,"customers" ); datagrid1.datasource = dataset11.tables["customers"].defaultview; sqlconnection1.close(); } La execuţia aplicaţiei se obţine un formular care conţine un tabel ca în imaginea de mai jos: 154

61 C. Afişarea rezultatelor unei interogări folosind un obiect DataView Clasa DataView permite afişarea numai a unora dintre liniile unui tabel (DataTable), folosind un filtru, precum şi ordonarea acestora după un criteriu dat În exemplul următor se execută o interogare a bazei de date Northwind (SELECT * FROM Customers where Country= filtru ORDER BY CustomerID) folosind un obiect DataSet. Datele din DataSet se afişează într-un obiect DataGrid folosind un obiect DataView, care permite filtrarea liniilor conform condiţiei de interogare (clauza WHERE a interogării) şi ordonarea lor după valorile atributului dat în clauza ORDER BY. Etapele de dezvoltare a proiectului în VS.NET sunt prezentate în continuare. 1. Se creează un proiect C# Windows Application cu numele Program4_20 şi se selectează panoul de afişare Server Explorer din meniul View al sistemului VS.NET. Se realizează conexiunea la baza de date introducând parola pentru userul de conectare dorit (în fereastra de conectare care se deschide atunci când selectăm sistemul de gestiune SQL Server). Se selectează tabelul Customers din baza de date Northwind şi se trage în formular. La această operaţie generatorul de cod generează obiectele sqlconnection1 (instanţă a clasei SqlConnection) şi sqldataadapter1 (instanţă a clasei 155

62 SqlDataAdapter), care sunt plasate sub formular (când este editat în modul Design). 2. Se editează proprietatea ConnectionString a obiectului sqlconnection1 pentru conectarea la baza de date aleasă. Nu uitaţi să adăugăţi în şirul de conectare parola pentru utilizatorul ales (deoarece generatorul de cod nu face automat acest lucru): pwd=parola; 3. Se selectează obiectul sqldataadapter1 şi se face click pe link-ul Generate Datase (care este afişat sub lista de proprietăţi, aşa cum se vede în figura de mai jos). Se acceptă datele implicite din fereastra de dialog care se deschide, iar la închiderea acesteia (cu butonul OK) se creează obiectul dataset11, care este afişat sub formular. 4. Se creează un obiect DataView prin selectarea acestuia în pagina Data a ferestrei de instrumente ToolBox şi tragere în formular; după creare obiectul (cu numele implicit dataview1) este afişat sub formular, aşa cum se vede în figura de mai jos. 5. Se setează proprietatea Tables a obiectului dataview1 (în fereastra Properties) selectând valoarea dataset11.customers din lista derulantă din partea dreapta a paginii Properties. De asemenea, se setează proprietatea RowFilter la valoarea: Country = UK şi proprietatea Sort la valoarea CustomerID (aşa cum se vede în figura de mai jos). 6. Se introduce un control DataGrid, selectându-l în pagina Windows Forms din fereastra ToolBox şi tragându-l în formular; prin această operaţie se creează obiectul cu numele implicit datagrid1 (instanţă a clasei DataGrid), care ocupă o anumită suprafaţă în fereastra formularului. Acestă suprafaţă se poate ajusta prin tragere cu mouse-ul. 7. Se setează proprietatea DataSource a obiectului datagrid1 la valoarea dataview1, folosind lista 156

63 derulantă din partea dreapta a proprietăţii DataSource. În acest moment în fereastra mediului de dezvoltare VS.NET se afişează datele care se pot vedea în imaginea de mai jos. 8. Interogarea bazei de date se face în metoda Form1_Load(), care este un handler de evenimente înregistrat pentru evenimentul Load al formularului Form1. Se completează această metodă astfel: private void Form1_Load(object sender, System.EventArgs e){ sqldataadapter1.fill(dataset11, "Customers"); } Se compilează şi se execută programul. În acest stadiu de dezvoltare al programului se obţine lista tuturor clienţilor firmei din ţara introdusă ca parametru de filtrare (UK), aşa cum se poate vedea în imaginea de mai jos. 157

64 9. Pentru filtarea liniilor rezultatului cu un parametru oarecare (filtru), introdus în mod dinamic în cursul execuţiei, se foloseşte un control combo-box care să conţină ca listă de elemente (Items) denumirile tuturor ţărilor clienţilor, din care se selectează ţara dorită. Controlul combo-box se introduce în formular prin tragerea acestuia din fereastra ToolBox în fereastra formularului (selectat în modul Design) şi se setează proprietăţile în fereastra Properties. Liste elementelor controlului combo-box se poate seta fie ca o colecţie de denumiri ale ţărilor prin editarea proprietăţii Items (Collection) a controlului, fie folosind o sursă de date, introdusă ca proprietate DataSource a controlului. În exemplul prezentat s-a ales cea de-a doua posibiltate, selectând pentru proprietatea DataSource valoarea dataset11.customers iar pentru proprietatea DisplayMember valoarea Country. Prin această setare lista de elemente conţinută de combo-box este lista valorilor coloanei (atributului) Country a tabelului Customers din obiectul dataset Se înregistrează un handler de eveniment de schimbare a selecţiei controlului combo-box (prin dublu-click pe controlul combo-box) şi se defineşte acest handler astfel: private void combobox1_selectedindexchanged(object sender, System.EventArgs e) { 158

65 object item = combobox1.selecteditem; string selectedtext = combobox1.getitemtext(item); this.dataview1.rowfilter = "Country = \'" + selectedtext + "\'"; sqldataadapter1.fill(dataset11, "Customers"); } În acest handler de citeşte elementul selectat în combo-box (folosind proprietatea SelectedItem a clasei ComboBox), se converteşte într-un şir de caractere (obiect string) (apelând metoda GetItemText) şi se modifică filtrul obiectului DataView la valoarea acestui şir de caractere, folosind proprietatea RowFilter a clasei DataView. 11. Se completează metoda Form1_Load() (handlerul de eveniment de încărcare a formulrului) astfel: private void Form1_Load(object sender, System.EventArgs e) { // Popularea ob. DataSet11 pentru incarcarea listei de elementei // in combo-box sqldataadapter1.fill(dataset11, "Customers"); // Setarea corespunzatoare a filtrului int index = combobox1.selectedindex; object item = combobox1.selecteditem; string selectedtext = combobox1.getitemtext(item); this.dataview1.rowfilter = "Country = \'" + selectedtext + "\'"; // Filtrarea liniilor rezultatului sqldataadapter1.fill(dataset11, "Customers"); } La execuţia programului se obţine o imagine ca cea de mai jos: 159

66 D. Afişarea datelor din două relaţii asociate într-un singur formular În programul următor se va prezenta modul în care se poate crea o aplicaţie Windows care conţine un formular de date, folosind generatorul Data Form Wizard din VS.NET. Pentru exemplificare, se vor folosi relaţiile Customers şi Orders, din baza de date Northwind, între care există o asociere 1:N prin intermediul cheii străine CustomersID din relaţia Orders, care referă cheia primară CustomerID din relaţia Customers. În sistemul de dezvoltare.net se folosesc denumirile de tabel părinte (parent table ) pentru relaţia referită (care conţine cheia primară referită de cheia străină), tabel fiu (child table ) pentru relaţia care referă, iar asocierea 1:N este numită asociere părinte-fiu (parent-child). Aplicaţia va afişa într-un formular câte o linie din tabelul părinte (Customers) prin intermediul mai multor casete de afişare (TextBox) şi pentru fiecare linie din acest tabel, se afişează toate liniile corespunzătoare (care au valoarea cheii străine egală cu valoarea cheii primare a liniei respective) din tabelul fiu (Orders) într-un tabel de date (DataGrid). Pentru crearea aplicaţiei se vor parcurge următorii paşi: 1. Selectaţi: File/New Project. În caseta de dialog New Project selectaţi Visual C# Empty Project şi introduceţi numele dorit al proiectului (Program4_21 în această prezentare). 160

67 Deoarece se va crea ulterior un formular de date, nu este necesar ca VS.NET să genereze obişnuitul formular gol (blank) cu care se încep în general aplicaţiile Windows Form, este suficintă crearea în acest stadiu a unui proiect vid. Apăsaţi butonul OK al ferestrei de dialog cu mouse-ul şi VS. NET va crea un proiect vid care va fi completat în continuare. 2. Selectaţi Project/Add New Item. Selectaţi Data Form Wizard din secţiunea dreapta (Templates) a ferestrei de dialog Add New Item şi introduceţi numele dorit al formularului (în exemplul dat s-a folosit numele Form1). Se va afişa pagina de start a generatorului Data Form Wizard. Apasaţi butonul Next pentru a continua. 3. Următoarea pagină a generatorului, (intitulată Choose the dataset you want to use), permite definirea unui obiect DataSet; selectaţi opţiunea Create a new dataset named, iar în caseta de text corespunzătoare introduceţi numele dorit (dataset1 în exemplul prezentat). Apăsaţi butonul Next pentru a continua. 4. În pagina următoare se alege o conexiune la baza de date, fie selectând o conexiune existentă, fie creând o conexiune nouă. Apăsaţi butonul Next pentru a continua. Urmează conectarea la baza de date, care necesită introducerea parolei în câmpul Password al casetei de dialog SQL Server login care se afişează în acest moment al generării proiectului. Apăsaţi butonul OK pentru a continua. 5. În continuare se vor selecta tabelele dorite (Customers şi Orders) din tabelele bazei de date Northwind. Selecţia se poate face fie prin dublu-click pe tabelul respectiv, fie selectându-l în secţiunea din stânga a ferestrei (Available Items) şi trimiţându-l (cu săgeata spre dreapta) în secţiunea din dreapta (Selected Items). În acest stadiu, fereastra Data Form Wizard arată ca în figura de mai jos. 161

68 Apăsaţi butonul Next pentru a continua. 6. În pagina următoare se creează asocierea (relationship ) între cele două tabele selectate. Se introduce denumirea asocierii (de exemplu customers_orders) în caseta de text Name, se selectează tabelul Customers ca tabel părinte (Parent Table), iar tabelul Orders ca tabel fiu (Child Table). Se selectează CustomerID, cheie în ambele tabele (în casetele combo-box Keys). Această asociere nu va fi înregistrată decât dacă se apasă săgeata spre dreapta, care o trimite în fereastra numită Relations (corect ar fi trebuit să fie denumită Relationships). Apăsaţi butonul Next pentru a continua. 7. În pagina următoare se selectează coloanele (atributele tabelelor) pe care dorim să le afişăm în formular, aşa cum se vede în imaginea de mai jos: 162

69 8. În ultima pagină a generatorului se selectează stilul de afişare a tabelului părinte. Selectaţi opţiunea Single record in individual control din grupul de radio-butoane How do you want to display your data şi toate celelalte opţiuni (casete chekbox): Add, Delete, Cancel, Navigation controls, Cancel All, care permit efectuarea operaţiunilor de inserare, ştergere şi parcurgere a liniilor tabelelor, precum şi anularea modficărilor efectuate. La apăsarea butonului Finish, se încheie operaţiile de creare a formularului, care este afişat în fereastra VS, aşa cum se vede în figura de mai jos. Se observă că generatorul Data Form Wizard foloseşte clase OLE DB, deşi se conectează la o bază de date SQL Server. Această soluţie este mai generală, deoarece se aplică pentru orice sistem de baze de date pentru care există un provider OLE DB şi majoritatea sistemelor actuale oferă un astfel de driver, dar, pentru SQL Server, este mai puţin eficientă decât dacă s-ar folosi clase SQL Server provider. Este preţul plătit pentru operaţiile de generare a codului şi acest cod nu este chiar simplu. 163

70 Dacă ne uităm în fişierul DataForm1.cs (cu opţiunea View Code în meniul contextual care se deschide la click cu mouseul pe numele fişierului în fereastra Solution Explorer), se observă că s-au generat peste 900 de linii de cod. 9. Pentru conectarea la server este necesară introducerea parolei pentru user-ul folosit (sa). Pentru aceasta se selectează obiectul oledbconnection1 prin selectare în fereastra de proiectare (sub formular) şi editarea proprietăţii ConnexionString, în care se introduce sub-şirul: pwd=parola; 10. Ultimul pas necesar pentru crearea aplicaţiei este introducerea (manuală) a funcţiei Main() în clasa DataForm1 (din fişierul DataForm1.cs): public static void Main(){ Application.Run(new DataForm1()); } 164

71 La execuţia aplicaţiei se afişează formularul de date care este populat cu valori din baza de date Northwind la comanda (butonul) Load, aşa cum se vede în imaginea de mai jos. Se observă asocierea dintre cele două tabele şi faptul că în formular se afişează valori corelate: liniei din tabelul părinte (Customers) afişată în partea de sus a formularului îi corespund toate liniile care o referă (au aceeaşi valoare a cheii) din tabelul fiu (Orders). Liniile din tabelul părinte (Customers) pot fi parcurse incremental în ambele sensuri (cu cele două butoane cu săgeţi simple) şi se poate ajunge direct la prima sau ultima linie (cu cele două butoane cu săgeţi duble). De asemenea se pot actualiza, adăuga sau şterge linii din tabelul părinte. E. Interogări pe mai multe relaţii asociate În programul următor se prezintă modul în care se poate afişa rezultatul unei interogări aplicate pe trei relaţii şi anume două relaţii puternice şi o relaţie de asociere, care asigură o asociere mulţi-la-mulţi între primele două relaţii. Pentru exemplificare se vor folosi tabelele Employees, Customers, Orders din baza de date Northwind din distribuţia SQL Server. 165

72 Într-un DataDrid se vor afişa rezultatele interogării Care sunt numele, prenumele, titlul (funcţia) angajaţilor şi ţara de rezidenţă a clienţilor dintr-o anumită ţară (dată ca parametru) către care angajaţii au efectuat ordine de livrare? Paşii care trebuie să fie executaţi sunt următorii: 1. Creaţi un proiect C# Windows Application cu numele Program4_ Creaţi un obiect SqlDataAdapter, trăgându-l din pagina Data a ferestrei ToolBox în formular şi în continuare efectuaţi setările cerute de generatorul Data Adapter Configuration Wizard. În prima pagină se crează (dacă nu a fost creată mai înainte) sau se selectează conexiunea localhost.nortwind.dbo (în loc de localhost generatorul afişează numele hostului pe care lucraţi), iar în pagina a doua se selectează opţiunea Use SQL statements. 3. În pagina următoare se creează comanda de selecţie SQL, fie scriind-o în fereastra de editare, fie invocând gneratorul Query Builder, care oferă o interfaţă grafică de generare a interogării (aşa cum se vede în figura de mai jos). Se adaugă tabelele Customers, Orders, Employees (între care există asocierile corespunzătoare) şi se va genera instrucţiunea SQL SELECT fără clauza WHERE de filtrare a valorilor dorite, deoarece această clauză se va introduce în mod dinamic în cursul execuţiei (printr-un control combo-box). Sintaxa folosită este o extensie a limbajului SQL standard, exprimând joncţiunea între două tabele prin INNER-JOIN Generatoul Query Builder ne anunţă că s-a generat un DataAdapter care poate efectua numai operaţii de interogare (SELECT). Se dau comenzile OK, apoi Finish. La crearea obiectului sqldataadapter1, s-a creat şi conexiunea necesară (obiectul sqlconnection1). Nu uitaţi să adăugaţi parola în şirul de conectare 166

73 (ConnectionString): pwd=parola; al obiectului sqlconnection1 creat. 3. Se creează obiectul dataset1, (tragând obiectul din pagina Data a ferestrei ToolBox în formular) şi se selectează opţiunea Untyped DataSet. Apoi se creează un obiect dataview1 (tragând obiectul din pagina Data a ferestrei ToolBox în formular). 4. Se inserează în formular un obiect DataGrid, a cărui proprietate DataSource se setează cu datawiew1, iar în proprietatea CaptionText se introduce textul Employees- Orders- Customers 5. Interogarea bazei de date se face în metoda Form1_Load(), care este un handler de evenimente înregistrat pentru evenimentul Load al formularului Form1. Se completează această metodă astfel: private void Form1_Load(object sender, System.EventArgs e){ this.sqldataadapter1.fill(dataset1); this.dataview1.table = dataset1.tables[0]; } După compilare şi execuţie se obţine imaginea de mai jos. În aceasta fază în tabel (data-grid) se afişează rezultatul interogării introduse în crearea adaptorului, adică o proiecţie a 167

74 joncţiunii dintre cele trei tabele pe atributele date (FirstName, LastName,Title etc). 6. Clauza de filtrare cu o condiţie dată ca parametru (Customers.Country = parametru) se intruduce ca filtru al obiectului dataview1, iar valoarea parametrului se selectează printr-un combo-box. Pentru aceasta se inserează un combo-box (combobox1) şi mai multe obiecte prin care sursa de date a acestuia să fie coloana Country din tabelul Customers. Se introduce un obiect dataset2 (cu opţiunea Untyped Data Set, la fel ca dataset1), un obiect dataview2 şi un obiect dataadapter2, care se configurează cu instrucţiunea SQL: SELECT DISTINCT Country FROM Customers. Apoi se completează metoda Form1_Load() astfel: 168

75 7. Se înregistrează un handler de eveniment de schimbare a selecţiei controlului combo-box (prin dublu-click pe controlul combo-box) şi se defineşte acest handler astfel: private void combobox1_selectedindexchanged(object sender, System.EventArgs e) { object item = combobox1.selecteditem; string selectedtext = combobox1.getitemtext(item); this.dataview1.rowfilter = "Country = \'" + selectedtext + "\'"; sqldataadapter1.fill(dataset1, "Customers"); } La execuţia programului se obţine o imagine ca cea din figura de mai jos. Aceasta este una dintre posibilităţile de creare a unei interogări parametrizate pe trei tabele corelate şi după cum se poate remarca, nu există un generator (Wizard) care să genereze automat o astfel de aplicaţie, unele obiecte şi configurări au fost scrise manual. 169

2. Setări configurare acces la o cameră web conectată într-un router ZTE H218N sau H298N

2. Setări configurare acces la o cameră web conectată într-un router ZTE H218N sau H298N Pentru a putea vizualiza imaginile unei camere web IP conectată într-un router ZTE H218N sau H298N, este necesară activarea serviciului Dinamic DNS oferit de RCS&RDS, precum și efectuarea unor setări pe

More information

Metrici LPR interfatare cu Barix Barionet 50 -

Metrici LPR interfatare cu Barix Barionet 50 - Metrici LPR interfatare cu Barix Barionet 50 - Barionet 50 este un lan controller produs de Barix, care poate fi folosit in combinatie cu Metrici LPR, pentru a deschide bariera atunci cand un numar de

More information

Versionare - GIT ALIN ZAMFIROIU

Versionare - GIT ALIN ZAMFIROIU Versionare - GIT ALIN ZAMFIROIU Controlul versiunilor - necesitate Caracterul colaborativ al proiectelor; Backup pentru codul scris Istoricul modificarilor Terminologie și concepte VCS Version Control

More information

MS POWER POINT. s.l.dr.ing.ciprian-bogdan Chirila

MS POWER POINT. s.l.dr.ing.ciprian-bogdan Chirila MS POWER POINT s.l.dr.ing.ciprian-bogdan Chirila chirila@cs.upt.ro http://www.cs.upt.ro/~chirila Pornire PowerPoint Pentru accesarea programului PowerPoint se parcurg următorii paşi: Clic pe butonul de

More information

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Proiect nr. 154/323 cod SMIS 4428 cofinanțat de prin Fondul European de Dezvoltare Regională Investiții pentru viitorul

More information

Textul si imaginile din acest document sunt licentiate. Codul sursa din acest document este licentiat. Attribution-NonCommercial-NoDerivs CC BY-NC-ND

Textul si imaginile din acest document sunt licentiate. Codul sursa din acest document este licentiat. Attribution-NonCommercial-NoDerivs CC BY-NC-ND Textul si imaginile din acest document sunt licentiate Attribution-NonCommercial-NoDerivs CC BY-NC-ND Codul sursa din acest document este licentiat Public-Domain Esti liber sa distribui acest document

More information

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Proiect nr. 154/323 cod SMIS 4428 cofinanțat de prin Fondul European de Dezvoltare Regională Investiții pentru viitorul

More information

Lucrarea de laborator nr. 4

Lucrarea de laborator nr. 4 Metode merice - Lucrarea de laborator 4 Lucrarea de laborator nr. 4 I. Scopul lucrării Elemente de programare în MAPLE II. III. Conţinutul lucrării 1. Atribuirea. Decizia. Structuri repetitive. 2. Proceduri

More information

Titlul lucrării propuse pentru participarea la concursul pe tema securității informatice

Titlul lucrării propuse pentru participarea la concursul pe tema securității informatice Titlul lucrării propuse pentru participarea la concursul pe tema securității informatice "Îmbunătăţirea proceselor şi activităţilor educaţionale în cadrul programelor de licenţă şi masterat în domeniul

More information

:= 950; BEGIN DELETE FROM

:= 950; BEGIN DELETE FROM Cursori în PLSQL La fiecare execuţie a unei instrucţiuni SQL serverul Oracle deschide o zonă de memorie în care este analizată şi executată instrucţiunea. Această zonă de memorie se numeşte cursor. Există

More information

CERERI SELECT PE O TABELA

CERERI SELECT PE O TABELA SQL - 1 CERERI SELECT PE O TABELA 1 STUD MATR NUME AN GRUPA DATAN LOC TUTOR PUNCTAJ CODS ---- ------- -- ------ --------- ---------- ----- ------- ---- 1456 GEORGE 4 1141A 12-MAR-82 BUCURESTI 2890 11 1325

More information

2. Setări configurare acces la o cameră web conectată într-un echipament HG8121H cu funcție activă de router

2. Setări configurare acces la o cameră web conectată într-un echipament HG8121H cu funcție activă de router Pentru a putea vizualiza imaginile unei camere web IP conectată într-un echipament Huawei HG8121H, este necesară activarea serviciului Dinamic DNS oferit de RCS&RDS, precum și efectuarea unor setări pe

More information

Figura x.1 Ecranul de pornire al mediului de dezvoltare

Figura x.1 Ecranul de pornire al mediului de dezvoltare x. Mediul de dezvoltare MICROSOFT VISUAL C++ În cadrul acestui capitol vom prezenta Microsoft Visual C++, din cadrul suitei Microsoft Visual Studio 2012, care este un mediu de programare care suportă dezvoltarea

More information

Nume şi Apelativ prenume Adresa Număr telefon Tip cont Dobânda Monetar iniţial final

Nume şi Apelativ prenume Adresa Număr telefon  Tip cont Dobânda Monetar iniţial final Enunt si descriere aplicatie. Se presupune ca o organizatie (firma, banca, etc.) trebuie sa trimita scrisori prin posta unui numar (n=500, 900,...) foarte mare de clienti pe care sa -i informeze cu diverse

More information

Modalitǎţi de clasificare a datelor cantitative

Modalitǎţi de clasificare a datelor cantitative Modalitǎţi de clasificare a datelor cantitative Modul de stabilire a claselor determinarea pragurilor minime şi maxime ale fiecǎrei clase - determinǎ modul în care sunt atribuite valorile fiecǎrei clase

More information

Universitatea George Bariţiu, Braşov

Universitatea George Bariţiu, Braşov LUCRUL CU BAZE DE DATE ÎN JAVA Lect.univ.dr.ing. IOAN-GHEORGHE RAŢIU Lect.univ. NICOLETA DAVID Universitatea George Bariţiu, Braşov Rezumat O bază de date reprezintă o modalitate de stocare a unor informaţii

More information

La fereastra de autentificare trebuie executati urmatorii pasi: 1. Introduceti urmatoarele date: Utilizator: - <numarul dvs de carnet> (ex: "9",

La fereastra de autentificare trebuie executati urmatorii pasi: 1. Introduceti urmatoarele date: Utilizator: - <numarul dvs de carnet> (ex: 9, La fereastra de autentificare trebuie executati urmatorii pasi: 1. Introduceti urmatoarele date: Utilizator: - (ex: "9", "125", 1573" - se va scrie fara ghilimele) Parola: -

More information

Proceduri stocate. Crearea procedurilor stocate. Varianta 1 În Management Studio se dă clic pe New Query ca în imaginea de mai jos: Fig.

Proceduri stocate. Crearea procedurilor stocate. Varianta 1 În Management Studio se dă clic pe New Query ca în imaginea de mai jos: Fig. Proceduri stocate Crearea procedurilor stocate. Varianta 1 În Management Studio se dă clic pe New Query ca în imaginea de mai jos: Fig. 1 Odată cu deschiderea editorului SQL, apare și bara de instrumente

More information

Itemi Sisteme de Operare

Itemi Sisteme de Operare Itemi Sisteme de Operare 1. Pentru a muta un dosar (folder) de pe partiţia C: pe partiţia D: folosim: a. New Folder b. Ctrl + C din bara de instrumente şi Copy; c. Ctrl + X şi Ctrl + V; d. Edit Paste;

More information

Ghid identificare versiune AWP, instalare AWP şi verificare importare certificat în Store-ul de Windows

Ghid identificare versiune AWP, instalare AWP şi verificare importare certificat în Store-ul de Windows Ghid identificare versiune AWP, instalare AWP 4.5.4 şi verificare importare certificat în Store-ul de Windows Data: 28.11.14 Versiune: V1.1 Nume fişiser: Ghid identificare versiune AWP, instalare AWP 4-5-4

More information

Documentaţie Tehnică

Documentaţie Tehnică Documentaţie Tehnică Verificare TVA API Ultima actualizare: 27 Aprilie 2018 www.verificaretva.ro 021-310.67.91 / 92 info@verificaretva.ro Cuprins 1. Cum funcţionează?... 3 2. Fluxul de date... 3 3. Metoda

More information

INTEROGĂRI ÎN SQL SERVER

INTEROGĂRI ÎN SQL SERVER INTEROGĂRI ÎN SQL SERVER Principala operaţie efectuată într-o bază de date este operaţia de extragere a datelor, care se realizează cu ajutorul unei clauze SELECT. SELECT Clauza SELECT are o sintaxă foarte

More information

9. CURSOARE. Obiective. În acest Capitol, vom învăţa despre: Manipularea cursoarelor. Folosirea Cursor FOR Loops şi Nesting Cursors.

9. CURSOARE. Obiective. În acest Capitol, vom învăţa despre: Manipularea cursoarelor. Folosirea Cursor FOR Loops şi Nesting Cursors. 9. CURSOARE Obiective. În acest Capitol, vom învăţa despre: Manipularea cursoarelor. Folosirea Cursor FOR Loops şi Nesting Cursors. Cursoare sunt zone de memorie care ne permit să alocam o zonă de memorie

More information

REVISTA NAŢIONALĂ DE INFORMATICĂ APLICATĂ INFO-PRACTIC

REVISTA NAŢIONALĂ DE INFORMATICĂ APLICATĂ INFO-PRACTIC REVISTA NAŢIONALĂ DE INFORMATICĂ APLICATĂ INFO-PRACTIC Anul II Nr. 7 aprilie 2013 ISSN 2285 6560 Referent ştiinţific Lector univ. dr. Claudiu Ionuţ Popîrlan Facultatea de Ştiinţe Exacte Universitatea din

More information

Arbori. Figura 1. struct ANOD { int val; ANOD* st; ANOD* dr; }; #include <stdio.h> #include <conio.h> struct ANOD { int val; ANOD* st; ANOD* dr; }

Arbori. Figura 1. struct ANOD { int val; ANOD* st; ANOD* dr; }; #include <stdio.h> #include <conio.h> struct ANOD { int val; ANOD* st; ANOD* dr; } Arbori Arborii, ca şi listele, sunt structuri dinamice. Elementele structurale ale unui arbore sunt noduri şi arce orientate care unesc nodurile. Deci, în fond, un arbore este un graf orientat degenerat.

More information

Colegiul Național Calistrat Hogaș Piatra-Neamț LIMBAJUL SQL

Colegiul Național Calistrat Hogaș Piatra-Neamț LIMBAJUL SQL LIMBAJUL SQL Prezentare generală SQL (Structured Query Language) este în prezent, unul din cele mai puternice limbaje structurate pentru interogarea bazelor de date relaţionale. Este un limbaj neprocedural

More information

Subiecte Clasa a VI-a

Subiecte Clasa a VI-a (40 de intrebari) Puteti folosi spatiile goale ca ciorna. Nu este de ajuns sa alegeti raspunsul corect pe brosura de subiecte, ele trebuie completate pe foaia de raspuns in dreptul numarului intrebarii

More information

Reflexia şi refracţia luminii. Aplicaţii. Valerica Baban

Reflexia şi refracţia luminii. Aplicaţii. Valerica Baban Reflexia şi refracţia luminii. Aplicaţii. Sumar 1. Indicele de refracţie al unui mediu 2. Reflexia şi refracţia luminii. Legi. 3. Reflexia totală 4. Oglinda plană 5. Reflexia şi refracţia luminii în natură

More information

Excel Advanced. Curriculum. Școala Informală de IT. Educație Informală S.A.

Excel Advanced. Curriculum. Școala Informală de IT. Educație Informală S.A. Excel Advanced Curriculum Școala Informală de IT Tel: +4.0744.679.530 Web: www.scoalainformala.ro / www.informalschool.com E-mail: info@scoalainformala.ro Cuprins 1. Funcții Excel pentru avansați 2. Alte

More information

Cap.5 Normalizarea relaţiilor

Cap.5 Normalizarea relaţiilor CAPITOLUL 5 NORMALIZAREA RELAŢIILOR Dependenţele de date reprezintă constrângeri care se impun valorilor atributelor unei relaţii şi determină proprietăţile relaţiei în raport cu operaţiile de inserare,

More information

Update firmware aparat foto

Update firmware aparat foto Update firmware aparat foto Mulţumim că aţi ales un produs Nikon. Acest ghid descrie cum să efectuaţi acest update de firmware. Dacă nu aveţi încredere că puteţi realiza acest update cu succes, acesta

More information

Baza de date: tabele, date. Componentele unei B.D.: tabele, constrangeri, relatii. Entitati ale unei B.D.: formulare, interogari, rapoarte

Baza de date: tabele, date. Componentele unei B.D.: tabele, constrangeri, relatii. Entitati ale unei B.D.: formulare, interogari, rapoarte 1. Introducere ~ Microsoft Access ~ Baze de Date Baza de date: tabele, date. Componentele unei B.D.: tabele, constrangeri, relatii. Entitati ale unei B.D.: formulare, interogari, rapoarte 2. Crearea unei

More information

Mai bine. Pentru c putem.

Mai bine. Pentru c putem. 1 CUPRINS: 1. SUMAR APLICAŢIE...... 3 1.1 Introducere... 3 1.2 Tipul de aplicaţie... 3 2. SPECIFICAŢII FUNCŢIONALE... 3 3. INSTALARE... 3 3.1 Introducere... 3 3.2 Ce trebuie să verificaţi înainte de a

More information

9. Memoria. Procesorul are o memorie cu o arhitectură pe două niveluri pentru memoria de program și de date.

9. Memoria. Procesorul are o memorie cu o arhitectură pe două niveluri pentru memoria de program și de date. 9. Memoria Procesorul are o memorie cu o arhitectură pe două niveluri pentru memoria de program și de date. Primul nivel conține memorie de program cache (L1P) și memorie de date cache (L1D). Al doilea

More information

Proiectarea bazelor de date. PL/SQL Înregistrări și Colecții # 13. Adrian Runceanu

Proiectarea bazelor de date. PL/SQL Înregistrări și Colecții # 13. Adrian Runceanu Proiectarea bazelor de date # 13 PL/SQL Înregistrări și Colecții 2016 Adrian Runceanu www.runceanu.ro/adrian Curs 13 Înregistrări și Colecții Proiectarea bazelor de date 2 Înregistrări și Colecții în PL/SQL

More information

Reţele Neuronale Artificiale în MATLAB

Reţele Neuronale Artificiale în MATLAB Reţele Neuronale Artificiale în MATLAB Programul MATLAB dispune de o colecţie de funcţii şi interfeţe grafice, destinate lucrului cu Reţele Neuronale Artificiale, grupate sub numele de Neural Network Toolbox.

More information

Structura și Organizarea Calculatoarelor. Titular: BĂRBULESCU Lucian-Florentin

Structura și Organizarea Calculatoarelor. Titular: BĂRBULESCU Lucian-Florentin Structura și Organizarea Calculatoarelor Titular: BĂRBULESCU Lucian-Florentin Chapter 3 ADUNAREA ȘI SCĂDEREA NUMERELOR BINARE CU SEMN CONȚINUT Adunarea FXP în cod direct Sumator FXP în cod direct Scăderea

More information

Proiectarea bazelor de date # 11. PL/SQL Funcții în PL/SQL (partea a II-a) Adrian Runceanu

Proiectarea bazelor de date # 11. PL/SQL Funcții în PL/SQL (partea a II-a) Adrian Runceanu Proiectarea bazelor de date # 11 PL/SQL Funcții în PL/SQL (partea a II-a) 2018 Adrian Runceanu www.runceanu.ro/adrian Curs 11 Funcţii în PL/SQL (partea II) Proiectarea bazelor de date 2 Cuprins Funcţii

More information

O bază de date (database), este o colecţie de date creată şi

O bază de date (database), este o colecţie de date creată şi CAPITOLUL 1 NOŢIUNI INTRODUCTIVE PRIVIND SISTEMELE DE GESTIUNE A BAZELOR DE DATE O bază de date (database), este o colecţie de date creată şi menţinută computerizat, care permite operaţii de inserare,

More information

Propuneri pentru teme de licență

Propuneri pentru teme de licență Propuneri pentru teme de licență Departament Automatizări Eaton România Instalație de pompare cu rotire în funcție de timpul de funcționare Tablou electric cu 1 pompă pilot + 3 pompe mari, cu rotirea lor

More information

SGBD Access 2010: Query

SGBD Access 2010: Query SGBD Access 2010: Query Interogarea (Query) este un obiect ce permite vizualizarea informaţiilor obţinute prin selectarea şi prelucrarea datelor din unul sau mai multe tabele (sau interogări) Rezultatul

More information

APLICAŢIE INFORMATICĂ PENTRU PREGĂTIREA MISIUNILOR DE NIVEL TACTIC

APLICAŢIE INFORMATICĂ PENTRU PREGĂTIREA MISIUNILOR DE NIVEL TACTIC APLICAŢIE INFORMATICĂ PENTRU PREGĂTIREA MISIUNILOR DE NIVEL TACTIC Asist.univ.drd. Romana OANCEA Conf.univ.dr.ing. Ghiţă BÂRSAN Academia Forţelor Terestre Nicolae Bălcescu Sibiu Abstract The paper describes

More information

Ghid pentru configurarea şi utilizarea aplicaţiei clicksign Demo

Ghid pentru configurarea şi utilizarea aplicaţiei clicksign Demo Ghid pentru configurarea şi utilizarea aplicaţiei clicksign Demo 2.6.9.223 Cuprins 1 Cadru general...2 2 Obţinerea unui certificat digital...3 3 Configurarea aplicaţiei clicksign...5 4 Utilizarea aplicaţiei

More information

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Proiect nr. 154/323 cod SMIS 4428 cofinanțat de prin Fondul European de Dezvoltare Regională Investiții pentru viitorul

More information

X-Fit S Manual de utilizare

X-Fit S Manual de utilizare X-Fit S Manual de utilizare Compatibilitate Acest produs este compatibil doar cu dispozitivele ce au următoarele specificații: ios: Versiune 7.0 sau mai nouă, Bluetooth 4.0 Android: Versiune 4.3 sau mai

More information

Laborator 1. Programare declarativă. Programare logică. Prolog. SWI-Prolog

Laborator 1. Programare declarativă. Programare logică. Prolog. SWI-Prolog Laborator 1 Programare declarativă O paradigmă de programare în care controlul fluxului de execuție este lăsat la latitudinea implementării limbajului, spre deosebire de programarea imperativă în care

More information

GHID DE TERMENI MEDIA

GHID DE TERMENI MEDIA GHID DE TERMENI MEDIA Definitii si explicatii 1. Target Group si Universe Target Group - grupul demografic care a fost identificat ca fiind grupul cheie de consumatori ai unui brand. Toate activitatile

More information

R O M Â N I A CURTEA CONSTITUŢIONALĂ

R O M Â N I A CURTEA CONSTITUŢIONALĂ R O M Â N I A CURTEA CONSTITUŢIONALĂ Palatul Parlamentului Calea 13 Septembrie nr. 2, Intrarea B1, Sectorul 5, 050725 Bucureşti, România Telefon: (+40-21) 312 34 84; 335 62 09 Fax: (+40-21) 312 43 59;

More information

3.2 Arhitectura setului de instrucţiuni ISA. Copyright Paul GASNER

3.2 Arhitectura setului de instrucţiuni ISA. Copyright Paul GASNER 3.2 Arhitectura setului de instrucţiuni ISA Copyright Paul GASNER Programarea CPU Programele scrise în limbaje de nivel înalt trebuie compilate pentru a obţine un program executabil Din punctul de vedere

More information

Ministerul Educaţiei Naţionale şi Cercetării Ştiinţifice Olimpiada de Tehnologia Informaţiei etapa judeţeană 2 aprilie 2016

Ministerul Educaţiei Naţionale şi Cercetării Ştiinţifice Olimpiada de Tehnologia Informaţiei etapa judeţeană 2 aprilie 2016 Subiect - Proba proiect 100 puncte GOOD FOOD Notă: Toate resursele le găsiţi în folder-ul Resurse aflat pe desktop. Creați un folder cu denumirea X, în care X este ID-ul de concurs și salvați în folder-ul

More information

1. Creaţi un nou proiect de tip Windows Forms Application, cu numele MdiExample.

1. Creaţi un nou proiect de tip Windows Forms Application, cu numele MdiExample. Aplicaţia MdiExample Aplicaţia implementează: Deschiderea şi închiderea ferestrelor child. Minimizarea şi maximizarea ferestrelor. Aranjarea ferestrelor. Tratarea mesajului de atenţionare la ieşirea din

More information

1 Vasile Violeta Ion Popescu Avram Maria Câmpuri în tabel

1 Vasile Violeta Ion Popescu Avram Maria Câmpuri în tabel ECDL MODULUL 5 Baze de date 1.1. Concepte generale privind bazele de date 1. Utilizarea aplicaţiei Access De ce foloisim bazele de date: Atunci când avem mai multe informaţii despre un anumit lucru si

More information

PROIECT. La Baze de date. Evidența activității pentru o firmă IT. Îndrumător: ș. l. dr. ing. Mirela Danubianu. Efectuat de: Grigoriev Sergiu gr.

PROIECT. La Baze de date. Evidența activității pentru o firmă IT. Îndrumător: ș. l. dr. ing. Mirela Danubianu. Efectuat de: Grigoriev Sergiu gr. PROIECT La Baze de date Evidența activității pentru o firmă IT Îndrumător: ș. l. dr. ing. Mirela Danubianu Efectuat de: Grigoriev Sergiu gr. 1131B Suceava 2011 Cuprins 1. DESCRIERE 3 2. MODELAREA CONCEPTUALĂ

More information

ARBORI AVL. (denumiti dupa Adelson-Velskii si Landis, 1962)

ARBORI AVL. (denumiti dupa Adelson-Velskii si Landis, 1962) ARBORI AVL (denumiti dupa Adelson-Velskii si Landis, 1962) Georgy Maximovich Adelson-Velsky (Russian: Гео ргий Макси мович Адельсо н- Ве льский; name is sometimes transliterated as Georgii Adelson-Velskii)

More information

Creare baza de data Deschidem aplicaţia Microsoft Access. Lansarea în execuţie a programului se face urmând calea:

Creare baza de data Deschidem aplicaţia Microsoft Access. Lansarea în execuţie a programului se face urmând calea: Baze de date Pentru început este bine să înţelegem noţiunile de bază din Access: modul de organizare a unei baze de date, a noţiunilor de tabel, înregistrare, câmp, tip de dată al câmpului, proprietăţi

More information

Procesarea Imaginilor

Procesarea Imaginilor Procesarea Imaginilor Curs 11 Extragerea informańiei 3D prin stereoviziune Principiile Stereoviziunii Pentru observarea lumii reale avem nevoie de informańie 3D Într-o imagine avem doar două dimensiuni

More information

Funcţii grup şi clauzele GROUP BY, HAVING. Operatorii ROLLUP şi CUBE.

Funcţii grup şi clauzele GROUP BY, HAVING. Operatorii ROLLUP şi CUBE. Baze de date-anul 2 Laborator 4 SQL Funcţii grup şi clauzele GROUP BY, HAVING. Operatorii ROLLUP şi CUBE. I. [Funcţii grup şi clauza GROUP BY] Clauza GROUP BY este utilizată pentru a diviza liniile unui

More information

Mecanismul de decontare a cererilor de plata

Mecanismul de decontare a cererilor de plata Mecanismul de decontare a cererilor de plata Autoritatea de Management pentru Programul Operaţional Sectorial Creşterea Competitivităţii Economice (POS CCE) Ministerul Fondurilor Europene - Iunie - iulie

More information

6. Bucle. 6.1 Instrucţiunea while

6. Bucle. 6.1 Instrucţiunea while 6. Bucle În capitolul trecut am văzut cum putem selecta diferite instrucţiuni pentru execuţie folosind instrucţiunea if. O buclă este o structură de control care provoacă executarea unei instrucţiuni sau

More information

5.1 Definirea datelor în SQL

5.1 Definirea datelor în SQL SQL Acronim pentru Structured Query Language Dezvoltat pentru sistemul de gestiune a bazelor de date System R, creat de IBM Research Laboratory, San Jose, California, la sfârşitul anilor 70. SQL a fost

More information

Mulțumim anticipat tuturor acelora care vor transmite critici/observații/sugestii

Mulțumim anticipat tuturor acelora care vor transmite critici/observații/sugestii Mulțumim anticipat tuturor acelora care vor transmite critici/observații/sugestii ilincamircea@yahoo.com TEMA III.1 v1 : ORGANIZAREA DATELOR UNUI PROGRAM C/C++ ÎN MO postat 02.11.2016 (sinteză) Coținutul

More information

[{CYCLE NOCYCLE}] [{CACHE

[{CYCLE NOCYCLE}] [{CACHE Laborator 10 1. Secvenţe Secvenţa este un obiect al bazei de date ce permite generarea de întregi unici pentru a fi folosiţi ca valori pentru cheia primară sau coloane numerice unice. Secvenţele sunt independente

More information

Capitolul IV Utilizarea bazelor de date în Internet

Capitolul IV Utilizarea bazelor de date în Internet Capitolul IV Utilizarea bazelor de date în Internet 4.1 Pagini Web dinamice 4.1.1. Pagini dinamice vs. Pagini statice Paginile Web dinamice sunt folosite atunci când se doreşte modificarea dinamică, a

More information

Semnale şi sisteme. Facultatea de Electronică şi Telecomunicaţii Departamentul de Comunicaţii (TC)

Semnale şi sisteme. Facultatea de Electronică şi Telecomunicaţii Departamentul de Comunicaţii (TC) Semnale şi sisteme Facultatea de Electronică şi Telecomunicaţii Departamentul de Comunicaţii (TC) http://shannon.etc.upt.ro/teaching/ssist/ 1 OBIECTIVELE CURSULUI Disciplina îşi propune să familiarizeze

More information

Interogarea (query), este operaţia prin care se obţin datele

Interogarea (query), este operaţia prin care se obţin datele CAPITOLUL 3 INTEROGAREA BAZELOR DE DATE Interogarea (query), este operaţia prin care se obţin datele dorite dintr-o bază de date, selectate conform unui anumit criteriu (condiţie). Întrucât operaţia de

More information

Managementul referinţelor cu

Managementul referinţelor cu TUTORIALE DE CULTURA INFORMAŢIEI Citarea surselor de informare cu instrumente software Managementul referinţelor cu Bibliotecar Lenuţa Ursachi PE SCURT Este gratuit Poţi adăuga fişiere PDF Poţi organiza,

More information

Baze de date - Lucrare de laborator 3 -

Baze de date - Lucrare de laborator 3 - Baze de date - Lucrare de laborator 3 - PROIECTAREA BAZELOR DE DATE RELATIONALE 1. NOTIUNI TEORETICE Proiectarea unei baze de date consta din proiectarea schemei conceptuale (logice) si fizice a acesteia,

More information

Subprograme şi pachete PL/SQL

Subprograme şi pachete PL/SQL Subprograme şi pachete PL/SQL Subprograme PL/SQL Subprogramele sunt blocuri PL/SQL care au nume, acceptă parametri şi pot fi apelate din alte blocuri PL/SQL. Subprogramele pot fi declarate ca proceduri

More information

Aspecte controversate în Procedura Insolvenţei şi posibile soluţii

Aspecte controversate în Procedura Insolvenţei şi posibile soluţii www.pwc.com/ro Aspecte controversate în Procedura Insolvenţei şi posibile soluţii 1 Perioada de observaţie - Vânzarea de stocuri aduse în garanţie, în cursul normal al activității - Tratamentul leasingului

More information

UNIVERSITATEA ŞTEFAN CEL MARE SUCEAVA

UNIVERSITATEA ŞTEFAN CEL MARE SUCEAVA UNIVERSITATEA ŞTEFAN CEL MARE SUCEAVA Facultatea de Ştiinţe Economice şi Administraţie Publică Nicolae Morariu BAZE DE DATE Îndrumar de laborator 2005 1 Referenţi ştiinţifici: Prof.univ.dr.ing. Alexandru

More information

Auditul financiar la IMM-uri: de la limitare la oportunitate

Auditul financiar la IMM-uri: de la limitare la oportunitate Auditul financiar la IMM-uri: de la limitare la oportunitate 3 noiembrie 2017 Clemente Kiss KPMG in Romania Agenda Ce este un audit la un IMM? Comparatie: audit/revizuire/compilare Diferente: audit/revizuire/compilare

More information

INFORMAȚII DESPRE PRODUS. FLEXIMARK Stainless steel FCC. Informații Included in FLEXIMARK sample bag (article no. M )

INFORMAȚII DESPRE PRODUS. FLEXIMARK Stainless steel FCC. Informații Included in FLEXIMARK sample bag (article no. M ) FLEXIMARK FCC din oțel inoxidabil este un sistem de marcare personalizată în relief pentru cabluri și componente, pentru medii dure, fiind rezistent la acizi și la coroziune. Informații Included in FLEXIMARK

More information

Ce este o BAZA DE DATE?

Ce este o BAZA DE DATE? Ce este o BAZA DE DATE? In sens larg un sistem proiectat pentru a oferi un mecanism organizat, capabil sa stocheze, sa actualizeze si sa regaseasca informatia Exemplu: o biblioteca Noţiunea de bază de

More information

Ce pot face pe hi5? Organizare si facilitati. Pagina de Home

Ce pot face pe hi5? Organizare si facilitati. Pagina de Home Ce este Hi5!? hi5 este un website social care, în decursul anului 2007, a fost unul din cele 25 cele mai vizitate site-uri de pe Internet. Compania a fost fondată în 2003 iar pana in anul 2007 a ajuns

More information

Actualizarea firmware-ului pentru aparatul foto digital SLR

Actualizarea firmware-ului pentru aparatul foto digital SLR Actualizarea firmware-ului pentru aparatul foto digital SLR Vă mulţumim că aţi ales un produs Nikon. Acest ghid descrie cum să realizaţi actualizarea firmwareului. Dacă nu sunteţi sigur că puteţi realiza

More information

MICROSOFT ACCESS 2007 (DE CĂUTAT???)

MICROSOFT ACCESS 2007 (DE CĂUTAT???) Access 2007 Modul A Pagina 1 MICROSOFT ACCESS 2007 (DE CĂUTAT???) 1. CONCEPTE GENERALE PRIVIND BAZELE DE DATE Evoluţia diferitelor metode şi tehnici de organizare a datelor pe suporturi de memorie externă

More information

Subinterogari SELECT salariul FROM angajaţi WHERE nume= Ionescu SELECT nume, prenume FROM angajaţi WHERE salariul>s

Subinterogari SELECT salariul FROM angajaţi WHERE nume= Ionescu SELECT nume, prenume FROM angajaţi WHERE salariul>s Subinterogari Sunteţi patronul unei firme. În ultima perioadă unul dintre salariaţii firmei, pe nume Ionescu, s-a remarcat în mod deosebit prin activitatea sa. Aţi decis de aceea să îi măriţi salariul

More information

Capitolul IF.02. Structurarea bazelor de date

Capitolul IF.02. Structurarea bazelor de date Capitolul Cuvinte-cheie: Normalizare, prima formă normală, a doua formă normală, a treia formă normală, cheie candidată, relatie 1 la 1, relație 1 la n, relație m la n IA.02.1. Scurt istoric În anii '60,

More information

MANAGEMENTUL CALITĂȚII - MC. Proiect 5 Procedura documentată pentru procesul ales

MANAGEMENTUL CALITĂȚII - MC. Proiect 5 Procedura documentată pentru procesul ales MANAGEMENTUL CALITĂȚII - MC Proiect 5 Procedura documentată pentru procesul ales CUPRINS Procedura documentată Generalități Exemple de proceduri documentate Alegerea procesului pentru realizarea procedurii

More information

UNIVERSITATEA DIN CRAIOVA FACULTATEA DE ELECTROMECANICĂ CATEDRA DE ACŢIONĂRI ELECTRICE. Şef lucrări dr. ing. Cătălin CONSTANTINESCU BAZE DE DATE

UNIVERSITATEA DIN CRAIOVA FACULTATEA DE ELECTROMECANICĂ CATEDRA DE ACŢIONĂRI ELECTRICE. Şef lucrări dr. ing. Cătălin CONSTANTINESCU BAZE DE DATE UNIVERSITATEA DIN CRAIOVA FACULTATEA DE ELECTROMECANICĂ CATEDRA DE ACŢIONĂRI ELECTRICE Şef lucrări dr. ing. Cătălin CONSTANTINESCU BAZE DE DATE Electromecanică - Frecvenţă redusă - Suport teoretic - 2006-2007

More information

Calculatoare Numerice II Interfaţarea unui dispozitiv de teleghidare radio cu portul paralel (MGSH Machine Guidance SHell) -proiect-

Calculatoare Numerice II Interfaţarea unui dispozitiv de teleghidare radio cu portul paralel (MGSH Machine Guidance SHell) -proiect- Universitatea Politehnica Bucureşti Facultatea de Automaticăşi Calculatoare Calculatoare Numerice II Interfaţarea unui dispozitiv de teleghidare radio cu portul paralel (MGSH Machine Guidance SHell) -proiect-

More information

ADO.NET - note de curs pentru disciplina "Servere de date"

ADO.NET - note de curs pentru disciplina Servere de date ADO.NET - note de curs pentru disciplina "Servere de date" Pentru lucrul cu sursele de date necesare într-o aplicaţie se poate folosi ADO.NET, care este o ierarhie de clase ce permite gestiunea datelor.

More information

O tranzacţie este o unitate logică de prelucrare

O tranzacţie este o unitate logică de prelucrare CAPITOLUL 6 GESTIUNEA TRANZACŢIILOR În mod obişnuit, un SGBD deserveşte mai mulţi utilizatori, care accesează concurent datele din tabele. Accesul concurent al utilizatorilor este asigurat prin capacitatea

More information

INTERPRETOARE DE COMENZI

INTERPRETOARE DE COMENZI Rularea lui determin afişarea mesajului hello world la consola 3.2. Facilităţi ale interpretoarelor de comenzi 3.1. Introducere Capitolul 3 INTERPRETOARE DE COMENZI Interpretorul de comenzi este un program

More information

Lucrarea nr.1. Crearea unui document Word

Lucrarea nr.1. Crearea unui document Word Lucrarea nr.1 Crearea unui document Word Scopul lucrării Lucrarea are drept scop inițiere și familiarizarea studenților cu interfața editorului de text Microsoft Word 2007. Modul de lucru Word este un

More information

CERERI SELECT PE MAI MULTE TABELE

CERERI SELECT PE MAI MULTE TABELE SQL - 2 CERERI SELECT PE MAI MULTE TABELE 1 STUD MATR NUME AN GRUPA DATAN LOC TUTOR PUNCTAJ CODS ---- ------- -- ------ --------- ---------- ----- ------- ---- 1456 GEORGE 4 1141A 12-MAR-82 BUCURESTI 2890

More information

Universitatea Politehnica Bucureşti Facultatea de Automatică şi Calculatoare Departamentul de Automatică şi Ingineria Sistemelor LUCRARE DE LICENŢĂ

Universitatea Politehnica Bucureşti Facultatea de Automatică şi Calculatoare Departamentul de Automatică şi Ingineria Sistemelor LUCRARE DE LICENŢĂ Universitatea Politehnica Bucureşti Facultatea de Automatică şi Calculatoare Departamentul de Automatică şi Ingineria Sistemelor LUCRARE DE LICENŢĂ Sistem Object Relational Mapping in Java Coordonator

More information

Proiectarea Sistemelor Software Complexe

Proiectarea Sistemelor Software Complexe Proiectarea Sistemelor Software Complexe Curs 3 Principii de Proiectare Orientată pe Obiecte Principiile de proiectare orientată pe obiecte au fost formulate pentru a servi ca reguli pentru evitarea proiectării

More information

Lucrarea Nr.1. Sisteme de operare. Generalitati

Lucrarea Nr.1. Sisteme de operare. Generalitati Lucrarea Nr.1 Sisteme de operare. Generalitati Scopul lucrarii Lucrarea îsi propune familiarizarea studentilor cu sistemele de operare disponibile în laborator, respectiv acele sisteme de operare cu ajutorul

More information

UTILIZAREA FOILOR DE CALCUL TABELAR - EXCEL

UTILIZAREA FOILOR DE CALCUL TABELAR - EXCEL UTILIZAREA FOILOR DE CALCUL TABELAR - EXCEL 1. Deschiderea aplicaţiei Excel - Start Programs Microsoft Excel; - Dublu clic pe pictograma de pe ecran sub care scrie Microsoft Excel; Pe ecranul monitorului

More information

ORARE DE EXECU}IE. Opțiunea se găseşte în MENTOR > Alte module > AdminJOBs > Orare de execuție.

ORARE DE EXECU}IE. Opțiunea se găseşte în MENTOR > Alte module > AdminJOBs > Orare de execuție. ORARE DE EXECU}IE Opțiunea se găseşte în MENTOR > Alte module > AdminJOBs > Orare de execuție. În funcție de setările fiecărui orar în parte, acesta produce activarea unei acțiuni pe serverul de Oracle.

More information

REVISTA NAŢIONALĂ DE INFORMATICĂ APLICATĂ INFO-PRACTIC

REVISTA NAŢIONALĂ DE INFORMATICĂ APLICATĂ INFO-PRACTIC REVISTA NAŢIONALĂ DE INFORMATICĂ APLICATĂ INFO-PRACTIC Anul III Nr. 21 iunie 2014 ISSN 2285 6560 Referent ştiinţific Lector univ. dr. Claudiu Ionuţ Popîrlan Facultatea de Ştiinţe Exacte Universitatea din

More information

Capitolul 4 SUBCERERI. F. Radulescu. Curs: Baze de date - Limbajul SQL

Capitolul 4 SUBCERERI. F. Radulescu. Curs: Baze de date - Limbajul SQL Capitolul 4 SUBCERERI 1 STUD MATR NUME AN GRUPA DATAN LOC TUTOR PUNCTAJ CODS ---- ------- -- ------ --------- ---------- ----- ------- ---- 1456 GEORGE 4 1141A 12-MAR-82 BUCURESTI 2890 11 1325 VASILE 2

More information

Macrocomenzi. Figura 1. Personalizarea barei de meniuri. Se va afișa fereastra din figura 2. Figura 2. Includerea tab ului Developer.

Macrocomenzi. Figura 1. Personalizarea barei de meniuri. Se va afișa fereastra din figura 2. Figura 2. Includerea tab ului Developer. Macrocomenzi Macrocomenzile (sau, prescurtat macrou rile) sunt colecții de comenzi înregistrate pentru a putea fi lansate în execuție, în bloc, ori de câte ori va fi nevoie. Avantajul lucrului cu macro

More information

Modulul 5 Baze de date

Modulul 5 Baze de date Scopul modulului Modulul 5, Baze de date, solicită din partea cititorului înţelegerea noţiunilor fundamentale despre bazele de date şi demonstrarea abilităţii de a folosi o bază de date pe un computer

More information

Curs 1 17 Februarie Adrian Iftene

Curs 1 17 Februarie Adrian Iftene Curs 1 17 Februarie 2011 Adrian Iftene adiftene@info.uaic.ro 1 Limbajele calculatorului Compilate Interpretate Scripting P-cod Orientate pe aspect Orientate spre date 2 Cum lucrează? Orice program trebuie

More information

M C I O H L BAZE DE CUNOŞTINŢE A H E O L N S I S T E M E D E R E P R E Z E N A R E Ş I P R O C E S A R E A A C U N O Ş T I N Ţ E L O R

M C I O H L BAZE DE CUNOŞTINŢE A H E O L N S I S T E M E D E R E P R E Z E N A R E Ş I P R O C E S A R E A A C U N O Ş T I N Ţ E L O R BAZE DE CUNOŞTINŢE S I S T E M E D E R E P R E Z E N A R E Ş I P R O C E S A R E A C U N O Ş T I N Ţ E L O R M C I O H L A H E O L N A TIPURI DE CUNOŞTINŢE Pentru a putea rezolva problemele complexe de

More information

Semnare digitală configurări și proceduri de lucru Manual de utilizare

Semnare digitală configurări și proceduri de lucru Manual de utilizare Semnare digitală configurări și proceduri de lucru Manual de utilizare Servicii informatice privind activităţi ale comunităţii portuare Acest document şi informaţiile conţinute în el sunt în proprietatea

More information

PROIECTAREA ALGORITMILOR

PROIECTAREA ALGORITMILOR Universitatea Constantin Brâncuşi Târgu-Jiu Facultatea de Inginerie Departamentul de Automatică, Energie şi Mediu 3 PROIECTAREA ALGORITMILOR Lect. univ. dr. Adrian Runceanu 1 Curs 3 Alocarea dinamică de

More information

Ghid de utilizare Modul CI+

Ghid de utilizare Modul CI+ Ghid de utilizare Modul CI+ www.orange.md Introducere Vă mulțumim că aţi ales modulul CI+. Acesta funcționează împreună cu televizorul Dvs. și vă ajută să vedeți conținutul oferit în cadrul pachetului

More information