zoukankan      html  css  js  c++  java
  • VC++下使用ADO编写数据库程序(关键文章)

     
    标题 VC++下使用ADO编写数据库程序
    类别 编程珠矶
    日期 07年02月09日
    长度 9298 Bytes [Copy to clipboard]
    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)连接  
    一般在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);
    2BSTR宽字符串与CString相互转换
     
    BSTR  bstr
    ;
    CString  strSql;
    CString  ->  BSTR:  bstr  =  strSql.AllocSysString();
    BSTR  
    ->  CString:  strSql  =  (LPCSTR)bstr;
    3_bstr_tCString相互转换
     
    _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);///显示错误信息
               
    }
    CopyRight By CoolDiyer All Rights Reserved
  • 相关阅读:
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十四)定义一个avro schema使用comsumer发送avro字符流,producer接受avro字符流并解析
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十三)kafka+spark streaming打包好的程序提交时提示虚拟内存不足(Container is running beyond virtual memory limits. Current usage: 119.5 MB of 1 GB physical memory used; 2.2 GB of 2.1 G)
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十二)VMW安装四台CentOS,并实现本机与它们能交互,虚拟机内部实现可以上网。
    Hadoop:安装ftp over hdfs
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十一)定制一个arvo格式文件发送到kafka的topic,通过Structured Streaming读取kafka的数据
    Hadoop:开发机运行spark程序,抛出异常:ERROR Shell: Failed to locate the winutils binary in the hadoop binary path
    自动化运维工具——ansible详解(一)
    缓存雪崩和缓存穿透问题解决方案
    Redis 和 Memcached 的区别
    mongo之 前后台创建索引 --noIndexBuildRetry
  • 原文地址:https://www.cnblogs.com/cy163/p/700596.html
Copyright © 2011-2022 走看看