实现批量记录提取 [英] Implementing bulk record fetching

查看:162
本文介绍了实现批量记录提取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的程序开始时,我需要从MS Access数据库(.mdb)读取数据到一个下拉控制。这样做的目的,只要在控制用户类型,应用程序可以自动完成。

At the start of my program, I need to read data from a MS Access database (.mdb) into a drop down control. This is done so that whenever the user types in that control, the application can auto-complete.

总之,从数据库中读取了永远,所以我想我会实现批量行获取。

Anyway, the reading from database took forever so I thought I'd implement bulk row fetching.

这是我有的代码:

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 p>

MultiRowset.cpp looks like:

#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 如下所示:

And in my database, the INFOTABLE looks like:

NAME    AGE
----    ---
Name1   Age1
Name2   Age2
      .
      .
      .
      .

我需要做的只是从数据库中读取数据。有人可以告诉我我做错了什么?我的代码现在的行为完全像一个正常的提取。没有发生大量抓取。

All I need to do is only read the data from the database. Can someone please tell me what I'm doing wrong? My code right now behaves exactly like a normal fetch. There's no bulk fetching happening.

编辑:

DBRFX.cpp ,并发现 RFX_Text_Bulk()初始化我传递的 m_NameData new char [nRowsetSize * nMaxLength]

I just poked around in DBRFX.cpp and found out that RFX_Text_Bulk() initializes my passed m_NameData as new char[nRowsetSize * nMaxLength]!

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

This means m_NameData is only a character array! I need to fetch multiple names, so wouldn't I need a 2D character array? The strangest thing is, the same RFX_Text_Bulk() initializes my passed m_NDCDataLengths as new long[nRowsetSize]. Why in the world would a character array need an array of lengths?!

推荐答案

您几乎得到了它的权利。要获取值,
我将更改你的

You almost got it right. To fetch the values, I would change your

        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选项

To fetch more than one row, remove the CRecordset::forwardOnly option

编辑2:您也可以保留CRecordset :: forwardonly,但添加CRecordset :: useExtendedFetch选项

EDIT 2 : You can also keep CRecordset::forwardonly, but add the CRecordset::useExtendedFetch option

这篇关于实现批量记录提取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆