方式1,使用OCCI:
直接上代码
class="cpp">#include <iostream> #include <string> #include <vector> #include <occi.h> using namespace oracle::occi; using std::vector; using namespace std; class conndba { private: Environment *env; Connection *conn; Statement *stmt; public: conndba(string user, string password, string db) { env = Environment::createEnvironment(Environment::DEFAULT); conn = env->createConnection(user, password, db); } ~conndba() { env->terminateConnection(conn); Environment::terminateEnvironment(env); } void insertBind(string s1, string s2, string s3, string s4) { string sqlStmt = "INSERT INTO t_user(userid, username, loginname, createdate) VALUES (:1, :2, :3, :4)"; stmt=conn->createStatement (sqlStmt); try { stmt->setString(1, s1); stmt->setString(2, s2); stmt->setString(3, s3); stmt->setString(4, s4); stmt->executeUpdate(); cout << "insert - Success" << endl; } catch (SQLException ex) { cout << "Exception thrown for insertBind" << endl; cout << "Error number: " << ex.getErrorCode() << endl; cout << ex.getMessage() << endl; } conn->terminateStatement(stmt); } void updateRow(string s1, string s2) { string sqlStmt = "UPDATE t_user SET userid = :x WHERE username = :y"; stmt = conn->createStatement(sqlStmt); try { stmt->setString(1, s2); stmt->setString(2, s1); stmt->executeUpdate(); cout << "update - Success" << endl; } catch (SQLException ex) { cout << "Exception thrown for updateRow" << endl; cout << "Error number: " << ex.getErrorCode() << endl; cout << ex.getMessage() << endl; } conn->terminateStatement(stmt); } void deleteRow(string s1) { string sqlStmt = "DELETE FROM t_user WHERE userid = :x"; stmt = conn->createStatement(sqlStmt); try { stmt->setString(1, s1); stmt->executeUpdate(); cout << "delete - Success" << endl; } catch (SQLException ex) { cout << "Exception thrown for deleteRow" << endl; cout << "Error number: " << ex.getErrorCode() << endl; cout << ex.getMessage() << endl; } conn->terminateStatement(stmt); } void displayAllRows() { string sql = "select userid, username, loginname, createdate from t_user"; stmt = conn->createStatement(sql); ResultSet *rs = stmt->executeQuery(); try { while (rs->next()) { cout << "userid: " << rs->getInt(1) << "\t" cout << "username: " << rs->getString(2) << "\t" cout << "loginname: " << rs->getString(3) << "\t" cout << "createdate: " << rs->getString(4) << endl; } } catch (SQLException ex) { cout << "Exception thrown for displayAllRows" << endl; cout << "Error number: " << ex.getErrorCode() << endl; cout << ex.getMessage() << endl; } stmt->closeResultSet(rs); conn->terminateStatement(stmt); } void displayAllRowsDesc() { string sql = "select userid, username, loginname, createdate from t_user order by userid desc"; stmt = conn->createStatement(sql); ResultSet *rs = stmt->executeQuery(); try { while (rs->next()) { cout << "userid: " << rs->getInt(1) << "\t" cout << "username: " << rs->getString(2) << "\t" cout << "loginname: " << rs->getString(3) << "\t" cout << "createdate: " << rs->getString(4) << endl; } } catch (SQLException ex) { cout << "Exception thrown for displayAllRows" << endl; cout << "Error number: " << ex.getErrorCode() << endl; cout << ex.getMessage() << endl; } stmt->closeResultSet(rs); conn->terminateStatement(stmt); } }; int main(int argc, char *argv[]) { string user = "UOP_ACT4"; string password = "123456"; string db = "hyacttst"; conndba *demo = new conndba(user, password, db); cout << "数据库中的记录:" << endl; demo->displayAllRowsDesc(); cout << "删除指定id的用户信息!" << endl; cout << "请输入需要删除的用户id:" << argv[1] << endl; demo->deleteRow(argv[1]); cout << "删除指定id的用户信息后!" << endl; demo->displayAllRows(); cout << "调用析构函数进行处理!"; delete (demo); }
?
?
?
方式2:使用OCI,我们项目中正在使用的方式,看起来及其复杂。
?
#include <oci.h> #include <iostream> #include <string> #include <string.h> #include <stdlib.h> using namespace std; //存放查询数据的结构体 struct result { char ename[20]; char cname[20]; result() { memset(ename, '\0', sizeof(ename)); memset(cname, '\0', sizeof(cname)); } }; int main() { // 初始化 OCI 环境句柄指针 OCIEnv *envhpp = NULL; // 初始化服务器句柄 OCIServer *servhpp = NULL; // 用于捕获 OCI 错误信息 OCIError *errhpp = NULL; // 初始化会话句柄 OCISession *usrhpp = NULL; // 初始化服务上下文句柄 OCISvcCtx *svchpp = NULL; // 初始化表达式句柄 OCIStmt *stmthpp = NULL; string server = "mydb"; // 创建 OCI 环境 , 并设置环境句柄。 sword swResult = OCIEnvCreate(&envhpp, OCI_DEFAULT, NULL, NULL, NULL, NULL, 0, NULL); if (swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO) { cout 《 "Oracle environment initialization error!" 《 endl; exit(1); } cout 《 "Oracle environment initialization success!" 《 endl; // 创建错误句柄 OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0); // 创建服务句柄 OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&servhpp, OCI_HTYPE_SERVER, (size_t)0, (dvoid **)0); // 连接服务器,如果失败则获取错误码 if (OCIServerAttach(servhpp, errhpp, (text *)server.c_str(), strlen(server.c_str()), 0) != OCI_SUCCESS) { int errcno; char errbuf[512] = ""; sb4 errcode; // 获取错误指针和 OCI 错误代码 OCIErrorGet((dvoid *)errhpp, (ub4)1, (text *)NULL, &errcode, (ub1 *)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); errcno = errcode; cout 《 "Oracle server attach error:" 《 errbuf 《 endl; OCIHandleFree((dvoid *)envhpp,OCI_HTYPE_ENV); OCIHandleFree((dvoid *)servhpp,OCI_HTYPE_SERVER); OCIHandleFree((dvoid *)errhpp,OCI_HTYPE_ERROR); exit(1); } cout 《 "Oracle server attach success!"《 endl; /***************** 连接数据库 ****************/ string user = "user"; string pas = "passwd"; errhpp = NULL; // 创建错误句柄 (void) OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0); // 创建服务上下文句柄 (void) OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&svchpp, OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **)0); // 设置属性 (void) OCIAttrSet((dvoid *)svchpp, OCI_HTYPE_SVCCTX, (dvoid *)servhpp, (ub4)0, OCI_ATTR_SERVER, (OCIError *)errhpp); // 创建用户连接句柄 (void) OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&usrhpp, (ub4)OCI_HTYPE_SESSION, (size_t) 0, (dvoid **)0); // 设置用户名、密码 (void) OCIAttrSet((dvoid *)usrhpp, (ub4)OCI_HTYPE_SESSION, (dvoid *)user.c_str(), (ub4)strlen(user.c_str()), (ub4)OCI_ATTR_USERNAME, errhpp); (void) OCIAttrSet((dvoid *)usrhpp, (ub4)OCI_HTYPE_SESSION, (dvoid *)pas.c_str(), (ub4)strlen(pas.c_str()), (ub4)OCI_ATTR_PASSWORD, errhpp); // 创建会话连接 if(OCISessionBegin(svchpp, errhpp, usrhpp, OCI_CRED_RDBMS, (ub4)OCI_DEFAULT) != OCI_SUCCESS) { int errcno; char errbuf[512]= { '\0'}; sb4 errcode; // 获取错误指针和 OCI 错误代码 OCIErrorGet((dvoid *)errhpp, (ub4)1, (text *)NULL, &errcode, (ub1 *)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); errcno = errcode; cout 《 "User session error:" 《 errbuf 《 endl; OCIHandleFree((dvoid *)errhpp,OCI_HTYPE_ERROR); OCIHandleFree((dvoid *)usrhpp,OCI_HTYPE_SESSION); OCIHandleFree((dvoid *)svchpp,OCI_HTYPE_SVCCTX); exit(1); } cout 《 "user session success!" 《 endl; (void) OCIAttrSet((dvoid *)svchpp, (ub4) OCI_HTYPE_SVCCTX, (dvoid *)usrhpp, (ub4)0, (ub4)OCI_ATTR_SESSION, errhpp); /***********************以上代码已经成建立了一条数据库连接************************/ /*************** 以下代码是对数据库的各种操作 *** 执行 查询SQL 语句 ******************/ errhpp = NULL; // 创建一个表达式句柄 if (OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&stmthpp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0) != OCI_SUCCESS) { cout 《 "Create STMT error !" 《 endl; exit(1); } cout 《 "Create stmt success !" 《 endl; // 创建错误句柄 OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0); // Select语句 char sql[255] = "select col1, col2 from table1 "; if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql, (ub4)strlen(sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) != OCI_SUCCESS) { cout 《 "Create prepare error!" 《 sql 《 endl; exit(1); } cout 《 "Create prepare success!" 《 endl; /********* 绑定参数 ***********/ // 申请绑定字段的句柄 OCIDefine *bhp1 = NULL; OCIDefine *bhp2 = NULL; // 存放数据的结构 struct result rst; // 指定提取数据长度 ub2 datalen = 0; // 定义指示器变量 , 用于取可能存在空值的字段 char isnul[6] = ""; // 定义输出变量 , OCIDefineByPos(stmthpp, &bhp1, errhpp, 1, (dvoid *)&rst.ename, sizeof(rst.ename), SQLT_CHR, NULL, &datalen, NULL, OCI_DEFAULT); OCIDefineByPos(stmthpp, &bhp2, errhpp, 2, (dvoid *)&rst.cname, sizeof(rst.cname), SQLT_STR, NULL, &datalen, NULL, OCI_DEFAULT); // 获取 SQL 语句类型 ub2 stmt_type; OCIAttrGet ((dvoid *)stmthpp, (ub4)OCI_HTYPE_STMT, (dvoid *)&stmt_type, (ub4 *)0, (ub4)OCI_ATTR_STMT_TYPE, errhpp); // 执行 SQL 语句 OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_DEFAULT); // 获取查询信息 int rows_fetched; do { cerr 《 rst.ename《 " "; cerr 《 rst.cname《 " \n"; } while(OCIStmtFetch2(stmthpp, errhpp, 1, OCI_FETCH_NEXT, 1, OCI_DEFAULT) != OCI_NO_DATA); // 获得记录条数 OCIAttrGet((CONST void *)stmthpp, OCI_HTYPE_STMT, (void *)&rows_fetched, (ub4 *)sizeof(rows_fetched), OCI_ATTR_ROW_COUNT, errhpp); cout 《 " rows :" 《 rows_fetched 《 endl; /*************** 执行 新增SQL 语句 ******************/ if (OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&stmthpp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0) != OCI_SUCCESS) { cout 《 "Create STMT error !" 《 endl; exit(1); } cout 《 "Create stmt success !" 《 endl; OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0); // Insert语句 char sql2[255] = "insert into table1 (col1, col2) values('testoci', 'testoci')"; // 准备Sql语句 if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql2, (ub4)strlen(sql2), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) != OCI_SUCCESS) { cout 《 "Create prepare error!" 《 sql2 《 endl; exit(1); } cout 《 "Create prepare success!" 《 endl; // 执行SQL 语句 OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)1, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_DEFAULT); // 断开用户会话 OCILogoff(svchpp, errhpp); // 断开服务器连接 OCIServerDetach(servhpp, errhpp, OCI_DEFAULT); // 释放资源 OCIHandleFree((dvoid *) stmthpp, OCI_HTYPE_STMT); OCIHandleFree((dvoid *) svchpp, OCI_HTYPE_SVCCTX); OCIHandleFree((dvoid *) servhpp, OCI_HTYPE_SERVER); OCIHandleFree((dvoid *) errhpp, OCI_HTYPE_ERROR); return 0; }
?
没有编译验证, 如果有错请看的童鞋多多包含。
?
明显OCCI是OCI的进阶版,个人认为,在硬件不是制约条件的今天,OCCI和OCI的执行效率不差上下,但是从程序员的调用方便来讲,明显OCCI要方便的多,如果以后的项目还要用到的话,本人会毫不犹豫的选择OCCI。