C++ 通过ADO连接Oracle数据库

背景

接触C++以来,因为之前学的java做Web时经常要和数据库打交道,所以也就一直想用C++来操作数据库。之前也听过ODBC数据源的方法听说比较麻烦,C++用ADO的方法连接数据比较方便。

下面就是具体的步骤和代码了。

1.导入ADO的库

使用ADO的话必须要导入它的库,这语句放到头文件.h中,因为我这里是用的MFC程序建的工程,所以我放在stdafx.h头文件中

//导入ADO的库
#import "C:\\Program Files\\Common Files\\System\\ado\\msado15.dll" no_namespace rename("EOF","adoEOF")
  文件msado15.dll可以在你的电脑中的相应路径C:\Program Files\Common Files\System\ado找到;no_namespace 表示没有命名空间,可以不写不过后面的ADO对象要加上ADODB::引入;rename("EOF","adoEOF")是用adoEOF替换EOF ,如果你用到BOF的话也可以通过这种方式替换。

2.在头文件中定义成员变量和成员函数

在AdoDlg.h文件中:

	//定义变量
	 _ConnectionPtr m_conn; //连接智能指针
	 _RecordsetPtr m_rec;//记录集智能指针
	HRESULT hr;
	 // //列表控件变量
	 CListCtrl m_listCtrl;
	 //函数
	  bool AdoOpen(char* userName,char* pwd,char* conStr,char* errStr); //连接数据库
	  //_RecordsetPtr AdoExucute(char* sqlStr); //执行sql语句,操作表
	  bool AdoClose();//关闭数据库
	  void InsertCol();//插入表头
	  void GetRecordSet();//获得记录集
	  void AdoQuery();//查询数据
	  bool AdoAdd();//增加数据
	  bool AdoUpdate();//修改数据
	  bool AdoDelete();//删除数据

3.在使用ADO前要初始化COM类库环境

在AdoDlg.cpp文件中:

a.在构造函数中初始化成员变量

m_conn=NULL;

b.在OnInitDialog()函数中

//初始化COM类库
	//CoInitialize返回的是HRESULT类型的值,返回S_OK(值为0)表示COM初始化成功,
	// 返回S_FALSE(值为1)表示当前线程已经初始化过COM,所以返回S_OK或S_FALSE都是对的
	/*if(FAILED(::CoInitialize(NULL))) 
	{
	MessageBox("初始化COM库失败");
	return FALSE;
	}*/
	AfxOleInit();//MFC工程建议用AfxOleInit();
//控制台建议用CoInitalize(),同时在Close函数或是析构函数中记得调用::CoUninitialize();卸载COM环境;

//MFC工程建议用AfxOleInit();就行了。


4.实现成员函数

 a .建立与数据库的连接

//连接数据库
bool CAdoDBDlg:: AdoOpen(char* userName,char* pwd,char* conStr,char* errStr)
{
	//捕获异常
	try{

		//创建Connection对象的一个实例
		hr=m_conn.CreateInstance(_uuidof(Connection));///创建Connection对象

		//通过用户名、密码以及连接字符串连接数据库
		m_conn->Open(conStr,userName,pwd,NULL);

	}catch(_com_error e)
	{
		MessageBox(e.ErrorMessage());
	}
	return TRUE;
}

b.获得查询的结果集

//获取结果集
void CAdoDBDlg::GetRecordSet()
{
		CString sql= "select * from MEMBERUSER"; //查询的SQL语句
		
		try{
			m_rec.CreateInstance(_uuidof(Recordset));//创建结果集对象
			m_rec->Open(_bstr_t(sql),m_conn.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
		}catch(_com_error e)
		{
			MessageBox(e.Description());
		}
}
aa. ADO中Recordset.Open()参数说明

bb.ADO中数据类型的介绍variant、BSTR

C.也可通过Execute函数来获得结果集

//执行SQL语句
_RecordsetPtr CAdoDBDlg::AdoExucute(char* sqlStr)
{
	try
	{
		if(m_conn==NULL)
		{
			MessageBox("请先连接数据库,再操作!");
			return NULL;
		}

		_variant_t RecordsAffected;//此次操作的记录数
		_RecordsetPtr PRecord;
		//通过sql语句操作数据库并返回结果集指针
		PRecord=m_conn->Execute(_bstr_t(sqlStr),&RecordsAffected,adCmdText);
		 
		/*int IntRecords = RecordsAffected.intVal;
		CString StrRecords="0";
		StrRecords.Format("此次操作了 %d 条数据.",IntRecords);
		AfxMessageBox(StrRecords);*/

		return PRecord;
	}
	catch (_com_error e)
	{
		MessageBox(e.ErrorMessage());
	}

}

D.关闭函数

//关闭数据库连接
bool CAdoDBDlg::AdoClose()
{
	if(m_conn!=NULL)
	{
		m_conn->Close();//关闭连接
		m_conn=NULL;
		m_rec->Close();//关闭结果集
		m_rec=NULL;

		//::CoUninitialize();//卸载COM环境
		
	}

	if(m_conn==NULL)
		return TRUE;
	else
		return FALSE;
}

E.插入列表控件的表头和设置样式

我用的是CListCtrl控件来显示查询到的数据,因为之前做类似Windows任务管理器时就是用的列表控件来显示数据,所以第一就想到了用它来显示表中的数据。

//插入表头
void CAdoDBDlg::InsertCol()
{	//表的列名
	 CString szItem[]={("记录数"),_T("ID"),_T("MemberName"),_T("AccounterNumber"),_T("Age"),_T("Gender"),_T("Birthday"),_T("RoleName"),_T("Pwd"),_T("Integal")};

	 //设置列表控件的样式
	 LONG lStyle;
	 lStyle= GetWindowLong(m_listCtrl.m_hWnd,GWL_STYLE);//获得列表控件的当前样式
	 lStyle &=~LVS_TYPEMASK; //清除显示方式位
	 lStyle |=LVS_REPORT; //设置view属性的值为Report
	 SetWindowLong(m_listCtrl.m_hWnd,GWL_STYLE,lStyle);
	 
	 //设置扩展风格--网格
	 m_listCtrl.SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);

	//设置列表控件的表头
	 int szLength = sizeof(szItem)/sizeof(szItem[0]);//求出数组长度

	 for (int i=0;i<szLength;i++)
	 {
		 m_listCtrl.InsertColumn(i,szItem[i],LVCFMT_RIGHT,70,-1);//向控件中插入表头
	 }


}
aa.遍历数据库中的所有表名和表的所有字段 第 6.7点


5.///增删改查

a.查询

void CAdoDBDlg::AdoQuery()
{
	//查询表中的数据
	m_rec=AdoExucute("SELECT * FROM MEMBERUSER M;");
}

如果使用了GetRecordSet()方法这个函数可以不用,因为Recordset.Open(sql,.....)里面的sql语句就是查询表数据,就可以得到结果集

b.增加数据

//增加数据
bool CAdoDBDlg::AdoAdd()
{
	if(m_conn==NULL)
	{
		MessageBox("数据库尚未连接,请连接后再操作!");
		return FALSE;
	}

	CString strId1,strName,strAccounterName,strAge,strGender,strBirthday,strPwd,strIntegral,strRoleId;
	int strId=12;
	strName="中国人";
	strAccounterName="zgr3";
	strAge="100";
	strGender="男";
        //获取系统当前时间
	SYSTEMTIME st = {0};
	GetLocalTime(&st);
	strBirthday.Format("%d-%02d-%02d %02d:%02d:%02d",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
		
	strPwd="123456";
	strIntegral="120";
	strRoleId="2";

	
	GetRecordSet();//获取记录集

	if(m_rec!=NULL)
	{
		UpdateData(TRUE);
		for(int i=0;i<3;i++)
			{
			strAccounterName.Format("lyx%d",i);//主键唯一,防止重复
			m_rec->AddNew();
			m_rec->PutCollect(_variant_t("MEMBERID"),_variant_t((long)(strId+i)));  <span style="font-family: Arial, Helvetica, sans-serif;">//主键唯一,防止重复</span>
			m_rec->PutCollect(_variant_t("MEMBERNAME"),_variant_t(strName));  
			m_rec->PutCollect(_variant_t("ACCOUNTNUMBER"),_variant_t(strAccounterName));  
			m_rec->PutCollect(_variant_t("AGE"),_variant_t(strAge));  
			m_rec->PutCollect(_variant_t("GENDER"),_variant_t(strGender));  
			m_rec->PutCollect(_variant_t("BIRTHDAY"),_variant_t(strBirthday));  
			m_rec->PutCollect(_variant_t("PWD"),_variant_t(strPwd)); 
			m_rec->PutCollect(_variant_t("MEMBER_INTEGRAL"),_variant_t(strIntegral));  
			m_rec->PutCollect(_variant_t("ROLEID"),_variant_t(strRoleId));  
			
		}
		m_rec->Update();

		return TRUE;

	}else
	{
		return FALSE;
	}
}
注意:

1.如果主键冲突就无法增加数据到数据库中,这个问题要注意,我就出现了这个问题,最后打断点运行才发现。

2.如果你有的字段没有插入,数据库为空,那就查询不出来,比如我因为生日日期类型之前没有想到如何处理,就直接把

m_rec->PutCollect(_variant_t("BIRTHDAY"),_variant_t(strBirthday));这句注释掉了,这样虽然可以正常插入到数据库中,但是当我点击查询按钮时,在数据库中这条数据及其以后的数据都无法在列表控件CListCtrl中显示出来。

c.删除数据

//删除数据
bool CAdoDBDlg::AdoDelete()
{
	if(m_conn==NULL)
	{
		MessageBox("数据库尚未连接,请连接后再操作!");
		return FALSE;
	}
	
	GetRecordSet();
	int pos =m_listCtrl.GetSelectionMark();//获得当前选中列表项索引,获得第几条数据

	try
	{
		m_rec->Move(long(pos),vtMissing);//移到指定的第几条数据
		m_rec->Delete(adAffectCurrent);//删除当前影响的数据
		m_rec->Update();

		return TRUE;
	}
	catch (_com_error e)
	{
		MessageBox(e.Description());
		return FALSE;
	}
}

D.修改数据

//修改
bool CAdoDBDlg::AdoUpdate()
{
	if(m_conn==NULL)
	{
		MessageBox("数据库尚未连接,请连接后再操作!");
		return FALSE;
	}

	UpdateData(TRUE);

	GetRecordSet();//获取记录集
		
	int pos =m_listCtrl.GetSelectionMark();//获得当前选中列表项索引
	try{
		
		m_rec->Move(long(pos),vtMissing);//移到指定条记录
		m_rec->PutCollect(_variant_t("gender"),_variant_t("女"));//修改指定字段的值
		m_rec->Update();//更新到数据库

		return TRUE;
	}catch(_com_error e)
	{
		MessageBox(e.Description());
		return FALSE;
	}
	

}

6.响应按钮函数

//按钮处理函数

//建立连接
void CAdoDBDlg::OnBnClickedBtnAdolink()
{
	// TODO: Add your control notification handler code here
	if(m_conn==NULL)
	{
		删除列表控件中的所有记录
		int ColNum=m_listCtrl.GetHeaderCtrl()->GetItemCount();
		for(int i=ColNum;i>=0;i--) //注意要从后面向前面删除,从前往后删会删不干净
		{
			m_listCtrl.DeleteColumn(i);
		}
		m_listCtrl.DeleteAllItems();//建立连接前删除控件内的所有数据


		连接oracle数据库的连接字符串
		CString connStr="";
		connStr.Format("Provider=OraOLEDB.Oracle.1;User ID=%s;Password=%s;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=%s)(PORT=%s))(CONNECT_DATA=(SERVICE_NAME=%s)));Persist Security Info=False",\
			"XXX", "XXX", "127.0.0.1", "1521", "orcl");//User, Psw, Ip, Port, DataBaseName
<span style="white-space:pre">		</span>// 上文 \ 表示连接上一行
		bool isConn=FALSE;
		isConn=AdoOpen("XXX","XXX",(LPSTR)(LPCSTR)connStr,NULL);//建立连接
		if(isConn)
		{
			MessageBox("连接oracle数据库成功!");

			插入表头
			InsertCol();
		}else
		{
			MessageBox("无法和数据库建立连接!");
		}

	}
}
//断开与数据库的连接
void CAdoDBDlg::OnBnClickedBtnAdobreak()
{
	// TODO: Add your control notification handler code here

	if(AdoClose())
	{
		MessageBox("数据库已断开连接!");
	}else{
		MessageBox("数据库断开失败!");
	}
}



//查询数据库
void CAdoDBDlg::OnBnClickedBtnQuery()
{
	m_rec.CreateInstance(_uuidof(Recordset));//创建记录实例

	
	m_listCtrl.DeleteAllItems();//查询前删除控件内的所有数据

	//先求出表中一共有多少条数据
	_RecordsetPtr recordSet;
	recordSet = AdoExucute("select count(*) from memberUser");
	variant_t count=0;
	_variant_t index=long(0);
	count = recordSet->GetCollect(index);//获得查询到的结果中的值
	int num = count.intVal;//转换成int类型
	// TODO: Add your control notification handler code here
	//AdoQuery();//查询数据
	GetRecordSet();//获取记录集

	int RecordNum=0;//计数
	while (!m_rec->adoEOF)
	{
		variant_t id,name,accounterNumber,age,gender,birthday,roleName,pwd,integral;

		for (int i=0;i<num;i++)
		{
			id= m_rec->GetCollect("memberId");
			name = m_rec->GetCollect("MEMBERNAME");
			accounterNumber=m_rec->GetCollect("ACCOUNTNUMBER");
			age=m_rec->GetCollect("AGE");
			gender=m_rec->GetCollect("GENDER");
			birthday=m_rec->GetCollect("BIRTHDAY");
			roleName=m_rec->GetCollect("ROLEID");
			pwd=m_rec->GetCollect("PWD");
			integral=m_rec->GetCollect("MEMBER_INTEGRAL");

			CString strid,strname,straccounterNumber,strage,strgender,strbirthday,strroleName,strpwd,strintegral,strRecordNum;
			strid=(LPCSTR)_bstr_t(id);
			strname=(LPCSTR)_bstr_t(name);
			straccounterNumber=(LPCSTR)_bstr_t(accounterNumber);
			strage=(LPCSTR)_bstr_t(age);
			strgender=(LPCSTR)_bstr_t(gender);
			strbirthday=(LPCSTR)_bstr_t(birthday);
			strroleName=(LPCSTR)_bstr_t(roleName);
			strpwd=(LPCSTR)_bstr_t(pwd);
			strintegral=(LPCSTR)_bstr_t(integral);

			RecordNum++;
			strRecordNum.Format("%d",RecordNum);


			//插入数据
			m_listCtrl.InsertItem(i,strRecordNum);
			m_listCtrl.SetItemText(i,1,strid);
			m_listCtrl.SetItemText(i,2,strname);
			m_listCtrl.SetItemText(i,3,straccounterNumber);
			m_listCtrl.SetItemText(i,4,strage);
			m_listCtrl.SetItemText(i,5,strgender);
			m_listCtrl.SetItemText(i,6,strbirthday);
			m_listCtrl.SetItemText(i,7,strroleName);
			m_listCtrl.SetItemText(i,8,strpwd);
			m_listCtrl.SetItemText(i,9,strintegral);

			m_rec->MoveNext();
		}

	}
	//AdoClose();//关闭连接
}


//删除
void CAdoDBDlg::OnBnClickedBtnDelete()
{
	// TODO: Add your control notification handler code here
	if(AdoDelete())
	{
		MessageBox("删除成功!");
	}else
	{
		MessageBox("删除失败!");
	}

}



//增加
void CAdoDBDlg::OnBnClickedBtnAdd()
{
	// TODO: Add your control notification handler code here
	// CAddDataDlg m_AddDateDlg;
	 //if(m_AddDateDlg)
		//m_AddDateDlg.DoModal();

	if(AdoAdd())
	{
		MessageBox("增加成功!");
	}else
	{
		MessageBox("增加失败!");
	}


}

//修改
void CAdoDBDlg::OnBnClickedBtnUpdate()
{
	// TODO: Add your control notification handler code here
	
	if(AdoUpdate())
	{
		MessageBox("更新成功!");
	}else
	{
		MessageBox("更新失败!");
	}
}


7.效果界面



版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://www.cnblogs.com/lovelyx/p/4867094.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C ado(ActiveX Data Objects)是一种用于连接数据库的编程技术,可以通过ADO对象来实现远程连接数据库。 远程连接数据库是指通过网络访问并操作位于其他计算机上的数据库。C ado提供了一种简单和高效的方法来连接不同类型数据库,包括Microsoft SQL Server、Oracle、MySQL等。 要实现远程连接数据库,首先需要在C程序引入相关的ADO库文件,并创建ADO连接对象。连接对象可以通过指定数据库连接字符串来传递必要的参数,如服务器地址、数据库名称、用户名和密码等。连接字符串的格式会根据使用的数据库类型而有所不同。 在连接对象创建后,可以使用其方法来建立实际的连接,这样程序就可以发送SQL查询和执行其他操作了。在成功连接后,可以使用SQL语句来执行插入、删除、更新和查询等操作。 连接数据库时,需要确保远程服务器的网络设置允许连接请求,并且目标服务器上的数据库服务处于运行状态。 在完成数据库操作后,应该记得关闭连接,释放资源,这样可以避免占用过多的系统资源和连接数。 总之,使用C ado可以方便地通过网络连接和操作远程数据库。通过适当的配置和编程,可以实现安全和高效的远程数据库连接,并对数据进行操作和管理。 ### 回答2: C ado 是一种用于远程连接数据库的技术。它是基于微软的ActiveX Data Objects(ADO)库开发的,并且是一种用于访问和操作各种数据库的标准接口。通过使用C ado,我们可以实现在应用程序远程连接并操作数据库,以便进行数据的读取、插入、更新和删除等操作。 首先,我们需要在应用程序引入C ado的库文件,并且初始化相关的对象和连接字符串。然后,我们可以使用C ado提供的函数和方法来创建连接对象,打开数据库连接,并执行SQL语句或存储过程等来对数据库进行操作。 在远程连接数据库时,我们需要确保数据库服务器开启远程连接功能,并且在连接字符串指定正确的数据库服务器地址、用户名和密码等信息。在连接成功后,我们就可以通过C ado提供的命令对象来执行SQL语句,例如SELECT语句用于查询数据,INSERT语句用于插入数据,UPDATE语句用于更新数据,DELETE语句用于删除数据等。 C ado还提供了一些其他的功能和特性,比如事务处理、数据类型转换、错误处理等,以便我们进行更加灵活和有效的数据库操作。同时,它还支持多种数据库类型,如SQL Server、Oracle、MySQL等,使得我们可以在不同的数据库系统之间无缝切换。 总的来说,通过C ado,我们可以轻松实现应用程序与远程数据库之间的连接和数据交互,提高数据的访问效率和操作便捷性。它是一种强大而灵活的技术,被广泛应用于各种类型的软件开发。 ### 回答3: cado是一种用于远程连接数据库的工具。它可以在计算机之间建立网络连接,并通过网络连接到远程数据库服务器。通过使用cado,用户可以在本地计算机上访问和操作远程数据库的数据。 cado提供了一种简单而有效的方法来连接和管理远程数据库。用户只需要提供远程数据库服务器的IP地址、用户名和密码,就可以使用cado建立连接。一旦连接建立成功,用户就可以执行各种数据库操作,例如查询、插入、更新和删除数据。 与传统的本地数据库相比,cado的远程连接功能具有许多优势。首先,它可以让用户从任何地方远程访问数据库,无论是在同一网络内还是在跨越不同地区的网络。这使得多人合作和远程工作变得更加容易和灵活。 其次,使用cado进行远程连接可以提高数据库的安全性。通过仅允许经过身份验证的用户访问数据库,远程连接可以帮助防止未经授权的访问和数据泄漏。 另外,cado还提供了许多其他的功能和工具,如数据备份和恢复、数据库管理和性能优化等。这些功能可以帮助用户更好地管理和使用远程数据库。 总而言之,cado是一种用于远程连接数据库的工具,它提供了一种方便、安全和灵活的方式来访问和操作远程数据库的数据。无论是为了多人合作、远程工作还是为了提高数据库的安全性,cado都是一个非常有用的工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值