实现批量记录抓取
Implementing bulk record fetching
在我的程序开始时,我需要从MS Access数据库(.mdb)读取数据到下拉控件。这样做是为了无论何时用户在该控件中输入,应用程序都可以自动完成。
无论如何,从数据库读取花了很长时间,所以我想我应该实现批量行读取。
这是我的代码:
CString sDsn;
CString sField;
sDsn.Format("ODBC;DRIVER={%s};DSN='';DBQ=%s",sDriver,sFile);
TRY
{
// Open the database
database.Open(NULL,false,false,sDsn);
// Allocate the rowset
CMultiRowset recset( &database );
// Build the SQL statement
SqlString = "SELECT NAME "
"FROM INFOTABLE";
// Set the rowset size. These many rows will be fetched in one bulk operation
recset.SetRowsetSize(25);
// Open the rowset
recset.Open(CRecordset::forwardOnly, SqlString, CRecordset::readOnly | CRecordset::useMultiRowFetch);
// Loop through each rowset
while( !recset.IsEOF() )
{
int rowsFetched = (int)recset.GetRowsFetched(); // This value is always 1 somehow
for( int rowCount = 1; rowCount <= rowsFetched; rowCount++ )
{
recset.SetRowsetCursorPosition(rowCount);
recset.GetFieldValue("NAME",sField);
m_nameDropDown.AddString(sField);
}
// Go to next rowset
recset.MoveNext();
}
// Close the database
database.Close();
}
CATCH(CDBException, e)
{
// If a database exception occured, show error msg
AfxMessageBox("Database error: "+e->m_strError);
}
END_CATCH;
MultiRowset.cpp
看起来像:
#include "stdafx.h"
#include "afxdb.h"
#include "MultiRowset.h"
// Constructor
CMultiRowset::CMultiRowset(CDatabase *pDB)
: CRecordset(pDB)
{
m_NameData = NULL;
m_NameDataLengths = NULL;
m_nFields = 1;
CRecordset::CRecordset(pDB);
}
void CMultiRowset::DoBulkFieldExchange(CFieldExchange *pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text_Bulk(pFX, _T("[NAME]"), &m_NameData, &m_NameDataLengths, 30);
}
MultiRowset.h
看起来像:
#if !defined(__MULTIROWSET_H_AD12FD1F_0566_4cb2_AE11_057227A594B8__)
#define __MULTIROWSET_H_AD12FD1F_0566_4cb2_AE11_057227A594B8__
class CMultiRowset : public CRecordset
{
public:
// Field data members
LPSTR m_NameData;
// Pointers for the lengths of the field data
long* m_NameDataLengths;
// Constructor
CMultiRowset(CDatabase *);
// Methods
void DoBulkFieldExchange(CFieldExchange *);
};
#endif
在我的数据库中,INFOTABLE
看起来像:
NAME AGE
---- ---
Name1 Age1
Name2 Age2
.
.
.
.
所有我需要做的只是读取从数据库的数据。谁能告诉我我做错了什么吗?我的代码现在的行为就像一个正常的取回。没有批量抓取。
编辑:我只是在DBRFX.cpp
中戳了一下,发现RFX_Text_Bulk()
将我传递的m_NameData
初始化为new char[nRowsetSize * nMaxLength]
!
这意味着m_NameData
只是一个字符数组!我需要获取多个名称,所以我不需要一个2D字符数组吗?最奇怪的是,同样的RFX_Text_Bulk()
将我传递的m_NDCDataLengths
初始化为new long[nRowsetSize]
。为什么字符数组需要长度数组?
根据http://msdn.microsoft.com/en-us/library/77dcbckz.aspx#_core_how_crecordset_supports_bulk_row_fetching你必须打开CRecordset与CRecordset::useMultiRowFetch标志之前调用SetRowsetSize:
要实现批量行抓取,必须指定参数dwOptions中的CRecordset::useMultiRowFetch选项打开成员函数。若要更改行集大小的设置,请调用SetRowsetSize .
你几乎答对了。要获取这些值,我会改变你的
for( int rowCount = 1; rowCount <= rowsFetched; rowCount++ )
{
recset.SetRowsetCursorPosition(rowCount);
recset.GetFieldValue("NAME",sField);
m_nameDropDown.AddString(sField);
}
被像这样的
for( int nPosInRowset = 0; nPosInRowset < rowsFetched; nPosInRowset++ )
{
//Check if value is null
if (*(recset.m_NameDataLengths + nPosInRowset) == SQL_NULL_DATA)
continue;
CString csComboString;
csComboString = (recset.m_NameData + (nPosInRowset * 30)); //Where 30 is the size specified in RFX_Text_Bulk
m_nameDropDown.AddString(csComboString);
}
编辑:获取多行,删除CRecordset::forwardOnly选项
编辑2:您也可以保持CRecordset::forward - only,但添加CRecordset::useExtendedFetch选项
刚刚遇到了同样的问题。您应该在recset.Open()
中使用dwOptions
参数的CRecordset::useMultiRowFetch
,而不是CRecordset::readOnly | CRecordset::useMultiRowFetch
。
EDIT:-重新检查后,这里是情况-当使用批量记录集并使用CRecordset::forwardOnly
和CRecordset::readOnly
打开时,您还必须在dwOptions
中指定CRecordset::useExtendedFetch
。对于其他类型的滚动,使用CRecordset::readOnly | CRecordset::useMultiRowFetch
就可以了。
- 为什么这个加载函数只抓取文件中的第一件事?
- 无法使用 OpenCv 3.4.5 从具有C++ dll 的网络摄像机 (rtsp) 中抓取帧
- 如何从日志文件中抓取状态代码?(在 C++ 中)
- DXGI API:AcquireTextFrame()从不抓取更新的图像,始终为空
- 如何从 avi 文件中抓取所有帧 - 如何修改 MS 样本采集卡样本
- 如何抓取指向Qt中弹出对话框的指针,该对话框阻止了QTest中的UI线程
- 为什么抓取窗口标题的代码会导致应用崩溃?
- 用Xcb而不是Xlib抓取像素的颜色
- 如何在C ++(qt)代码中使用python脚本?(网页抓取方面)
- OpenCV 3.2 在抓取时提供选择超时,但 fscyber 可以工作
- 使用 Matrox 进行帧抓取
- C++生产者使用者中,同一使用者线程会抓取所有任务
- 在编译时间之前抓取常数值
- OpenCV + QML(从另一个线程抓取帧)
- OpenCV视频捕获抓取和检索
- 从文本中抓取句子,将所有句子分别存储在某个数据结构中
- 视频抓取不起作用 OpenCV
- 不抓取时的QGraphicsPixmapItem mouseMoveEvent
- 从二进制文件中抓取文本时,为什么 xdg_vtnr=8 是我的结果
- 实现批量记录抓取