c++ Oracle OCCI 编程
來源:http://blog.csdn.net/gumingyaotangwei/article/details/7337893
OCCI數據庫Oracle編程步驟
1.?配置環境
(1)?Occi訪問數據庫需要occi.h頭文件,此文件在oracle安裝目錄下,必須有oracle庫的支持。安裝oracle服務端或客戶端;
(2)?配置NLS_LANG環境變量,必須與數據庫的字符編碼一致,否則可能出現中文亂碼;
(3)?配置環境變量,使客戶端支持中文顯示;
(4)?安裝C++編程工具和g++編譯工具。
2.?編寫C++程序
(1)?Environment類創建occi環境變量;
(2)?Environment類下的createConnection方法創建連接數據庫的Connection對象;
(3)?Statement類創建對象,由數據庫連接對象調用createStatement方法創建;
(4)?Statement類創建對象調用setSQL()準備SQL語句;
(5)?Statement類創建對象調用execute()或executeUpdate()或executeQurey()或executeArrayUpdate()方法執行查詢,如果是查詢的,創建ResultSet對象接收數據集;如果是數據更新回插入:Statement:: setAutoCommit (TRUE); 設置自動提交;Statement::setAutoCommit(FALSE); 設置手動提交,手動提交:Connection::commit();Connection::rollback();
(6)?Statement類創建對象調用getxxx()方法獲取字段數據;
(7)?terminateStatement()終止Statement對象;
(8)?terminateConnection()斷開數據庫連接;
(9)?Environment::terminateEnvironment()終止環境變量。
3.?編寫makefile文件
Makefile:
includepath=${ORACLE_HOME}/rdbms/public
libpath=${ORACLE_HOME}/lib
libfile=-L ${libpath} -locci -lclntsh /usr/lib/libstdc++.so.5
incfile=-I ${includepath}
occiselect:select.cpp
??????? g++ -o occiselect select.cpp? ${libfile} ${incfile}
clean:
??????? rm occiselect
4.?編譯程序
Make occiselect.
1.??OCCI編程模式
1.1. 總體流程圖
編寫OCCI程序的總體流程圖,如下所示:
?
1.2. 執行SQL語句的流程圖
在OCCI中處理SELECT語句跟處理INSERT、UPDATE、CREATE等語句的方法是不一樣的,其中SELECT語句是有返回結果,其它語句沒有返回結果,所以必須區分SQL語句是否為查詢語句,然后按照各自的流程處理。流程圖如下所示:
注:標*號的過程為可選項
?
2.??流程圖具體說明
2.1. 創建與終止OCCI環境變量
???????????????????????創建OCCI環境變量
Environment類是OCCI程序的基礎類,所有的OCCI對象的建立都是依計Environment對象來創建的,所以Environment對象的建立必須放在第一位,而且也必須是最后一個被終止的。例如:首先創建一個Environment對象env,然后通過env創建一個Connection對象conn,conn是連接了數據庫的對象;終止時,卻反過來先終止對象conn,再終止對象env。具體Environment對象的創建方法如下所示:
?
Environment *env = Environment::createEnvironment();
?
注意:createEnvironment()方法有以下幾個參數模式:
1.?在線程環境中運行分為互斥線程(THREADEC_MUTEXED)、并行線程(THREADEC_UMMUTEXED)。
2.?使用對象(OBJECT)。
3.?利用共享數據結構(SHARED)。
???????????????????????終止OCCI環境變量
Environment對象的終止必須是放在最后一位,即等所有其它OCCI對象被終止完后再終止Environment對象。終止Environment對象的方法如下所示:
?
Environment::terminateEnvironment(env);
2.2. 連接與斷開數據庫
???????????????????????連接數據庫
創建完一個Environment對象env后,可以調用Environment類下的方法createConnection()來創建一個Connection對象conn;通過createConnection()方法我們可以連接到任意一個數據庫中。連接數據庫的具體方法如下所示:
?
Connection *conn = env->createConnection(usename,password,[connectionstring]);
?
參數說明:usename是登錄數據庫的用戶名;
????????????? ? password是登錄數據庫用戶的密碼;
????????????? ? connectstingr是數據庫的連接串(可選)。
???????????????????????斷開數據庫
當對數據庫操作完成之后,我們必須斷開程序與數據庫的連接,斷開數據庫的連接方法與創建的方法一樣來自Environment類下的terminateConnection()函數。方法如下所示:
?
env->terminateConnection(conn);
2.3. 創建與斷開連接池
???????????????????????創建連接池
對于很多共享服務器或中間層應用程序而言,數據庫的連接必須要能被許多線程所使用,如果為每個線程都開一個數據庫連接的話,當數量一大效率會明顯的降低,所以我們通過創建連接池來處理這樣的情況。創建完一個Environment對象env后,可以調用Environment類下的方法createConnectionPool()來創建一個Connection對象connPool;通過createConnectionPool()方法我們可以連接到任意一個數據庫中。連接池創建的具體方法如下所示:
?
ConnectionPool ?*connPool= env->createConnectionPool(
const? string?&poolUseName,
const? string?&poolPassWord,
const? string?&connectstring,
unsigned? int?? minConn,
unsigned? int?? maxConn,
unsigned? int?? incrConn);
?
參數說明:poolUseName是連接池的用戶名;
????????????? ? poolPassWord是連接數據庫的密碼;
????????????? ? connectstring是數據庫連接串;
????????????? ? minConn是最小連接數;
????????????? ? maxConn是最大連接數;
incrConn是指所有已連接數處于繁忙中且小于最大連接數時,每次增加的連接數。
???????????????????????斷開連接池
當對數據庫操作完成之后,我們必須斷開程序與數據庫的連接,斷開數據庫的連接方法與創建的方法一樣來自Environment類下的terminateConnectPool()函數。方法如下所示:
?
env->terminateConnectPool(connPoll);
2.4. 創建與終止Statement對象
2.4.1.??? 創建Statement對象
Statement類包含了執行SQL語句的所有方法,是對數據庫操作的具體實現。Statement對象stmt的創建是通過調用Connection類下的createStatement()函數實現,所以Statement對象的創建必須是在Connection對象創建之后。createStatement()函數可以帶參數或不帶參數,如果帶參數的話,參數必須是一個SQL語句;如果沒有帶參數,則在后面必須用Statement類下setSQL()函數為Statement對象賦一個SQL語句。Statement對象的創建方法如下所示:
?
Statement?*stmt = conn->createStatement();
???????????????????????終止Statement對象
當對數據庫的操作完成時,我們必須先終止Statement對象,再斷開Connection對象。終止Statement對象的方法如下所示:
?
Conn->terminateStatement(stmt);
3.??執行SQL語句(Statement類)
3.1. 執行SQL語句的方法
執行SQL的所有方法都包含在Statement類下。SQL語句按返回結果分,可以分為兩種:一種是有返回值的(查詢語句),另外一種是沒有返回值的(非查詢語句)。一般情況下,在執行查詢SQL語句我們使用executeQurey()函數,在執行非查詢SQL語句時我們使用executeUpdate()函數。
?
1.?stmt->execute();執行所有非特殊聲明的SQL語句。
2.?stmt->executeUpdate();執行所有DDL和DML(一條記錄)的SQL語句。
3.?stmt->executeQurey();執行所有查詢SQL語句。
4.?stmt->executeArrayUpdate();執行多記錄的DML的SQL語句。
例如:
?????? stmt->executeUpdate(“createtable student (sno number(10),sname varchar2)”);
?????? stmt->executeUpdate(“insertinto student (sno,sname)? values(1,’ZHANGSAN’)”);
?????? stmt->executeQurey(“select? sno?from student ”);
3.2. 執行非查詢語句
當我們創建了一個Statement對象stmt后,可以通過Statement類下的方法setSQL()為stmt設置不同的SQL語句。
?
3.2.1.???準備SQL語句
stmt->setSQL(string &sql);
例如:
stmt->setSQL(“insertinto student (sno,sname)? values(:1,:2)”)
其中::1、:2是參數,通過給參數賦不同的值來實現。
?
與之對應的函數getSQL()是取出當前對象對應的SQL語句。
?
3.2.2.???綁定輸入參數值
在Statement類中包含了所有參數的賦值方法,賦值方法set×××(unsignedint paramindex,type values),其中paramindex參數是代表所賦值參數在SQL語句中的第幾個參數,×××與type代表中所賦值的類型,values是所賦的值?!痢痢量梢允荌nt、String、Date等等。
例如:
stmt->setString(1,’zhangsan’);指把’zhangsan’賦值給第一個參數,參數類型為字符串型。
stmt->setInt(2,1009);指把1009賦值給第二個參數,參數類型為整型。
?
3.2.3.???執行非查詢語句
當SQL語句準備好后,就可以執行SQL語句了,方法如下所示:
?
stmt->executeUpdate();
?
3.3. 執行查詢語句(SELECT)
在執行查詢語句時有返回查詢結果(可能是一條,也可能是多條),我們必須創建一個ResultSet對象來處理,通過使用ResultSet對象的next()方法我們可以一條一條(或批量)地處理結果集。具體使用如下所示:
?
?
3.3.1.???準備SQL語句
詳見3.2.1。
?
3.3.2.???綁定輸入參數值
詳見3.2.2。
?
3.3.3.???執行查詢語句
?
ResultSet?*rs = stmt->executeQuery();
3.3.4.???定義輸出變量
?????? 根據SELECT語句查詢的列的類型定義對應的變量,此變量用于存儲SELECT查詢的結果集。
3.3.5.???推進或處理數據
如果結果集為多條記錄,我們可以批量或者一條條處理數據,使用ResultSet類下的方法next(unsigned int numRows)。
在Statement類中包含了所有參數的取值方法。取值方法get×××(unsignedint paramindex),其中paramindex參數是代表所取值列在SQL語句中的第幾列,×××代表該列對應的類型。×××可以是Int、String、Date等等。
例如:
rs->next(unsignedint numRows);//其中numRows為批量處理的記錄行數。
?
stmt->getInt(paramindex);獲取整型參數值,其中paramindex為參數所在的位置;
stmt->getString(paramindex);獲取字符型參數值其中paramindex為參數所在的位置;
3.4. 輸出參數聲明
在調用存儲過程時,有時候有返回參數,這些返回參數都必須在調用之前先用Statement類下的registerOutParam()方法聲明,聲明方法的使用如下所示:
stmt->registerOutParam(paramName,paramType,paramSize);
其中:paramName是參數名或者參數所在位置;
?????? ? paramType是參數類型(比如:TYPE::OCCIINT);
?????? ? paramSize是參數的大小。
?
3.5. 事務提交
3.5.1.???手動提交
當事務的提交設置為手動時,每完成一個事務我們都必須調用Connection類下的commit()或rollback()方法來提交一個事務。使用方法如下所示:
?
手動提交必須調用以下函數:
Connection::commit();
Connection::rollback();
3.5.2.???自動提交
在對數據庫進行操作的過程中,一個事務的提交是用手動還是自動,我們可以調用Statement類下的setAutoCommit()方法來設置。使用方法如下所示:
?
設置自動提交:
Statement:: setAutoCommit (TRUE);
設置手動提交:
Statement::setAutoCommit(FALSE);
?
4.??OCCI常用類簡要介紹
4.1. Environment類
Environment類提供了管理OCCI對象的內存及其它資源的一個環境,包含以下方法:
1.?createConnection(const stringusename,const string password,const string connstring);指與數據庫建立一個連接。
2.?createConnectionPoll(
const? string?&poolUseName,
const? string?&poolPassWord,
const? string?&connectstring,
unsigned? int? ?minConn,
unsigned? int??maxConn,
unsigned? int??incrConn);? 創建連接池。
參數說明:poolUseName是連接池的用戶名;
????????????? ? ??? ??poolPassWord是連接數據庫的密碼;
????????????? ????? connectstring是數據庫連接串;
????????????? ????? minConn是最小連接數;
????????????? ????? maxConn是最大連接數;
incrConn是指所有已連接數處于繁忙中且小于最大連接數時,每次增加的連接數。
3.?createEnironment(Mode? mode );創建一個環境對象,其中mode是模式(可選DEFAULT、THREADED_MUTEXED、THREADED_UN-MUTEXED、OBJECT、SHARED值)。
4.?getCurrentHeapSize();指在同一環境下已經分配的內存數。
5.?getOCIEnironment();返回一個OCI環境指針。
6.?terminateConnection(Connection*conn);斷開與數據庫的連接。
7.?terminateConnection(ConnectionPool*poolconn);斷開與數據庫的連接池。
8.?terminateEnironment(Einironment? *env);終止OCCI環境變量。
4.2. Connection類
Connection類提供了C++程序與指定數據庫的連接,包含以下方法:
1.?changePassword(const string&user,const string &oldPassword,const string &newPassword);改變當前用戶的密碼。
2.?Commit();提交事務。
3.?createStatement(const string&sql=””);創建一個Statement對象。
4.?flushCache();
5.?rollback();事務的回滾。
6.?terminateStatement(Statement*stmt).終止一個Statement對象,并釋放它占有的所有資源。
4.3. ConnectionPool類
ConnectionPoll類提供了C++程序與指定數據庫間的連接池,包含以下方法:
1.?createConnection(const string&username,const string &password);創建一個連接。
2.?getBusyConnections();返回連接池中被占用的連接數量。
3.?getMaxConnections();返回連接池的最大連接數。
4.?getMinConnections();返回連接池的最小連接數。
5.?getOpenConnections();返回連接池中已經被打開的連接數。
6.?getPollName();返回連接池的名稱。
7.?getTimeOut();返回連接池的超時時間。
8.?setErrorOnBusy();設置異常,當連接池處于繁忙或達到最大連接數后。
9.?serPoolSize(unsigned intminConn,unsigned int maxConn,unsigned int incrConn);設置連接池的大小,其中參數minConn是最小連接數,maxConn是最大連接數,incrConn是遞增連接數。
10.?????????????setTimeOut();設置超時時間。
11.?????????????terminateConnection(Connection? *conn);斷開連接。
4.4. Statement類
Statement對象主要被用來執行SQL語句,它可以運行一個查詢語句返回一個結果集也可以運行UPDATE、DELETE等SQL語句。
1.?addIteration();增加一個循環。
2.?closeResultSet(ResultSet *rs);關閉一個結果集。
3.?closeStream(Stream? *stream);關閉一個已定義的流。
4.?execute(const string &sql =“”);執行一個SQL語句,如果前面使用的setSQL()方法,則參數sql可以為空。
5.?executeArrayUpdate(unsigned intarrayLength);同時修改多條記錄,前面必須使用了setDataBuffer()方法設置一個數量或設置了一個流(stream)。
6.?executeQuery();執行一個查詢語句。
7.?executeUpdate();執行DDL、DML語句,如:INSERT、UPDATE、DELETE、CREATE等等。
8.?getAutoCommit();返回是否事務自動提交。
9.?getDate(unsigned int paramindex);返回DATE型數據。
10.?????????????getDouble(unsigned intparamindex);返回DOUBLE型數據。
11.?????????????getFloat(unsigned int paramindex);返回FLOAT型數據。
12.?????????????getInt(unsigned intparamindex);返回INT型數據。
13.?????????????getNumber(unsigned intparamindex);返回NUMBER型數據。
14.?????????????getRef(unsigned intparamindex);返回REF參數值。
15.?????????????getResultSet();得到一個結果集(ResultSet)。
16.?????????????getSQL();返回當前的SQL語句。
17.?????????????getString(unsigned intparamindex);返回STRING型數據。
18.?????????????getUpdateCount();返回被更新的數量。
19.?????????????isNull(unsigned intparamindex);判斷第X個值是否為空。
20.?????????????isTruncated(unsigned intparamindex);判斷第X個值是否被截取。
21.?????????????setAutoCommit(bool autocommit);設置事務是否自動提交。
22.?????????????setDouble(unsigned intparamindex,double x);賦一個double型的值。
23.?????????????setFloat(unsigned intparamindex,float x);賦一個float型的值。
24.?????????????setInt(unsigned intparamindex,int x);賦一個INT型的值。
25.?????????????setNull(unsigned intparamindex,TYPE type);某參數設置為空。
26.?????????????setNumber(unsigned intparamindex,const number &x);賦一個Number型的值。
27.?????????????setObject(unsigned intparamindex,PObject *x);賦一個PObject型的值。
28.?????????????setString(unsigned intparamindex,const string &x);賦一個string型的值。
29.?????????????setSQL(const string &sql);設置一個SQL語句。
30.?????????????Status();返回當前的狀態。
4.5. ResultSet類
ResultSet類是查詢數據表的結果集,它包含以下方法:
1.?cancel();取消結果集。
2.?closeStream(Stream? *stream);關閉一個流。
3.?getDouble(unsigned intcolIndex);返回double型的值。
4.?getFloat(unsigned intcolIndex);返回float型的值。
5.?getInt(unsigned int colIndex);返回int型的值。
6.?getMaxColumnSize(unsigned intcolIndex);返回某列包含的數據量。
7.?getNumber(unsigned intcolIndex);返回number型的數據。
8.?getPObject(unsigned intcolIndex);返回PObject型的數據。
9.?getRowid(unsigned intcolIndex);返回rowid值。
10.?????????????getString(unsigned intcolIndex);返回string型的數據。
11.?????????????isNull(unsigned int colIndex);判斷值是否為空。
12.?????????????isTruncated(unsigned intcolIndex);判斷值是否被刪。
13.?????????????next(unsigned int numRows);取下numRows條記錄。
14.?????????????status();返回當前狀態。
4.6. PObject類
PObject類包含以下方法:
1.?fush();
2.?Connection *getConnection();從一個實例化的永久對象中返回連接。
3.?isLocked();判斷永久對象是否被鎖(TRUE或FALSE)。
4.?isNull();判斷永久對象是否為空(TRUE或FALSE)。
5.?Lock(PObject::LockOption? lock_option);在數據庫中鎖住一個對象,其中lock_option取值為OCCI_LOCK_WAIT、OCCI_LOCK_NOWAIT。
6.?markDelete();刪除數據庫中的永久對象。
7.?markModified();修改永久對象。
8.?PObject &operator(constPObject &obj);賦值(對象)。
9.?operator delete(void*obj,size_t size);刪除對象,但不能刪除數據庫中的對象。
10.?????????????*operator new(size_t size);創建臨時對象。
11.?????????????*operator new(size_t size,constConnection *x,const string &tablename,const char *type_name);創建永久對象。
12.?????????????pin();
13.?????????????setNull();設置對象為空。
14.?????????????unmark();不標記永久對象為刪除或修改。
15.?????????????unpin(UnpinOption mode);其中,mode的取值為OCCI_PINCOUNT_RESET、OCCI_PINCOUNT_DECR。
4.7. SQLException類
SQLException類提供錯誤代碼及其錯誤信息,包含以下方法:
1.?getErrorCode();返回數據庫中的錯誤編碼。
2.?getMessage();返回錯誤信息,沒有則為空。
4.8. Date類
Date類包含以下方法:
1、?addDays(int i);返回增加i天后的日期。
2、?addMonths(int i);返回增加i個月后的日期。
3、?intervalDS daysBetween(constDate &d);返回與d相差的天數。
4、?getDate(int &year,unsignedint &month,unsigned int &day,unsigned int &hour,unsigned int&minute,unsigned int &second );返回分年月日小時分秒格式。
5、?getSystemDate(const Environment*env);返回系統日期。
6、?isNull();判斷是否為空;
7、?lastDay();返回當月的最后一天日期。
8、?setDate(int&year=1,unsigned int &month=1,unsigned int &day=1,unsigned int&hour=0,unsigned int &minute=0,unsigned int &second=0);設置日期值。
9、?setNull();設置為空。
4.9. Number類
Number類包含以下常用方法:
1、?abs();返回絕對值。
2、?floor();向下取整。
3、?isNull();判斷是否為空。
4、?operator+(const Number&a,const Number &b);兩數相加。
5、?operator-( const Number&a,const Number &b);兩數相減(a-b)。
6、?operator*(const Number&a,const Number &b);兩數相乘。
7、?operator/(const Number&a,const Number &b);兩數相除。
8、?operator%(const Number&a,const Number &b);求余。
9、?operator<(const Number&a,const Number &b);a是否小于b。
10、?????????????operator<=(const Number&a,const Number &b);a是否小于等于b。
11、?????????????operator>(const Number&a,const Number &b);a是否大于b。
12、?????????????operator>=(const Number&a,const Number &b);a是否大于等于b。
13、?????????????operator==(const Number&a,const Number &b);a與b是否相等。
14、?????????????operator!=(const Number&a,const Number &b);判斷a是否不等于b。
15、?????????????operator char();將number型轉化為char型。
16、?????????????operator signed char();將number型轉化為有符號char型。
17、?????????????operator double();將number型轉化為double型。
18、?????????????operator float();將number型轉化為float型。
19、?????????????operator int();將number型轉化為int型。
20、?????????????operator long();將number型轉化為long型。
21、?????????????operator short();將number型轉化為short int型。
22、?????????????setNull();設置為空。
23、?????????????trunk();取整。
5.??附錄:代碼示例
5.1. 查詢流程處理示例
下面給出了一個查詢的例子qrystudent.cpp,通過使用OCCI接口函數查詢數據庫表student的信息(學號,學生姓名)。
?
#include <iostream>
#include <occi.h>
?
using namespace oracle::occi;
using namespace std;
?
int main ()
{
Environment *env;
Connection *conn;
Statement *stmt;
ResultSet *rs;
?
string username = “ipd”;
string password = “ipd”;
string connstring = “ora9i”;
string sql,strname;
int isno;
?
env = Environment::createEnvironment(); //創建一個環境變量
conn = env->createConnection(username,password,connstring);//創建一個數據庫連接對象
stmt = conn->createStatement(); //創建一個Statement對象
?
sql = “ SELECT sno,sname FROM student “;? //拼接一個SQL語句
stmt->setSQL(sql); //設置SQL語句到Statement對象中
try {
?????? rs=? stmt->executeQuery();//執行SQL語句
?????? while(rs->next()) { //用循環,一條一條地取得查詢的結果記錄
????????????? isno= rs->getInt(1);//取出第一列的值(對應為int型)
????????????? strname=rs->getString(2);//取出第二列的值(對應為string型)
????????????? cout<< isno << “? AND? “ << strname << endl;
?????? }
?????? cout<< “SELECT ―― SUCCESS”<< endl;
} catch (SQLException ex) {
?????? cout<< “ Error Number : “<< ex.getErrorCode() << endl; //取出異常代碼
?????? cout<< ex.getMessage() << endl; //取出異常信息
}
?
conn->terminateStatement(stmt); //終止Statement對象
env->terminateConnection(conn); //斷開數據庫連接
Environment::terminateEnvironment(env); //終止環境變量
?
return 1;
}
5.2. 非查詢流程處理示例
下面給出了一個insert例子inserttab.cpp,通過使用OCCI接口函數往數據庫表student中插入信息(學號,學生姓名)。
?
#include <iostream>
#include <occi.h>
?
using namespace oracle::occi;
using namespace std;
?
int main ()
{
Environment *env;
Connection *conn;
Statement *stmt;
?
string username = “ipd”;
string password = “ipd”;
string connstring = “ora9i”;
string sql;
?
env = Environment::createEnvironment(); //創建一個環境變量
conn =env->createConnection(username,password,connstring); //創建一個數據庫連接對象
stmt = conn->createStatement(); //創建一個Statement對象
?
sql = “ INSERT INTO student(sno,sname)? VALUES ( :x,:y) “; //拼接SQL語句
stmt->setSQL(sql); //設置SQL語句到Statement對象中
try {
?????? stmt->setInt(1,10001);//給第一個參數x賦值
?????? stmt->setString(2,”zhangsan”);//給第二個參數y賦值
?????? stmt->executeUpdate();//執行SQL語句
?????? cout<< “INSERT ―― SUCCESS”<< endl;
} catch (SQLException ex) {
?????? cout<< “ Error Number : “<< ex.getErrorCode() << endl; //獲得異常代碼
?????? cout<< ex.getMessage() << endl; //獲得異常信息
}
?
conn->terminateStatement(stmt); //終止Statement對象
env->terminateConnection(conn); //斷開數據庫連接
Environment::terminateEnvironment(env); //終止環境變量
?
return 1;
}
5.3. 批量處理非查詢語句
在批量處理非查詢語句時,首先必須使用m_stmt->setMaxIterations(unsigned int maxnum)方法設置最大的批處理數;然后使用setMaxParamSize(unsignedint paramindex,int paramsize)方法設置對應參數的大小,對于有固定長度的參數可以不必重新設置,如int,double;最后循環綁定參數使用set×××()方法,每循環一次必須使用addIteration()方法再進行下一次循環,直到最后一次。例子如下所示:
#include <iostream>
#include <occi.h>
?
using namespace oracle::occi;
using namespace std;
?
int main ()
{
???Environment *env;
???Connection *conn;
???Statement *stmt;
???
???string username = "bill";
???string password = "bill";
???string connstring = "jftest";
???string sql;
?
intisno[2]={21,22},i,iage[2]={18,19};
stringcsname[2]={"namea","nameb"};
?
???try {
???????env = Environment::createEnvironment();
???????conn = env->createConnection(username,password,connstring);
???????stmt = conn->createStatement();
???????stmt->setAutoCommit(false);
???????
???????sql = " INSERT INTO student (sno,sname,age)? VALUES (:x,:y,:z) ";
???????
???????m_stmt->setSQL(sql);
???????m_stmt->setMaxIterations(2);
???????m_stmt->setMaxParamSize(1,sizeof(int));
???????m_stmt->setMaxParamSize(2,sizeof(string));
???????m_stmt->setMaxParamSize(3,sizeof(int));
???????cout<<"setMaxIterations success !"<<endl;
???????//cout<<"getMaxIterations = "<<m_stmt->getMaxIterations()<<endl;
???????for (i=0;i<2;i++)
???????{
???????????m_stmt->setInt(1,isno[i]);
???????????m_stmt->setString(2,csname[i]);
???????????m_stmt->setInt(3,iage[i]);
???????????
????????????//cout <<isno[i]<< " and " <<csname[i]<< " and " << iage[i] <<endl;
????
???????????if (i!=1) m_stmt->addIteration();
???????}
???????
???????cout<<"getMaxIterations ="<<m_stmt->getMaxIterations()<<endl;
??????
??? ?????? cout<<"setsuccess"<<endl;
??? ?????? inum = m_stmt->executeUpdate();
??? ?????? m_conn->commit();
??? ?????? cout << "INSERT ¨D¨DSUCCESS" << endl;
??? }catch (SQLException ex) {
??? ?????? inum = m_stmt->getUpdateCount();
??? ?????? cout << "ON" <<inum+1 << " shi fail !" << endl;
??? ?????? cout << " INSERT Error Number: "<< ex.getErrorCode() << endl;
??? ?????? cout << ex.getMessage() <<endl;
??? ?????? m_conn->rollback();
??? ?????? return 0;
??? }
???
???conn->terminateStatement(stmt);
???env->terminateConnection(conn);
???Environment::terminateEnvironment(env);
???
???cout << "PROGRAM IS END ." << endl;
???return 1;
}
5.4. 查詢語句中批量取數
在批量取數時,使用setDataBuffer()方法來設置接收數據緩沖區大小,例子如下所示:
#include <iostream>
#include <occi.h>
?
using namespace oracle::occi;
using namespace std;
?
int main ()
{
???Environment *env;
???Connection *conn;
???Statement *stmt;
???ResultSet *rs;
???
???string username = "bill";
???string password = "bill";
???string connstring = "jftest";
???string sql;
???int i,numrows=5,isnum,ilnum,ipos=0;
???int isno[5],vsno[20],ii=0,x[20];
???ub2 isnolen[5],snamelen[5];
???char sname[5][20],vsname[20][20];
???
??? for (i=0;i<20;i++)
??? {
???????isnolen[i]=sizeof(isno[i]);
snamelen[i]=strlen(sname[i]+1);
??? }
???
???cout << "PROGRAM START ..." << endl;
???
???try {
???????env = Environment::createEnvironment();
???????conn = env->createConnection(username,password,connstring);
???????stmt = conn->createStatement();
???????
???????sql = " SELECT sno,sname FROM student ";?
???????stmt->setSQL(sql);
???
??? ?????? rs =?stmt->executeQuery();
??? ??????
??? ?????? rs->setDataBuffer(1,isno,OCCIINT,sizeof(int));
??? ?????? rs->setDataBuffer(2,sname,OCCI_SQLT_STR,sizeof(sname[0]),snamelen);
??? ?????? ilnum = rs->getNumArrayRows();
??? ?????? cout << " ilnum = "<< ilnum <<endl;
??? ??????
??? ?????? while (rs->next(numrows)) {
??? ????????????? isnum = rs->getNumArrayRows();
??? ?????? ????cout << " isnum = "<< isnum <<endl;
??? ?????????????
??? ????????????? for(i=0;i<numrows;i++)
????????????? {
????????????? ????vsno[ipos] = isno[i];
????????????? ????vsname[ipos] = sname[i];
????????????? ????ipos = ipos+1;
????????????? }
??? ?????? }
???????ilnum = rs->getNumArrayRows();
??? ?????? cout << " ilnum = "<< ilnum <<endl;
??? ?????? for(i=0;i<ilnum-isnum;i++)
???????{
???????????vsno[ipos] = isno[i];
???????????vsname[ipos] = sname[i];
???????????ipos = ipos+1;
???????}
???????
???????cout << "SELECT RESULT IS ..." << endl;
???????for(i=0;i<ilnum;i++)
???????{
???????????cout<<vsno[i]<<" AND"<<vsname[i]<<endl;
???????}
???????cout << "SELECT RESULT END !" << endl;
??? ??????
??? ?????? cout << "SELECT ¨D¨DSUCCESS" << endl;
??? }catch (SQLException ex) {
??? ?????? cout << " Error Number :"<< ex.getErrorCode() << endl;
??? ?????? cout << ex.getMessage() <<endl;
??? }
???
???conn->terminateStatement(stmt);
???env->terminateConnection(conn);
???Environment::terminateEnvironment(env);
???
???cout << "PROGRAM END !" << endl;
???return 1;
}
5.5. MERGE語句的使用
在使用MEGER語句時,USING部分的取值應該使用表或者SELECT param1,param2FROM DUAL,其中param1,param2是常量值,可以通過數組賦值,并且每列值都應該取別名,在后面的使用中就只用別名。例子如下所示:
#include <iostream>
#include <occi.h>
?
using namespace oracle::occi;
using namespace std;
?
int main ()
{
???Environment *env;
???Connection *conn;
???Statement *stmt;
???
???string username = "bill";
???string password = "bill";
???string connstring = "jftest";
???string sql;
?
???int isno[2]={21,22},i,iage[2]={18,19};
?
???try {
???????env = Environment::createEnvironment();
???????conn = env->createConnection(username,password,connstring);
???????stmt = conn->createStatement();
???????stmt->setAutoCommit(false);
???????
???????sql = " merge into student a?";
???????sql += "??? using (select :xbid,:y bage from dual) b ";
???????sql += "??? on (a.sno =b.bid) ";
???????sql += "??? when matched then";
???????sql += "??? update set a.age=a.age+b.bage ";
???????sql += "??? when not matchedthen ";
???????sql += "??? insert(a.sno,a.age) ";
???????sql += "??? values(b.bid,b.bage) ";
???????
???????stmt->setSQL(sql);
???????stmt->setMaxIterations(2);
???????stmt->setMaxParamSize(1,sizeof(int));
???????//stmt->setMaxParamSize(2,sizeof(string));
???????cout<<"setMaxIterations success !"<<endl;
???????//cout<<"getMaxIterations = "<<stmt->getMaxIterations()<<endl;
???????for (i=0;i<2;i++)
???????{
???????????stmt->setInt(1,isno[i]);
???????????stmt->setInt(2,iage[i]);
????
???????????if (i!=1) stmt->addIteration();
???????}
???????
???????cout<<"getMaxParamSize = "<<stmt->getMaxParamSize(2)<<endl;??
???????cout<<"getMaxIterations ="<<stmt->getMaxIterations()<<endl;
?
??? ?????? cout<<"setsuccess"<<endl;
??? ?????? stmt->executeUpdate(); //?′DDSQLó???
??? ?????? conn->commit();
??? ?????? cout << "INSERT ¨D¨DSUCCESS" << endl;
??? }catch (SQLException ex) {
??? ?????? cout << " Error Number :"<< ex.getErrorCode() << endl;
??? ?????? cout << ex.getMessage() <<endl;
??? ?????? conn->rollback();
??? }
???
???conn->terminateStatement(stmt);
???env->terminateConnection(conn);
???Environment::terminateEnvironment(env);
???
???cout << "PROGRAM IS END ." << endl;
???return 1;
}
總結
以上是生活随笔為你收集整理的c++ Oracle OCCI 编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言常用输出格式
- 下一篇: postgresql 安装使用