OCCI介紹
OCCI:Oracle C++調用介面(OCCI),即Oracle的C++API,允許你使用物件導向的特性、本地類、C++語言的方法來訪問Oracle資料庫。
OCCI優勢基於標準C++和物件導向的設計;效率較高;適合開發C/S模式的程式,軟體中介層;OCCI特性完整支援SQL/PLSQL為不斷增長的使用者和請求提供了彈性選項為使用使用者自訂類型,如C中的類,提供了無縫介面支援所有的Oracle資料類型以及LOB types可以訪問資料庫中繼資料OCCI標頭檔及動態連結程式庫
OCCI 標頭檔
•occi.h•occiCommon.h•occiControl.h•occiData.h•occiObjects.h
OCCI庫
•libocci.so/libocci.a/oraocci9.dll構建應用程式
步驟1:初始化OCCI通過建立一個Environment的對象完成初始化工作。可以通過Environment建立資料庫連接,從而進行其它的操作要建立Environment,應該調用Environment類的靜態方法createEnvironment()樣本:
//include 1 header file for all OCCI classes/interfaces#include <occi.h>//create EnvironmentEnvironment *env = Environment::createEnvironment();//建立連線物件指標//use the Environment instance to create connections,//database access…//terminate Environment by calling static method//Environment::terminateEnvironmentEnvironment::terminateEnvironment(env);//關閉
步驟二:串連資料庫
串連資料庫通過Connection類的對象執行個體實現調用Environment類的
createConnection()方法可以建立一個Connection對象;
Connection *Environment::createConnection( const string &userName,const string &password, const string &connectString )
串連資料庫成功後,可以用它來訪問資料,執行SQL語句;使用
Environment::terminateConnection()中斷連線;樣本:
//First need EnvironmentEnvironment *env = Environment::createEnvironment();Connection *conn=env->createConnection(“scott”,”tiger”,””);//3rd parameter is db name/TNS alias..//database access – use the Connection object....//logoff and terminate connectionenv->terminateConnection(conn);//中斷連線
步驟三:執行SQL/PLSQL
Statement類用於執行SQL/PLSQL語句,並擷取返回結果。ResultSet 類用於處理SELECT 查詢的結果。對於所有類型的資料的綁定或者擷取,OCCI都提供了統一的方法
- setXXX 方法用於Statement
- getXXX 方法用於Statement & ResultSet
OCCI會自動處理類型之間的轉換。使用方法:使用Connection::
createStatement()建立Statement對象指定 SQL 命令(DDL/DML/query)作為參數
Connection::createStatement(string &sql);
Statement::setSQL(string &sql);
Statement::execute(string &sql); - can be used for any SQL, returnsstatus
Statement::executeUpdate(string &sql); - returns Insert/Update/Delete count
Statement::executeQuery(string &sql); - returns ResultSet(結果集)
使用 setXXX 方法傳遞要綁定用於輸入的值使用合適的execute方法執行SQL對於SELECT 查詢, 使用ResultSet 對象處理返回結果簡單的DML Insert樣本:
//createStatement() on Connection class gives a Statement//instanceStatement *stmt = conn->createStatement(“ insert into Dept(Deptno,Dname, Loc) values (1, ‘ACCOUNTS’, ‘ZONE1’ ”);//executeUpdate for all INSERT/UPDATE/DELETEstmt->executeUpdate();conn->terminateStatement(stmt);
使用綁定參數的DML樣本:
Statement *stmt = conn->createStatement(“ insert intoEmp(EmpNo,Ename) values(:1, :2) ”);//1 and 2 are bind placeholdersint empno = 2;string empname = “JOHN W”;//first parameter is bind position, second is valuestmt->setInt(1, empno); stmt->setString(2, empname);stmt->executeUpdate();
執行SELECT查詢並處理結果:
Statement *stmt = conn->createStatement(“ select Empno, Ename, Sal from Emp where Hiredate >= :1”);//automatically converted to Datestmt->setString(1, “01-JAN-1987”);//executeQuery returns a ResultSetResultSet *rs = stmt->executeQuery(); //ResultSet::next fetches rows and returns FALSE //when no more rowswhile (rs->next() == true){ //get values using the getXXX methods of ResultSet empno = rs->getInt(1); empname = rs->getString(2); empsalary = rs->getFloat(3);}stmt->closeResultSet(rs);//to free resources
執行PL/SQL:
要執行PL/SQL,應該在建立Statement的時候指定PL/SQL塊使用setXXX將所有的輸入參數(IN andIN/OUT)傳給PLSQL函數或者過程使用Statement::registerOutParam來指定OUT參數,參數的大小通過Statement::setMaxParamSize指定使用Statement::execute()執行PL/SQL使用getXXX方法來擷取函數執行的結果及OUT/IN OUT參數樣本:Calling PL/SQL function/procedure
//PLSQL function : functionCalculateBonus(EmpNo INNumber,// EmpStatus IN OUT VARCHAR2,// Bonus OUT Number)RETURN VARCHAR2//call function usinganonymous blockStatement *stmt = conn->createStatement(“ begin :1 := CalculateBonus( :2, :3, :4); end;”);//bind position 1 is thefunction’s return valuestmt->setInt(2, 100); //IN parameterstmt->setString(3, “Active”); //IN OUT parameter//call registerOutParam for each OUT parameterstmt->registerOutParam(1, OCCISTRING, 1000);//function’sreturn valuestmt->setMaxParamSize(1, 100);//setMaxParamSize for STRING typesstmt->registerOutParam(4, OCCIFLOAT);stmt->execute();//use getXXX methods of Statement to get OUTparameters, return valuestring msg = stmt->getString(1);//function return valuestring newstatus = stmt->getString(3);//IN OUT parameterfloat bonus = stmt->getFloat(4); //OUT parameter
步驟四:錯誤處理OCCI使用C++異常機制來返回所有的錯誤資訊應用程式中應該使用try-catch結構來處理異常拋出的異常屬於SQLException類型,該類型繼承自標準C++中的exception類可以使用getErrorCode和getMessage方法來擷取Oracle的錯誤資訊
樣本:
分別處理Oracle和C++ STL錯誤
try{ ResultSet *rs = stmt->executeQuery(); while (rs->next()) ……….}catch (SQLException &oraex) //Oracle/OCCI errors{ int errno = oraex->getErrorCode();//returns the ORA number string errmsg = oraex->getMessage(); //more application error handling}catch (exception &ex) //any other C++/STL error{ cout << “Error “ << ex.what() << endl;}