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