EDB 数据库实现多字段排序的问题。

在Wince6.0里面实现EDB数据库多字段排序一直没有新的进展,始终只能够实现一个字段的排序,不知道哪里出了问题,代码附上:

按照设想,将 PINYIN_QUANPIN 作为主排序字段,MAINMOBILE作为辅助排序的字段 创建数据卷及数据库:

 SORTORDERSPECEX dbSortInfo;
 dbSortInfo.wVersion = 2;
 dbSortInfo.wNumProps = 2;

 dbSortInfo.wKeyFlags = 0;
 dbSortInfo.rgPropID[0] =PINYIN_QUANPIN;
 dbSortInfo.rgdwFlags[0] = CEDB_SORT_CASEINSENSITIVE;

 dbSortInfo.rgPropID[1] = MAINMOBILE;
 dbSortInfo.rgdwFlags[1] = CEDB_SORT_CASEINSENSITIVE;
 if (!m_database.CreateDataBase(CEPropSpec, nFieldIndex, &dbSortInfo, 1))//将原来的dbSortInfo.wNumProps修改成1,因为参数排序的字段是一个而不是两个

 {
  MessageBox(L"创建数据库失败", L"ERROR", MB_OK);
  return ;
 }

 

函数m_database.CreateDataBase 的实现如下:

BOOL CDataBase::CreateDataBase(PCEPROPSPEC CEPropSpec, int nPropCount, SORTORDERSPECEX *pdbSortInfo, int ndbSortCount)
{
 BOOL ret = FALSE;//, bExit = FALSE;
 if(m_szVolumName == NULL || m_szDbaseName== NULL)
  return FALSE;

 

 CEDBASEINFOEX info = {0};
 info.wVersion = 2;
 info.wNumSortOrder = ndbSortCount; //由参数传如应该参与排序创建数据库的字段

 info.dwFlags = (CEDB_VALIDNAME | CEDB_VALIDTYPE | CEDB_VALIDSORTSPEC);
 wcscpy(info.szDbaseName, m_szDbaseName);
 info.dwDbaseType = 0x777;
 info.dwSize = nPropCount; 
 info.dwNumRecords = 1500;

/* for(int i=0; i < ndbSortCount; i++)
 {
  info.rgSortSpecs[0].rgPropID[i] = pdbSortInfo->rgPropID[i];
  info.rgSortSpecs[0].rgdwFlags[i] = pdbSortInfo->rgdwFlags[i];
  info.rgSortSpecs[0].wKeyFlags = pdbSortInfo->wKeyFlags;
  info.rgSortSpecs[0].wNumProps = pdbSortInfo->wNumProps;
  info.rgSortSpecs[0].wReserved = pdbSortInfo->wReserved;
  info.rgSortSpecs[0].wVersion = pdbSortInfo->wVersion;
 }*/

 

//这样书写才是正确的,以上写法错误

 for(int i=0; i < ndbSortCount; i++)
 {
  info.rgSortSpecs[i] = pdbSortInfo[i];
 }

 

 ret = CeMountDBVolEx(&m_guid, m_szVolumName, NULL, CREATE_NEW);//CREATE_NEW
 int nError = GetLastError();
 if(nError == ERROR_ALREADY_EXISTS)//数据库卷存在
 {
  ret = CeMountDBVolEx(&m_guid, m_szVolumName, NULL, OPEN_ALWAYS);//OPEN_EXISTING
 }
 if(ret == FALSE)
 {
  RETAILMSG(1, (TEXT("CreateDataBase FAILED 2 nError=%d"), GetLastError() ));
  return FALSE;
 }

 if((m_oid = CeCreateDatabaseWithProps(&m_guid, &info, nPropCount, CEPropSpec)) == NULL)
 {
  nError = GetLastError();
  if(ERROR_DUP_NAME == nError)//数据库已经在卷中存在
  {
   CeUnmountDBVol(&m_guid);
   CREATE_SYSTEMGUID(&m_guid);
   m_oid = 0;
   m_hDataBaseHandle = NULL;
   SetLastError(0);
   return TRUE;
  }
  CeUnmountDBVol(&m_guid);
  CREATE_SYSTEMGUID(&m_guid);
  m_oid = 0;
  m_hDataBaseHandle = NULL;
  SetLastError(nError);
  RETAILMSG(1, (TEXT("CreateDataBase FAILED 3 nError=%d"), nError ));
  return FALSE;
 }

 CeUnmountDBVol(&m_guid);
 return TRUE;
}

此后,数据库卷以及数据库创建成功

然后打开空的数据库,方式如下:

 SORTORDERSPECEX dbSortInfo;
 dbSortInfo.wVersion = 2;
 dbSortInfo.wNumProps = 2;
 dbSortInfo.wKeyFlags = 0; 
 dbSortInfo.rgPropID[0] = OPPO_PINYIN_QUANPIN;
 dbSortInfo.rgdwFlags[0] = CEDB_SORT_CASEINSENSITIVE;

 dbSortInfo.rgPropID[1] = OPPO_MAINMOBILE;
 dbSortInfo.rgdwFlags[1] = CEDB_SORT_CASEINSENSITIVE;

 if(!m_database.OpenDataBase(&dbSortInfo))
 {
  MessageBox(L"打开数据库失败", L"ERROR", MB_OK);
  return ;
 }
 return ;

 

BOOL CDataBaseDll::OpenDataBase(SORTORDERSPECEX *pdbSortInfo)
{
 BOOL ret = FALSE;
 int dwError = 0;
 if(m_szVolumName == NULL || m_szDbaseName== NULL)
  return FALSE;

 ret = CeMountDBVolEx(&m_guid, m_szVolumName, NULL, OPEN_ALWAYS);
 if(ret == FALSE)
 {
  RETAILMSG(1, (TEXT("OpenDataBase FAILED 1 nError=%d"), GetLastError()));
  return FALSE;
 }

 HANDLE hSession = CeCreateSession(&m_guid);
 CloseHandle(m_hDataBaseHandle);

 if((m_hDataBaseHandle = CeOpenDatabaseInSession(hSession, &m_guid, &m_oid, m_szDbaseName, pdbSortInfo, 0, NULL)) == INVALID_HANDLE_VALUE)
 {
  dwError = GetLastError();
  CeUnmountDBVol(&m_guid);
  CREATE_SYSTEMGUID(&m_guid);
  m_oid = 0;
  m_hDataBaseHandle = NULL;
  SetLastError(dwError);
  return FALSE;
 }

 return TRUE;
}

 

这样打开数据库也没有任何错误。

然后就是一直让里面写入具体的纪录内容了。写完之后再用另一个应用程序以上面相同的方式打开数据库,可以看到内容是以PINYIN_QUANPIN字段进行排序读出来的。

这个时候,我又想以MAINMOBILE字段进行查找某个字段,定位方式如下:

CEPROPVAL CEpropval[2];

 CEpropval[0].propid = PINYIN_QUANPIN;
 CEpropval[0].val.lpwstr = L"";

CEpropval[1].propid = MAINMOBILE;
CEpropval[1].val.lpwstr = strSearch.GetBuffer();

 

CEOID oid = theApp.m_Contact.SeekToValueGreater(CEpropval);

 while(oid)
 {
  theApp.m_Contact.ReadRecord();
  oid = theApp.m_Contact.SeekToNext();
 }

 

这样的出的结果是以PINYIN_QUANPIN字段来进行数据定位,确实与MAINMOBILE字段输入参数无关。

 

 终于搞定了关于多个字段排序之后的一些查找算法了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值