• VC中使用ADO的方法


    ADO中打开一个连接:

    pConnection->ConnectionString = "这里的字符串有下面四种写法";      //对连接字符串赋值

    pConnection->Open(ConnectionString,"","",adModeUnknown);       //连接数据库

    第二三个参数分别为用户的ID与密码,因为在连接字符串ConnectionCstring中已经设置好了,这里可以为空。

    第四个参数可以取下面两个参数:adAsyncConnect,异步打开数据库,在ASP中直接用16。    adConnectUnspecified,同步打开数据库,在ASP中直接用-1。

    ConnectionString根据不同的数据源,分别对应不同的写法(要记下来很困难,可以在VB中利用ADO控件先连接好,再将其拷贝在VC中,这样不容易出错)

      1访问Access 2000

        "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=databaseName;User ID=userName;Password=userPassWord"

      2)访问ODBC数据

        "Provider=MADASQL;DSN=dsnName;UID=userName;PWD=userPassword;"

      3)访问Oracle数据库

        “Provider=MSDAORA;Data Sourse=serverName;User ID=userName;Password=userPassword;"

      4)访问MS SQL数据库

        "Provider=SQLOLEDB,Data Source=serverName;Initial Catalog=databaseName;User ID=userName;Password=userPassword;"

      

    使用ADO开发应用程序有两种方法,一种是直接在应用程序中使用ADO数据控件,该方法最简单,无需编写一行代码即可实现对数据库的访问,另一种方法是直接使用ADO对象实现对数据库的操作,该方法较复杂,但可以让程序员更深入的控制数据库。   
     一.使用ActiveX控件建立应用程序   
        该方法需要两个ActiveX控件:Microsoft   ADO   Data   Control   ,version   6.0(OLE   DB)和Microsoft   ADO   DataGrid   Control   ,version   6.0(OLE   DB)。下面我们就使用这两个控件,建立一个访问SQL   Server   7.0数据库的应用程序,步骤如下:   
    1.启动VC6.0,使用MFC   AppWizard建立一个单文档应用程序,命为AdoCtl,在Step1到Step   5中使用缺设置,直接按Next即可,在Step   6中,选择视图类的基类为CFormView,然后按Finish,按OK,生成应用程序框架;   
    2.在应用程序的ResourceView中,删除IDD_ADOCTL_FORM对话框中自动生成的静态文本,然后在该对话框的编辑窗口中击鼠标右键,在弹出的快捷菜单中选择Insert   ActiveX   Control...命令;   
    3.在接下来的Insert   ActiveX   Control对话框中选择Microsoft   ADO   Data   Control   ,version   6.0(OLE   DB),按OK,就可以将该控件插入到对话框中。   
    4.重复步骤2、3,在对话框中插入Microsoft   ADO   DataGrid   Control   ,version   6.0(OLE   DB)控件;   
    5.选中Data控件,击右键,设置该控件的属性;   
    6.选择Control页面,该属性页要连接的数据源,其中提供了3种连接数据源的方法:   
    a.使用数据连接文件(Use   Data   Link   File);   
    b.使用ODBC数据源(Use   ODBC   Data   Source   Name);   
    c.使用连接字符串(Use   Connection   String).。   
    在本程序中,我们使用连接字符串,连接SQL   Server7.0数据库。连接字符串中包含了程序与数据源的连接信息,其形式为Argument=Value,每个连接字符串可以包含多个Argument=Value表达式,不同的表达式之间以分号间隔,如访问SFJ55.MDB数据库的连接字符串可以写成如下形式:   
    Provider=Microsoft.Jet.OLEDB.4.0;Data   Source=e:\\sfj55.mdb   
    ADO支持如下的四种连接字符串的属性设置:   
        
        
        
      选择Use   Connection   String选项,按Build...钮,在数据链接属性对话框中选择OLE   DB   Provider(OLE   DB提供者),此处我们选择Microsoft   OLE   DB   Provider   for   SQL   Server,按下一步;   
    7.在连接属性页中输入服务器名称,笔者使用NT工作站,名称为BUILDER,SQL   Server装在本机,故此处服务器名称为BUILDER,再选择使用Windows   NT集成安全设置,在服务器上选择数据库,笔者选择DcProduct,这是一个存放生产明细的数据库。测试连接成功后按确定。也可以选择SQL   Server   7.0自带的其他数据库和数据表。   
    8.选择Data控件属性的RecordSource属性页,其中Command   Type   中有4个选项:   
        
        
      对于SQL语句和数据表名,使用过Access97的读者一定很熟悉,至于存储过程的有关信息请参考SQL   Server的有关书籍。此处我们选择2-adCmdTable,表名选择[SFJ55-27-00-000MX](注意在表名两边加中括号),关闭属性对话框。Data控件属性设置完毕;   
    9.选择DataGrid控件,击右键,设置该控件的属性;   
    10.选择All属性页,设置DataSource属性,设置为Data控件的ID号,即IDC_ADODC1,关闭属性对话框;   
    11.编译并运行应用程序,即可在DataGrid控件中显示数据表SFJ55-27-00-000MX中的数据。   
    到此为止,我们在VC6.0中使用ADO技术建立的最简单的应用程序已经完成,整个过程中没有编写一行代码。只是该程序只能浏览和修改数据,不能对记录进行添加和删除。如果想增加充足添加和删除记录的功能,在DataGrid控件的All属性页中,设置AllowAddNew和AllowDelete属性为TRUE。   
    这中方法尽管简单,但是对数据库的访问效率较低,使用起来也不灵活,程序员对数据库的控制较少,不能最大限度的发挥ADO技术高速灵活的特点。下面通过一个实例来介绍在VC6.0中使用ADO对象访问SQL   Server数据库。   


    二.使用ADO对象建立数据库应用程序   
      在VC中使用过DAO的读者对于CDaoWorkspace,CDaoDatabase,CDaoRecordset,CDaoTableDef等MFC类应该非常熟悉,然而,遗憾的是VC中并没有提供有关ADO对象的类,那么我们将怎样使用ADO对象呢?实际上,这可以通过在应用程序中使用预编译指令#import来引入相关类的指针。在使用ADO对象之前必须首先在程序中加入如下的代码:   
        
    #define   INITGUID //定义有关的变量   
    #import   "C:\program   files\common   files\system\ado\msado15.dll"rename_namespace("ADOCG")rename("EOF","EndOfFile") //引入动态链接库   
    using   namespace   ADOCG;   
    #include   "icrsint.h" //包含头文件   
        
    以上代码在程序的运行过程中将产生名为msado15.tlh的头文件,该头文件中定义了一些有用的智能指针,以下是该文件关于智能指针定义的一段代码:   
    //   
    //   Smart   pointer   typedef   declarations   
    //   
        
    ......   
    _COM_SMARTPTR_TYPEDEF(Properties,   __uuidof(Properties));   
    _COM_SMARTPTR_TYPEDEF(Property,   __uuidof(Property));   
    _COM_SMARTPTR_TYPEDEF(Error,   __uuidof(Error));   
    _COM_SMARTPTR_TYPEDEF(Errors,   __uuidof(Errors));   
    _COM_SMARTPTR_TYPEDEF(_Connection,   __uuidof(_Connection));   
    _COM_SMARTPTR_TYPEDEF(_Recordset,   __uuidof(_Recordset));   
    _COM_SMARTPTR_TYPEDEF(Fields,   __uuidof(Fields));   
    _COM_SMARTPTR_TYPEDEF(Field,   __uuidof(Field));   
    _COM_SMARTPTR_TYPEDEF(_Parameter,   __uuidof(_Parameter));   
    _COM_SMARTPTR_TYPEDEF(Parameters,   __uuidof(Parameters));   
    _COM_SMARTPTR_TYPEDEF(_Command,   __uuidof(_Command));   
    ......   
    这是基于ADO的支持类_com_ptr_t的一些指针的定义,其中宏_COM_SMARTPTR_TYPEDEF()在VC6.0头文件COMDEF.H中定义。   
    下面是我们经常使用的几个智能指针:   
    _ConnectionPtr   连接对象指针   
    _RecordsetPtr 记录集对象指针   
    _ParameterPtr 参数对象指针   
    _CommandPtr   命令对象指针   
    FieldPtr 域对象指针   
    PropertyPtr 属性对象指针   
    ErrorPtr 错误对象指针   
    下面在一个程序实例中说明这些指针的用法,程序访问的数据库为SQL   Server   7.0中自带的NothWind,数据表名为Employees,这里只访问EmployeeID,LastName,FirstName,Title等4个字段:   
    步骤1.启动VC6.0,使用MFC   AppWizard建立一个单文档应用程序,命为AdoCls,在Step1到Step   5中使用缺设置,直接按Next即可,在Step   6中,选择视图类的基类为CFormView,然后按Finish,按OK,生成应用程序框架,在应用程序的ResourceView中,删除IDD_ADOCLS_FORM对话框中自动生成的静态文本;   
    步骤2.新建一个文本文件,并在其中输入如下内容,然后将其保存为MyData.h,再将其添加到AdoCls工程中(菜单命令:Project\Add   To   Project\Files...),输入内容如下:   
    //MyData.h   
    #define   INITGUID   
    #import   "C:\program   files\common   files\system\ado\msado15.dll"rename_namespace("ADOCG")rename("EOF","EndOfFile")   
    using   namespace   ADOCG;   
    #include   "icrsint.h"   
        
    #if   _MSC_VER   >   1000   
    #pragma   once   
    #endif   //   _MSC_VER   >   1000   
        
    class   CMyRecord   :   public   CADORecordBinding   
    {   
    BEGIN_ADO_BINDING(CMyRecord   ) //开始数据捆绑   
    ADO_FIXED_LENGTH_ENTRY(1,adInteger,m_id,lid,TRUE);   
    ADO_VARIABLE_LENGTH_ENTRY2(2,adVarChar,m_lastname,sizeof(m_lastname),llastname,TRUE)   
    ADO_VARIABLE_LENGTH_ENTRY2(3,adVarChar,m_firstname,sizeof(m_firstname),lfirstname,TRUE)   
    ADO_VARIABLE_LENGTH_ENTRY2(4,adVarChar,m_title,sizeof(m_title),ltitle,TRUE)   
    END_ADO_BINDING() //结束数据捆绑   
    public:   
    long   m_id;   
    ULONG   lid;   
    char   m_lastname[20];   
    ULONG   llastname;   
    char   m_firstname[10];   
    ULONG   lfirstname;   
    char   m_title[30];   
    ULONG   ltitle;   
        
    };   
        
    在MyData.h头文件中定义了一个CMyRecord类,该类的基类必须是CADORecordBinding,且没有构造函数和析构函数,只有一组用于数据捆绑和映射的宏和一组变量。其中以“m_”开头的4个变量分别对应数据表Employees中EmployeeID,LastName,FirstName,Title等4个字段,它们将用于存取这4个字段的实际值,以“l”开头的4个ULONG类型的变量是对应字段的状态值,用于判断数据的捆绑是否成功,后面的程序代码中将看到其应用。用于数据捆绑和映射的宏在头文件icrsint.h中定义,数据的捆绑和映射主要用到如下的几个宏:   
    (1).   BEGIN_ADO_BINDING   ()和   END_ADO_BINDING()   
    BEGIN_ADO_BINDING()宏的参数是用户自定义的用于数据捆绑的记录集类,本例中为CMyRecord。END_ADO_BINDING()宏不带参数。   
    (2).   ADO_FIXED_LENGTH_ENTRY()宏,该宏用于数据库中所有长度固定的字段,如Date/Time,BOOL,int,或定长的字符型字段。有两个版本:   
    (1)#define   ADO_FIXED_LENGTH_ENTRY(Ordinal,DataType,Buffer,Status,Modify);   
    (2)#define   ADO_FIXED_LENGTH_ENTRY2(Ordinal,DataType,Buffer,,Modify);   
    (3).   ADO_NUMERIC_ENTRY(),用于数值型字段。也有两个版本:   
    (1)#define   ADO_NUMERIC_ENTRY(Ordinal,DataType,Buffer,Precision,Scale,Status,Modify);   
    (2)#define   ADO_NUMERIC_ENTRY(Ordinal,DataType,Buffer,Precision,Scale,Modify);   
    (4).ADO_VARIABLE_LENGTH_ENTRY(),有四个版本:   
    (1)#define     ADO_VARIABLE_LENGTH_ENTRY(Ordinal,DataType,Buffer,Size,Status,Length,Modify);   
    (2)#define     ADO_VARIABLE_LENGTH_ENTRY2(Ordinal,DataType,Buffer,Size,Status,Modify);   
    (3)#define     ADO_VARIABLE_LENGTH_ENTRY3(Ordinal,DataType,Buffer,Size,Length,Modify);   
    (4)#define     ADO_VARIABLE_LENGTH_ENTRY4(Ordinal,DataType,Buffer,Size,Modify);   
    Ordinal 被访问的记录集中的字段的序号,数据表Employees中EmployeeID,LastName,FirstName,Title等4个字段的序号分别为1、2、3、4;   
    DataType 字段数据类型,见头文件msado15.tlh(在程序的运行过程中将产生);   
    Buffer 字段中的值所要映射到的变量   
    Status 被映射字段的状态值   
    Modify 是否允许修改   
    Precision 字段值的精度(数值型)   
    Scale 字段值的数值范围(数值型)   
    Size 变长度字段值的长度(如:字符串)   
    步骤3.进入ResourceView,在IDD_ADOCLS_FORM对话框中添加如下图所示几个控件:   
        
        
    4个文本框控件对应的变量分别是m_id,m_firstname,m_lastname,m_title,这4个变量均属于CAdoClsView类。   
    步骤4.在CAdoClsDoc类头文件包含MyRecord.h,并在其中添加如下几个私有成员变量:   
    private:   
    CMyRecord   m_rsRecSet;   
    _RecordsetPtr   m_pRs;   
    IADORecordBinding   *   m_piAdoRecordBinding;   
    CString   m_strCmdText;   
    CString   m_strConnection;   
    HRESULT   hr;   
    步骤5.在文档类构造函数中初始化COM环境和建立与数据库的连接,在析构函数中清除COM环境和释放有关变量。在CAdoClsDoc类构造函数中添加如下内容:   
    ::CoInitialize(NULL);//初始化COM环境   
    m_piAdoRecordBinding=NULL;   
    m_strConnection=_T("Provider=SQLOLEDB.1;Integrated   Security=SSPI;Persist   Security   Info=False;Initial   Catalog=Northwind;Data   Source=BUILDER");       
    m_strCmdText=_T("select   EmployeeID,LastName,FirstName,Title   from   Employees");   
        
    //创建对象实例   
    m_pRs.CreateInstance(__uuidof(Recordset));   
    //利用智能指针打开记录集   
    m_pRs->Open(LPCTSTR(m_strCmdText),LPCTSTR(m_strConnection),adOpenDynamic,adLockOptimistic,adCmdText);   
    hr=m_pRs->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&m_piAdoRecordBinding);   
    hr=m_piAdoRecordBinding->BindToRecordset(&m_rsRecSet);//与CMyRecord记录类捆绑   
    //此处,变量hr仅仅是用来判函数的调用是否成功,如果成功则hr等于0,否则hr小于0。   
    在CAdoClsDoc类析构函数中添加如下内容:   
    //在析构函数中关闭与数据源的连接,释放有关变量   
    if(m_pRs)m_pRs->Close();   
    if(m_piAdoRecordBinding)m_piAdoRecordBinding->Release();   
    m_pRs=NULL;   
    CoUninitialize();//清除COM环境   
    注意:在ADO中,获得记录集的方法有大约3种:1.通过连接对象的Execute()方法;2.通过命令对象的Execute()方法(但是,该命令对象必须首先与连接对象建立关联pCmd->ActiveConnection=);3.直接建立并打开记录集对象(在这种方法里面,其Open()函数中的ActiveConnection参数既可以是连接对象指针,又可以是连接字符串)。因此,使用ADO技术访问数据库的数据是非常自由的,不象DAO,必须先建立Database对象,然后再建立Recordset对象。我们这里采用第3中方法,这种方法只适用与简单的应用中,如果在应用中需要访问多哥数据源,则必须采用1和2两种方法显式的建立连接,以加快访问速度。   
    步骤6.在文档类中添加记录集的Move类函数,MoveFirst()、MovePrevious()、MoveNext()、MoveLast()、AddNew()、CreateBlankRecord():   
    void   CAdoClsDoc::MoveFirst()   
    {   
    if(m_pRs->Supports(adUpdate))   
    hr=m_piAdoRecordBinding->Update(&m_rsRecSet);   
    m_pRs->MoveFirst();   
    }   
        
    void   CAdoClsDoc::MovePrevious()   
    {   
    if(!m_pRs->BOF)   
    {   
    hr=m_piAdoRecordBinding->Update(&m_rsRecSet);   
    m_pRs->MovePrevious();   
    }   
    }   
        
    void   CAdoClsDoc::MoveNext()   
    {   
    if(!m_pRs->EndOfFile){   
    hr=m_piAdoRecordBinding->Update(&m_rsRecSet);   
    m_pRs->MoveNext();   
    }   
    }   
        
    void   CAdoClsDoc::MoveLast()   
    {   
    hr=m_piAdoRecordBinding->Update(&m_rsRecSet);   
    m_pRs->MoveLast();   
    }   
    步骤7.在CAdoClsDoc类中添加GetMyRecord()函数:   
    CMyRecord   *   CAdoClsDoc::GetMyRecord()   
    {   
    return(&m_rsRecSet);   
    }   
    步骤8.在void   CAdoClsView::OnInitialUpdate()函数中添加如下代码:   
    {.......   
    RefreshBoundData();}   
    步骤9.在CAdoClsView类中添加RefreshBoundData()函数及其实现代码:   
    void   CAdoClsView::RefreshBoundData()   
    {   
    CMyRecord   *   pRs;   
    pRs=GetDocument()->GetMyRecord();   
    m_firstname=adFldOK==pRs->lfirstname?pRs->m_firstname:"";   
    m_lastname=adFldOK==pRs->llastname?pRs->m_lastname:"";   
    m_title=adFldOK==pRs->ltitle?pRs->m_title:"";   
    UpdateData(FALSE);   
    }   
    步骤10.在CAdoClsView类中添加UpdateBoundData()函数及其实现代码:   
    void   CAdoClsView::UpdateBoundData()   
    {   
    CMyRecord   *   pRs;   
    pRs=GetDocument()->GetMyRecord();   
    UpdateData(TRUE);   
    if(pRs->m_id!=m_id)   
    pRs->m_id=m_id;   
    if(pRs->m_firstname!=m_firstname)   
    strcpy(pRs->m_firstname,LPCTSTR(m_firstname));   
        if(pRs->m_lastname   !=   m_lastname)   
    strcpy(pRs->m_lastname,LPCTSTR(m_lastname));   
    if(pRs->m_title   !=m_title)   
    strcpy(pRs->m_title   ,LPCTSTR(m_title));   
    }   
    步骤10.在CAdoClsView类中添加IDD_ADOCLS_FORM对话框中四个按钮对应的消息映射函数:   
    void   CAdoClsView::OnButtonFirst()     
    { UpdateBoundData();   
    GetDocument()->MoveFirst   ();   
    RefreshBoundData();   
    }   
    void   CAdoClsView::OnButtonLast()     
    { UpdateBoundData();   
    GetDocument()->MoveLast   ();   
    RefreshBoundData();   
    }   
    void   CAdoClsView::OnButtonNext()     
    { UpdateBoundData();   
    GetDocument()->MoveNext   ();   
    RefreshBoundData();   
    }   
    void   CAdoClsView::OnButtonPrevious()     
    { UpdateBoundData();   
    GetDocument()->MovePrevious   ();   
    RefreshBoundData();   
    }   
    步骤11.编译运行该应用程序,即可实现对数据库的浏览。   
    使用ADO在VC6中建立数据库应用程序,至此结束,关于这一方法以及本程序例子,作以下几点说明:   
    1.运行上面的程序,试着改变数据库中的某个列的数值,读者将会发现,在数据记录的移动时,数据库并没有被更新。这是因为本程序所涉及到的四个字段中,其中有一个标识列,EmployeeID,标识列具有自动增长的特性,用户不能更新,否则将出错,这时,语句hr=m_piAdoRecordBinding->Update(&m_rsRecSet);将返回一个负值,即hr<0,读者可以SQL   Server   7中的Enterprise   Manager打开NothWind数据库,修改其中的数据表Employees,在该表的设计视图中将其EmployeeID所在行的Identify复选框取消,然后保存。这时用户即可实现对数据库的更新。在调试时注意一下语句hr=m_piAdoRecordBinding->Update(&m_rsRecSet),hr将等于0。   
    2.CMyRecord类的基类是CADORecordBinding,IADORecordBinding   是CADORecordBinding类的一个COM接口,它也是记录集类CADORecordBinding的一部分,用户可以通过该接口实现数据的捆绑、更新和添加,它对应3个(仅有3个)函数:BindToRecordset()、AddNew()和Update(),这三个函数可以参见头文件icrsint.h。其中BindToRecordset()和Update()我们已经使用过,AddNew()的用法与Update()很相似,首先,将MyRecord类中各个数值变量(以m_开头)赋初值,然后调用m_piAdoRecordBinding->AddNew(&m_rsRecSet)和m_pRs->MoveLast()(将记录指针移到新添加的空白记录处),即可实现记录的添加功能。   
    3.在宏ADO_VARIABLE_LENGTH_ENTRY2(Ordinal,DataType,Buffer,Size,Status,Modify);中,第一个参数Ordinal指的是在当前记录集中字段的位置,而不是原数据表中该字段的位置。如本程序中的LastName字段,在程序中所要访问的记录集中的位置是2,如果将记录集改为:“select   LastName,FirstName,Title   from   Employees”,则LastName的位置将为1,Ordinal=1。   
    4.如果读者不喜欢数据捆绑的方式访问数据库,ADO提供了对记录集中单个域进行访问的方法,如以下代码可以更新当前记录中的FirstName字段:   
    _variant_t   vFld,vValue;   
    vFld.SetString("FirstName");   
    vValue.SetString("Rose   Tom");   
    m_pRs->Update(vFld,vValue);   
    以下代码可以取得FirstName字段值:   
    _variant_t   vValue;   
    CString   strValue;   
    vValue=m_pRs->GetCollect(_variant_t   ("FirstName"));   
    vValue.ChangeType(VT_BSTR);   
    strValue=vValue.bstrVal;   
    这种直接访问字段值的方法很灵活,缺点是编程人员必须频繁的调用ChangeType函数进行数据类型的转换。

  • 相关阅读:
    后勤数据抽取流程图 Logistic Data Extraction
    WINDOWS两条线路上网的解决办法
    Zabbix Agent for Linux部署
    Java项目的自动更新并构建脚本
    使用Goole搜索引擎
    golang程序性能优化方法----不断更新
    golang性能分析策略
    问题分析:引入新elastic api导致的TIME_WAIT堆积
    数据权限限定办法
    MariaDB集群搭建
  • 原文地址:https://www.cnblogs.com/renyuan/p/2620713.html
Copyright © 2020-2023  润新知