プログラムの開始時に、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]
です。なぜ世界で文字配列に長さの配列が必要なのですか?!