VC++下使用ADO编写数据库程序

VC++下使用ADO编写数据库程序

准备:
(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
{
hr   =   m_pConnection.CreateInstance( "ADODB.Connection ");///创建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( "连接数据库失败!\r\n错误信息:%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));

//   在ADO操作中建议语句中要常用try...catch()来捕获错误信息,
//   因为它有时会经常出现一些意想不到的错误。jingzhou   xu
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)
{
var   =   m_pRecordset-> GetCollect( "Name ");
if(var.vt   !=   VT_NULL)
strName   =   (LPCSTR)_bstr_t(var);
var   =   m_pRecordset-> GetCollect( "Age ");
if(var.vt   !=   VT_NULL)
strAge   =   (LPCSTR)_bstr_t(var);
m_AccessList.AddString(   strName   +   "   -->   "+strAge   );
m_pRecordset-> MoveNext();
}

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

一是

//表示取得第0个字段的值   m_pRecordset-> GetCollect( "Name ");

或者   m_pRecordset-> GetCollect(_variant_t(long(0));

二是
pRecordset-> get_Collect( "COLUMN_NAME ");

或者   pRecordset-> get_Collect(long(index));

(2)、添加

a)、调用m_pRecordset-> AddNew();
b)、调用m_pRecordset-> PutCollect();给每个字段赋值
c)、调用m_pRecordset-> Update();确认

(3)、修改
(4)、删除
a)、把记录指针移动到要删除的记录上,然后调用Delete(adAffectCurrent)   try
{
//   假设删除第二条记录
m_pRecordset-> MoveFirst();
m_pRecordset-> Move(1);                
//   从0开始
m_pRecordset-> Delete(adAffectCurrent);    
//   参数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   Connection15::Execute   (   _bstr_t   CommandText,  
                                                                            VARIANT   *   RecordsAffected,  
                                                                            long   Options   )  

其中CommandText是命令字串,通常是SQL命令。  
参数RecordsAffected是操作完成后所影响的行数,  
参数Options表示CommandText中内容的类型,Options可以取如下值之一:  
adCmdText:表明CommandText是文本命令  
adCmdTable:表明CommandText是一个表名  
adCmdProc:表明CommandText是一个存储过程  
adCmdUnknown:未知

例子:
_variant_t   RecordsAffected;
m_pConnection-> Execute( "UPDATE   users   SET   old   =   old+1 ",&RecordsAffected,adCmdText);  
5.调用存储过程
(1)、利用_CommandPtr
_CommandPtr m_pCommand;
m_pCommand.CreateInstance(__uuidof(Command));
m_pCommand-> ActiveConnection   =   m_pConnection;     //   将库连接赋于它
m_pCommand-> CommandText   =   "Demo ";    
m_pCommand-> Execute(NULL,NULL,   adCmdStoredProc);    
(2)、直接用_ConnectionPtr直接调用(见4.(2))

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)///捕捉异常  
{    
CString   errormessage;    
errormessage.Format( "连接数据库失败!rn错误信息:%s ",e.ErrorMessage());

AfxMessageBox(errormessage);
return   -1;
}
7.遍历一个表中的所有字段
Field   *       field   =   NULL;
HRESULT       hr;
Fields   *     fields   =   NULL;
hr   =   m_pRecordset-> get_Fields   (&fields); //得到记录集的字段集和
 
if(SUCCEEDED(hr))  
        fields-> get_Count(&ColCount);

//得到记录集的字段集合中的字段的总个数
for(i=0;iItem[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( "连接数据库失败!\r\n错误信息:%s ",e.ErrorMessage());
AfxMessageBox(errormessage);///显示错误信息
}
posted @ 2011-04-21 14:16  Yaoquan.Luo  阅读(221)  评论(0编辑  收藏  举报