您的位置:首页 > 数据库 > Oracle

C++ 连接oracle数据库

2014-04-03 17:41 155 查看

方式1,使用OCCI:

直接上代码

#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。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: