加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

OCI编程(C++)

(2013-10-29 20:58:27)
分类: DataBase

最简单的OCI程序是运行一个既无参数输入,又无参数输出的SQL语句(复杂的OCI程序,加上了动态SQL、数据的输入、数据的输出、会话处理等)
基本步骤如下:
1、建立环境
2、分配必须的句柄和数据结构
3、连接登陆到数据库
4、建立会话
5、执行SQL语句
6、断开数据库连接
7、释放分配的句柄和结构

即: 初始化环境OCIEnvCreate( ) -->
分配句柄(至少包含错误、服务器、服务环境、会话) -->
连接到服务器 OCIServerAttach( ) -->
设置各种属性,包括会话的用户名和密码,OCIAttrSet( ) -->
开始会话,并把此会话设为此服务环境的缺省会话,OCISessionBegin( ), OCIAttrSet( ) -->
分配建立语句并设置SQL语句,OCIHandleAlloc( ) , OCIStmtPrepare( ) -->
执行SQL语句并提交,OCIExecute( ) , OCITransCommit( ) -->
释放句柄和环境, OCIHandleFree( )
注:上面同时列出了OCI接口的几个常用函数

见如下示例:
1、tora.cpp 文件代码

extern "C" {
#include <</span>oci.h>
#include <</span>oratypes.h>
}
#include <</span>string.h>
#include <</span>stdio.h>
extern "C"
{
typedef dvoid *(* MALOCFP)(dvoid *,size_t);
typedef dvoid *(* RALOCFP)(dvoid *,dvoid *,size_t);
typedef void (*MFREEFP)(dvoid *,dvoid *);
}


class COraConn
{
public:
COraConn(void);
~COraConn(void);
OCIEnv *m_pOCIEnv;
OCIError * m_pOCIError;
OCIServer * m_pOCIServer;
OCISvcCtx * m_pOCISvcCtx;
OCISession * m_pOCISession;
int m_nLastCode;
// 最后一次调用OCI的返回值

int Connect(const char * szUserName, const char * szPasswd,
const char * szServer);
int DisConnect(void);
int Commit(void);
int Rollback(void);
int GetErrorInfo(char * szInfo , int nLen, int & nErrorCode);
};

COraConn::COraConn(void)
{
m_pOCIEnv=NULL;
m_pOCIServer=NULL;
m_pOCIError=NULL;
m_nLastCode=OCI_SUCCESS;
m_pOCISvcCtx=NULL;
m_pOCISession=NULL;
}

COraConn::~COraConn(void)
{
DisConnect();
}


int COraConn::Connect(const char * szUserName,
const char * szPasswd, const char * szServer)
{
// 连接到数据库

DisConnect();
m_nLastCode=(int)OCIEnvCreate(&m_pOCIEnv,OCI_THREADED|OCI_OBJECT,NULL,
(MALOCFP)NULL,(RALOCFP)NULL,(MFREEFP)NULL,0,NULL);
// 分配环境句柄

if((m_nLastCode!=OCI_SUCCESS)&&(m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

m_nLastCode=OCIHandleAlloc(m_pOCIEnv,(dvoid **)(&m_pOCIError),
OCI_HTYPE_ERROR,0,(dvoid **)NULL);
// 分配错误句柄

if((m_nLastCode!=OCI_SUCCESS)&&(m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

m_nLastCode=OCIHandleAlloc(m_pOCIEnv,(dvoid **)(&m_pOCIServer),
OCI_HTYPE_SERVER,0,(dvoid **)NULL);
// 分配服务器句柄

if((m_nLastCode!=OCI_SUCCESS)&&(m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

int nStrLen=0;
if(szServer!=NULL)
nStrLen=(int)strlen(szServer);
m_nLastCode=OCIServerAttach(m_pOCIServer,m_pOCIError,
(const OraText *)szServer,nStrLen,OCI_DEFAULT);
// 连接到服务器

if(m_nLastCode==OCI_ERROR)
return 0;
// 有错误,可以取错误信息

if((m_nLastCode!=OCI_SUCCESS)&&(m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

m_nLastCode=OCIHandleAlloc(m_pOCIEnv,(dvoid **)(&m_pOCISvcCtx),
OCI_HTYPE_SVCCTX,0,(dvoid **)NULL);
// 分配服务环境句柄

if((m_nLastCode!=OCI_SUCCESS)&&(m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

m_nLastCode=OCIAttrSet( (dvoid *) m_pOCISvcCtx, (ub4) OCI_HTYPE_SVCCTX,
(dvoid *) m_pOCIServer, (ub4) 0,
(ub4) OCI_ATTR_SERVER, (OCIError *) m_pOCIError);
// 设置服务环境的服务器句柄

if(m_nLastCode==OCI_ERROR)
return 0;
// 有错误,可以取错误信息

if((m_nLastCode!=OCI_SUCCESS)&&(m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

m_nLastCode=OCIHandleAlloc(m_pOCIEnv,(dvoid **)(&m_pOCISession),
OCI_HTYPE_SESSION,0,(dvoid **)NULL);
// 分配会话句柄

if((m_nLastCode!=OCI_SUCCESS)&&(m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

nStrLen=0;
if(szUserName!=NULL)
nStrLen=(int)strlen(szUserName);
m_nLastCode=OCIAttrSet( (dvoid *) m_pOCISession, (ub4) OCI_HTYPE_SESSION,
(dvoid *) szUserName, (ub4) nStrLen,
(ub4) OCI_ATTR_USERNAME, (OCIError *) m_pOCIError);
// 设置会话句柄的用户名

if(m_nLastCode==OCI_ERROR)
return 0;
// 有错误,可以取错误信息

if((m_nLastCode!=OCI_SUCCESS)&&(m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

nStrLen=0;
if(szPasswd!=NULL)
nStrLen=(int)strlen(szPasswd);
m_nLastCode=OCIAttrSet( (dvoid *) m_pOCISession, (ub4) OCI_HTYPE_SESSION,
(dvoid *) szPasswd, (ub4) nStrLen,
(ub4) OCI_ATTR_PASSWORD, (OCIError *) m_pOCIError);
// 设置会话句柄的用户密码

if(m_nLastCode==OCI_ERROR)
return 0;
// 有错误,可以取错误信息

if((m_nLastCode!=OCI_SUCCESS)&&(m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

m_nLastCode=OCISessionBegin(m_pOCISvcCtx,m_pOCIError,m_pOCISession,
OCI_CRED_RDBMS,OCI_DEFAULT);
// 开始一个会话,以普通用户的身份

if(m_nLastCode==OCI_ERROR)
return 0;
// 有错误,可以取错误信息

if((m_nLastCode!=OCI_SUCCESS)&&(m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

m_nLastCode=OCIAttrSet( (dvoid *) m_pOCISvcCtx, (ub4) OCI_HTYPE_SVCCTX,
(dvoid *) m_pOCISession, (ub4) 0,
(ub4) OCI_ATTR_SESSION, (OCIError *) m_pOCIError);
// 设置服务环境的会话句柄

if(m_nLastCode==OCI_ERROR)
return 0;
// 有错误,可以取错误信息

if((m_nLastCode!=OCI_SUCCESS)&&(m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

return 1;
}

int COraConn::DisConnect(void)
{
if(m_pOCISession!=NULL)
{
OCISessionEnd(m_pOCISvcCtx,m_pOCIError,m_pOCISession,OCI_DEFAULT);
OCIHandleFree(m_pOCISession,OCI_HTYPE_SESSION);
m_pOCISession=NULL;
}
if(m_pOCISvcCtx!=NULL)
{
OCIHandleFree(m_pOCISvcCtx,OCI_HTYPE_SVCCTX);
m_pOCISvcCtx=NULL;
}
if(m_pOCIServer!=NULL)
{
OCIServerDetach(m_pOCIServer,m_pOCIError,OCI_DEFAULT);
OCIHandleFree(m_pOCIServer,OCI_HTYPE_SERVER);
m_pOCIServer=NULL;
}
if(m_pOCIError!=NULL)
{
OCIHandleFree(m_pOCIError,OCI_HTYPE_ERROR);
m_pOCIError=NULL;
}
if(m_pOCIEnv!=NULL)
{
OCIHandleFree(m_pOCIEnv,OCI_HTYPE_ENV);
m_pOCIEnv=NULL;
}
return 1;
}

class COraStmt
{
public:
COraConn * m_pConn;
OCIStmt * m_pOCIStmt;
public:
COraStmt(COraConn * pConn);
~COraStmt(void);
int SetStmtText(const char * szStmtText);
int CloseStmt(void);
int ExecStmt(void);
};

COraStmt::COraStmt(COraConn * pConn)
{
m_pConn=pConn;
m_pOCIStmt=NULL;
}

COraStmt::~COraStmt(void)
{
CloseStmt();
}

int COraStmt::SetStmtText(const char * szStmtText)
{
// 设置要运行的语句

if(m_pConn==NULL)
return -1;
if(szStmtText==NULL)
return -1;
int nStrLen=(int)strlen(szStmtText);
if(nStrLen<</span>=0)
return -1;
CloseStmt();
m_pConn->m_nLastCode=OCIHandleAlloc(m_pConn->m_pOCIEnv,
(dvoid **)(&m_pOCIStmt),
OCI_HTYPE_STMT,0,(dvoid **)NULL);
// 分配操作语句句柄

if((m_pConn->m_nLastCode!=OCI_SUCCESS)&&
(m_pConn->m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

m_pConn->m_nLastCode=OCIStmtPrepare(m_pOCIStmt,m_pConn->m_pOCIError,
(const OraText *)szStmtText,(ub4)nStrLen,OCI_NTV_SYNTAX,OCI_DEFAULT);
// 执行prepare

if(m_pConn->m_nLastCode==OCI_ERROR)
return 0;
// 有错误,可以取错误信息

if((m_pConn->m_nLastCode!=OCI_SUCCESS)&&
(m_pConn->m_nLastCode!=OCI_SUCCESS_WITH_INFO))
return -1;
// 有错误,但不能取错误信息

return 1;
}

int COraStmt::CloseStmt(void)
{
if(m_pConn==NULL)
return -1;
if(m_pOCIStmt==NULL)
return 1;
OCIHandleFree(m_pOCIStmt,OCI_HTYPE_STMT);
m_pOCIStmt=NULL;
return 1;
}

int COraStmt::ExecStmt(void)
{
// 运行准备好的语句

if(m_pConn==NULL)
return -1;
if(m_pOCIStmt==NULL)
return -1;
m_pConn->m_nLastCode=OCIStmtExecute(m_pConn->m_pOCISvcCtx,
m_pOCIStmt,m_pConn->m_pOCIError,1,0,NULL,NULL,OCI_DEFAULT);
// 执行语句

if(m_pConn->m_nLastCode==OCI_ERROR)
return 0;
// 有错误,可以取错误信息

if((m_pConn->m_nLastCode!=OCI_SUCCESS)&&
(m_pConn->m_nLastCode!=OCI_SUCCESS_WITH_INFO)&&
(m_pConn->m_nLastCode!=OCI_NO_DATA))
return -1;
// 有错误,但不能取错误信息

return 1;
}

int COraConn::Commit(void)
{
if(m_pOCIError==NULL)
return -1;
if(m_pOCISvcCtx==NULL)
return -1;
m_nLastCode=OCITransCommit(m_pOCISvcCtx,m_pOCIError,OCI_DEFAULT);
// 执行commit

if(m_nLastCode==OCI_ERROR)
return 0;
// 有错误,可以取错误信息

if((m_nLastCode!=OCI_SUCCESS)&&
(m_nLastCode!=OCI_SUCCESS_WITH_INFO)&&
(m_nLastCode!=OCI_NO_DATA))
return -1;
// 有错误,但不能取错误信息

return 1;
}

int COraConn::Rollback(void)
{
if(m_pOCIError==NULL)
return -1;
if(m_pOCISvcCtx==NULL)
return -1;
m_nLastCode=OCITransRollback(m_pOCISvcCtx,m_pOCIError,OCI_DEFAULT);
// 执行rollback

if(m_nLastCode==OCI_ERROR)
return 0;
// 有错误,可以取错误信息

if((m_nLastCode!=OCI_SUCCESS)&&
(m_nLastCode!=OCI_SUCCESS_WITH_INFO)&&
(m_nLastCode!=OCI_NO_DATA))
return -1;
// 有错误,但不能取错误信息

return 1;
}

int COraConn::GetErrorInfo(char * szInfo , int nLen, int & nErrorCode)
{
if(m_pOCIError==NULL)
return -1;
sb4 localErrorCode;
static int nErrorOff=1;
int rc=OCIErrorGet(m_pOCIError,nErrorOff,NULL,&localErrorCode,
(OraText *)szInfo,(ub4)nLen,OCI_HTYPE_ERROR);
nErrorCode=localErrorCode;
if(rc==OCI_NO_DATA)
{
nErrorOff=1;
return 1;
}
if((rc==OCI_SUCCESS)||(rc==OCI_SUCCESS_WITH_INFO))
{
nErrorOff++;
return 2;
}
nErrorOff=1;
return 0;
}

int main(int argc,char * argv[])
{
char szServer[]="orcl";
char szUserName[]="system";
char szPasswd[]="passwd123";
char szSQLCommand[]="create table USER_BASE ( USER_NAME varchar2(32) NOT NULL,"
"USER_CODE number(8) NOT NULL,ENABLE_FLAG number(4) default 1 NOT NULL ,"
"CONSTRAINT KEY_USER_BASE_NAME PRIMARY KEY (USER_NAME))";
COraConn * localConn=new COraConn();
int rc=localConn->Connect(szUserName,szPasswd,szServer);
int nErrorCode;
int nMsgLen=1023;
char szErrMsg[1024];
if(rc<</span>0)
{
delete localConn;
printf("error to connect server %s\n",szServer);
return -1;
}
if(rc==0)
{
do
{
rc=localConn->GetErrorInfo(szErrMsg,nMsgLen,nErrorCode);
if(rc<</span>=0)
{
printf("error to connect server %s\n",szServer);
delete localConn;
return -1;
}
if(rc==1)
break;
printf("error code is %d,error info is %s\n",nErrorCode,szErrMsg);
}
while(rc>1);
delete localConn;
return -1;
}
COraStmt * localStmt=new COraStmt(localConn);
rc=localStmt->SetStmtText(szSQLCommand);
if(rc<</span>0)
{
delete localStmt;
delete localConn;
printf("error to perpare sql %s\n",szSQLCommand);
return -1;
}
if(rc==0)
{
do
{
rc=localConn->GetErrorInfo(szErrMsg,nMsgLen,nErrorCode);
if(rc<</span>=0)
{
printf("error to perpare sql %s\n",szSQLCommand);
delete localStmt;
delete localConn;
return -1;
}
if(rc==1)
break;
printf("error code is %d,error info is %s\n",nErrorCode,szErrMsg);
}
while(rc>1);
delete localStmt;
delete localConn;
return -1;
}
rc=localStmt->ExecStmt();
if(rc<</span>0)
{
delete localStmt;
delete localConn;
printf("error to exec sql %s\n",szSQLCommand);
return -1;
}
if(rc==0)
{
do
{
rc=localConn->GetErrorInfo(szErrMsg,nMsgLen,nErrorCode);
if(rc<</span>=0)
{
printf("error to exec sql %s\n",szSQLCommand);
delete localStmt;
delete localConn;
return -1;
}
if(rc==1)
break;
printf("error code is %d,error info is %s\n",nErrorCode,szErrMsg);
}
while(rc>1);
delete localStmt;
delete localConn;
return -1;
}
localConn->Commit();
delete localStmt;
delete localConn;
printf("sql execute ok\n");
return 0;
}


0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有