c – 实现批量记录提取

在我的程序开始时,我需要从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,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初始化为新的char [nRowsetSize * nMaxLength]!

这意味着m_NameData只是一个字符数组!我需要获取多个名称,所以不需要一个2D字符数组?最奇怪的是,同样的RFX_Text_Bulk()会将传递的m_NDCDataLength初始化为new long [nRowsetSize].为什么在世界上一个字符数组需要一个长度的数组?

解决方法

你差点就对了要获取值,
我会改变你的
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 :: forwardonly,但添加CRecordset :: useExtendedFetch选项

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...