ADO编程总结

1)引入ADO库定义文件

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

rename (“EOF”,”adoEOF”)

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

msado15.tlh和ado15.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连接不同的数据库的方式:

根据不同的数据提供者可以分为ODBC和OLEDB等若干种方式,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);

3)Microsoft 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方法将数据写入就会出错,至少这是使用VC、ADO和

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;

 

你可能感兴趣的:(编程)