• vc访问ACCESS数据库


     在现代软件开发中,数据库技术被越来越广泛应用,很多项目都存在着大量的数据需要存储,通常都会采用数据库来存储这些数据。最初,数据库厂商推出一个新的数据库产品时,相应的,他会为程序员提供一套访问该数据库的接口,即API。不同的数据库厂商提供的访问接口是不一样的,这样在使用一个新的数据库时,就要学习一套新的API,当然这就加大了开发数据库的难度,也不利于数据库在软件开发过程中的应用。因此,后来Microsoft就推出了一些标准的访问数据库的技术。

          这一部分主要介绍ADO访问数据库的情况,对于其它技术,可以自行查阅相应书籍,ADO中有以下3个核心对象。

    @Connection对象

          Connection对象表示到数据库的链接,它管理应用程序和数据库之间的通信,下面的2个对象都有一个ActiveConnection属性,该属性用来引用Connection对象。

    @Command对象

          Command对象用来 处理 重复执行的查询,或处理 需要检查 在存储过程中的输出或返回值 的查询。

    @RecordSet对象

          RecordSet对象用来保存数据,存放查询的结果,这些结果由数据的行(记录)和列(字段)组成。每一列都存放在RecordSet的Fields集合中的一个Field对象中。

    第一步:

          在VC中利用ADO访问数据库时,首先需要导入ADO库。在程序的预编译头文件stdAfx.h中导入该库,方法是利用import指令将此动态链接库导入,具体代码如下:#import "c:/program files/common files/system/ado/msado15.dll" no_namespace rename("EOF","rsEOF"),代码中使用了no_namespace关键字,namespace是命名空间,本例中不需要命名空间,主要是为了访问方便,在程序中可以直接访问ADO提供的Connection、Command、RecordSet这3个COM接口。最后利用rename将EOF改为rsEOF。EOF表示 记录集 的结尾,因为文件也是以EOF为结尾的,为了避免冲突,在导入ADO库时,需要将EOF改为rsEOF。至于将其改为什么名字,可以根据自己的习惯来定。

          在导入ADO库之后,编译程序,会出现一条警告,在VC中利用ADO访问数据库时都会存在这一警告,对程序并没有影响,可以不用理会。编译之后,在Debug目录下,可以看到编译器为我们产生了两个文件,msado15.tlh和msado15.tli。可以将msado15.tlh看作是一个头文件,msado15.tli看作是一个源文件,这两个文件是在导入ADO库之后,编译器在编译的时候自动生成的,利用ADO技术访问数据库并不需要为工程导入这两个文件。

    第二步:

          为需要访问数据库的类添加2个成员变量,_RecordsetPtr m_pRs(数据集对象);_ConnectionPtr m_pConn;(数据库链接对象)   接着在程序初始化的时候初始化这2个对象

    [cpp] view plaincopy
     
    1. CoInitialize(NULL);  
    2.     try  
    3.     {  
    4.         //初始化数据库连接对象  
    5.         m_pConn.CreateInstance("ADODB.Connection");  
    6.         m_pRs.CreateInstance(__uuidof(Recordset));//这里必须初始化。  
    7.         //定义数据库连接字符串,打开本地Access库  
    8.         m_pConn->ConnectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=DBS.mdb;Persist Security Info=False";  
    9.         //打开数据库连接  
    10.         m_pConn->Open("","","",adConnectUnspecified);  
    11.           
    12.     }  
    13.     catch(_com_error &e)  
    14.     {  
    15.         ::CoUninitialize();  
    16.         ::AfxMessageBox(e.ErrorMessage());  
    17.         return FALSE;  
    18.           
    19.     }  

    COM组件在使用时,需要初始化COM库,这就需要调用CoInitialize(NULL);函数来实现,该函数有一个参数,该参数是保留的,直接传递NULL即可,同时在访问完COM库之后,程序需要调用CoUninitialize();函数卸载COM库。

          接着,初始化 数据链接对象 和 数据集对象。在初始化这两个对象时,利用__uuidof获取ADO Connection和ADO RecordSet对象的全局唯一标识符(GUID)。对m_pConn对象进行初始化。

          然后,利用智能指针对象去访问该对象的属性和方法了。首先,为数据库链接对象的链接字符串赋值。然后调用链接对象的Open方法打开与数据库的链接。关于链接字符串的获得:不必死记硬背,可以利用VB开发环境来得到链接字符串,P756。

          接下来就可以利用链接对象的Execute方法来从数据库获得数据了。

    [cpp] view plaincopy
     
    1. void CMy_DbsDlg::OnBtnQue()   
    2. {     
    3.     try  
    4.     {  
    5.         CString strsql;  
    6.         strsql.Format("SELECT * FROM RoomStandard");  
    7.         HRESULT hr=m_pRs->Open(_variant_t(strsql),(m_pConn.GetInterfacePtr()),adOpenStatic,adLockOptimistic,adCmdText);  
    8.         //m_pRs=m_pConn->Execute((_bstr_t)strsql,NULL,adCmdText);  
    9.         _variant_t vFieldValue;  
    10.         if(SUCCEEDED(hr))  
    11.         {  
    12.             //m_pRs->MoveFirst();//移至第一条记录---------默认指针在第一条记录上  
    13.             m_list.DeleteAllItems();  
    14.             int i=0,n=0;  
    15.             while(!(m_pRs->GetrsEOF()))//while(!m_pRs->rsEOF)  
    16.             {  
    17.                 int k=0;  
    18.                 vFieldValue=m_pRs->GetCollect(_variant_t(long(k)));  
    19.                 if(vFieldValue.vt!=NULL)  
    20.                 {                 
    21.                     k=1;  
    22.                     m_list.InsertItem(n,_bstr_t(vFieldValue));//插入列表控件  
    23.                     for(;k<9;k++)                      
    24.                     {  
    25.                         vFieldValue=m_pRs->GetCollect(_variant_t(long(k)));  
    26.                         if(vFieldValue.vt!=NULL)  
    27.                         {  
    28.                             m_list.SetItemText(n,k,_bstr_t(vFieldValue));  
    29.                         }  
    30.                     }  
    31.                 }  
    32.                 n++;//记录数加1;  
    33.                 m_pRs->MoveNext();  
    34.             }  
    35.             m_pRs->Close();  
    36.         }  
    37.     }  
    38.     catch(_com_error e)  
    39.     {  
    40.         AfxMessageBox(e.ErrorMessage());  
    41.         AfxMessageBox((LPCTSTR)(e.Description()));  
    42.     }  
    43.     ///////////////////////////////////////////  
    44.     //这里要判断一下记录是不是打开的,要以防不正常的情况下记录没有关闭!  
    45.     if(m_pRs)  
    46.     {  
    47.         if (m_pRs->State)  
    48.         {         
    49.             m_pRs->Close();  
    50.         }  
    51.     }  
    52. }  

          当数据操作完成之后,调用记录集对象的Close方法关闭记录集,最后调用链接对象的Close方法关闭链接。然后还需要释放智能指针在COM接口上的引用计数,即分别调用记录集对象和链接对象的Release方法,该方法将释放相应COM接口的引用计数。智能指针有一个特点,在访问其它属性和方法时,都是用->操作符,但在调用Release方法释放引用计数时,必须使用.操作符。

  • 相关阅读:
    animation——鼠标放上图片旋转
    docker安装Redis并设置密码
    Docker安装MySQL详细教程(mysql是5.7版本,可以根据自己需要修改版本)
    Linux安装jdk(两种方式)
    Nginx http 反向代理高级应用
    jenkins 远程启动tomcat报错:Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
    从一个Git仓库转移到另外一个仓库
    使用Spring @DependsOn控制bean加载顺序
    Swagger2异常:Illegal DefaultValue null for parameter type integer java
    springboot的实体类Integer和int如何选择
  • 原文地址:https://www.cnblogs.com/xihong2014/p/13669598.html
Copyright © 2020-2023  润新知