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

VC++下使用ADO编写数据库程序
VC ++下使用 ADO 编写数据库程序
 
准备:
( 1 )、引入 ADO    

 在stdafx.h中加入如下语句:
#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 )连接  
一般在 App 类成员函数 InitInstance ()里初始化
例子:连接 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 ); ///显示错误信息
         
return FALSE ;
           
}
 
 
( 2 )、关闭  
 
一般在 App 类成员函数 InitInstance ()里关闭数据库连接
//如果数据库连接有效
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 ();
  m_pRecordset
= NULL ;
 
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 ( "Name" , _variant_t ( m_szName ));给每个字段赋值( m_szName 为控件所对应的字符串变量)
c
)、调用 m_pRecordset -> Update ();确认
 
// 添加完后可读取显示
 
对于 MFC 有些控件显示需要更新(比如 ListBox )

( 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 ); ///显示错误信息
           
}

你可能感兴趣的:(VC++下使用ADO编写数据库程序)