ADO技术访问数据库
来源:互联网 发布:java尚学堂马士兵微盘 编辑:程序博客网 时间:2024/04/30 21:37
用VC和ADO技术访问数据库,该数据库中某个待访问的表有100万条记录。现在一条select查询语句要求返回该表中的所有记录。为了让用户能够及时地得到反馈信息,而不是在ADO取完这100万条记录之后才将信息返回给用户,假设我们以每次1000条记录为单位向用户返回数据,即ADO检索完前1000条记录后,就将这1000条记录数据返回给用户同时它继续取检索后1000条记录,依此方式取记录,直到取完数据库中的所有记录为止。于是我的程序代码如下:
void CAccessDBDlg::OnQuery()
{
HRESULT hr;
_ConnectionPtr pConn;
_RecordsetPtr pRst;
DWORD dwConnEvt;
DWORD dwRstEvt;
IConnectionPointContainer* pCPC = NULL;
IConnectionPoint* pCP = NULL;
IUnknown* pUnk = NULL;
CConnEvent* pConnEvent= NULL;
CRstEvent* pRstEvent = NULL;
//Initialize
hr = ::CoInitialize(NULL);
hr = pConn.CreateInstance(__uuidof(Connection));
hr = pRst.CreateInstance(__uuidof(Recordset));
//Start using the Connection events
hr = pConn->QueryInterface(__uuidof(IConnectionPointContainer),
(void **)&pCPC);
if (FAILED(hr)) return ;
hr = pCPC->FindConnectionPoint(__uuidof(ConnectionEvents), &pCP);
pCPC->Release();
if (FAILED(hr)) return ;
pConnEvent = new CConnEvent();
hr = pConnEvent->QueryInterface(__uuidof(IUnknown), (void **) &pUnk);
if (FAILED(hr)) return ;
hr = pCP->Advise(pUnk, &dwConnEvt);
pCP->Release();
if (FAILED(hr)) return ;
//Start using the Recordset events
hr = pRst->QueryInterface(__uuidof(IConnectionPointContainer),
(void **)&pCPC);
if (FAILED(hr)) return ;
hr = pCPC->FindConnectionPoint(__uuidof(RecordsetEvents), &pCP);
pCPC->Release();
if (FAILED(hr)) return ;
pRstEvent = new CRstEvent();
hr = pRstEvent->QueryInterface(__uuidof(IUnknown), (void **) &pUnk);
if (FAILED(hr)) return ;
hr = pCP->Advise(pUnk, &dwRstEvt);
pCP->Release();
if (FAILED(hr)) return ;
//Set recordset property
PropertiesPtr pProperties;
PropertyPtr pProperty;
VARIANT varIndex,varValue;
varIndex.vt = VT_BSTR;
varValue.vt = VT_I4;
pRst->put_CursorLocation(adUseClient);
pRst->get_Properties(&pProperties);
varIndex.bstrVal = ::SysAllocString(L"Initial Fetch Size");
pProperties->get_Item(varIndex,&pProperty);
varValue.lVal = 1000;
pProperty->put_Value(varValue);
varIndex.bstrVal = ::SysAllocString(L"Background Fetch Size");
pProperties->get_Item(varIndex,&pProperty);
varValue.lVal = 1000;
pProperty->put_Value(varValue);
//Open connection
BSTR bstrConnectionString = ::SysAllocString(L"Provider=SQLOLEDB.1;Password=billtw;Persist Security Info=True;User ID=sa;Initial Catalog=WingingDB;Data Source=WEITAO");
pConn->Open(bstrConnectionString,"","",-1);
//Open recordset
VARIANT varConnString,varCommandText;
varConnString.vt = VT_DISPATCH;
varConnString.pdispVal = pConn;
varCommandText.vt = VT_BSTR;
varCommandText.bstrVal = ::SysAllocString(L"select * from cardnumber");
pRst->Open(varCommandText,varConnString,adOpenStatic,adLockOptimistic,adCmdText | adAsyncFetch);
//Close recordset and connection
pRst->Close();
pConn->Close();
}
Recordset对象的FetchProgress事件处理函数如下:
STDMETHODIMP CRstEvent::raw_FetchProgress(
long Progress,
long MaxProgress,
EventStatusEnum *adStatus,
struct _Recordset *pRecordset)
{
CString strRecordsetCount;
long lRecordCount;
pRecordset->get_RecordCount(&lRecordCount);
strRecordsetCount.Format("Fetch progress %d",lRecordCount);
AfxMessageBox(strRecordsetCount);
return S_OK;
};
现在的问题是,从理论上说,既然Recordset对象动态属性集中的Initial Fetch Size和Background Fetch Size属性被设置为1000,且Recordset是以adAsyncFetch方式打开的,那么FetchProgress事件就应该被触发100次(100万记录数/1000),且每次触发时,pRecordset中记录了取得的1000条记录。可是我实际运行时,FetchProgress事件只被触发了一次(只显示了一次AfxMessageBox中的内容),且此时得到的lRecordCount值为1000000,实际的运行结果似乎和理论上的不一致,这是什么原因呢?如果这种方法不行,我又该以什么方法来实现我上述的需求呢?
void CAccessDBDlg::OnQuery()
{
HRESULT hr;
_ConnectionPtr pConn;
_RecordsetPtr pRst;
DWORD dwConnEvt;
DWORD dwRstEvt;
IConnectionPointContainer* pCPC = NULL;
IConnectionPoint* pCP = NULL;
IUnknown* pUnk = NULL;
CConnEvent* pConnEvent= NULL;
CRstEvent* pRstEvent = NULL;
//Initialize
hr = ::CoInitialize(NULL);
hr = pConn.CreateInstance(__uuidof(Connection));
hr = pRst.CreateInstance(__uuidof(Recordset));
//Start using the Connection events
hr = pConn->QueryInterface(__uuidof(IConnectionPointContainer),
(void **)&pCPC);
if (FAILED(hr)) return ;
hr = pCPC->FindConnectionPoint(__uuidof(ConnectionEvents), &pCP);
pCPC->Release();
if (FAILED(hr)) return ;
pConnEvent = new CConnEvent();
hr = pConnEvent->QueryInterface(__uuidof(IUnknown), (void **) &pUnk);
if (FAILED(hr)) return ;
hr = pCP->Advise(pUnk, &dwConnEvt);
pCP->Release();
if (FAILED(hr)) return ;
//Start using the Recordset events
hr = pRst->QueryInterface(__uuidof(IConnectionPointContainer),
(void **)&pCPC);
if (FAILED(hr)) return ;
hr = pCPC->FindConnectionPoint(__uuidof(RecordsetEvents), &pCP);
pCPC->Release();
if (FAILED(hr)) return ;
pRstEvent = new CRstEvent();
hr = pRstEvent->QueryInterface(__uuidof(IUnknown), (void **) &pUnk);
if (FAILED(hr)) return ;
hr = pCP->Advise(pUnk, &dwRstEvt);
pCP->Release();
if (FAILED(hr)) return ;
//Set recordset property
PropertiesPtr pProperties;
PropertyPtr pProperty;
VARIANT varIndex,varValue;
varIndex.vt = VT_BSTR;
varValue.vt = VT_I4;
pRst->put_CursorLocation(adUseClient);
pRst->get_Properties(&pProperties);
varIndex.bstrVal = ::SysAllocString(L"Initial Fetch Size");
pProperties->get_Item(varIndex,&pProperty);
varValue.lVal = 1000;
pProperty->put_Value(varValue);
varIndex.bstrVal = ::SysAllocString(L"Background Fetch Size");
pProperties->get_Item(varIndex,&pProperty);
varValue.lVal = 1000;
pProperty->put_Value(varValue);
//Open connection
BSTR bstrConnectionString = ::SysAllocString(L"Provider=SQLOLEDB.1;Password=billtw;Persist Security Info=True;User ID=sa;Initial Catalog=WingingDB;Data Source=WEITAO");
pConn->Open(bstrConnectionString,"","",-1);
//Open recordset
VARIANT varConnString,varCommandText;
varConnString.vt = VT_DISPATCH;
varConnString.pdispVal = pConn;
varCommandText.vt = VT_BSTR;
varCommandText.bstrVal = ::SysAllocString(L"select * from cardnumber");
pRst->Open(varCommandText,varConnString,adOpenStatic,adLockOptimistic,adCmdText | adAsyncFetch);
//Close recordset and connection
pRst->Close();
pConn->Close();
}
Recordset对象的FetchProgress事件处理函数如下:
STDMETHODIMP CRstEvent::raw_FetchProgress(
long Progress,
long MaxProgress,
EventStatusEnum *adStatus,
struct _Recordset *pRecordset)
{
CString strRecordsetCount;
long lRecordCount;
pRecordset->get_RecordCount(&lRecordCount);
strRecordsetCount.Format("Fetch progress %d",lRecordCount);
AfxMessageBox(strRecordsetCount);
return S_OK;
};
现在的问题是,从理论上说,既然Recordset对象动态属性集中的Initial Fetch Size和Background Fetch Size属性被设置为1000,且Recordset是以adAsyncFetch方式打开的,那么FetchProgress事件就应该被触发100次(100万记录数/1000),且每次触发时,pRecordset中记录了取得的1000条记录。可是我实际运行时,FetchProgress事件只被触发了一次(只显示了一次AfxMessageBox中的内容),且此时得到的lRecordCount值为1000000,实际的运行结果似乎和理论上的不一致,这是什么原因呢?如果这种方法不行,我又该以什么方法来实现我上述的需求呢?
- ADO技术访问数据库
- ADO数据库访问技术
- ADO数据库访问技术
- ADO数据库访问技术概述
- 数据库访问技术之ADO
- ADO.NET数据库访问技术
- ADO.NET数据库访问技术
- ADO数据库访问技术总结
- ADO.NET数据库访问技术
- ADO.NET数据库访问技术
- VC使用ADO技术访问数据库
- ODBC OLEDB ADO等数据库访问技术
- 使用ADO技术访问SQL 数据库
- ADO.NET数据库访问技术(一)
- ADO.NET数据库访问技术(二)
- ADO.net数据库访问技术(一)
- VC++的ADO技术访问sql server 2000数据库
- VC++数据库技术系列(二)ADO数据库访问技术概述
- MFC之subclass
- SQL Server 2005 Remote Access
- JavaScript FAQ(十一)——表单(Form)
- 奇虎是如何招聘并用好软件人才的
- 《顶点, 几何和像素着色器编程》全书目录
- ADO技术访问数据库
- [创业] 海归名词新解
- Google 2008十大产品
- 我对现代人爱情的几点看法!
- 1125 Stockbroker Grapevine 解题报告
- Apache for windows中错误的一些解决方法
- Linux 进程管理
- 内存管理[5]
- 转载__ Netfilter实现机制分析