當前位置:成語大全網 - 新華字典 - ADO編程技術概述

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(longi=0;i<* pcActualColSize;i++)

{

varIndex.lVal=i;

field=fields->GetItem(varIndex);

adoType=field->GetType();

}

下面是類型對應表

enumDataTypeEnum

{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;

typedefenumParameterDirectionEnum

{dbParamInput= 1,

dbParamOutput= 2,

dbParamInputOutput= 3,

dbParamReturnValue= 4

}ParameterDirectionEnum;