虚拟机linux连接宿主机调用oci接口练习
1.环境搭建
1.1 虚拟机环境:
VMware Workstation ACE Edition 版本号: 6.0.0 build-45731
虚拟系统: Red Hat Enterprise Linux 4-u3
1.2 宿主机环境
Windows xp sp3
Oracle 实例
1.3 安装虚拟机VMware Workstation。按部就班的安装即可。安装完之后”File”à”open”打开虚拟机linux目录。打开”Red Hat Enterprise Linux 4.vmx”.
启动虚拟机。
1.4 用root登陆linux系统后,察看
vi /etc/inittab
如果是id:3:initdefault: 要修改成id:5:initdefault: 这样做的目的是将启动级别由3改为5,启动图形化界面以修改虚拟linux的ip地址和网关。
1.5 查看linux的vsftpd服务启动已否。如果未启动启动之。有关方法可查阅linux Red
Hat 启动系统服务方法。不同版本可能方法不同?
1.6 重启linux后进入图形化登陆界面。用root用户登录。
如果虚拟机linux系统和宿主机可能互联的话ip地址和网关必须是同一网段的。
Windows系统的ip地址为192.168.1.101,网关是255.255.255.0那设置
ApplicationsàSystem SetingsàNetwork.修改linux 系统为 ip为192.168.1.144。网关为255.255.255.0
1.7 修改完之后重启虚假机linux。之后在windows下ping 192.168.1.144,如果ping
同就可能了如:
C:/WINDOWS/system32>ping 192.168.1.144
Pinging 192.168.1.144 with 32 bytes of data:
Reply from 192.168.1.144: bytes=32 time=2ms TTL=64
Reply from 192.168.1.144: bytes=32 time<1ms TTL=64
Reply from 192.168.1.144: bytes=32 time<1ms TTL=64
Reply from 192.168.1.144: bytes=32 time<1ms TTL=64
Ping statistics for 192.168.1.144:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 2ms, Average = 0ms
1.8 在windows下使用ftp工具连接虚拟机linux系统,如cuteftppro,用户名是登陆虚拟机linux的用户名和密码。如果能连上就ok了
1.9 在保证windows下oracle实例启动后,(这可以用pl/sql developer工具检验下),在虚拟机上保证安装oracle 客户端。修改linux下的tnsnames.ora,添加连接宿主机的oracle实例语句如:
orcl =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.101)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
)
其中192.168.1.101是宿主ip地址,orc是数据库实例。
2.Linux下oci连接windows数据库实例
2.1 ex_8_1.cpp代码如下:
extern "C" {
#include <oci.h>
#include <oratypes.h>
}
#include <string.h>
#include <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<=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[]="prm_owner_user";
char szPasswd[]="prm_owner_user";
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<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<=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<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<=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<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<=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;
}
2.2 Makefile代码如下:
CC= g++
CFLAGS= -c -g -pthread -D_REENTRANT -D`uname -s` -Wall
LDFLAGS= -g -lpthread
CDBFLAGS= -I$(ORACLE_HOME)/rdbms/demo -I$(ORACLE_HOME)/plsql/public /
-I$(ORACLE_HOME)/rdbms/public
LDDBFLAGS = -L$(ORACLE_HOME)/lib -lclntsh -laio
target = ex_8_1
all: $(target)
target_objects=ex_8_1.o
ex_8_1 :$(target_objects)
$(CC) $(LDFLAGS) $(LDDBFLAGS) -o $@ $^
@echo $@ Build OK.
.SUFFIXES:.cpp .o
.cpp.o :
$(CC) $(CFLAGS) $(CDBFLAGS) -o $@ $<
clean:
@rm -rf $(target) $(target_objects)
2.3 Makefile代码如下:
这连个文件可能是在windows下写的,写好之后用FTP工具上传到linux下的某目录下。
之后”make all” 生成ex_8_1可执行文件,之后执行它!提示”sql execute ok”表示执行成功。