Adatbázis rendszerek II Kovács László Az SQL-CLI és ODBC környezet
SQL-CLI Az SQL parancsok 80%-át gazdanyelvből adják ki 1992: erős igény egy új SQL API-ra E-SQL: elüt a gazdanyelvtől alapvetően statikus egyetlen kapcsolatra épül adatbázis függő (előfordító) új SQL API: gazdanyelvhez illeszkedik dinamikus több párhuzamos kapcsolat adatbázis független ISO SQL Access Group
SQL-CLI ISO-SQL-CLI(ODBC): - a gazdanyelv függvényeihez simul, az SQL parancsok paraméterként mennek át a DBMS-hez - nincs előfordító - leíró struktúrákat használ egy-egy kapcsolathoz - az API függvény könyvtár réteges felépítésű is lehet gazdanyelvi program scanf(”%d”,&n); SQLExec(kapcs,”UPDATE dolgozo SET fiz=0”) … DBMS SQL-CLI Library DBMS API Library
SQL-CLI szoros kapcsolat egymásra hatás SQL-CLI: ISO szabvány ODBC: az MS CLI implementációja Az API felületet definiálja Az API működési logikát értelmezi Implementáció kétrétegű library adatbázis függetlenség PHP C VFP VB Delphi … ODBC Oracle MSServer DB2 VFP Excel …
SQL-CLI ODBC struktúrája kliens alkalmazás (ODBC API hívások) ODBC vezérlő (meghajtók és kapcsolatok felügyelete ODBC meghajtó (hívások, parancsok konvertálása, kapcsolat tartás) adatforrás (relációs, táblázatkezelő,...)
SQL-CLI CLI-API elemek a kapcsolat, parancs leíró struktúrát handler-nek nevezik A handlerek létrehozása után adhatók ki a függvényhívások párhuzamosan több handler és kapcsolat élhet handler-ek létrehozása handler-ek lezárása
SQL-CLI CLI-API elemek A parancsok végrehajtásához is több API hívás kapcsolódik Lehet egylépcsős és kétlépcsős végrehajtás A CURSOR koncepcióra épül Az eredmény közvetlenül is lekérdezhető, vagy változóba irányítható A parancsok paraméterezhetőek
KÉP Thom Evans (?): Repetition
SQL-CLI session h. connection h. connection h. command h. command h. Handlerek típusai session h. connection h. connection h. command h. command h. command h. A handlerek feladatai: - azonosítás - aktuális állapotot tárolása - aktuális parancs leírása - státusz tárolása A parancsokban a handlereket adjuk meg azonosítóként
SQL-CLI Handlerek kezelése Session handler: a kliens azonosítás Connecton handler: adatforrás kapcsolat azonosítás Statement handler: parancs azonosítás e = sqlAllocEnv() c = sqlAllocConnect(e) p = sqlAllocStmt(c) sqlFreeStmt(p) sqlFreeConnect(c) sqlFreeEnv(e) handler-ek létrehozása handler-ek felszabadítása
SQL-CLI Adatbázis kapcsolat kezelése DBMS kapcsolódásnál név/jelszó azonosítás is élhet: SQLConnect(c_h, server, user, password); DBMS kapcsolat bontás: SQLDisConnect(c_h, server, user, password); session transaction transaction Explicit tranzakció nyitás: SQLStartTran(h_type,handl, acc_mode, isol_lev); Tranzakció lezárás: SQLEndTran(h_type,handl, mode);
SQL-CLI SQL parancs kiadása kód SQL-parancs QEP cache QEP Parancs végrehajtási módok: - közvetlen - kétlépcsős (paraméterezhető)
SQL-CLI Közvetlen SQL parancs kiadása SQLExecDirect (s_h,parancs) egyszeri Kétlépcsős SQL parancs kiadása SQLPrepare (s_h, parancs) ismétlődő SQLExecute (s_h) SQLPrepare QEP kód Alkalmazás SQLExecute program
DBMS Alkalmazás kurzor SQL-CLI Eredmény adatok feldolgozása A kurzor mechanizmusra épül DBMS Alkalmazás kurzor Ugrás a következő rekordra: SQLFetch (c_h) Mező értékek átvétele: SQLGetData (s_h, mező_sz, típus,...)
SQL-CLI Információ lekérés: SQLTables() SQLGetEnvAttr() AB SQLGetStmtAttr() SQLGetInfo() ... Alkalmazás Paraméter beállítás: AB SQLSetEnvAttr() SQLSetStmtAtt ... Alkalmazás Hiba észlelése: 1. API függvény visszatérési értéke 2. SQLError(e_h, c_h,s_h,sqlstate,message,… )
SQL-CLI
SQL-ODBC ODBC struktúra Lehet egyszintű és kétszintű meghajtó DSN: data source name (adatforrás azonosító) Gazdanyelv függő API Működési paraméterek: - izolációs szint - tranzakció szint - timeout - adat konverziók
SQL-ODBC ODBC Driver 1 Driver manager Driver 1 Driver 1 meghajtók kezelése kapcsolat az alkalmazással hibakezelés memória kezelés elemi konverziók információ nyújtás parancs konverzió adat konverzió kapcsolat felvétel funkció bővítés hibakezelés információ nyújtás
SQL-ODBC SQLAllocEnv(&henv); //session létesítés SQLAllocConnect(henv,&hdbc); //kapcsolat leíró foglalás SQLConnect(hdbc,(unsigned char*) // kapcsolódás ”HELLO”,SQL_NTS,NULL,0, NULL,0); SQLAllocStmt(hdbc,&hstmt); //parancs leíró foglalás SQLExecDirect(nstmt,(unsigned char*) “SELECT * FROM Minta “, SQL_NTS); //parancs végrehajtás for (rc=SQLFetch(hstmt);rc==SQL_SUCCESS; rc=SQLFetch(hstmt)){ //rekordok lekérdezése ciklusban SQLGetData(hstmt,1,SQL_C_CHAR,SzData, Sizeof(sydata),&cbData); //mező lekérdezése MessageBox(NULL,syData,”ODBC”,MB_OK); //az eredmény kiírása } SQLFreeStmt(hstmt,SQL_DROP); //parancs leírás SQLDisconnect(hdbe); //lekapcsolódás SQLFreeConnet(hdbe); //leíró felszabadítás SQLFreeEno(henv) //session leíró
automatikus konverzió SQL-CLI Gazdanyelvi változók kötése DB Alkalmazás adatcsere mező változó Fontos a konzisztens értelmezés (koccintás, villogás, bólintás,…) Értelmezés leíró struktúrákra van szükség mező név típus hossz cím ... változó név típus hossz cím ... automatikus konverzió
SQL-CLI Értelmezés leíró struktúrák Command Handler IPD APD DB Alkalmazás IRD ARD A leíró struktúrák feltöltése: - manuális - automatikus
SQL-CLI Közvetlen kezelés, paraméterezett SQL parancs int skod = 0; // kapcsolati változó SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE, &henv); SQLAllocHandle(SQL_HANDLE_DBC,henv, &hdbc); SQLAllocStmt(hdbc1, &hstmt); // handlerek allokálása SQLCHAR parancs = ”UPDATE dolg SET fiz=fiz*0.5 WHERE kod=? ”; // parancs szöveg, a ? Jel jelöli a paramétert if (SQLPrepare (hstmt,parancs,SQL_NTS) != SQL_SUCCESS) {…} // parancs előkészítése SQLGetStmtAttr(hstmt, SQL_ATTR_APP_PARAM_DESC, &hdesc1,…); // APD struktúra címének lekérdezése SQLSetDescRec(hdesc1, ..., SQL_INTEGER, &skod,…); // APD paraméterek beállítása SQLGetStmtAttr(hstmt, SQL_ATTR_IMP_PARAM_DESC, &hdesc2,…); // IPD struktúra címének lekérdezése SQLSetDescRec(hdesc2,..., SQL_INTEGER, 1,…); // IPD mezőinek beállítása
folytatás ... … scanf(„%d”, &skod); // változó értékadása if (SQLExecute(hstmt) != SQL_SUCCESS) {…} // parancs végrehajtás SQLEndTran(SQL_HANDLE_ENV, henv, SQL_COMMIT); // tranzakció lezárás SQLFreeHandle(SQL_HANDLE_STMT, hstmt); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); // handlerek felszabadítása
SQL-CLI Közvetett kezelés, paraméterezett SQL parancs … char snev[100]; // gazdanyelvi változók int sfiz,skod = 0; SQLCHAR parancs = ”UPDATE dolg SET fiz=fiz*0.5 WHERE kod=? ”; if (SQLPrepare (hstmt,parancs,SQL_NTS) != SQL_SUCCESS) {…} // parancs előkészítés if (SQLBindParameter(hstmt,…,SQL_INTEGER, &skod,…) != SQL_SUCCES ) {…} // input paraméterek kötése scanf(„%d”, &skod); if (SQLExecute(hstmt) != SQL_SUCCESS) {…} // végrehajtás if (SQLExecDirect(hstmt,”SELECT nev, fiz FROM dolg”,SQL_NTS) != SQL_SUCCES ) {…} // lekérdezés végrehajtás if (SQLBindCol(hstmt,…,1,SQL_CHAR,snev,…) != SQL_SUCCES){…} // eredmény mezők kötése while (SQLFetch(hstmt == SQL_SUCCESS) { sfiz = SQLGetData(hstmt,1,SQL_INTEGER,…); // direkt olv printf (”%s = %d\n”, snev, sfiz); // indirekt olv. } // beolvasási ciklus
ODBC / SQL-CLI / DB2-CLI Adatkapcsolati függvények SQLAllocConnect() Depr 95 V 1.1 SQLAllocEnv() Depr 95 V 1.1 SQLAllocHandle() Core 95 V 5 SQLBrowseConnect() Level 1 95 V 5 SQLConnect() Core 95 V 1.1 SQLDriverConnect() Core SQL3 V 2.1 SQLDrivers() Core No No SQLSetConnectAttr() Core 95 V 5 SQLSetConnectOption() Depr 95 V 2.1 SQLSetConnection() No SQL3 V 2.1
ODBC / SQL-CLI / DB2-CLI Parancs előkészítési függvények SQLAllocStmt() Depr 95 V 1.1 SQLPrepare() Core 95 V 1.1 SQLExtendedPrepare() No No V 6 SQLExtendedBind() No No V 6 SQLBindParameter() Lvl 1 95 V 2.1 SQLSetParam() Depr No V 1.1 SQLParamOptions() Depr No V 2.1 SQLGetCursorName() Core 95 V 1.1 SQLSetCursorName() Core 95 V 1.1 Kapcsolat lezárás SQLDisconnect() Core 95 V 1.1 SQLEndTran() Core 95 V 5 SQLFreeConnect() Depr 95 V 1.1 SQLFreeEnv() Depr 95 V 1.1
ODBC / SQL-CLI / DB2-CLI Parancs elküldési függvények SQLDescribeParam() Level 2 SQL3 V 5 SQLExecute() Core 95 V 1.1 SQLExecDirect() Core 95 V 1.1 SQLNativeSql() Lvl 2 95 V 2.1 SQLNumParams() Lvl 2 95 V 2.1 SQLParamData() Lvl 1 95 V 2.1 SQLPutData() Core 95 V 2.1 Felszabadítás SQLFreeHandle() Core 95 V 1.1 SQLFreeStmt() Core 95 V 1.1 SQLCancel() Core 95 V 1.1 SQLCloseCursor() Core 95 V 5
ODBC / SQL-CLI / DB2-CLI Eredmény lekérdezése ODBC SQL-CLI DB2-CL SQLRowCount() Core 95 V 1.1 SQLDescribeCol() Core 95 V 1.1 SQLColAttribute() Core Yes V 5 SQLColAttributes() Depr Yes V 1.1 SQLColumnPrivileges() Lev 2 95 V 2.1 SQLSetColAttributes() No No V 2.1 SQLBindCol() Core 95 V 1.1 SQLFetch() Core 95 V 1.1 SQLFetchScroll() Core 95 V 5 SQLExtendedFetch() Depr 95 V 2.1 SQLGetData() Core 95 V 1.1 SQLMoreResults() Lvl 1 SQL3 V 2.1 SQLNextResult() No Yes V7.1 SQLError() Depr 95 V 1.1 SQLGetDiagField() Core 95 V 5 SQLGetDiagRec() Core 95 V 5 SQLSetPos() Level 1 SQL3 V 5 SQLGetSQLCA() No No V 2.1
ODBC / SQL-CLI / DB2-CLI Információ lekérdezése ODBC SQL-CLI DB2-CL SQLColumns() Lvl 1 SQL3 V 2.1 SQLForeignKeys() Lvl 2 SQL3 V 2.1 SQLPrimaryKeys() Lvl 1 SQL3 V 2.1 SQLProcedureColumns() Lvl 2 No V 2.1 SQLProcedures() Lvl 2 No V 2.1 SQLSpecialColumns() Core SQL3 V 2.1 SQLStatistics() Core SQL3 V 2.1 SQLTablePrivileges() Lvl 2 SQL3 V 2.1 SQLTables() Core SQL3 V 2.1
PHP-ODBC odbc_connect() : adatbázis kapcsolódás odbc_exec() : közvetlen parancsvégrehajtás odbc_prepare() : előkészítés odbc_execute() : előkészített parancs végrehajtás odbc_fetch_row(): rekord beolvasás odbc_result() : egy mező átvétele az eredményből odbc_close() : kapcsolat zárása odbc_commit() : véglegesítés odbc_rollback() : visszagörgetés odbc_num_rows() : rekordok száma odbc_tables() : táblák adatai odbc_columns() : mezők adatai odbc_error() : hibakód odbc_fetch_array() : eredmény rekord átvétele tömbbe odbc_num_fields() : mezők darabszáma odbc_field_name() : mező neve odbc_set_options() : kapcsolati paraméter beállítás
PHP-ODBC <html> <body> <?php $conn=odbc_connect('northwind','',''); if (!$conn) {exit("Connection Failed: " . $conn);} $sql="SELECT * FROM customers"; $rs=odbc_exec($conn,$sql); if (!$rs) {exit("Error in SQL");} echo "<table><tr>"; echo "<th>Companyname</th>"; echo "<th>Contactname</th></tr>"; while (odbc_fetch_row($rs)) { $compname=odbc_result($rs,"CompanyName"); $conname=odbc_result($rs,"ContactName"); echo "<tr><td>$compname</td>"; echo "<td>$conname</td></tr>"; } odbc_close($conn); echo "</table>"; ?> </body> </html>
VFP-ODBC egyszerűsített nyilvántartás - egy leíró struktúra (egész típusú azonosító) egyszerűsített adatkezelés - VFP lokális kurzorba tölti át az eredményt hdbe=SQLConnect(DSN, felhasználó, jelszó) SQLExec(hdbc,”SQL”,cursornev) SQLColumns(hdbc,”tabla”) SQLCommit (hdbc) SQLTables(hdbc) SQLSETProp(hdbc,parameter,ertek) SQLGetProp(hdbe,parmeter) SQLRollback(hdbc) SQLDisConnect(hdbc)
VFP-ODBC pw = allt(thisform.jszo.value) con = sqlconnect("LocalServer","ujabb",pw) if con < 0 …… endif p = sqlexec(con,"SELECT max(kod) db FROM dolg","cu1") if p > 0 select cu1 kod = cu1.db + 1 endif p = sqlexec(con,"INSERT INTO DOLG VALUES(" + allt(str(kod))+ ",'" + allt(thisform.nev.value)+"') ")
kép Thom Evans: Whispers
Adatkezelés speciális elemei ODBC szintek ODBC kurzor módok CLI APD/IPD leíró területek CLI ARD/IRD leíró terület API: getDesc/SetDesc API : kötések (Binding) Deffered parameters Környezet beállítások
Thom Evans: My new hat