ADO编程总结

原创 2004年12月30日 14:12:00

 

 

1)引入ADO库定义文件

# import “c:/program files/common files/system/ado/msado15.dll” no_namespace

rename (“EOF”,”adoEOF”)

使得编译的时候,为我们的工程文件生成两个头文件:

msado15.tlhado15.tli

 

注意,msado15.dll的路径可能有所区别,请核对自己的电脑所在的路径

 

2)初始化COM

在工程的App类的InitInstance ( )函数里面加上

AfxOleInit ( );//MFC用法

C++的常规方法是--------

:::CoInitialize(NULL);

.

::CoUninitialize();

 

3)使用记录集对象得到一个纪录集的基本步骤

//生成一个Connection对象,并连结上数据库

_ConnectionPtr m_pConnection;

HRESULT hr;

       try

       {

              hr=m_pConnection.CreateInstance(__uuidof(Connection));

              if(SUCCEEDED(hr))

              {

m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;

Data Source=小学.mdb","","",adModeUnknown);

              }

       }

       catch(_com_error e)

       {

              CString errormessage;

              errormessage.Format("连接数据库失败!/r/n/错误信息:%s",e.ErrorMessage());

              AfxMessageBox(errormessage);

       }

             

//生成RecordSet对象,并得到纪录集

_RecordsetPtr m_pRecordset;

m_pRecordset.CreateInstance("ADODB.Recordset");

CString temp="SELECT * FROM "+tablename;//tablename假设是一个CString类型的表名

_variant_t sql;

sql.SetString(temp);

m_pRecordset->Open(sql,

                 m_pConnection.GetInterfacePtr( ),

               adOpenDynamic,adLockOptimistic,adCmdText );

 

4)动态查询

CString tablename;

tablename=_T("学籍");

CString temp=_T("SELECT * FROM ")+tablename+_T(" WHERE NAME='")+

dlg.m_name+_T("'");

_variant_t sql;

sql.SetString(temp);

m_pRecordset->Open(sql,m_pConnection.GetInterfacePtr(),

                            adOpenDynamic,adLockOptimistic,adCmdText);

 

5)遍历纪录集

 

int line=0;

while(!m_pRecordset->adoEOF)//遍历记录集,并将所有纪录显示在列表视图中

{

       。。。。。。

       line++;

       m_pRecordset->MoveNext();

}

 

其余操作都很简单,可以参见其他文章,最关键的是,不要忘了关闭纪录集,因为这通常会造成异常

 

6)使用ADO连接不同的数据库的方式:

根据不同的数据提供者可以分为ODBCOLEDB等若干种方式,ODBC兼容性更好,支持OLEDB的数据库相对少一点;

连接SQL Server数据库:

1)  Microsoft OLE DB Provider for ODBC

m_pConnection->Open(Provider=SQLOLEDB.1;DRIVER=SQLServer;SERVER=lzhm;DATABASE=haitang,"sa","sa",adModeUnknown);

2)未知方法,但是可行,注意Initial Catalog用空格分开

m_pConnection->Open(“Provider=SQLOLEDB.1;Data Source=lzhm;Initial Catalog=haitang”,"sa","sa",adModeUnknown);

m_pConnection->Open ("Provider=SQLOLEDB;Data Source=172.20.2.97;Network Library=DBMSSOCN;Initial Catalog=haitang",”sa”,”sa”,adModeUnknown);

m_pConnection->Open ("Provider=SQLOLEDB;Network Address=172.20.2.97;Initial Catalog=haitang",”sa”,”sa”,adModeUnknown);

m_pConnection->Open ("Provider=SQLOLEDB;Network Address=172.20.2.97; Network Library=DBMSSOCN;Initial Catalog=haitang",”sa”,”sa”,adModeUnknown);

3Microsoft OLE DB Provider for SQL Server

m_pConnection->Open(“Provider=SQLOLEDB.1;Data Source=lzhm;Initial Catalog=haitang”,"sa","sa",adModeUnknown);

4)不使用DSN进行连接

m_pConnection->Open("driver={SQL Server};server=lzhm;database=haitang”,"sa","sa",adModeUnknown);

连接ACCESS 2000数据库的方式:

m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=小学.mdb","","",adModeUnknown);

 

连接ACCESS 97数据库的方式:

m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.3.51;Data Source=小学.mdb","","",adModeUnknown);

 

7)一个常用的函数,传递一句SQL语句,然后打开一个记录集,假设记录集对象m_pRecordset存在:

BOOL CHaiTangView::GetRecordSet(CString sql)

{//如果生成的记录集不为空,就返回TRUE

       if(m_pRecordset->GetState()==1)//如果记录集对象已经打开,则先关闭

              m_pRecordset->Close();

       HRESULT hr;

       _variant_t v_sql;

       v_sql.SetString(sql);

       try

       {

              hr=m_pRecordset->Open(v_sql,m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);

           if(SUCCEEDED(hr))

              {

              }

       }

       catch(_com_error e)

       {

              CString errormessage;

              errormessage.Format("查询数据表失败!/r/n错误信息:%s",e.ErrorMessage());

              AfxMessageBox(errormessage);

              return 0;

       }

       m_pRecordset->MoveFirst();

       if(!m_pRecordset->adoEOF)//SUCCEEDED(hr)无法判断记录集的生成是否为空

       {                                  //所以要用生成后的纪录集的最大纪录数是否为0来判别

              return TRUE;                   //SUCCEEDED(hr)应该是来判别异常的,纪录集为空不属于异常

       }

       else

       {

              MessageBox("对不起,找不到符合条件的纪录,请联系系统管理员");

              return FALSE;

       }

}

 

 

8)调用Recordset::PutCollect出现的问题:

select 岸线属性表.序号,s1.NAME,岸线属性表.岸线性质,岸线属性表.起点桩号,岸线属性表.终点桩号,岸线属性表.岸线长度,岸线属性表.堤顶高程,岸线属性表.结构形式小类,岸线属性表.结构形式大类,岸线属性表.达标标准,岸线属性表.地域位置,岸线属性表.备注 from 岸线属性表,数据字典表 AS s1 where s1.ID=岸线属性表.岸线名 ORDER BY 岸线属性表.序号

 

 

select * from 海塘绿化表 ORDER BY 序号

 

select 岸线属性表.序号,s1.NAME,s2.NAME from 岸线属性表,数据字典表 AS s1,数据字典表 AS s2 where s1.ID=岸线属性表.岸线名 AND s2.ID=岸线属性表.责任单位 ORDER BY 岸线属性表.序号

 

在海塘开发的过程中,发现如果使用了RecordSet::Open的方法调用SQL语句打开记录集,如果SQL语句中使用了ORDER BY语句,在使用Recordset::PutCollect方法将数据写入就会出错,至少这是使用VCADO

SQL Server7.0或者2000的情况。

 

9)调用存储过程,在ATL里面的存储过程

STDMETHODIMP CFBGET::GetDataByProc(BSTR bstrProcName, BSTR bstrParam, BSTR* plPower)

{

       // TODO: Add your implementation code here

       *plPower = NULL;

 

       USES_CONVERSION;

 

      

       ////////////////////////////////////////////////////////////////////////////

       ///建立和数据库的连接

       _ConnectionPtr m_pCon;

       m_pCon.CreateInstance(_uuidof(Connection));

      

       char array[200];

       GetWindowsDirectory(array,200);

       strcat(array,"//FB_DATA.INI");

       char servername[100];

       GetPrivateProfileString("ServerName","NAME","",servername,100,array);

       char str_con[1024];

       wsprintf(str_con,"Provider=SQLOLEDB.1;Data Source=%s;Initial Catalog=haitang;User ID=haitang;PWD=haitang",servername);

      

       m_pCon->Open(str_con,"","",adModeUnknown);

      

       ///////////////////////////////////////////////////////////////////////////////

      

       ///建立命令对象

      

       _CommandPtr m_pCommand;

       m_pCommand.CreateInstance("ADODB.Command");

       m_pCommand->ActiveConnection = m_pCon;

      

       _variant_t name="proc_user";

       BSTR bname=SysAllocString(OLESTR("proc_user"));

       m_pCommand->CommandText=bname;

       m_pCommand->CommandType=adCmdStoredProc;

       ///将参数转换成char*类型,提取出两个char*参数

       char *p=W2A(bstrParam);

             

       char* temp=p;

       char* p1=temp;

       while(*temp!='T')

       {

              temp++;

       }

       *temp='/0';

       temp++;

       char* p2=temp;

       while(*temp!='T')

       {

              temp++;

       }

       *temp='/0';

       //将两个参数转换成BSTR类型

       BSTR bstrP1=A2W(p1);

       BSTR bstrP2=A2W(p2);

 

       ///建立参数对象1

       _ParameterPtr p_Param1;

       p_Param1.CreateInstance("ADODB.Parameter");

       p_Param1->Name="name";

       p_Param1->Type=adVarChar;

       p_Param1->Size=50;

       p_Param1->Direction=adParamInput;

       p_Param1->Value=bstrP1;

       m_pCommand->Parameters->Append(p_Param1);

      

       ///建立参数对象2

       _ParameterPtr p_Param2;

       p_Param2.CreateInstance("ADODB.Parameter");

       p_Param2->Name="key";

       p_Param2->Type=adVarChar;

       p_Param2->Size=50;

       p_Param2->Direction=adParamInput;

       p_Param2->Value=bstrP2;

       m_pCommand->Parameters->Append(p_Param2);

 

      

       ///建立参数对象3

       _bstr_t bstrP3;

       _ParameterPtr p_Param3;

       p_Param3.CreateInstance("ADODB.Parameter");

       p_Param3->Name="power";

       p_Param3->Type=adInteger;

       p_Param3->Size=10;

       p_Param3->Direction=adParamOutput;

//     p_Param3->Value=bstrP3;   //由于是输出参数,所以千万不能指定Value

       m_pCommand->Parameters->Append(p_Param3);

 

       ///执行存储过程,并获得输出参数

       m_pCommand->Execute(NULL,NULL,adCmdStoredProc);      

 

       _bstr_t value=p_Param3->GetValue();

 

       const char* ppp = value;

      

       *plPower = SysAllocString(A2W(ppp));

       return S_OK;

}

注意,如果存储过程里面只写了一个select语句,执行后将返回一个记录集对象,ADO可以通过

m_pRecordet=m_pCommand->Execute (….)来接受,

但是如果存储过程中包含了多个select语句,ADO接受到的记录集对象是不可一使用的。

 

10)使用命令对象执行SQL语句

_CommandPtr m_pCommand;

    m_pCommand.CreateInstance("ADODB.Command");

    m_pCommand->ActiveConnection = m_pCon;//m_pCon为数据库连接对象

    m_pCommand->CommandText="UPDATE TABLE1 set num_id = '2' WHERE value = '44'";

    m_pCommand->CommandType=adCmdText;

    m_pCommand->Parameters->Refresh();

    ///执行存储过程,并获得输出参数

    m_pCommand->Execute(NULL,NULL,adCmdUnknown);   

 

11) 得到记录集中字段的数目

m_pRecordset->Fields->GetCount();

也可以通过类似的方式获得字段类型

FieldsPtr fields=m_Rec->GetFields();

     * pcActualColSize=fields->GetCount();

 

     VARIANT varIndex;

     VariantInit(&varIndex);

     varIndex.vt=VT_I4;

     FieldPtr field;

     DataTypeEnum adoType;

     for(long i=0;i<* pcActualColSize;i++)

     {

         varIndex.lVal=i;

         field=fields->GetItem(varIndex);

         adoType=field->GetType();

     }

下面是类型对应表

enum DataTypeEnum

    {    adEmpty  = 0,

     adTinyInt = 16,

     adSmallInt    = 2,

     adInteger = 3,

     adBigInt = 20,

     adUnsignedTinyInt  = 17,

     adUnsignedSmallInt = 18,

     adUnsignedInt = 19,

     adUnsignedBigInt   = 21,

     adSingle = 4,

     adDouble = 5,

     adCurrency    = 6,

     adDecimal = 14,

     adNumeric = 131,

     adBoolean = 11,

     adError  = 10,

     adUserDefined = 132,

     adVariant = 12,

     adIDispatch   = 9,

     adIUnknown    = 13,

     adGUID   = 72,

     adDate   = 7,

     adDBDate = 133,

     adDBTime = 134,

     adDBTimeStamp = 135,

     adBSTR   = 8,

     adChar   = 129,

     adVarChar = 200,

     adLongVarChar = 201,

     adWChar  = 130,

     adVarWChar    = 202,

     adLongVarWChar     = 203,

     adBinary = 128,

     adVarBinary   = 204,

     adLongVarBinary    = 205,

     adChapter = 136,

     adFileTime    = 64,

     adPropVariant = 138,

     adVarNumeric  = 139

}    DataTypeEnum;

 

 

typedef enum ParameterDirectionEnum

    {    dbParamInput  = 1,

     dbParamOutput = 2,

     dbParamInputOutput = 3,

     dbParamReturnValue = 4

    }    ParameterDirectionEnum;

版权声明:本文为博主原创文章,未经博主允许不得转载。

ADO 操作总结

工程在VS2013 完成 *支持基本的Sql语句 *支持存储过程(输入输出参数) *支持记录集查询也遍历 *每次调用完成之后应判断返回值,如果不对,调用GetLastError查看具体错误说明...
  • CAir2
  • CAir2
  • 2016年06月06日 14:18
  • 443

<SQL >ADO操作m_pConnection->Open和m_pRecordset->Open

m_pConnection->Open用在InitInstance()函数中, 用法: m_pConnection.CreateInstance("ADODB.Connection"); ...
  • qq_31209383
  • qq_31209383
  • 2016年04月20日 10:32
  • 2235

VC++ ADO操作总结

1、导入库文件 #import "C:\Program Files\commonfiles\system\ado\msado15.dll" no_namespace rename("EOF","En...
  • harvic880925
  • harvic880925
  • 2012年06月18日 19:32
  • 9594

ADO MoveFirst, MoveLast, MoveNext, 与 MovePrevious 方法

The MoveFirst Method MoveFirst方法 This method is used to move to the first record in a Recordset ...
  • foreverhuylee
  • foreverhuylee
  • 2014年06月27日 16:36
  • 3554

ADO编程详解(C++)

一、概述          ADO即Microsoft ActiveXData Object,是Microsoft继ODBC之后,基于OLE DB技术的一种数据库操作技术,使您能够编写通过 OL...
  • LearnLHC
  • LearnLHC
  • 2017年05月24日 20:38
  • 284

Visual C++ ADO数据库编程入门(上)

   ADO 是目前在Windows环境中比较流行的客户端数据库编程技术。ADO是建立在OLE DB底层技术之上的高级编程接口,因而它兼具有强大的数据处理功能(处理各种不同类型的数据源、分布式的数据处...
  • zgl_dm
  • zgl_dm
  • 2008年02月01日 11:04
  • 5469

MFC ADO数据库操作

内容比较乱,作为草稿,对现有的ado数据库操作函数方法进行汇总。 小函数 m_pRecordset->RecordCount//取得记录数量 全局变量 #import "msado15.dll...
  • guoming0000
  • guoming0000
  • 2012年02月21日 16:15
  • 7194

MFC中用Ado连接数据库

VC++中使用MFC通过ADO连接数据库方法小结(不包括异常的捕捉) 这里主要讲MFC与SQL2000数据库的连接。 1.在StdAfx.h头文件中加入此句子 #import "c:\progr...
  • g710710
  • g710710
  • 2012年06月14日 10:02
  • 4386

VC中ADO编程

介绍VC用ADO访问数据库全攻略,介绍了VC用ADO来访问数据库的各个对象及各方法,很经典,也很实用,很值得一看。   正文一、ADO概述ADO是Microsoft为最新和最强大的数据访问范例 OLE...
  • bwmwm
  • bwmwm
  • 2007年04月27日 14:29
  • 2695

vc++中ADO技术入门

摘要 本文简要介绍了在VC++ 6.0中使用 ADO进行客户端数据库编程的基本步骤,以及常见问题的解决方法,可供入门级的参考之用。    关键字 ADO VC++ 数据库编程 ADO 是...
  • coolboylai2
  • coolboylai2
  • 2012年07月01日 16:48
  • 3726
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ADO编程总结
举报原因:
原因补充:

(最多只允许输入30个字)