VS2019 C++ 使用 OCCI 连接调用 oracle (Windows 10)

一 :下载和配置客户端连接套件:

oracle 官方下载地址:Oracle Instant Client下载 注意区分 x86和 x64。
在这里插入图片描述
我自己用的是 x64 , Oracle 也是 x64. :(Microsoft Windows(x64)的即时客户端)
点进去:下载最新版 Version 19.6.0.0.0

在这里插入图片描述
在这里插入图片描述
两个压缩包:sdk(头文件,lib) 和 windows x64 基本客户端(内涵 .dll) 。
下载后解压到电脑:
SDK: 文件结构 ,包含头文件和 lib 以及dome文件等。
在这里插入图片描述
Client: 解压后有240MB。
在这里插入图片描述
注意 两个压缩包都包含 V14 文件加 ,对应 VS平台工具集 v14:(vs2015 ~ vs2019)。vs2013 是v12 要下载对用低版本的。

在这里插入图片描述

二:配置与引用:

1:配置头文件引用:在 SDK 中:
在这里插入图片描述
F:\oracleClient\X64\instantclient_sdk\instantclient_19_6\sdk\include。这个不做强制规定,根据个人习惯来放置文件。
打开项目属性:C/C++ / 附加包含目录。
在这里插入图片描述
2:引用 lib 文件

F:\oracleClient\X64\instantclient_sdk\instantclient_19_6\sdk\lib\msvc\vc14
在这里插入图片描述
打开项目属性:连接器 / 常规 / 附加库目录。
在这里插入图片描述
3:添加静态库。
连接器 / 输入 / 附加依赖项 添加 oraocci19d.lib 静态库 。需要注意的是,文件中有两个lib,一个是oraocci12.lib,另一个是oraocci12d.lib文件。第一个lib文件是用在release模式的,第二个lib文件是用在debug模式的。
在这里插入图片描述
4 引用动态库。
动态库 dll 文件比较大,这里不用拷贝到项目中,使用添加 环境变量来引用:
F:\oracleClient\X64\instantclient_basic\instantclient_19_6
在这里插入图片描述
在环境变量 path 中添加。
在这里插入图片描述

五 Dome 演示:

#pragma once
#include <iostream>
#include <occi.h>
using namespace oracle::occi;
using namespace std;

typedef struct emptable
{
	int empno;
	string ename;
	string	job;
	double	mgr;
	string	hiredate;
	double sal;
	double	comm;
	int	deptno;
}EMP;

class occiemp
{
public:
	occiemp(string user, string passwd, string db);
	~occiemp();

	void displayAllRows();//显示所有数据
	void updateRow(int empno, double sal);
	void deleteRow(int empno, string ename);
	void insertRow(EMP emp);//插入一行数据
	Date Todate(string time);
private:
	Environment* env=nullptr;//上下文环境
	Connection* conn=nullptr;//数据库连接句柄
	Statement* stmt=nullptr;//指向SQL语句声明类

};
#include "occiemp.h"
#include <iomanip> 
//构造函数
occiemp::occiemp(string user, string passwd, string db)
{
	try
	{
		this->env = Environment::createEnvironment();//创建环境
		this->conn = env->createConnection(user, passwd, db);//创建连接
	}
	catch(SQLException ex)
	{
		cout << "Error number: " << ex.getErrorCode() << endl;
		cout << ex.getMessage() << endl;
	}
	
}

//析构函数
occiemp::~occiemp()
{
	if (this->env != nullptr)
	{
		this->env->terminateConnection(this->conn);//释放连接
	}
	if (this->env)
	{
		Environment::terminateEnvironment(this->env);//释放环境
	}
}

//显示所有数据
void occiemp::displayAllRows()
{
	string sqlStmt = "select empno,ename,job, mgr,hiredate,sal,comm, deptno from emp order by empno ";
	this->stmt = this->conn->createStatement(sqlStmt);
	//执行查询语句
	ResultSet* rset = this->stmt->executeQuery();//ResultSet提供对通过执行生成的数据表的访问Statement。表行按顺序检索。在一行中,可以按任何顺序访问列值。ResultSet保持光标指向其当前数据行。最初,光标位于第一行之前。next() 方法将光标移动到下一行。
	try
	{
		cout << "empno" << setw(10) << "ename" << setw(10) << "job" << setw(20) << "mgr" << setw(30) << "hiredate" << setw(20) << "sal" << setw(10) << "comm" << setw(10) << "deptno" << endl;
		while (rset->next())
		{
			cout << rset->getInt(1) << setw(10) << rset->getString(2) << setw(10) << rset->getString(3) << setw(20) << rset->getInt(4) << setw(30) << (rset->getDate(5).toText()) << setw(20)<< rset->getDouble(6) << setw(10) << rset->getDouble(7) << setw(10) << rset->getInt(8) << endl;
		}
	}
	catch (SQLException ex)
	{
		cout << "Exception thrown for displayAllRows" << endl;
		cout << "Error number: " << ex.getErrorCode() << endl;
		cout << ex.getMessage() << endl;
	}
	this->stmt->closeResultSet(rset);//释放集合数据
	this->conn->terminateStatement(this->stmt);//释放SQL语句
}

//更新数据
void occiemp::updateRow(int empno, double sal)
{
	string sqlStmt ="UPDATE emp SET sal = :x WHERE empno= :y";
	try 
	{
		this->stmt = this->conn->createStatement(sqlStmt);
		stmt->setInt(1, empno);
		stmt->setDouble(2, sal);
		//执行非查询语句
		unsigned int res = stmt->executeUpdate();
		if (res > 0)
		{
			cout << "update - Success "<<res<<" 行受影响。" << endl;
		}
		
	}
	catch (SQLException ex)
	{
		cout << "Exception thrown for updateRow" << endl;
		cout << "Error number: " << ex.getErrorCode() << endl;
		cout << ex.getMessage() << endl;
	}

	this->conn->terminateStatement(this->stmt);
}

//根据条件删除数据
void occiemp::deleteRow(int empno, string ename)
{
	string sqlStmt ="DELETE FROM emp WHERE empno= :x AND ename = :y";
	
	try 
	{
		this->stmt = this->conn->createStatement(sqlStmt);
		this->stmt->setInt(1, empno);
		this->stmt->setString(2, ename);
		unsigned int res = this->stmt->executeUpdate();
		if (res > 0)
		{
			cout << "delete - Success" << res << " 行受影响。" << endl;
		}
		
	}
	catch (SQLException ex)
	{
		cout << "Exception thrown for deleteRow" << endl;
		cout << "Error number: " << ex.getErrorCode() << endl;
		cout << ex.getMessage() << endl;
	}

	this->conn->terminateStatement(this->stmt);
}

//插入一行数据
void occiemp::insertRow(EMP emp)
{
	string sqlStmt = "INSERT INTO EMP VALUES (:x1, :x2, :x3, :x4 ,:x5, :x6, :x7,:x8)";
	this->stmt = this->conn->createStatement(sqlStmt);
	try
	{
		this->stmt->setInt(1, emp.empno);
		this->stmt->setString(2, emp.ename);
		this->stmt->setString(3, emp.job);
		this->stmt->setDouble(4, emp.mgr);
		
		this->stmt->setDate(5, Todate(emp.hiredate));
		this->stmt->setDouble(6, emp.sal);
		this->stmt->setDouble(7, emp.comm);
		this->stmt->setInt(8, emp.deptno);
		unsigned int res=this->stmt->executeUpdate();
		if (res >0)
		{
			cout << "Data saved successfully ," << res << " 行数据!" << endl;
		}
	}
	catch (SQLException ex)
	{
		cout << "Exception thrown for insertRow of emp" << endl;
		cout << "Error number: " << ex.getErrorCode() << endl;
		cout << ex.getMessage() << endl;
	}
	this->conn->terminateStatement(this->stmt);//释放SQL语句
}

Date occiemp::Todate(string strtime)
{
	try
	{
		int year = stoi((strtime.substr(0, 4)));
		unsigned int month= stoi((strtime.substr(4,2)));
		unsigned int day= stoi((strtime.substr(6, 2)));
		unsigned int hour = stoi((strtime.substr(8, 2)));
		unsigned int minute = stoi((strtime.substr(10, 2)));
		unsigned int seconds= stoi((strtime.substr(12, 2)));
		Date date(this->env, year, month, day, hour, minute, seconds);
		return date;

	}
	catch (const std::exception& e)
	{
		cout << e.what() << endl;
		return nullptr;
	}
	
	
}

#define WIN32COMMON
#include<cstdlib>
#include"occiemp.h"

using namespace std;
using namespace oracle::occi;


int main(void)
{
	string username = "scott";
	string password = "12345678";
	string srvName = "127.0.0.1:1521/orcl";

	try
	{
		occiemp* emp = new occiemp(username, password, srvName);
		emp->displayAllRows();

		EMP info{ 7777,"whx","MANAGER",7839,"20200607171123",2000,500,10 };
		emp->insertRow(info);
		emp->displayAllRows();
		
		emp->updateRow(7777, 2555.88);

		emp->displayAllRows();

		emp->deleteRow(7777, "whx");

		emp->displayAllRows();

		delete emp;
	}
	catch (const std::exception& e)
	{
		cout << e.what() << endl;
		system("pause");
		return -1;
	}
	


	return 0;
}

oracle 程序员指南:OCCI使用介绍
lynate的博客 http://blog.itpub.net/16203369/viewspace-1116537/

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页
评论

打赏作者

haixin-561

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值