首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

对access开展循环查询操作,应该怎样优化比较好

2014-06-27 
对access进行循环查询操作,应该怎样优化比较好?比如我的代码如下所示:for (int i=0; i

对access进行循环查询操作,应该怎样优化比较好?
比如我的代码如下所示:



for (int i=0; i<szSecondRecordTypeArray.GetSize(); i++)
{
CString szSecondRecordTypeCode = szSecondRecordTypeArray.GetAt(i);
CString szMXRefSysSQL = "Select * from errorinfo where key_field = '" + szSecondRecordTypeCode + "'order by err_code";
         if(pset->Open(szMXRefSysSQL.GetBuffer(0)))
         {
              //具体操作
          }
}



我程序中的szSecondRecordTypeArray通常会很大,这样循环就会执行好多次,可能会有上千次查询,有没有什么好的方法对这种问题进行优化呢?这个程序运行时间太长了。数据库是Access的,索引我也建立了,会不会跟数据库执行效率有关呢?

非常感谢大家帮忙!
[最优解释]
引用:
引用:
1、取出所有的记录,sql语句:Select * from errorinfo。
2、以key_field为键,做一个map映射。
3、在查找时根据键值到map中去查找对应的数据。

对于几千到上万条数据的数据库来说,这样查询,效率可以极大的提高。


你好,能举一个详细点的例子吗?我之前没用过map类型,您给我贴一段数据库map映射的代码示例可以吗?我……


例子:
1、定义一个结构体,用于表示数据表中的一条记录.
struct SRecord
{
    __int64  m_nId;
    CString  m_strKeyField;
    ...
};

2、定义一个map类型的变量,用于存储从数据库的查询到的记录。
std::map<CString,SRecord*> m_mapRecords;

3、执行查询语句(Select * from errorinfo),将表中的数据一次性查询出来,遍历记录集,将查询出来
的数据存储到map中.
_RecordsetPtr pSet = m_pConnection->Open(_T("Select * from errorinfo"));
while (!pSet->adoEof)
{
    SRecord* pRecord = new SRecord();
    pRecord->m_nId = pSet->GetCollect(_T("Id"));
    pRecord->m_strKeyField = (char*)(_bstr_t)pSet->GetCollect(_T("key_field"));
    ...

    m_mapRecords[pRecord->m_strKeyField] = pRecord;

    pSet->MoveNext();
}

pSet->Close();

4、使用map进行快速查找

for (int i=0; i<szSecondRecordTypeArray.GetSize(); i++)
{
    CString szSecondRecordTypeCode = szSecondRecordTypeArray.GetAt(i);
    std::map<CString,SRecord*>::iterator ite =      m_mapRecords.find(szSecondRecordTypeCode);
    if (ite != m_mapRecords.end())
    {
        SRecord& pRecord = ite->second;
        ...///<得到你要的一条记录的数据,进行处理
    }
    else
    {
        ///<没有想要的数据,容错处理
    }
}

[其他解释]
把所有的记录集都查出来,在程序里面做按需读取。
数据量特别大的话换成SQL server或者Oracle试试。
SQL可以这样。

Select * from errorinfo  order by key_field, err_code

[其他解释]
1、取出所有的记录,sql语句:Select * from errorinfo。
2、以key_field为键,做一个map映射。
3、在查找时根据键值到map中去查找对应的数据。

对于几千到上万条数据的数据库来说,这样查询,效率可以极大的提高。
------其他解决方案--------------------


引用:
1、取出所有的记录,sql语句:Select * from errorinfo。
2、以key_field为键,做一个map映射。
3、在查找时根据键值到map中去查找对应的数据。

对于几千到上万条数据的数据库来说,这样查询,效率可以极大的提高。


你好,能举一个详细点的例子吗?我之前没用过map类型,您给我贴一段数据库map映射的代码示例可以吗?我自己搜了一下没找到具体的示例。谢谢了!
[其他解释]
引用:
比如我的代码如下所示:

C/C++ code


for (int i=0; i<szSecondRecordTypeArray.GetSize(); i++)
{
    CString szSecondRecordTypeCode = szSecondRecordTypeArray.GetAt(i);
    CString szMXRefSysSQL = "Select * from……

ADO里面有一个预编译技术,你可以参考一下ADO.NET,MSDN里面有这个技术的详细介绍。

推荐使用Xproer.OleDb类库。
过去对于开发人员来说在VC中进行数据库开发是一件并不轻松的事情,就算是一个简单的添加或者是删除操作都需要开发人员编写大量的代码。由于VC操作数据库需要使用一些特殊的语法和类型,这些类型没有统一的规范文档和示例,导致开发人员不能深理解。从而使得开发人员编写的代码不能简单高效。随着时间的推移这些代码最终将会变成产品的负担。因为它将影响产品的后续开发工作。

现在Xproer.OleDb类库采用全新的设计理念为VC数据库开发带来了革命性的变化。采用Xproer.OleDb类库将使得VC数据库开发工作变得比以往任何时侯都要简单。对于常用的增删改查功能开发人员再也不需要编写大量的代码了,甚至有时侯只需要编写一行代码就能实现删除功能。

由于良好的构架设计,开发人员能够根据业务需求来对Xproer.OleDb进行扩展和修改。借助于一些代码生成器,开发人员能够在10秒钟内实现对一张包含30个字段的数据表的所有操作(增,删,改,查)。对于信息管理系统的开发商来讲,这些改进将会成倍的提高公司的开发效率。新的设计为后期的维护工作节省了成本,对于系统后期的维护人员来讲,不再需要理解复杂的数据库操作代码,只需要关心业务逻辑,而且即便是调试代码也将会变得前所未有的轻松。

与同类C++库相比,Xproer.OleDb拥有更高的可扩展性,更佳的易用性。Xproer.OleDb不仅使用简单,而且开发文档完善,各种示例丰富。在信息管理系统领域Xproer.OleDb是企业的最佳组件。
在Xproer.OleDb的设计之初就充分考虑到了开发人员的需求,特别是在易用性和可扩展性方面做了许多的努力。如果一个组件的易用性非常差,用这个组件写出来的代码非常冗余,而且也难已理解,那么随着时间的推移这些代码将会使得项目越来越难已维护和升级,这相当于为一个商业项目埋下了一颗巨大的定时炸弹~。
,如果一个组件的易用性和可扩展性非常差,那么即便是这个组件功能再强大,开发人员也不愿意使用。因为一个难用的类库不仅给开发人员带来额外的负担,而且还使得项目开发成本几何式的增加。

无论是VC数据库开发新手,还是一个拥有多年VC数据库开发经验的人都能够在10分钟内掌握Xproer.OleDb类库的使用。Xproer.OleDb类库为开发人员带来的不仅是开发工作效率的提升,更是为解决更复杂的业务需求提供了最佳的解决方案。

以下示例演示如何从数据表中删除一条数据

#include "stdafx.h"
#include "XproerDataDef.h"
#include "OleDb/OleDbCommand.h"
#include "OleDb/OleDbConnection.h"
#include "OleDb/OleDbDataReader.h"
#include "OleDb/DataTable.h"
#include "OleDb/DataRow.h"
#include "OleDb/DataValue.h"

using namespace Xproer::OleDb;

int _tmain(int argc, _TCHAR* argv[])
{
::CoInitialize(NULL);
OleDbConnection con;
//设置Access数据库,兼容Access 97,Access 2000,Access 2003,Access 2007,Access 2010
con.SetAccessConStr(L"F:\\vc9\\adoDemo\\Debug\\db.mdb");
con.Open();

OleDbCommand cmd(&con);
//设置SQL命令
cmd.SetCommandText(L"delete from xdb_news where id=1"); 
cmd.ExecuteNonQuery();

con.Close();//关闭数据库连接

::CoUninitialize();
system("pause");
return 0;
}


以下示例演示对数据库的多种操作:

#include "stdafx.h"
#include "XproerDataDef.h"
#include "OleDb/OleDbCommand.h"
#include "OleDb/OleDbConnection.h"
#include "OleDb/OleDbDataReader.h"
#include "OleDb/DataTable.h"
#include "OleDb/DataRow.h"
#include "OleDb/DataValue.h"

using namespace Xproer::OleDb;

//获取DataTable的示例
void ADODataTable(OleDbCommand& cmd)
{
int count = 0;
cmd.ExecuteScalar(L"select count(*) from xdb_news",count);
auto_ptr<DataTable> table;
table.reset(cmd.ExecuteDataTable(L"select top 10 IsTop from xdb_news"));

size_t rowCount = table->GetRowsCount();
for (int i = 0 ; i < rowCount ; ++i)


{
DataRow* row = table->GetRow(i);
DataValue* val = row->GetCel(0);

printf("时间:%d \r\n", val->ToBoolean() );
}
}

//使用OleDbDataReader快速读取数据的示例
void ADORead(OleDbCommand& cmd)
{
OleDbDataReader* r = cmd.ExecuteReader(L"select ProductPrice from xdb_news");
USES_CONVERSION;
wstring title;
while(r->Read())
{
//r->GetString(0,title);
//printf("标题:%s \r\n",W2A(title.c_str()));
printf("ID:%f \r\n", r->GetFloat(0) );
}
r->Close();
}

//通过变量向数据库安全添加数据的示例
void ADOAdd(OleDbCommand& cmd)
{
cmd.SetCommandText(L"insert into xdb_about(VDouble) values(@VDouble)");
cmd.AddDoubleParam(L"@VDouble",125022.3180);

cmd.ExecuteNonQuery();
}

//高性能向数据库插入数据的示例
void ADOParam(OleDbCommand& cmd)
{
cmd.SetCommandText(L"delete from xdb_news where ID=@ID;");
cmd.AddInt32Param(L"@ID",886);
cmd.SetPrepared(true);

_variant_t index = (short)0;
_ParameterPtr param = cmd.GetCommand()->Parameters->GetItem(index);
param->Value = 887;
cmd.ExecuteNonQuery();
param->Value = 888;
cmd.ExecuteNonQuery();
param->Value = 889;
cmd.ExecuteNonQuery();
param->Value = 890;
cmd.ExecuteNonQuery();
param->Value = 891;
cmd.ExecuteNonQuery();
}

//向数据库添加实数的示例
void NumericScaleX(OleDbCommand& cmd)
{
OleDbDataReader* r = cmd.ExecuteReader(L"select ProductPrice from xdb_news");
_RecordsetPtr& rs = r->GetRecordsetPtr();
rs->MoveFirst();

_variant_t vi = (short)0;
FieldPtr fd = rs->Fields->GetItem(vi);
unsigned char numeri = fd->GetNumericScale();
unsigned char precision = fd->GetPrecision();

printf("GetNumericScale:%d\r\n", fd->GetNumericScale() );
printf("GetPrecision:%d\r\n", fd->GetPrecision() );
printf("Value:%f\r\n", (float)fd->Value );
r->Close();
}

int _tmain(int argc, _TCHAR* argv[])
{
::CoInitialize(NULL);
OleDbConnection con;
con.SetAccessConStr(L"F:\\vc9\\adoDemo\\Debug\\db.mdb");
con.Open();

OleDbCommand cmd(&con);

ADORead(cmd);

con.Close();

::CoUninitialize();
//printf("总数:%d",count);
system("pause");
return 0;
}



[其他解释]
推荐使用Xproer.OleDb类库。
过去对于开发人员来说在VC中进行数据库开发是一件并不轻松的事情,就算是一个简单的添加或者是删除操作都需要开发人员编写大量的代码。由于VC操作数据库需要使用一些特殊的语法和类型,这些类型没有统一的规范文档和示例,导致开发人员不能深理解。从而使得开发人员编写的代码不能简单高效。随着时间的推移这些代码最终将会变成产品的负担。因为它将影响产品的后续开发工作。

现在Xproer.OleDb类库采用全新的设计理念为VC数据库开发带来了革命性的变化。采用Xproer.OleDb类库将使得VC数据库开发工作变得比以往任何时侯都要简单。对于常用的增删改查功能开发人员再也不需要编写大量的代码了,甚至有时侯只需要编写一行代码就能实现删除功能。

由于良好的构架设计,开发人员能够根据业务需求来对Xproer.OleDb进行扩展和修改。借助于一些代码生成器,开发人员能够在10秒钟内实现对一张包含30个字段的数据表的所有操作(增,删,改,查)。对于信息管理系统的开发商来讲,这些改进将会成倍的提高公司的开发效率。新的设计为后期的维护工作节省了成本,对于系统后期的维护人员来讲,不再需要理解复杂的数据库操作代码,只需要关心业务逻辑,而且即便是调试代码也将会变得前所未有的轻松。

与同类C++库相比,Xproer.OleDb拥有更高的可扩展性,更佳的易用性。Xproer.OleDb不仅使用简单,而且开发文档完善,各种示例丰富。在信息管理系统领域Xproer.OleDb是企业的最佳组件。
在Xproer.OleDb的设计之初就充分考虑到了开发人员的需求,特别是在易用性和可扩展性方面做了许多的努力。如果一个组件的易用性非常差,用这个组件写出来的代码非常冗余,而且也难已理解,那么随着时间的推移这些代码将会使得项目越来越难已维护和升级,这相当于为一个商业项目埋下了一颗巨大的定时炸弹~。
,如果一个组件的易用性和可扩展性非常差,那么即便是这个组件功能再强大,开发人员也不愿意使用。因为一个难用的类库不仅给开发人员带来额外的负担,而且还使得项目开发成本几何式的增加。



无论是VC数据库开发新手,还是一个拥有多年VC数据库开发经验的人都能够在10分钟内掌握Xproer.OleDb类库的使用。Xproer.OleDb类库为开发人员带来的不仅是开发工作效率的提升,更是为解决更复杂的业务需求提供了最佳的解决方案。

以下示例演示如何从数据表中删除一条数据


#include "stdafx.h"
#include "XproerDataDef.h"
#include "OleDb/OleDbCommand.h"
#include "OleDb/OleDbConnection.h"
#include "OleDb/OleDbDataReader.h"
#include "OleDb/DataTable.h"
#include "OleDb/DataRow.h"
#include "OleDb/DataValue.h"

using namespace Xproer::OleDb;

int _tmain(int argc, _TCHAR* argv[])
{
::CoInitialize(NULL);
OleDbConnection con;
//设置Access数据库,兼容Access 97,Access 2000,Access 2003,Access 2007,Access 2010
con.SetAccessConStr(L"F:\\vc9\\adoDemo\\Debug\\db.mdb");
con.Open();

OleDbCommand cmd(&con);
//设置SQL命令
cmd.SetCommandText(L"delete from xdb_news where id=1"); 
cmd.ExecuteNonQuery();

con.Close();//关闭数据库连接

::CoUninitialize();
system("pause");
return 0;
}


以下示例演示对数据库的多种操作:

#include "stdafx.h"
#include "XproerDataDef.h"
#include "OleDb/OleDbCommand.h"
#include "OleDb/OleDbConnection.h"
#include "OleDb/OleDbDataReader.h"
#include "OleDb/DataTable.h"
#include "OleDb/DataRow.h"
#include "OleDb/DataValue.h"

using namespace Xproer::OleDb;

//获取DataTable的示例
void ADODataTable(OleDbCommand& cmd)
{
int count = 0;
cmd.ExecuteScalar(L"select count(*) from xdb_news",count);
auto_ptr<DataTable> table;
table.reset(cmd.ExecuteDataTable(L"select top 10 IsTop from xdb_news"));

size_t rowCount = table->GetRowsCount();
for (int i = 0 ; i < rowCount ; ++i)
{
DataRow* row = table->GetRow(i);
DataValue* val = row->GetCel(0);

printf("时间:%d \r\n", val->ToBoolean() );
}
}

//使用OleDbDataReader快速读取数据的示例
void ADORead(OleDbCommand& cmd)
{
OleDbDataReader* r = cmd.ExecuteReader(L"select ProductPrice from xdb_news");
USES_CONVERSION;
wstring title;
while(r->Read())
{
//r->GetString(0,title);
//printf("标题:%s \r\n",W2A(title.c_str()));
printf("ID:%f \r\n", r->GetFloat(0) );
}
r->Close();
}

//通过变量向数据库安全添加数据的示例
void ADOAdd(OleDbCommand& cmd)
{
cmd.SetCommandText(L"insert into xdb_about(VDouble) values(@VDouble)");
cmd.AddDoubleParam(L"@VDouble",125022.3180);

cmd.ExecuteNonQuery();
}

//高性能向数据库插入数据的示例
void ADOParam(OleDbCommand& cmd)
{
cmd.SetCommandText(L"delete from xdb_news where ID=@ID;");
cmd.AddInt32Param(L"@ID",886);
cmd.SetPrepared(true);

_variant_t index = (short)0;
_ParameterPtr param = cmd.GetCommand()->Parameters->GetItem(index);
param->Value = 887;
cmd.ExecuteNonQuery();
param->Value = 888;
cmd.ExecuteNonQuery();
param->Value = 889;
cmd.ExecuteNonQuery();
param->Value = 890;
cmd.ExecuteNonQuery();
param->Value = 891;
cmd.ExecuteNonQuery();
}

//向数据库添加实数的示例
void NumericScaleX(OleDbCommand& cmd)
{
OleDbDataReader* r = cmd.ExecuteReader(L"select ProductPrice from xdb_news");


_RecordsetPtr& rs = r->GetRecordsetPtr();
rs->MoveFirst();

_variant_t vi = (short)0;
FieldPtr fd = rs->Fields->GetItem(vi);
unsigned char numeri = fd->GetNumericScale();
unsigned char precision = fd->GetPrecision();

printf("GetNumericScale:%d\r\n", fd->GetNumericScale() );
printf("GetPrecision:%d\r\n", fd->GetPrecision() );
printf("Value:%f\r\n", (float)fd->Value );
r->Close();
}

int _tmain(int argc, _TCHAR* argv[])
{
::CoInitialize(NULL);
OleDbConnection con;
con.SetAccessConStr(L"F:\\vc9\\adoDemo\\Debug\\db.mdb");
con.Open();

OleDbCommand cmd(&con);

ADORead(cmd);

con.Close();

::CoUninitialize();
//printf("总数:%d",count);
system("pause");
return 0;
}



[其他解释]
引用:
引用:

引用:
1、取出所有的记录,sql语句:Select * from errorinfo。
2、以key_field为键,做一个map映射。
3、在查找时根据键值到map中去查找对应的数据。

对于几千到上万条数据的数据库来说,这样查询,效率可以极大的提高。


你好,能举一个详细点的例子吗?我之前没用过map类型,您给我贴一段数据库ma……

讲的很详细,我明白了!非常感谢!好人一生平安!呵呵

热点排行