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

    2 楼wangjia184(我就是传说中的。。。。。。SB)回复于 2005-04-29 08:53:28 得分 0

    ODBC链接  
       
      适合数据库类型   链接方式    
      access   "Driver={microsoft   access   driver(*.mdb)};dbq=*.mdb;uid=admin;pwd=pass;"    
      dBase     "Driver={microsoft   dbase   driver(*.dbf)};driverid=277;dbq=------------;"    
      Oracle     "Driver={microsoft   odbc   for   oracle};server=oraclesever.world;uid=admin;pwd=pass;"    
      MSSQL   server   "Driver={sql   server};server=servername;database=dbname;uid=sa;pwd=pass;"    
      MS   text     "Driver={microsoft   text   driver(*.txt;   *.csv)};dbq=-----;extensions=asc,csv,tab,txt;Persist   SecurityInfo=false;"    
      Visual   Foxpro   "Driver={microsoft   Visual   Foxpro   driver};sourcetype=DBC;sourceDB=*.dbc;Exclusive=No;"    
      MySQL   "Driver={mysql};database=yourdatabase;uid=username;pwd=yourpassword;option=16386;"    
       
       
      OLEDB链接  
       
      适合的数据库类型   链接方式    
      access   "Provider=microsoft.jet.oledb.4.0;data   source=your_database_path;user   id=admin;password=pass;"    
      Oracle   "Provider=OraOLEDB.Oracle;data   source=dbname;user   id=admin;password=pass;"    
      MS   SQL   Server   "Provider=SQLOLEDB;data   source=machinename;initial   catalog=dbname;userid=sa;password=pass;"    
      MS   text     "Provider=microsof.jet.oledb.4.0;data   source=your_path;Extended   Properties'text;FMT=Delimited'"    

  • 相关阅读:
    鼠标不灵了,还好只是线的问题。自己DIY修下了
    [摘]编译MPlayer
    TPLINK路由器 硬重启方法
    Visual C++线程同步技术剖析 (转载)
    CListCtrl一行显示多个图标问题
    一位软件工程师的6年总结
    CCIE红头发讲解CCNA、CCNP视频教程
    图片链
    [摘]如何级联两个TPLINK路由器
    [摘]测试一下你对IP地址的掌握水平
  • 原文地址:https://www.cnblogs.com/smallmuda/p/1358088.html
Copyright © 2020-2023  润新知