2017年6月1日09:24:02
大概在一个月前就接触过OCCI的一些东西,当时想做一个C++连接Oracle的程序,网上搜索了之后,觉得用OCCI效率高,功能强大,所以就开工了。结果,当时就撞得找不着北了。后来被找工作的事情耽搁了,一直到今天才把这里面的东西理清楚。
开始正文:
首先来说一下这篇文章不一样的地方。
这里我们着重说明是如何在VS上配置OCCI,而不是OCCI的使用方式。
问题1:VC、VS、Oracle Client、Oracle Server的版本问题。
首先是VC和VS的version问题,现在还在用的有
VC8 -- VS2005
VC9 -- VS2008
VC10 -- VS2010
VC11 -- VS2012
VC12 -- VS2013
VC14 -- VS2015
然后再说一下Oracle Client 和Oracle Server的问题。
我们使用Oracle Client链接Server的时候通常用的都是一样的版本,不过,如果用Oracle 10g的Client 也可以连接Oracle 11g的Server。所以这里我们需要注意的不是Oracle Server的版本,而是Oracle Client的版本信息。
另外如果本机没有安装Oracle Client 的话,那么可以使用Instant Client。什么是Instant Client呢?
Instant Client 简介,及下载链接
http://www.oracle.com/technetwork/cn/database/features/instant-client/index-092537-zhs.html
利用 Instant Client,您无需安装标准的 Oracle 客户端或拥有 ORACLE_HOME 就可运行应用程序。OCI、OCCI、Pro*C、ODBC 和 JDBC 应用程序无需进行修改即可运行,同时显著节省磁盘空间。甚至 SQL*Plus 也可与 Instant Client
一起使用。无需重新编译,也就没有烦恼。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------/
简单的说就是Instant Clinet就是一个简化的客户端,可以用它来运行需要Oracle Client的程序。
比较早的版本: http://www.oracle.com/technetwork/cn/topics/winsoft-095945-zhs.html
新的版本:
http://www.oracle.com/technetwork/topics/winsoft-085727.html
Version 12.2.0.1.0 VC14
Version 12.1.0.2.0 VC10、11、12
Version 12.1.0.1.0 VC10、11
Version 11.2.0.4.0 VC8、9 (10)
Version 11.2.0.3.0 VC8、9 (10) 10需要再下载另外的OCCI
Version 11.2.0.2.0 VC8、9 (10)
Version 11.2.0.1 VC8、9
Version 11.1.0.7.0 VC71、8
Version 11.1.0.6.0 VC71、8
Version 10.2.0.4 VC7、71
也就是说,如果你是Oracle 11.2.0.1的话,最好是用VS2005和VS2008。 这样VS 、 Oracle Client、 Oracle Server 都是配套的,用起来不会有其他问题
如果你的VS 是2010 的,想要用Oracle 11g, 同样可以用Oracle 12c的Client。
如果你明白了他们之间的关系,一般情况下,都可以建立起连接了。
其实这里面还有一个问题没有说,那就是X32 和X64的问题。
如果你的Oracle Client是64位的,那么你就需要64位的OCCI,并且,在VS中,程序也需要以64位的方式进行编译连接。 否则就找不到对应的函数,发生Link2019错误。
OCCI 库用到的是OCCIX.dll
Client 中用到的库是OCI.dll\ MSVCR
71.dll\ociwin32.dll等
在开始下面的内容前,请先确保已经基本理解了上面的对应关系。
现在开始在VS 中开始一次连接测试。
先来一次标准的。VS 2005 -- VC8 -- Oracle 11.2.0.1 Instant Client -- Oracle 11.2.0.1 Server
代码如下,说明:代码取自网上。
// TestOcci.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#define WIN32COMMON //避免函数重定义错误
#include <occi.h>
using namespace std;
using namespace oracle::occi;
int _tmain(int argc, _TCHAR* argv[])
{
system("pause");
//创建OCCI上下文环境
Environment *env = Environment::createEnvironment();
if (NULL == env) {
printf("createEnvironment error.\n");
return -1;
}
else
cout << "success" << endl;
string name = "scott";
string pass = "tiger";
string srvName = "//218.28.221.106:1521/VPAXS";
try
{
//创建数据库连接
Connection *conn = env->createConnection(name, pass, srvName);//用户名,密码,数据库名
if(NULL == conn) {
printf("createConnection error.\n");
return -1;
}
else
cout << "conn success" << endl;
// 数据操作,创建Statement对象
Statement *pStmt = NULL; // Statement对象
pStmt = conn->createStatement();
if(NULL == pStmt) {
printf("createStatement error.\n");
return -1;
}
// 查询数据库时间
std::string strTemp;
ResultSet *pRs = pStmt->executeQuery(
"SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') FROM DUAL");
while(pRs->next()) {
strTemp = pRs->getString(1);
printf("db time:%s.\n", strTemp.c_str());
// int类型取值用getInt()
break;
}
pStmt->closeResultSet(pRs);
// 终止Statement对象
conn->terminateStatement(pStmt);
// 关闭连接
env->terminateConnection(conn);
// pEnv->terminateConnection(pConn);
}
catch (SQLException e)
{
cout << e.what() << endl;
system("pause");
return -1;
}
// 释放OCCI上下文环境
Environment::terminateEnvironment(env);
cout << "end!" << endl;
system("pause");
return 0;
}
C/C++ 常规 :附加包含目录,添加Instant Client 的include 目录
链接器:常规:附加库目录,添加Instant Client 的Lib 目录
输入:附加依赖项,oraocci11.lib
进行生成, 生成成功,但是运行时出现错误,找不到dll文件。
由于默认是在当成的当前面目录去找的,或者在path中查找,为了简便,我们把occi11.dll拷贝到程序的文件夹。
再运行,发生找不到MSVCR71.dll,这个是在SDK外面的文件夹里面的,同样拷过去
再运行,发生 无法定位程序输入点 于oci.dll动态链接库,原因是它去Oracle_HOME里面找oci.dll了,由于我这里的Oracle_HOME配置的时一个10g的Client,所以出错了。
把Instant Client 里面的oci.dll也拷过去
再运行,OK了
这里我们从Oracle 查了一下当前时间。
再来一次比较凌乱的:
VS2010 -- VC10 -- Oracle 12.1.0.1Client -- Oracle 11g server
程序代码同上。
还是按照之前的配置方法,配置之后运行同样OK。
不过这个并不是标准的连接方法,所以在执行某些命令时可能会出错,VS2010 连接11g是有对应的OCCI的。只不过需要没有Instant Client可以用。需要下载之后手动配置。
大概在一个月前就接触过OCCI的一些东西,当时想做一个C++连接Oracle的程序,网上搜索了之后,觉得用OCCI效率高,功能强大,所以就开工了。结果,当时就撞得找不着北了。后来被找工作的事情耽搁了,一直到今天才把这里面的东西理清楚。
开始正文:
首先来说一下这篇文章不一样的地方。
这里我们着重说明是如何在VS上配置OCCI,而不是OCCI的使用方式。
问题1:VC、VS、Oracle Client、Oracle Server的版本问题。
首先是VC和VS的version问题,现在还在用的有
VC8 -- VS2005
VC9 -- VS2008
VC10 -- VS2010
VC11 -- VS2012
VC12 -- VS2013
VC14 -- VS2015
然后再说一下Oracle Client 和Oracle Server的问题。
我们使用Oracle Client链接Server的时候通常用的都是一样的版本,不过,如果用Oracle 10g的Client 也可以连接Oracle 11g的Server。所以这里我们需要注意的不是Oracle Server的版本,而是Oracle Client的版本信息。
另外如果本机没有安装Oracle Client 的话,那么可以使用Instant Client。什么是Instant Client呢?
下面从Oracle 官网上摘抄了一段话:
Instant Client 简介,及下载链接
http://www.oracle.com/technetwork/cn/database/features/instant-client/index-092537-zhs.html
利用 Instant Client,您无需安装标准的 Oracle 客户端或拥有 ORACLE_HOME 就可运行应用程序。OCI、OCCI、Pro*C、ODBC 和 JDBC 应用程序无需进行修改即可运行,同时显著节省磁盘空间。甚至 SQL*Plus 也可与 Instant Client
一起使用。无需重新编译,也就没有烦恼。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------/
简单的说就是Instant Clinet就是一个简化的客户端,可以用它来运行需要Oracle Client的程序。
比较早的版本: http://www.oracle.com/technetwork/cn/topics/winsoft-095945-zhs.html
新的版本:
http://www.oracle.com/technetwork/topics/winsoft-085727.html
Version 12.2.0.1.0 VC14
Version 12.1.0.2.0 VC10、11、12
Version 12.1.0.1.0 VC10、11
Version 11.2.0.4.0 VC8、9 (10)
Version 11.2.0.3.0 VC8、9 (10) 10需要再下载另外的OCCI
Version 11.2.0.2.0 VC8、9 (10)
Version 11.2.0.1 VC8、9
Version 11.1.0.7.0 VC71、8
Version 11.1.0.6.0 VC71、8
Version 10.2.0.4 VC7、71
也就是说,如果你是Oracle 11.2.0.1的话,最好是用VS2005和VS2008。 这样VS 、 Oracle Client、 Oracle Server 都是配套的,用起来不会有其他问题
如果你的VS 是2010 的,想要用Oracle 11g, 同样可以用Oracle 12c的Client。
如果你明白了他们之间的关系,一般情况下,都可以建立起连接了。
其实这里面还有一个问题没有说,那就是X32 和X64的问题。
如果你的Oracle Client是64位的,那么你就需要64位的OCCI,并且,在VS中,程序也需要以64位的方式进行编译连接。 否则就找不到对应的函数,发生Link2019错误。
OCCI 库用到的是OCCIX.dll
Client 中用到的库是OCI.dll\ MSVCR
71.dll\ociwin32.dll等
在开始下面的内容前,请先确保已经基本理解了上面的对应关系。
现在开始在VS 中开始一次连接测试。
先来一次标准的。VS 2005 -- VC8 -- Oracle 11.2.0.1 Instant Client -- Oracle 11.2.0.1 Server
代码如下,说明:代码取自网上。
// TestOcci.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#define WIN32COMMON //避免函数重定义错误
#include <occi.h>
using namespace std;
using namespace oracle::occi;
int _tmain(int argc, _TCHAR* argv[])
{
system("pause");
//创建OCCI上下文环境
Environment *env = Environment::createEnvironment();
if (NULL == env) {
printf("createEnvironment error.\n");
return -1;
}
else
cout << "success" << endl;
string name = "scott";
string pass = "tiger";
string srvName = "//218.28.221.106:1521/VPAXS";
try
{
//创建数据库连接
Connection *conn = env->createConnection(name, pass, srvName);//用户名,密码,数据库名
if(NULL == conn) {
printf("createConnection error.\n");
return -1;
}
else
cout << "conn success" << endl;
// 数据操作,创建Statement对象
Statement *pStmt = NULL; // Statement对象
pStmt = conn->createStatement();
if(NULL == pStmt) {
printf("createStatement error.\n");
return -1;
}
// 查询数据库时间
std::string strTemp;
ResultSet *pRs = pStmt->executeQuery(
"SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') FROM DUAL");
while(pRs->next()) {
strTemp = pRs->getString(1);
printf("db time:%s.\n", strTemp.c_str());
// int类型取值用getInt()
break;
}
pStmt->closeResultSet(pRs);
// 终止Statement对象
conn->terminateStatement(pStmt);
// 关闭连接
env->terminateConnection(conn);
// pEnv->terminateConnection(pConn);
}
catch (SQLException e)
{
cout << e.what() << endl;
system("pause");
return -1;
}
// 释放OCCI上下文环境
Environment::terminateEnvironment(env);
cout << "end!" << endl;
system("pause");
return 0;
}
配置信息:
C/C++ 常规 :附加包含目录,添加Instant Client 的include 目录
链接器:常规:附加库目录,添加Instant Client 的Lib 目录
输入:附加依赖项,oraocci11.lib
进行生成, 生成成功,但是运行时出现错误,找不到dll文件。
由于默认是在当成的当前面目录去找的,或者在path中查找,为了简便,我们把occi11.dll拷贝到程序的文件夹。
再运行,发生找不到MSVCR71.dll,这个是在SDK外面的文件夹里面的,同样拷过去
再运行,发生 无法定位程序输入点 于oci.dll动态链接库,原因是它去Oracle_HOME里面找oci.dll了,由于我这里的Oracle_HOME配置的时一个10g的Client,所以出错了。
把Instant Client 里面的oci.dll也拷过去
再运行,OK了
这里我们从Oracle 查了一下当前时间。
再来一次比较凌乱的:
VS2010 -- VC10 -- Oracle 12.1.0.1Client -- Oracle 11g server
程序代码同上。
还是按照之前的配置方法,配置之后运行同样OK。
不过这个并不是标准的连接方法,所以在执行某些命令时可能会出错,VS2010 连接11g是有对应的OCCI的。只不过需要没有Instant Client可以用。需要下载之后手动配置。