在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字段输入参数无关。
终于搞定了关于多个字段排序之后的一些查找算法了。