VC中使用ADO操作数据库的方法(比较详细)

37 篇文章 0 订阅

参考:http://blog.csdn.net/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();

(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语句

(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:未知,或默认

try 
{ 
	m_pCommand->CommandText ="INSERT INTO tTest(age) VALUES('23f2') "; 
	m_pRecordset = m_pCommand->Execute(NULL,NULL, adCmdText); 
}
//捕捉异常 
catch(_com_error e)
{
	//显示错误信息 
	AfxMessageBox(e.ErrorMessage());
}

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直接调用

特殊应用:

显示数据库、表信息

使用_ConnectionPtr 的成员函数openSchema()可以获取数据库的模式信息;

函数原型:

_RecordsetPtr recordset = connection.OpenSchema (QueryType, Criteria, SchemaID)
参数:

1. QueryType

SchemaEnum枚举类型的值,指出获取模式(Schema)的类型;

2. Criteria

可选项,对应SchemaEnum的查询选项

3. SchemaID

可选项,仅当 QueryType 被设置为adSchemaProviderSpecific 的时候才有用,否则不使用该参数; 

SchemeEnum枚举类型的常用取值如下:

adSchemaColumns:返回用户可访问的数据库目录中表的列名(包括视图View);

返回结果集中的列名(字段名):

TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
COLUMN_NAME

adSchemaTables:返回用户可访问的数据库目录中的表名;

返回结果集中的列名(字段名):

TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
TABLE_TYPE

示例1:遍历数据库中的所有表名;

_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());
}

示例2:遍历一个表中的所有字段

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();//释放指针 
	}
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值