參考:http://blog.csdn.net/augusdi/article/details/7005597,做了部分補充和刪除
準備工作:
(1)、引入ADO類
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename ("EOF", "adoEOF")
(2)、初始化COM
在MFC中可以用 AfxOleInit();
非MFC環境中用 CoInitialize(NULL);/ CoUnInitialize();
(3)#import 包含後就可以用3個智能指針了:_ConnectionPtr、_RecordsetPtr和_CommandPtr
使用步驟:
1. 連接和關閉數據庫
(1)連接
例子:連接Access數據庫
- //初始化
- AfxOleInit();
- HRESULT hr;
- try
- {
- ///創建Connection對象
- hr = m_pConnection.CreateInstance("ADODB.Connection");
- if(SUCCEEDED(hr))
- {
- m_pConnection->ConnectionTimeout = 0;
- hr = m_pConnection->Open( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db.mdb", "", "", adModeUnknown);
- //m_pConnection->PutDefaultDatabase ((_bstr_t)"DB"); //設置默認數據庫
- m_pCommand.CreateInstance(__uuidof(Command));
- m_pCommand->CommandTimeout = 5;
- m_pCommand->ActiveConnection = m_pConnection;
- }
- }
- catch(_com_error e)///捕捉異常
- {
- CString errormessage;
- errormessage.Format(" 連接數據庫失敗! 錯誤信息:%s",e.ErrorMessage());
- AfxMessageBox(errormessage);///顯示錯誤信息
- }
(2)、關閉
- //如果數據庫連接有效
- if( m_pConnection->State )
- m_pConnection->Close();
- m_pConnection = NULL;
(3)、設置連接時間
- //設置連接時間
- pConnection->put_ConnectionTimeout(long(5));
2.打開一個結果集
(1) 打開,首先創建一個_RecordsetPtr實例,然後調用Open()得到一條SQL語句的執行結果
- _RecordsetPtr m_pRecordset;
- m_pRecordset.CreateInstance(__uuidof(Recordset));
- try
- {
- m_pRecordset->Open("SELECT * FROM DemoTable",// 查詢DemoTable表中所有字段
- m_pConnection.GetInterfacePtr(), // 獲取庫接庫的IDispatch指針
- adOpenDynamic,
- adLockOptimistic,
- adCmdText);
- }
- catch(_com_error *e)
- {
- AfxMessageBox(e->ErrorMessage());
- }
(2) 關閉結果集
m_pRecordset->Close();
3. 操作一個結果集
(1)、遍歷(讀取)
a)、用pRecordset->adoEOF來判斷數據庫指針是否已經移到結果集的末尾了;
m_pRecordset->BOF判斷是否在第一條記錄前面:
- while(!m_pRecordset->adoEOF)
- {
- //獲取字段值
- _variant_t var = m_pRecordset->GetCollect("Name");
- if(var.vt != VT_NULL)
- {
- CString strName = (LPCSTR)_bstr_t(var);
- }
- var = m_pRecordset->GetCollect("Age");
- if(var.vt != VT_NULL)
- {
- CString strAge = (LPCSTR)_bstr_t(var);
- }
- m_pRecordset->MoveNext();
- }
b)、取得一個字段的值的辦法有兩種辦法
第一種:
//表示取得第0個字段的值
rdset->GetCollect("Name");
// 或者
rdset->GetCollect(_variant_t(long(0));
第二種
pRecordset->get_Collect("COLUMN_NAME");
//或者
pRecordset->get_Collect(long(index));
(2)、添加
調用m_pRecordset->AddNew();
調用m_pRecordset->PutCollect();給每個字段賦值
調用m_pRecordset->Update();確認
(3)、修改
調用m_pRecordset->PutCollect();給每個字段賦值
調用m_pRecordset->Update();確認
(4)、刪除
把記錄指針移動到要刪除的記錄上,然後調用Delete(adAffectCurrent)
- try
- {
- // 假設刪除第二條記錄
- m_pRecordset->MoveFirst();
- //從當前位置向下移動一條記錄
- m_pRecordset->Move(1);
- //參數adAffectCurrent 爲刪除當前記錄
- m_pRecordset->Delete(adAffectCurrent);
- m_pRecordset->Update();
- }
- catch(_com_error *e)
- {
- AfxMessageBox(e->ErrorMessage());
- }
4. 直接執行SQL語句
(1)、用_CommandPtr和_RecordsetPtr配合
- _CommandPtr m_pCommand;
- m_pCommand.CreateInstance(__uuidof(Command));
- // 將庫連接賦於它
- m_pCommand->ActiveConnection = m_pConnection;
- // SQL語句
- m_pCommand->CommandText = "SELECT * FROM DemoTable";
- // 執行SQL語句,返回記錄集
- m_pRecordset = m_pCommand->Execute(NULL, NULL,adCmdText);
(2)、直接用_ConnectionPtr執行SQL語句
_RecordsetPtr Connection::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
參數:
RecordsAffected是操作完成後所影響的行數;
Options表示CommandText中內容的類型,Options可以取如下值之一:
adCmdText:表明CommandText是文本命令,通常是SQL語句;
adCmdTable:表明CommandText是一個表名;
adCmdProc:表明CommandText是一個存儲過程
adCmdUnknown:未知,或默認
- try
- {
- m_pCommand->CommandText ="INSERT INTO tTest(age) VALUES('23f2') ";
- m_pRecordset = m_pCommand->Execute(NULL,NULL, <span style="color:#66cccc;">adCmdText</span>);
- }
- //捕捉異常
- catch(_com_error e)
- {
- //顯示錯誤信息
- AfxMessageBox(e.ErrorMessage());
- }
5. 調用存儲過程
(1)、利用_CommandPtr
- _CommandPtrm_pCommand;
- m_pCommand.CreateInstance(__uuidof(Command));
- //將庫連接賦於它
- m_pCommand->ActiveConnection = m_pConnection;
- m_pCommand->CommandText = "Demo";
- m_pCommand->Execute(NULL,NULL, <span style="color:#ff6666;">adCmdStoredProc</span>);
(2)、直接用_ConnectionPtr直接調用
特殊應用:
顯示數據庫、表信息
使用_ConnectionPtr 的成員函數openSchema()可以獲取數據庫的模式信息;
函數原型:
_RecordsetPtr recordset = connection.OpenSchema (QueryType, Criteria, SchemaID)參數:
1. QueryType
SchemaEnum枚舉類型的值,指出獲取模式(Schema)的類型;
2. Criteria
可選項,對應SchemaEnum的查詢選項
3. SchemaID
可選項,僅當 QueryType 被設置爲adSchemaProviderSpecific 的時候纔有用,否則不使用該參數;
SchemeEnum枚舉類型的常用取值如下:
adSchemaColumns:返回用戶可訪問的數據庫目錄中表的列名(包括視圖View);
返回結果集中的列名(字段名):
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
COLUMN_NAME
adSchemaTables:返回用戶可訪問的數據庫目錄中的表名;
返回結果集中的列名(字段名):
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
TABLE_TYPE
示例1:遍歷數據庫中的所有表名;
- _ConnectionPtr m_pConnect;
- _RecordsetPtr pSet;
- HRESULT hr;
- try
- {
- hr = m_pConnect.CreateInstance("ADODB.Connection");
- if(SUCCEEDED(hr))
- {
- CString dd;
- dd.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s",file);
- hr=m_pConnect->Open((_bstr_t)dd, "", "", adModeUnknown);
- pSet=m_pConnect->OpenSchema(adSchemaTables);
- while(!(pSet->adoEOF))
- {
- //獲取表格名稱
- _bstr_t table_name = pSet->Fields->GetItem("TABLE_NAME")->Value;
- //獲取表格類型
- _bstr_t table_type = pSet->Fields->GetItem("TABLE_TYPE")->Value;
- //過濾一下,只輸出表格名稱,其他的省略
- if(strcmp(((LPCSTR)table_type),"TABLE")==0)
- {
- CString tt;
- tt.Format("%s",(LPCSTR)table_name);
- AfxMessageBox(tt);
- }
- pSet->MoveNext();
- }
- pSet->Close();
- }
- m_pConnect->Close();
- }
- //捕捉異常
- catch(_com_error e)
- {
- AfxMessageBox(e.ErrorMessage());
- }
示例2:遍歷一個表中的所有字段
- HRESULT hr;
- Fields * fields = NULL;
- //得到記錄集的字段集,並存儲在fields中
- hr=m_pRecordset->get_Fields(&fields);
- if(SUCCEEDED(hr))
- {
- //得到記錄集的字段集合中的字段的總個數
- fields->get_Count(&ColCount);
- for(i=0;i ...
- {
- Item[i]->get_Name(&bstrColName);//得到記錄集//中的字段名
- strColName=bstrColName;
- nameField = strColName;
- m_FieldsList.AddString(nameField);
- }
- if(SUCCEEDED(hr))
- {
- fields->Release();//釋放指針
- }
- }