• VC中使用ADO操作数据库的方法(转)


    VC中使用ADO操作数据库的方法

    准备工作

    (1)、引入ADO类

    1. #import "c:\program files\common files\system\ado\msado15.dll" \
    2.     no_namespace \
    3.     rename ("EOF""adoEOF"

    (2)、初始化COM

        在MFC中可以用AfxOleInit();非MFC环境中用:
    1. CoInitialize(NULL);
    2. CoUnInitialize(); 

    (3)#import 包含后就可以用3个智能指针了:_ConnectionPtr、_RecordsetPtr和_CommandPtr

    1.连接和关闭数据库

    (1)连接

        例子:连接Access数据库
    1. AfxOleInit();//初始化
    2. HRESULT hr;
    3. try
    4. {
    5.     hr = m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象
    6.     if(SUCCEEDED(hr))
    7.     {
    8.         m_pConnection->ConnectionTimeout = 0;
    9.         hr = m_pConnection->Open( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db.mdb""""", adModeUnknown);
    10.         //m_pConnection->PutDefaultDatabase ((_bstr_t)"DB");//设置默认数据库
    11.         m_pCommand.CreateInstance(__uuidof(Command));
    12.         m_pCommand->CommandTimeout = 5;
    13.         m_pCommand->ActiveConnection = m_pConnection;
    14.     }
    15. }
    16. catch(_com_error e)///捕捉异常
    17. {
    18.     CString errormessage;
    19.     errormessage.Format("连接数据库失败! 错误信息:%s",e.ErrorMessage());
    20.     AfxMessageBox(errormessage);///显示错误信息

    (2)、关闭

    1. //如果数据库连接有效
    2. if( m_pConnection->State )
    3.     m_pConnection->Close();
    4. m_pConnection = NULL;  

    (3)、设置连接时间 
     

    1. //设置连接时间-----------------------------------
    2.     pConnection->put_ConnectionTimeout(long(5));

    2.打开一个结果集

    (1)打开,首先创建一个_RecordsetPtr实例,然后调用Open()得到一条SQL语句的执行结果

    1. _RecordsetPtr m_pRecordset;
    2. m_pRecordset.CreateInstance(__uuidof(Recordset));
    3. // 在ADO操作中建议语句中要常用try...catch()来捕获错误信息,
    4. // 因为它有时会经常出现一些意想不到的错误。jingzhou xu
    5. try
    6. {
    7.     m_pRecordset->Open("SELECT * FROM DemoTable",// 查询DemoTable表中所有字段
    8.         m_pConnection.GetInterfacePtr(),  // 获取库接库的IDispatch指针
    9.         adOpenDynamic,
    10.         adLockOptimistic,
    11.         adCmdText);
    12. }
    13. catch(_com_error *e)
    14. {
    15.     AfxMessageBox(e->ErrorMessage());

    (2)关闭结果集

    1. m_pRecordset->Close(); 

    3.操作一个结果集

    (1)、遍历(读取)

        a)、用pRecordset->adoEOF来判断数据库指针是否已经移到结果集的末尾了;m_pRecordset->BOF判断是否 在第一条记录前面:

    1. while(!m_pRecordset->adoEOF)
    2. {
    3.     var = m_pRecordset->GetCollect("Name");
    4.     if(var.vt != VT_NULL)
    5.     strName = (LPCSTR)_bstr_t(var);
    6.     var = m_pRecordset->GetCollect("Age");
    7.     if(var.vt != VT_NULL)
    8.     strAge = (LPCSTR)_bstr_t(var);
    9.     m_AccessList.AddString( strName + " --> "+strAge );
    10.     m_pRecordset->MoveNext();

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

        一是
    1.  //表示取得第0个字段的值
    2. rdset->GetCollect("Name");
    3. // 或者
    4. rdset->GetCollect(_variant_t(long(0));

        二是
    1. pRecordset->get_Collect("COLUMN_NAME");
    2.         //或者 
    3. pRecordset->get_Collect(long(index)); 

    (2)、添加

    1.     调用m_pRecordset->AddNew();
    2.     调用m_pRecordset->PutCollect();给每个字段赋值
    3.     调用m_pRecordset->Update();确认

    (3)、修改

    (4)、删除

        a)、把记录指针移动到要删除的记录上,然后调用

    1. Delete(adAffectCurrent)
    2. try
    3. {
    4.     // 假设删除第二条记录
    5.     m_pRecordset->MoveFirst();
    6.     m_pRecordset->Move(1);       
    7.     // 从0开始
    8.     m_pRecordset->Delete(adAffectCurrent); 
    9.     // 参数adAffectCurrent为删除当前记录
    10.     m_pRecordset->Update();
    11. }
    12. catch(_com_error *e)
    13. {
    14.     AfxMessageBox(e->ErrorMessage());

    4.直接执行SQL语句,除了要用到结果集其余的大部分功能都可以直接用SQL语言实现

    (1)、用_CommandPtr和_RecordsetPtr配合

    1. _CommandPtr m_pCommand;
    2. m_pCommand.CreateInstance(__uuidof(Command));
    3. // 将库连接赋于它
    4. m_pCommand->ActiveConnection = m_pConnection; 
    5. // SQL语句
    6. m_pCommand->CommandText = "SELECT * FROM DemoTable"
    7. // 执行SQL语句,返回记录集
    8. m_pRecordset = m_pCommand->Execute(NULL, NULL,adCmdText); 

    (2)、直接用_ConnectionPtr执行SQL语句

    1. _RecordsetPtr Connection15::Execute ( _bstr_t CommandText,
    2.     VARIANT * RecordsAffected,
    3.     long Options ) 

        其中CommandText是命令字串,通常是SQL命令。
        参数RecordsAffected是操作完成后所影响的行数,
        参数Options表示CommandText中内容的类型,Options可以取如下值之一:
    •         adCmdText:表明CommandText是文本命令
    •         adCmdTable:表明CommandText是一个表名
    •         adCmdProc:表明CommandText是一个存储过程
    •         adCmdUnknown:未知
        例子:
    1. _variant_t RecordsAffected;
    2. m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText); 

    5.调用存储过程

    (1)、利用_CommandPtr

    1. _CommandPtrm_pCommand;
    2. m_pCommand.CreateInstance(__uuidof(Command));
    3. m_pCommand->ActiveConnection = m_pConnection;  // 将库连接赋于它
    4. m_pCommand->CommandText = "Demo"
    5. m_pCommand->Execute(NULL,NULL, adCmdStoredProc); 

    (2)、直接用_ConnectionPtr直接调用(见4.(2))

    6.遍历数据库中的所有表名

    1. _ConnectionPtr m_pConnect;
    2.  
    3. _RecordsetPtr pSet;
    4. HRESULT hr;
    5. try
    6.     hr = m_pConnect.CreateInstance("ADODB.Connection");   
    7.     if(SUCCEEDED(hr)) 
    8.     {
    9.         CString dd; 
    10.         dd.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s",file); 
    11.         hr = m_pConnect->Open((_bstr_t)dd,"","",adModeUnknown); 
    12.         pSet = m_pConnect->OpenSchema(adSchemaTables);     
    13.         while(!(pSet->adoEOF)) 
    14.         {       
    15.             //获取表格   
    16.             _bstr_t table_name = pSet->Fields->GetItem("TABLE_NAME")->Value;
    17.             //获取表格类型       
    18.             _bstr_t table_type = pSet->Fields->GetItem("TABLE_TYPE")->Value;
    19.             //过滤一下,只输出表格名称,其他的省略
    20.             if ( strcmp(((LPCSTR)table_type),"TABLE")==0){
    21.                 CString tt;
    22.                 tt.Format("%s",(LPCSTR)table_name);   
    23.                 AfxMessageBox(tt);       
    24.             }     
    25.             pSet->MoveNext();   
    26.         } 
    27.         pSet->Close(); 
    28.     } 
    29.     m_pConnect->Close(); 
    30. }catch(_com_error e)///捕捉异常
    31.     CString errormessage; 
    32.     errormessage.Format("连接数据库失败!rn错误信息:%s",e.ErrorMessage());
    33.     AfxMessageBox(errormessage);
    34.     return -1;

    7.遍历一个表中的所有字段

    1. Field *  field = NULL;
    2. HRESULT  hr;
    3. Fields *  fields = NULL;
    4. hr = m_pRecordset->get_Fields (&fields);//得到记录集的字段集和
    5.  
    6. if(SUCCEEDED(hr))
    7.     fields->get_Count(&ColCount);
    8. //得到记录集的字段集合中的字段的总个数
    9. for(i=0;i ...
    10.     Item[i]->get_Name(&bstrColName);//得到记录集//中的字段名
    11.     strColName=bstrColName;
    12.     nameField = strColName;
    13.     m_FieldsList.AddString(nameField);
    14. }
    15. if(SUCCEEDED(hr))
    16.     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("连接数据库失败! 错误信息:%s",e.ErrorMessage());
            AfxMessageBox(errormessage);///显示错误信息
        }
  • 相关阅读:
    Delphi 日期函数的单元 DateUtils
    学习官方示例 SysUtils.DecodeDate、DecodeTime
    msp430的常量可以这样定义
    学习官方示例 SysUtils.EncodeDate、EncodeTime、StrToDate、StrToTime、StrToDateTime
    Delphi中Format与FormatDateTime函数详解
    csdn太慢了搬到园子里来
    .net 2.0 真的能与1.1 安全正确地运行在同一台电脑上吗?
    照着这些做,生活自然很开心
    【转】SQL中取当前记录的ID>SCOPE_IDENTITY()
    [转]Windows XP Service Pack 2中弹出窗口拦截器的研究
  • 原文地址:https://www.cnblogs.com/feng801/p/1394196.html
Copyright © 2020-2023  润新知