一、环境的配置

1、系统环境:要想使用OCI编程需要安装Oracle的客户端,而这个普通的客户端比较大,方便起见,可以安装即时客户端(Instantclient)作为Oracle的访问客户端。 

具体的配置可以参考这里:
http://www.cnblogs.com/ychellboy/archive/2010/04/16/1713884.html

2、执行环境:

windows下的配置可以参考这里:
http://blog.csdn.net/sherlockhua/article/details/4353531
linux下的配置可以参考这里:
http://blog.csdn.net/sherlockhua/article/details/4353531

二、基本理论

1、首先要创建OCI环境,即创建和初始化OCI工作环境,其他的OCI函数需要OCI环境才能执行。
2、分配OCI环境句柄:它定义所有OCI函数的调用环境,是其他句柄的父句柄。( 由OCIEnvInit 或OCIEnvCreate 生成 ) 。
3、错误句柄:作为一些OCI函数的参数,用来记录这些OCI函数操作过程中所产生的错误,当有错误发生时,可用OCIErrorGet()来读取错误句柄中记录的错误信息。
4、服务器环境句柄:定义OCI调用的服务器操作环境,它包含服务器、用户会话和事务三种句柄。
5、服务器句柄:标识数据源,它转换为与服务器的物理连接。
6、用户会话句柄:定义用户角色和权限及OCI调用的执行环境。
7、事务句柄:定义执行SQL操作的事务环境,事务环境中包含用户的会话状态信息。

注意:Bind/Define 句柄在执行具体的SQL语句的时候,被隐含创建并连接到表达句柄(Statement Handle)上,当表达句柄释放时,它们也被隐含释放。所以在执行每一个sql语句时,先分配表达句柄,执行结束后,释放表达句柄,这样做保证不发生由于定位句柄和绑定变量句柄引起的内存泄漏。

三、操作步骤 


OCI连接Oracle数据库的步骤比较复杂,除了分配设置各个基本句柄外,还要明确彼此之间的联系,大致流程如下:

1、创建环境句柄: OCIEnvCreate(&envhp, „);
2、创建一个指定环境的错误句柄: OCIHandleAlloc((dvoid *)envhp, (dvoid **)&errhp,„);
3、创建一个指定环境的服务器句柄: OCIHandleAlloc((dvoid *)envhp, (dvoid **)&servhp,„);
4、建立到数据源的访问路径 : OCIServerAttach(servhpp, errhpp,„);
5、创建一个指定环境的服务上下文句柄: (void) OCIHandleAlloc((dvoid *)envhpp,„);
6、为指定的句柄及描述符设置特定的属性: (void) OCIAttrSet((dvoid *)svchpp,„);
7、创建一个指定环境的用户连接句柄: (void) OCIHandleAlloc((dvoid *)envhpp,„);
8、为用户连接句柄设置登录名及密码: (void) OCIAttrSet((dvoid *)usrhpp,„);
9、认证用户建立一个会话连接: OCISessionBegin(svchpp, errhpp,„);
10、创建一个句子句柄: OCIHandleAlloc((dvoid *)envhpp,„);
11、准备 SQL 语句: OCIStmtPrepare(stmthpp, errhpp,„);
12、绑定输入变量: OCIBindByPos(stmtp &hBind, errhp,„);
13、绑定输出变量: OCIDefineByPos(stmthpp, &bhp1, errhpp,„);
14、获得 SQL 语句类型: OCIAttrGet ((dvoid *)stmthpp, (ub4)OCI_HTYPE_STMT,„);
15、执行 SQL 语句: OCIStmtExecute(svchpp, stmthpp,„);
17、释放一个会话: OCISessionEnd();
18、删除到数据源的访问 : OCIServerDetach(servhpp, errhpp, OCI_DEFAULT);
19、释放句柄: OCIHandleFree((dvoid *) stmthpp, OCI_HTYPE_STMT);

四、示例

程序1

//============================================================================
// Name : CExercise.cpp
// Author : Haier
// Version : 0.1
// Copyright : Your copyright notice
// Description : Connect Oracle in C++, Ansi-style
//============================================================================ #include <oci.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <ociapr.h>
#include <ocidem.h>
using namespace std; Lda_Def lda;
cda_def cda; dvoid oci_error(void)
{
text msg[600];
sword rv;
//取错误信息
rv=oerhms(&lda,cda.rc,msg,600);
//显示错误码和错误信息
printf("\n\n%.*s",rv,msg);
//显示发生错误的oci函数
printf("processing oci function %s\n",oci_func_tab[cda.fc]);
//关闭光标
if(oclose(&cda))
printf("error closing cursor!\n");
if(ologof(&lda))
printf("error logging off!\n"); exit(1);
} int main()
{
char szDbUser[]="so1@KFCS";
char szPassword[] ="1qaz!QAZ";
char pc_msg[256];
char sql[256] = "update so1.ins_prod_a set state='1' where bill_id='15238075968'"; if(olon( &lda,(OraText*)szDbUser, -1, (OraText*)szPassword, -1, 0))
{
oci_error();
} cout<<"Connect to Oracle DB Successed!"<<endl; if(oopen(&cda,&lda,(OraText*)0,-1,-1,(OraText*)0,-1))
{
oci_error();
} cout<<"Open Curse Successed!"<<endl; if(oparse(&cda,(OraText*)sql,-1,0,2))
{
oci_error();
} cout<<"Parse Sql Successed!"<<endl; if(oexn( &cda, 1, 0 ))
{
oci_error();
} cout<<"exec Sql Successed!"<<endl; if(oparse(&cda,(text*)"commit",-1,0,2))
{
oci_error();
} cout<<"Commit Successed!"<<endl; if(oclose(&cda))
{
printf("error closing cursor!/n");
exit(1);
} //结束事务,退出oracle
if(ologof(&lda))
{
printf("error logging off!/n");
exit(1);
} return 0;
}

运行

Connect to Oracle DB Successed!
Open Curse Successed!
Parse Sql Successed!
exec Sql Successed!
Commit Successed!

程序2

//============================================================================
// Name : CExercise.cpp
// Author : Haier
// Version : 0.1
// Copyright : Your copyright notice
// Description : Connect Oracle in C++ by oci, Ansi-style
//============================================================================ #include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <oci.h>
#include <ociapr.h>
#include <ocidem.h>
using namespace std; Lda_Def lda;
cda_def cda; dvoid oci_error(void)
{
text msg[600];
sword rv;
//取错误信息
rv=oerhms(&lda,cda.rc,msg,600);
//显示错误码和错误信息
printf("\n\n%.*s",rv,msg);
//显示发生错误的oci函数
printf("processing oci function %s\n",oci_func_tab[cda.fc]);
//关闭光标
oclose(&cda);
ologof(&lda);
exit(1);
} sword Login()
{
char username[20];
char password[20] ;
int times=0; do
{
if(++times>3)
{
return 1;
} cout<<"Enter user-name:";
cin>>username;
cout<<"Enter password:";
cin>>password; }while(olon( &lda,(OraText*)username, -1, (OraText*)password, -1, 0)); return 0;
} int main()
{ char bill_id[20];
char password[20];
char sql[256] = "select bill_id,password from so1.ins_prod_a where bill_id='15238075968'"; //登陆oracle
if(Login())
{
oci_error();
} //禁止自动提交
if(ocof(&lda))
{
oci_error();
} //打开curse
if(oopen(&cda,&lda,(OraText*)0,-1,-1,(OraText*)0,-1))
{
oci_error();
} //分析sql
if(oparse(&cda,(OraText*)sql,-1,0,2))
{
oci_error();
} //定义输入
if(odefin(&cda,1,(ub1 *)bill_id,sizeof(bill_id),5,-1,(sb2 *)0,(OraText *)0,0,-1,(ub2 *)0,(ub2 *)0))
{
oci_error();
} if(odefin(&cda,2,(ub1 *)password,sizeof(password),5,-1,(sb2 *)0,(OraText *)0,0,-1,(ub2 *)0,(ub2 *)0))
{
oci_error();
} //执行sql
if(oexn( &cda, 1, 0 ))
{
oci_error();
} //提取结果
if(ofen(&cda,1))
{
oci_error();
} //输出结果
cout<<"\n"<<bill_id<<"\t"<<password<<endl; //关闭curse
if(oclose(&cda))
{
printf("error closing cursor!/n");
exit(1);
} //结束事务,退出oracle
if(ologof(&lda))
{
printf("error logging off!/n");
exit(1);
} return 0;
}

运行

Enter user-name:so1@KFCS
Enter password:1qaz!QAZ 15238075968 W*_6oJ

程序3

//============================================================================
// Name : CExercise.cpp
// Author : Haier
// Version : 0.1
// Copyright : Your copyright notice
// Description : Connect Oracle in C++ by oci, Ansi-style
//============================================================================ #include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <oci.h>
#include <oratypes.h>
#include <ocidfn.h>
#include <ociapr.h>
#include <ocidem.h>
using namespace std; #define MAX_BINDS 12
#define MAX_ITEM_BUFFER_SIZE 32
#define MAX_SELECT_LIST_SIZE 12
#define MAX_SQL_IDENTIFIER 31
#define PARSE_NO_DELAY 0
#define PARSE_V7_LNG 2
#define RAWWIDTH 18 struct describe
{
sb4 dbsize;
sb2 dbtype;
sb1 buf[MAX_ITEM_BUFFER_SIZE];
sb4 buflen;
sb4 dsize;
sb2 precision;
sb2 scale;
sb2 nullok;
}; struct define
{
ub1 buf[MAX_ITEM_BUFFER_SIZE];
float flt_fuf;
sword int_buf;
sb2 indp;
sb2 col_retlen,col_retcode;
}; Lda_Def lda;
Cda_Def cda;
ub1 hda[256];
text errorMsg[600];
sword stmtLevel;
static text sqlStatement[2048];
static sword sqlFunction;
static sword numwidth = 8;
struct describe desc[MAX_SELECT_LIST_SIZE];
struct define def[MAX_SELECT_LIST_SIZE];
text bindValue[MAX_BINDS][MAX_ITEM_BUFFER_SIZE]; sword connect()
{
text username[20];
text password[20];
sword n; printf("Copyright (c) 1982, 2014, Oracle. All rights reserved.\n");
printf("Connected to Oracle Database:\n\n");
for(n=3; --n>=0; )
{
setbuf(stdout,NULL);
printf("Enter user-name: ");
gets((char*)username);
printf("Enter password: ");
gets((char*)password); if(orlon(&lda,hda,(OraText*)username,-1,(OraText*)password,-1,-1))
{
oerhms(&lda,lda.rc,(OraText*)errorMsg,sizeof(errorMsg));
printf("%sPlease try again.\n",errorMsg);
}
else
return TRUE; } printf("Connect failed.Exiting...\n");
return FALSE;
} sword getSqlStatement()
{
text sqlBuf[1024];
text *cp; while(1)
{
if(1==(++stmtLevel)){
*sqlStatement='\0';
printf("\nSQL>");
}else{
printf("%3d>",stmtLevel);
} fflush(stdin);
gets((char*)sqlBuf);
if(*sqlBuf=='\0'){
continue;
}else
{
if(!strncmp((char*)sqlBuf,"exit",4) || !strncmp((char*)sqlBuf,"quit",4))
{
return 1;
}
} if(stmtLevel>1)
{
strcat((char*)sqlStatement," ");
}
strcat((char*)sqlStatement,(char*)sqlBuf); cp = &sqlStatement[strlen((char*)sqlStatement)-1]; while(isspace(*cp))
{
cp--;
} if(*cp==';')
{
*cp='\0';
break;
} } return 0;
} void exitOracle(sword code)
{
if(oclose(&cda))
{
oerhms(&cda,cda.rc,(OraText*)errorMsg,sizeof(errorMsg));
printf("%s\n",errorMsg);
} if(ologof(&lda))
{
oerhms(&lda,lda.rc,(OraText*)errorMsg,sizeof(errorMsg));
printf("%s\n",errorMsg);
} exit(code);
} void oci_error(Cda_Def *cda)
{
char choice; oerhms(&lda,lda.rc,(OraText*)errorMsg,sizeof(errorMsg));
printf("%s\n",errorMsg); fprintf(stderr,"Do you want to continue ?[y/n]");
fscanf(stdin,"%c",&choice); if(toupper(choice)!='Y')
{
exitOracle(1);
} fputc('\n',stdout);
} sword bind(Cda_Def *cda,text *sqlStatement)
{
sword i,inLiteral,n;
text *cp,*ph; for(i=0,inLiteral=0,cp=sqlStatement; *cp && i<MAX_BINDS; cp++)
{
/* if(*cp=='\'')
{
inLiteral=-n;
}*/ if(*cp==':' && !inLiteral)
{
for(ph=(++cp),n=0; *cp && (isalnum(*cp) || *cp=='_') && n<MAX_SQL_IDENTIFIER; cp++,n++)
{ } *cp='\0';
printf("Enter value for %s:",ph);
gets((char*)&bindValue[i][0]); if(obndrv(cda,(OraText *)ph,-1,(ub1*)bindValue[i],-1,VARCHAR2_TYPE,-1,(sb2*)0,(OraText*)0,-1,-1))
{
oci_error(cda);
return -1;
} i++;
}
} return i;
} sword describeDefine(Cda_Def *cda)
{
sword col,deflen,deftype;
static ub1 *defptr; for(col=0; col<MAX_SELECT_LIST_SIZE; col++)
{
desc[col].buflen = MAX_ITEM_BUFFER_SIZE; if(odescr(cda,col+1,(sb4*)&desc[col].dbsize,(sb2*)&desc[col].dbtype,(sb1*)(int)desc[col].buf,(sb4*)&desc[col].buflen,(sb4*)desc[col].dsize,(sb2*)(int)desc[col].precision,(sb2*)(int)desc[col].scale,(sb2*)(int)desc[col].nullok))
{
if(cda->rc==VAR_NOT_IN_LIST)
{
break;
}else{
oci_error(cda);
return -1;
}
} switch(desc[col].dbtype)
{
case NUMBER_TYPE:
{
desc[col].dbsize = numwidth; if(desc[col].scale != 0)
{
defptr = (ub1*)&def[col].flt_fuf;
deflen = (sword)sizeof(float);
deftype= FLOAT_TYPE;
desc[col].dbtype = FLOAT_TYPE;
}else{
defptr = (ub1*)&def[col].int_buf;
deflen = (sword)sizeof(sword);
deftype= INT_TYPE;
desc[col].dbtype = INT_TYPE;
}
break;
}
case DATE_TYPE:
{
desc[col].dbsize = 9;
defptr = def[col].buf;
deflen = desc[col].dbsize > MAX_ITEM_BUFFER_SIZE ? MAX_ITEM_BUFFER_SIZE : desc[col].dbsize+1;
deftype= STRING_TYPE;
break;
}
case ROWID_TYPE:
{
desc[col].dbsize = 18;
defptr = def[col].buf;
deflen = desc[col].dbsize > MAX_ITEM_BUFFER_SIZE ? MAX_ITEM_BUFFER_SIZE : desc[col].dbsize+1;
deftype= STRING_TYPE;
break;
}
default:
{
defptr = def[col].buf;
deflen = desc[col].dbsize > MAX_ITEM_BUFFER_SIZE ? MAX_ITEM_BUFFER_SIZE : desc[col].dbsize+1;
deftype= STRING_TYPE;
break;
} } if(odefin(cda,col+1,(ub1*)defptr,deflen,deftype,-1,(sb2*)(int)def[col].indp,(OraText*)0,-1,-1,(ub2*)&def[col].col_retlen,(ub2*)(int)def[col].col_retcode))
{
oci_error(cda);
return -1;
}
} return col;
} void printHeader(sword ncols)
{
sword col,n,i; for(col=0; col<ncols; col++)
{
n=RAWWIDTH -desc[col].buflen; if(desc[col].dbtype==FLOAT_TYPE || desc[col].dbtype==INT_TYPE)
{
printf("%*.*s",desc[col].buflen,desc[col].buflen,desc[col].buf);
printf("%*c",n,' ');
}else{
printf("%*.*s",desc[col].buflen,desc[col].buflen,desc[col].buf);
printf("%*c",n,' ');
}
} fputc('\n',stdout); for(col=0; col<ncols; col++)
{
n=RAWWIDTH -desc[col].buflen; for(i=desc[col].buflen; i; i--)
{
fputc('-',stdout); } if(desc[col].dbtype==FLOAT_TYPE || desc[col].dbtype==INT_TYPE)
{
printf("%*c",n,' ');
}else
{
printf("%*c",n,' ');
} } fputc('\n',stdout); } void printRaw(Cda_Def *cda,sword ncols)
{
sword col,n; while(1)
{
fputc('\n',stdout); if(ofetch(cda))
{
if(cda->rc==NO_DATA_FOUND)
{
break;
}
if(cda->rc!=NULL_VALUE_RETURNED)
{
oci_error(cda);
}
} for(col=0; col<ncols; col++)
{ if(def[col].indp<0)
{
printf("%*c",desc[col].dbsize,' ');
}else{ switch(desc[col].dbtype)
{
case FLOAT_TYPE:
{
n = printf("%f",def[col].flt_fuf);
n = RAWWIDTH - n;
if(n)
{
printf("%*c",n,' ');
}
break;
}
case INT_TYPE:
{
n = printf("%d",def[col].int_buf);
n = RAWWIDTH - n;
if(n)
{
printf("%*c",n,' ');
}
break;
}
default:
{
n = printf("%s",def[col].buf);
n = RAWWIDTH - n;
if(n)
{
printf("%*c",n,' ');
}
break;
}
}
} }
}
} int main()
{
sword ncols; //登陆oracle
if(!connect())
{
exit(-1);
} //打开curse
if(oopen(&cda,&lda,(OraText*)0,-1,-1,(OraText*)0,-1))
{
oerhms(&lda,lda.rc,(OraText*)errorMsg,sizeof(errorMsg));
printf("%s,Please try again.\n",errorMsg);
exit(-1);
} while(1)
{
stmtLevel=0; //输入sql
if(getSqlStatement())
{
exitOracle(0);
} //分析sql
if(oparse(&cda,(OraText*)sqlStatement,-1,PARSE_NO_DELAY,PARSE_V7_LNG))
{
oci_error(&cda);
continue;
} sqlFunction = cda.ft; //绑定变量
if((ncols = bind(&cda,sqlStatement))==-1)
{
continue;
} if(sqlFunction==FT_SELECT)
{
if((ncols=describeDefine(&cda)) == -1)
{
continue;
}
} //执行sql
if(oexec(&cda))
{
oci_error(&cda);
continue;
} //若是查询,则显示查询结果;否则,提示事件
if(sqlFunction==FT_SELECT)
{
printHeader(ncols);
printRaw(&cda,ncols);
}else{
if(ocom(&lda))
{
oci_error(&lda);
continue;
}
} //显示处理行数
if(sqlFunction==FT_SELECT || sqlFunction==FT_UPDATE || sqlFunction==FT_DELETE || sqlFunction==FT_INSERT)
{
printf("\n\n%d row%c processed.\n",cda.rpc,cda.rpc==1 ? '\0' : 's');
}else{
printf("\n\nStatement processed.\n");
}
}
}

运行

Copyright (c) 1982, 2014, Oracle.  All rights reserved.
Connected to Oracle Database: Enter user-name: so1@KFCS
Enter password: 1qaz!QAZ SQL>select * from res.res_head_imsi where hlr='G04';
HLR WRITE_TYPE MANAGE_STATUS BILL_ID STANDBYFLAG NULL_FLAG IS_CONFIRM RES_CODE RES_STATUS HEADIMSI TOTAL
--- ---------- ------------- ------- ----------- --------- ---------- -------- ---------- -------- ----- G04 1 0 13673526099 0 0 K09111 1 46000 1 1 row

OCI 编程的更多相关文章

  1. VS2010下配置OCI编程

    OCI是Oracle官方出品的用于C/C++语言连接.操作Oracle数据库的API.在windows操作系统下使用VS等IDE编写.编译C++程序十分方便.简单,不需要使用Makefile.使用OC ...

  2. 学习OCI编程

    转自:http://kulong0105.blog.163.com/blog/static/174406191201162145944574/ 最近公司做的一个项目,要处理海量数据,数据是存放在Ora ...

  3. OCI编程

    OCI编码步骤: .定义OCI数据结构 .连接到Oracle数据库:使用orlon函数调用还可以并发连接多个数据库. .打开光标.通过调用oopen来打开一个光标. .分析语句.使用oparse来分析 ...

  4. [Oracle] Bulk Insert Data

    命名空间:Oracle.DataAccess.Client 组件:Oracle.DataAccess.dll(2.112.1.0) ODP.NET 版本:ODP.NET for .NET Framew ...

  5. Bulk Insert Data

    Bulk Insert Data 命名空间:Oracle.DataAccess.Client 组件:Oracle.DataAccess.dll(2.112.1.0) ODP.NET 版本:ODP.NE ...

  6. Oracle学习的一些建议(转)

    核心提示:学习Oracle是一个漫长艰辛的过程.如果没有兴趣,只是被迫学习,那么是很难学好的.学习到一定程度的时候,要想进一步提高,就不得不接触很多Oracle之外的东西 学习Oracle是一个漫长艰 ...

  7. C++使用ocilib访问oracle数据库

    引用: http://blog.csdn.net/u011311985/article/details/51221898 测试程序我放到 http://download.csdn.NET/detail ...

  8. [转帖]Oracle数据库lob大对象数据类型字段总结,值得收藏

    Oracle数据库lob大对象数据类型字段总结,值得收藏 原创 波波说运维 2019-07-11 00:02:00 https://www.toutiao.com/i67108943269703357 ...

  9. PL/SQL存储过程编程

    PL/SQL存储过程编程 /**author huangchaobiao *Email:huangchaobiao111@163.com */ PL/SQL存储过程编程(上) 1. Oracle应用编 ...

随机推荐

  1. MySql 链接字符串

    MySql连接字符串总结 1.本地数据库连接    <connectionStrings>        <add name="ConnectionString" ...

  2. python学习之RabbitMQ-----消息队列

    RabbitMQ队列 首先我们在讲rabbitMQ之前我们要说一下python里的queue:二者干的事情是一样的,都是队列,用于传递消息 在python的queue中有两个一个是线程queue,一个 ...

  3. nginx、TP框架实现兼容pathinfo和rewrite两种url访问方式

    环境:centos7,yum安装的nginx1.10.php-fpm,tp3.2 本方法只需要配置nginx.conf的一个文件就可以支持pathinfo和rewrite两种url访问方式 vim / ...

  4. zabbix配合脚本监控Kafka

    简介: Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据.Kafka如下特性,受到诸多公司的青睐. 1.高吞吐量:即使是非常普通的硬件Kafka也可以支持 ...

  5. jpa-jpql-basic-test

    jpql 基本测试 //可以使用 JPQL 完成 UPDATE 和 DELETE 操作. @Test public void testExecuteUpdate(){ String jpql = &q ...

  6. HTML5 Canvas ( 径向渐变, 升级版的星空 ) fillStyle, createRadialGradient

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. JDK9-模块化系统

    Content 0. 实例 0.1 使用命令行编写和运行模块程序 0.1.1 设置目录 0.1.2 编写源代码 0.1.3 编译 0.1.4 打包模块代码 0.1.5 运行程序 0.2 使用eclip ...

  8. 使用curl发起https请求

    "SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:S ...

  9. DataTable转换成实体

    public static class DataTableToEntity { /// <summary> /// 将DataTable数据源转换成实体类 /// </summary ...

  10. 行矩阵列矩阵D3D&GL&U3D

    void Start () { //矩阵函数原型:Matrix4x4(Vector4 colum0, Vector4 colum1, Vector4 colum2, Vector4 colum3),这 ...