ADO编程总结

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;

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