VC中使用ADO操作数据库的方法

本文详细介绍ADO类在数据库操作中的使用方法,包括连接数据库、打开结果集、操作结果集、执行SQL语句及调用存储过程等核心功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://blog.youkuaiyun.com/augusdi/article/details/7005597

讲解详细而且全面

准备工作

(1)、引入ADO类

#import "c:\program files\common files\system\ado\msado15.dll"  no_namespace rename ("EOF", "adoEOF")

(2)、初始化COM

在MFC中可以用  AfxOleInit();

非MFC环境中用  CoInitialize(NULL);/ CoUnInitialize(); / CoInitialize(NULL); /CoUnInitialize();

(3)#import 包含后就可以用3个智能指针了:_ConnectionPtr、_RecordsetPtr和_CommandPtr

1.连接和关闭数据库

(1)连接

例子:连接Access数据库

//初始化
AfxOleInit();

HRESULT hr;
try
{
	///创建Connection对象
	hr = m_pConnection.CreateInstance("ADODB.Connection");
	if(SUCCEEDED(hr))
	{
		m_pConnection->ConnectionTimeout = 0;
		hr = m_pConnection->Open( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db.mdb", "", "", adModeUnknown);
		//m_pConnection->PutDefaultDatabase ((_bstr_t)"DB"); //设置默认数据库
		m_pCommand.CreateInstance(__uuidof(Command));
		m_pCommand->CommandTimeout = 5;
		m_pCommand->ActiveConnection = m_pConnection;
	}
}
catch(_com_error e)///捕捉异常
{
	CString errormessage;
	errormessage.Format(" 连接数据库失败! 错误信息:%s",e.ErrorMessage());
	AfxMessageBox(errormessage);///显示错误信息
}

(2)、关闭

//如果数据库连接有效
if( m_pConnection->State )
m_pConnection->Close();
m_pConnection = NULL; 

(3)、设置连接时间

//设置连接时间
pConnection->put_ConnectionTimeout(long(5));

2.打开一个结果集

(1)打开,首先创建一个_RecordsetPtr实例,然后调用Open()得到一条SQL语句的执行结果

_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance(__uuidof(Recordset));
try
{
	m_pRecordset->Open("SELECT * FROM DemoTable",// 查询DemoTable表中所有字段
                        m_pConnection.GetInterfacePtr(), // 获取库接库的IDispatch指针
                        adOpenDynamic,
                        adLockOptimistic,
                        adCmdText);
}
catch(_com_error *e)
{
	AfxMessageBox(e->ErrorMessage());
} 

(2)关闭结果集
m_pRecordset->Close();

3.操作一个结果集

(1)、遍历(读取)

a)、用pRecordset->adoEOF来判断数据库指针是否已经移到结果集的末尾了;

            m_pRecordset->BOF判断是否在第一条记录前面:

while(!m_pRecordset->adoEOF)
{
	//获取字段值
	_variant_t var = m_pRecordset->GetCollect("Name");
	if(var.vt != VT_NULL)
	{
		CString strName = (LPCSTR)_bstr_t(var);
	}
	
	var = m_pRecordset->GetCollect("Age");
	if(var.vt != VT_NULL)
	{
		CString strAge = (LPCSTR)_bstr_t(var);
	}

	m_pRecordset->MoveNext();
} 

b)、取得一个字段的值的办法有两种办法

第一种:

//表示取得第0个字段的值
rdset->GetCollect("Name");
// 或者
rdset->GetCollect(_variant_t(long(0));

第二种

pRecordset->get_Collect("COLUMN_NAME");
//或者
pRecordset->get_Collect(long(index));

(2)、添加

调用m_pRecordset->AddNew();

调用m_pRecordset->PutCollect();给每个字段赋值

调用m_pRecordset->Update();确认

(3)、修改

调用m_pRecordset->PutCollect();给每个字段赋值

调用m_pRecordset->Update();确认

(4)、删除

把记录指针移动到要删除的记录上,然后调用Delete(adAffectCurrent)

try
{
	// 假设删除第二条记录
	m_pRecordset->MoveFirst();
	//从当前位置向下移动一条记录
	m_pRecordset->Move(1); 
	//参数adAffectCurrent 为删除当前记录
	m_pRecordset->Delete(adAffectCurrent); 
	m_pRecordset->Update();
}
catch(_com_error *e)
{
	AfxMessageBox(e->ErrorMessage());
}

4.直接执行SQL语句,除了要用到结果集其余的大部分功能都可以直接用SQL语言实现

(1)、用_CommandPtr和_RecordsetPtr配合

_CommandPtr m_pCommand;
m_pCommand.CreateInstance(__uuidof(Command));
// 将库连接赋于它
m_pCommand->ActiveConnection = m_pConnection; 
// SQL语句
m_pCommand->CommandText = "SELECT * FROM DemoTable"; 
// 执行SQL语句,返回记录集
m_pRecordset = m_pCommand->Execute(NULL, NULL,adCmdText); 

(2)、直接用_ConnectionPtr执行SQL语句

_RecordsetPtr Connection::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )

参数:

RecordsAffected是操作完成后所影响的行数;

Options表示CommandText中内容的类型,Options可以取如下值之一:

adCmdText:表明CommandText是文本命令,通常是SQL语句;

adCmdTable:表明CommandText是一个表名;

adCmdProc:表明CommandText是一个存储过程

adCmdUnknown:未知,或默认

5.调用存储过程

(1)、利用_CommandPtr

_CommandPtrm_pCommand;
m_pCommand.CreateInstance(__uuidof(Command));
//将库连接赋于它
m_pCommand->ActiveConnection = m_pConnection; 
m_pCommand->CommandText = "Demo"; 
m_pCommand->Execute(NULL,NULL, adCmdStoredProc); 

(2)、直接用_ConnectionPtr直接调用

6.遍历数据库中的所有表名

_ConnectionPtr m_pConnect;

_RecordsetPtr pSet;
HRESULT hr;
try
{ 
	hr = m_pConnect.CreateInstance("ADODB.Connection"); 
	if(SUCCEEDED(hr)) 
	{
		CString dd; 
		dd.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s",file);
		hr=m_pConnect->Open((_bstr_t)dd, "", "", adModeUnknown); 
		pSet=m_pConnect->OpenSchema(adSchemaTables); 
		while(!(pSet->adoEOF)) 
		{ 
			//获取表格 
			_bstr_t table_name = pSet->Fields->GetItem("TABLE_NAME")->Value;
			//获取表格类型
			_bstr_t table_type = pSet->Fields->GetItem("TABLE_TYPE")->Value;
			//过滤一下,只输出表格名称,其他的省略
			if(strcmp(((LPCSTR)table_type),"TABLE")==0)
			{
				CString tt;
				tt.Format("%s",(LPCSTR)table_name); 
				AfxMessageBox(tt); 
			} 
			pSet->MoveNext(); 
		} 
		pSet->Close(); 
	} 

	m_pConnect->Close(); 
}
//捕捉异常
catch(_com_error e)
{
	AfxMessageBox(e.ErrorMessage());
}

7.遍历一个表中的所有字段

HRESULT hr;
Fields * fields = NULL;
//得到记录集的字段集,并存储在fields中
hr=m_pRecordset->get_Fields(&fields);

if(SUCCEEDED(hr))
{
	//得到记录集的字段集合中的字段的总个数
	fields->get_Count(&ColCount);

	for(i=0;i ...
	{
		Item[i]->get_Name(&bstrColName);//得到记录集//中的字段名
		strColName=bstrColName;
		nameField = strColName;
		m_FieldsList.AddString(nameField);
	}
	if(SUCCEEDED(hr))
	{
		fields->Release();//释放指针 
	}
}

附:

1、_variant_t

(1)、一般传给这3个指针的值都不是MFC直接支持的数据类型,而要用_variant_t转换一下

_variant_t(XX)可以把大多数类型的变量转换成适合的类型传入

(2)、_variant_t var;

_variant_t -> long: (long)var;

_variant_t -> CString: CString strValue = (LPCSTR)_bstr_t(var);

CString -> _variant_t: _variant_t(strSql);

2、BSTR宽字符串与CString相互转换

BSTR bstr;

CString strSql;

CString -> BSTR: bstr = strSql.AllocSysString();

BSTR -> CString: strSql = (LPCSTR)bstr;

3、_bstr_t与CString相互转换

_bstr_t bstr;

CString strSql;

CString -> _bstr_t: bstr = (_bstr_t)strSql;

_bstr_t -> CString: strSql = (LPCSTR)bstr;

4、关于时间

Access:表示时间的字符串#2004-4-5#

Sql:表示时间的字符串''2004-4-5''

DateField(时间字段)

select * from my_table where DateField > #2004-4-10#

try
{
m_pCommand->CommandText = "INSERT INTO tTest(age) VALUES('23f2') ";
m_pRecordset = m_pCommand->Execute(NULL,NULL, adCmdText);
}
catch(_com_error e)///捕捉异常
{
CString errormessage;
errormessage.Format("连接数据库失败! 错误信息:%s",e.ErrorMessage());
AfxMessageBox(errormessage);///显示错误信息
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值