问题:VC/MFC ADO ACCESS数据库:m_pRecordset->BOF和m_pRecordset->EndOfFile是不是不可靠?

xiaojie10090 2012-05-10 04:16:54
遇到了一个非常让我头疼的问题,下面是在一个对话框中一个“查看历史”按钮的程序,点击该按钮是要弹出历史记录对话框的:

void CRegion1Dlg::OnBnClickedHistory()
{
// TODO: 在此添加控件通知处理程序代码
m_pRecordset.CreateInstance(__uuidof(Recordset));
// 在ADO操作中建议语句中要常用try...catch()来捕获错误信息
// 因为它有时会经常出现一些意想不到的错误
try
{
m_pRecordset->Open("SELECT * FROM 区域1温湿度历史记录",m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
}
catch(_com_error *e)
{
AfxMessageBox(e->ErrorMessage());
}

try
{
if((m_pRecordset->BOF)&&(m_pRecordset->EndOfFile)) //就是这个地方,有时候历史记录明明清空了,但是却不进入if,而去执行else,将else里的对话框打开了,所以可能是括号内的条件不满足,所以我就感觉可能是用这种方法判断数据表是否为空不可靠
{
AfxMessageBox(_T("提示:无历史记录!"));
return ;
}
else
{
CRegion1HistoryDlg dlg;
if(!dlg.DoModal())
{
return;
}
}
}
catch(_com_error *e)
{
AfxMessageBox(e->ErrorMessage());
}
}

现在我具体描述一下这个让我非常头疼的问题:当数据表内有历史记录的时候,我点击“历史记录”按钮,肯定是会弹出历史记录对话框的,然后在历史记录对话框里面点击“清除历史记录按钮”将历史记录全部清除,然后关闭对话框回到原来的对话框,这时再点击“历史记录”按钮肯定是不会弹出历史记录对话框的,而是提示“无历史记录”,因为历史记录已经清除了,到目前为止是没有什么问题的;
然后问题就来了,就是我发现在数据表内有历史记录的时候,我第一次点击“历史记录”按钮,打开历史记录对话框,这个时候我不点击“清除历史记录按钮”,而是点击“关闭按钮”回到原对话框,然后再点击“历史记录按钮”再次弹出历史记录对话框,这个时候我再点击“清除历史记录按钮”将历史记录清除,然后点击“关闭按钮”回到原对话框,问题这就来了,再点击“历史记录按钮”没有提示“无历史记录”,而是打开了历史记录对话框!但是很显然,历史记录对话框里肯定是空空如也!后面再点击关闭,再点击“历史记录”,就正常提示,不会再弹出历史记录对话框了
请大神们指点迷津啊!头快炸了,也没想出来,我都在怀疑会不会是VS2010的Bug?
...全文
331 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaojie10090 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]
编辑错误
1.

if(!dlg.DoModal())
{
pRecordset->Close();
pRecordset.Release();
pRecordset = NULL;
return;
}
2.在函数CRegion1Dlg::OnBnClickedHistory()
退出的时候,也加上
pRecordset->Close();
pRecordset.Rele……
[/Quote]


再补充一下,这种方法问题依然存在%>_<%。。。。
还是的重新连接才好啊。。。。
xiaojie10090 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]
编辑错误
1.

if(!dlg.DoModal())
{
pRecordset->Close();
pRecordset.Release();
pRecordset = NULL;
return;
}

[/Quote]

这个地方我给补充一下,如果if括号中的条件是!dlg.DoModal(),那么
pRecordset->Close();
pRecordset.Release();
pRecordset = NULL;
要放到if语句的前面,也就是这样
pRecordset->Close();
pRecordset.Release();
pRecordset = NULL;
if(!dlg.DoModal())
{
return;
}
否则就要把!去掉,像下边这样
if(dlg.DoModal())
{
pRecordset->Close();
pRecordset.Release();
pRecordset = NULL;
return;
}
按你原先的那种写法,if中的语句是执行不了的,应该是dlg.DoModal()返回值为真的原因吧,这是我试出来的,呵呵
xiaojie10090 2012-05-14
  • 打赏
  • 举报
回复
多谢各位~
SONG_CA 2012-05-11
  • 打赏
  • 举报
回复
编辑错误
1.

if(!dlg.DoModal())
{
pRecordset->Close();
pRecordset.Release();
pRecordset = NULL;
return;
}
2.在函数CRegion1Dlg::OnBnClickedHistory()
退出的时候,也加上
pRecordset->Close();
pRecordset.Release();
pRecordset = NULL;


SONG_CA 2012-05-11
  • 打赏
  • 举报
回复
楼主,我赞同7楼的说法,其实有两个地方需要加记录集关闭代码
1.

if(!dlg.DoModal())
{
pRecordset->Close();
pRecordset.Release();
pRecordset = NULL;
}
2.在函数CRegion1Dlg::OnBnClickedHistory()
退出的时候,也加上
pRecordset->Close();
pRecordset.Release();
pRecordset = NULL;


return;
}
xiaojie10090 2012-05-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

pRecordset->Close();
pRecordset.Release();
pRecordset = NULL;

楼主应该不用重新连接数据。释放记录集然后重新生成记录集试试。应该是这里的问题
[/Quote]

这一招我试过了,一样,我怀疑跟模态对话框有关。。。
GPoint 2012-05-11
  • 打赏
  • 举报
回复
pRecordset->Close();
pRecordset.Release();
pRecordset = NULL;

楼主应该不用重新连接数据。释放记录集然后重新生成记录集试试。应该是这里的问题
xiaojie10090 2012-05-11
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

if((m_pRecordset->BOF)||(m_pRecordset->EndOfFile))
[/Quote]


我觉得“||”不如“&&”准确
xiaojie10090 2012-05-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

你可以用m_pRecordset->GetRecordCount()来得到的记录数来判断数据是否为空,但这种结果不一定准,想得到正确的结果应该先m_pRecordset->MoveLast();m_pRecordset->GetRecordCount();这样才能得到正确的结果
[/Quote]

如果数据表为空的话,MoveLast()会出错的吧
hdg3707 2012-05-10
  • 打赏
  • 举报
回复
你可以用m_pRecordset->GetRecordCount()来得到的记录数来判断数据是否为空,但这种结果不一定准,想得到正确的结果应该先m_pRecordset->MoveLast();m_pRecordset->GetRecordCount();这样才能得到正确的结果
xiaojie10090 2012-05-10
  • 打赏
  • 举报
回复
不是的,我找到问题了,呵呵,每次点击“历史记录”之后,最好再重新连接一下数据库,就是在上面的程序一开始加上:
m_pConnection.CreateInstance(__uuidof(Connection));
// 在ADO操作中建议语句中要常用try...catch()来捕获错误信息
// 因为它有时会经常出现一些意想不到的错误。
try
{
// 打开本地Access库LDSAMSDatabase.mdb
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=LDSAMSDatabase.mdb","","",adModeUnknown);
}
catch(_com_error e)
{
AfxMessageBox(_T("数据库连接失败!请联系管理员"));
return ;
}

至于判断表内数据是否为空,我感觉我那种写法就比较好,只有当两个同时满足时,才能肯定是空的
oyljerry 2012-05-10
  • 打赏
  • 举报
回复
if((m_pRecordset->BOF)||(m_pRecordset->EndOfFile))
BombZhang 2012-05-10
  • 打赏
  • 举报
回复
只要判断BOF就够了吧:
if((m_pRecordset->BOF))

4,011

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 数据库
社区管理员
  • 数据库
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧