CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
英特尔®游戏设计大赛100美元现金周周送 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  数据库

ADO中,如何将指针移动到末记录?

楼主xggpro()2003-06-03 12:47:42 在 VC/MFC / 数据库 提问

在查询后返回到m_pRecordset里只有一条记录的情况下  
  m_pRecordset->MoveLast();  
   
  为什么会出现   C++   RUNTIME   ERROR?  
   
  如何判断m_pRecordset只有一条记录?  
  或者如何得到m_pRecordset里包含的记录数目? 问题点数:100、回复次数:34Top

1 楼llm06(blacksheep)回复于 2003-06-03 12:50:38 得分 0

m_pRecordset有一个属性recordcount,不过只对static的记录集有效。  
   
  m_pRecordset->MoveLast();  
   
  简单处理,使用  
  try  
  {  
  m_pRecordset->MoveLast();  
  }  
  catch(_com_error   e)  
  {  
  }就ok了Top

2 楼llm06(blacksheep)回复于 2003-06-03 12:52:48 得分 20

还有  
  使用   MoveLast   方法将当前记录位置移动到   Recordset   中的最后一个记录。Recordset   对象必须支持书签或向后光标移动;否则调用该方法将产生错误。  
   
  Top

3 楼bianhh(蓝色烟圈)回复于 2003-06-03 12:58:05 得分 0

try  
  {  
        if(!m_pRecordset->ADOEOF)  
            m_pRecordset->MOVELAST();  
  }catch(_com_error   e)  
  {  
   
  }Top

4 楼xggpro()回复于 2003-06-03 12:58:22 得分 0

怎样让Recordset支持支持书签或向后光标移动?  
   
  我就是不想用try   catch来处理啊Top

5 楼xggpro()回复于 2003-06-03 13:05:21 得分 0

我试过了  
  如果用try   catch处理的话可以不报错,但是达不到我要把指针移动到最后一条纪录的目的。  
   
  而且在Recordset里有多条纪录的情况下,还是会出错  
  看来应该是不支持书签或向后光标移动而出错的  
   
  怎样让Recordset支持支持书签或向后光标移动?  
  Top

6 楼xggpro()回复于 2003-06-03 13:39:33 得分 0

MoveFist没任何问题  
   
  为什么MoveLast就出现C++   RUNTIME   ERROR?  
   
  急Top

7 楼bysen()回复于 2003-06-03 16:04:03 得分 0

我试过一条记录然后movelast,是没问题的,建议你找找别的原因  
  是否open时的参数不对Top

8 楼llm06(blacksheep)回复于 2003-06-03 16:15:16 得分 0

_pConOracle.CreateInstance("ADODB.Connection");  
  /******************连接数据库********************/  
  try  
  {  
  _pConOracle->ConnectionTimeout   =   8;  
  _pConOracle->Open("Provider=oraoledb.oracle;Data   Source=wztc;User   ID=WZTC;Password=KWZTCJL;PLSQLRSet=1","","",adModeUnknown);  
  }  
  catch(_com_error   e)///捕捉异常  
  {  
  AfxMessageBox("无法连接到oracle数据库,请检查数据库连接设置,否则程序无法正常工作!");  
  }    
   
  _pROracle.CreateInstance("ADODB.Recordset");  
  try  
  {  
  _pROracle->CursorLocation=adUseClient;  
  _pROracle->Open((_variant_t)strsql,_variant_t((IDispatch   *)(_pConOracle),true),adOpenStatic,adLockBatchOptimistic,adCmdText);  
  }  
  catch   (_com_error   e)  
  {  
  }  
   
  看语句,我这样作就可以。检查一下连接字符串和open时的参数。连接的库不同,连接字符串会有不同Top

9 楼xggpro()回复于 2003-06-03 20:44:32 得分 0

void   CTabTwo::GetRecords(int   Operation)  
  {  
  UpdateData(TRUE);  
   
  CToolLibrary   ToolLib;  
  ToolLib.OpenConnection();  
   
  _bstr_t   Command   =   "select   *   from   ddflml";  
  _variant_t   RecordsAffected;  
  ToolLib.m_pRecordset   =   ToolLib.m_pConnection->Execute(Command,&RecordsAffected,adCmdText);  
   
   
  //  
  //记录为空  
  //  
   
  if(ToolLib.m_pRecordset->BOF   ||   ToolLib.m_pRecordset->adoEOF)    
  {  
  m_szCodeView   =   "";  
  m_szNameView   =   "";  
  m_szAreaView   =   "";  
  m_szLayerView   =   "";  
  m_szKindView   =   "";  
   
  UpdateData(FALSE);  
   
  ToolLib.m_pRecordset->Close();  
  ToolLib.m_pConnection->Close();  
   
  if   (Operation   ==   RECORED_NEXT)  
  {  
  iPostion--;  
  }  
  if   (Operation   ==   RECORED_PRE)  
  {  
  iPostion++;  
  }  
   
  return;  
  }  
   
   
  if((Operation   ==   RECORED_PRE)   ||   (Operation   ==   RECORED_NEXT))  
  {  
  m_szCodeView   =   "";  
  m_szNameView   =   "";  
  m_szAreaView   =   "";  
  m_szLayerView   =   "";  
  m_szKindView   =   "";  
   
  UpdateData(FALSE);  
   
  for   (int   i=1;   i<iPostion;i++)  
  {  
  ToolLib.m_pRecordset->MoveNext();  
  if   (ToolLib.m_pRecordset->adoEOF)  
  {  
  iPostion   =   i;  
  break;  
  }  
  }  
  }  
  else  
  {  
  if   (Operation   ==   RECORED_FIRST)  
  {  
  ToolLib.m_pRecordset->MoveFirst();  
  }  
  if   (Operation   ==   RECORED_LAST)  
  {  
  ToolLib.m_pRecordset->MoveLast();   //就这里出错,把这里改成ToolLib.m_pRecordset->MoveFirst();则没有问题  
  }  
  }  
   
   
   
   
   
  连接库的OpenConnection函数  
   
  BOOL   CToolLibrary::OpenConnection()  
  {  
  HRESULT   hr;  
  try  
  {  
  hr=m_pConnection.CreateInstance(__uuidof(Connection));///创建Connection对象  
  if(SUCCEEDED(hr))    
  {  
  char   buffer[128];  
  ZeroMemory(buffer,128);  
  CString   FilePath   =   MakeCurrentPath();  
  ::GetPrivateProfileString("database","Address",NULL,buffer,128,FilePath);  
  CString   szAddress   =   buffer;  
  ZeroMemory(buffer,128);  
  ::GetPrivateProfileString("database","UserName",NULL,buffer,128,FilePath);  
  CString   szUserName   =   buffer;  
  ZeroMemory(buffer,128);  
  ::GetPrivateProfileString("database","Password",NULL,buffer,128,FilePath);  
   
  CString   strCode   =   RestoreCode(buffer);  
  CString   szPassword   =   DecryptDes(strCode);  
   
  _bstr_t   DataString="Provider=SQLOLEDB;SERVER=";  
  _bstr_t   temp=_bstr_t(szAddress);  
  DataString+=temp;  
  DataString+=";DATABASE=arch;UID=";  
  DataString+=_bstr_t(szUserName);  
  DataString+=";   PWD=";  
  temp=_bstr_t(szPassword);  
  DataString+=temp;  
   
  hr=m_pConnection->Open(DataString,"","",adModeUnknown);  
  }  
  }  
  catch(_com_error   e)///捕捉异常    
  {  
  CString   errormessage;    
  errormessage.Format("连接数据库失败!程序即将退出,请联系系统管理员!\r\n错误信息:%s",e.ErrorMessage());  
  ::MessageBox(NULL,errormessage,"错误",MB_ICONWARNING);  
  ExitProcess(1);  
  }  
   
  return   TRUE;  
  }  
   
   
  我实在找不到问题出在哪里了Top

10 楼yangzhb2003()回复于 2003-06-04 08:53:17 得分 0

ToolLib.m_pRecordset->MoveNext();  
  if   (ToolLib.m_pRecordset->adoEOF)  
  {  
  iPostion   =   i;  
  break;  
  }  
  这一段应当改为  
   
  while(ToolLib.m_pRecordset->adoEOF)  
  {  
  ToolLib.m_pRecordset->MoveNext();  
  }  
  iPostion   =   i;  
  Top

11 楼yangzhb2003()回复于 2003-06-04 08:53:53 得分 0

其它类似地方也如此.Top

12 楼yangzhb2003()回复于 2003-06-04 08:57:05 得分 0

sorry  
  for   (int   i=1;   i<iPostion;i++)  
  {  
  ToolLib.m_pRecordset->MoveNext();  
  if   (ToolLib.m_pRecordset->adoEOF)  
  {  
  iPostion   =   i;  
  break;  
  }  
  }  
   
  改为:  
  int   i=0;  
  while(ToolLib.m_pRecordset->adoEOF)  
  {  
  ToolLib.m_pRecordset->MoveNext();  
  }  
  iPostion   =   i;  
   
   
  Top

13 楼xggpro()回复于 2003-06-04 13:56:37 得分 0

谢谢你的回复  
  不过你说的这段程序和出错的MoveLast那段程序块根本是不会同时执行的  
  你仔细看看那个if   else结构  
   
  换句话说,就是修改这段程序根本不会影响到MoveLast所在的那段程序  
   
  if((Operation   ==   RECORED_PRE)   ||   (Operation   ==   RECORED_NEXT))  
  {  
  m_szCodeView   =   "";  
  m_szNameView   =   "";  
  m_szAreaView   =   "";  
  m_szLayerView   =   "";  
  m_szKindView   =   "";  
   
  UpdateData(FALSE);  
   
  for   (int   i=1;   i<iPostion;i++)  
  {  
  ToolLib.m_pRecordset->MoveNext();  
  if   (ToolLib.m_pRecordset->adoEOF)  
  {  
  iPostion   =   i;  
  break;  
  }  
  }  
  }  
  else  
  {  
  if   (Operation   ==   RECORED_FIRST)  
  {  
  ToolLib.m_pRecordset->MoveFirst();  
  }  
  if   (Operation   ==   RECORED_LAST)  
  {  
  ToolLib.m_pRecordset->MoveLast();   //就这里出错,把这里改成ToolLib.m_pRecordset->MoveFirst();则没有问题  
  }  
  }  
  Top

14 楼yangzhb2003()回复于 2003-06-04 14:25:58 得分 0

if   (Operation   ==   RECORED_LAST)  
  {  
  ToolLib.m_pRecordset->MoveLast();   //就这里出错,把这里改成ToolLib.m_pRecordset->MoveFirst();则没有问题  
  }  
  改为:  
  if   (Operation   ==   RECORED_LAST)  
  {  
  if(!ToolLib.m_pRecordset->adoEOF)  
  ToolLib.m_pRecordset->MoveLast();   //就这里出错,把这里改成ToolLib.m_pRecordset->MoveFirst();则没有问题  
  }  
  Top

15 楼xggpro()回复于 2003-06-04 14:28:31 得分 0

没用  
  一样出错Top

16 楼quengzi(Hades)回复于 2003-06-04 14:40:23 得分 0

ado中要得到查询结果的记录数,一般都是返回-1(GetRecordCount),你可以用  
  “select   counts(*)   as   记录数   from   YoutTable   where   XXX"查询语句来获取记录数量  
  然后通过:  
  _variant_t   vt   ;  
  vt.clear();  
  vt   =   record->fields->getitem(_variant_t("记录数"))->value;  
  long   lcounts   =   0;  
  lcounts   =   vt.lval;Top

17 楼xggpro()回复于 2003-06-04 14:50:02 得分 0

现在我已经确定  
  不管返回的纪录集里有单条记录或者只有一条记录  
  MoveLast都会出错  
  但是MoveFist就没问题Top

18 楼xggpro()回复于 2003-06-04 14:50:32 得分 0

现在我已经确定  
  不管返回的纪录集里有单条记录或者有多条记录  
  MoveLast都会出错  
  但是MoveFist就没问题  
  Top

19 楼hooey(伍思水)回复于 2003-06-04 15:14:38 得分 0

不用着急,你可以试试下面的代码,别忘了给我加分,呵呵:  
  while(VARIANT_FALSE   ==   pRecSet->EndOfFile)  
  {  
      //干你该干的事情  
      。。。  
      //--------------  
      pRecSet->MoveNext();  
  }  
  这样保证到最后一条记录!!Top

20 楼xggpro()回复于 2003-06-04 16:19:21 得分 0

hooey(伍思水)   :  
   
  我现在的要求很简单。。。。  
  就是用Execute执行了SQL查询语句后,直接使用pRecSet->MoveLast();移动到最后一条记录。  
   
  你写的代码是可行的,但是效率很低,如果返回的记录集有很多的话,效率太低。。。。  
   
  问题是我现在直接MoveLast会出现C++   RUNTIME   ERROR  
  而用MoveNext或者MoveFirst都很正常Top

21 楼hooey(伍思水)回复于 2003-06-04 16:38:39 得分 0

你把错误信息照葫芦画瓢,会诊会诊!Top

22 楼xggpro()回复于 2003-06-04 17:48:25 得分 0

执行到  
  m_pRecordset->MoveLast();  
  弹出一对话框,  
  C++   Runtime   error!  
  Program:   e:\Project\test.exe  
   
  abnormal   program   termination  
   
  把m_pRecordset->MoveLast();改为  
  m_pRecordset->MoveFirst();  
  则没任何错误。。。。程序运行正常  
   
  整个函数代码已经在上面贴出来了  
   
  调用函数的代码  
  GetRecords(RECORED_LAST);  
   
  函数代码  
  void   CTabTwo::GetRecords(int   Operation)  
  {  
  UpdateData(TRUE);  
   
  CToolLibrary   ToolLib;  
  ToolLib.OpenConnection();  
   
  _bstr_t   Command   =   "select   *   from   ddflml";  
  _variant_t   RecordsAffected;  
  ToolLib.m_pRecordset   =   ToolLib.m_pConnection->Execute(Command,&RecordsAffected,adCmdText);  
   
   
  //  
  //记录为空  
  //  
   
  if(ToolLib.m_pRecordset->BOF   ||   ToolLib.m_pRecordset->adoEOF)    
  {  
  m_szCodeView   =   "";  
  m_szNameView   =   "";  
  m_szAreaView   =   "";  
  m_szLayerView   =   "";  
  m_szKindView   =   "";  
   
  UpdateData(FALSE);  
   
  ToolLib.m_pRecordset->Close();  
  ToolLib.m_pConnection->Close();  
   
  if   (Operation   ==   RECORED_NEXT)  
  {  
  iPostion--;  
  }  
  if   (Operation   ==   RECORED_PRE)  
  {  
  iPostion++;  
  }  
   
  return;  
  }  
   
   
  if((Operation   ==   RECORED_PRE)   ||   (Operation   ==   RECORED_NEXT))  
  {  
  m_szCodeView   =   "";  
  m_szNameView   =   "";  
  m_szAreaView   =   "";  
  m_szLayerView   =   "";  
  m_szKindView   =   "";  
   
  UpdateData(FALSE);  
   
  for   (int   i=1;   i<iPostion;i++)  
  {  
  ToolLib.m_pRecordset->MoveNext();  
  if   (ToolLib.m_pRecordset->adoEOF)  
  {  
  iPostion   =   i;  
  break;  
  }  
  }  
  }  
  else  
  {  
  if   (Operation   ==   RECORED_FIRST)  
  {  
  ToolLib.m_pRecordset->MoveFirst();  
  }  
  if   (Operation   ==   RECORED_LAST)  
  {  
  ToolLib.m_pRecordset->MoveLast();   //就这里出错,把这里改成ToolLib.m_pRecordset->MoveFirst();则没有问题  
  }  
  }  
   
   
   
   
   
  连接库的OpenConnection函数  
   
  BOOL   CToolLibrary::OpenConnection()  
  {  
  HRESULT   hr;  
  try  
  {  
  hr=m_pConnection.CreateInstance(__uuidof(Connection));///创建Connection对象  
  if(SUCCEEDED(hr))    
  {  
  char   buffer[128];  
  ZeroMemory(buffer,128);  
  CString   FilePath   =   MakeCurrentPath();  
  ::GetPrivateProfileString("database","Address",NULL,buffer,128,FilePath);  
  CString   szAddress   =   buffer;  
  ZeroMemory(buffer,128);  
  ::GetPrivateProfileString("database","UserName",NULL,buffer,128,FilePath);  
  CString   szUserName   =   buffer;  
  ZeroMemory(buffer,128);  
  ::GetPrivateProfileString("database","Password",NULL,buffer,128,FilePath);  
   
  CString   strCode   =   RestoreCode(buffer);  
  CString   szPassword   =   DecryptDes(strCode);  
   
  _bstr_t   DataString="Provider=SQLOLEDB;SERVER=";  
  _bstr_t   temp=_bstr_t(szAddress);  
  DataString+=temp;  
  DataString+=";DATABASE=arch;UID=";  
  DataString+=_bstr_t(szUserName);  
  DataString+=";   PWD=";  
  temp=_bstr_t(szPassword);  
  DataString+=temp;  
   
  hr=m_pConnection->Open(DataString,"","",adModeUnknown);  
  }  
  }  
  catch(_com_error   e)///捕捉异常    
  {  
  CString   errormessage;    
  errormessage.Format("连接数据库失败!程序即将退出,请联系系统管理员!\r\n错误信息:%s",e.ErrorMessage());  
  ::MessageBox(NULL,errormessage,"错误",MB_ICONWARNING);  
  ExitProcess(1);  
  }  
   
  return   TRUE;  
  }  
   
   
   
  Top

23 楼CharmDream()回复于 2003-06-04 19:12:30 得分 0

支持书签:  
  m_pConnection->CursorLocation   =   adUseClient;  
  m_pRecordset->CursorLocation   =   adUseClient;  
  ///   且记录集打开时不用adOpenForwardOnly  
  支持向后:  
  ///   只要记录集打开时不用adOpenForwardOnly应该都可以  
  Top

24 楼CharmDream()回复于 2003-06-04 19:13:12 得分 0

try   catch为什么不用,给我一个理由先Top

25 楼xggpro()回复于 2003-06-04 21:45:07 得分 0

CharmDream()   :  
  用try   catch可以捕捉到错误,但是并没有达到我的目的,记录集指针并没有移动到最后一条记录去。。。。。  
  Top

26 楼ahphone(阿丰--重出江湖,陌生的容颜)回复于 2003-06-04 23:04:31 得分 0

唉,再不行的话,就怀疑数据库了!  
  我看完前3张回帖我就觉得问题应该搞定了。Top

27 楼xggpro()回复于 2003-06-04 23:15:38 得分 0

唉。。。。。  
   
  我都不知该怎么办  
  FUCK。。。问题是除了MoveLast别的MoveNext和MoveFirst都可以。  
  还有BLOB存取都没有问题,INSERT和UPDATE都正常。Top

28 楼xggpro()回复于 2003-06-04 23:16:33 得分 0

问题一开始我怀疑是因为返回的记录集只有一条纪录的问题  
  结果发现在返回的纪录集有多条的情况下也一样地出错Top

29 楼xggpro()回复于 2003-06-05 11:22:55 得分 0

upTop

30 楼hooey(伍思水)回复于 2003-06-05 11:31:36 得分 80

请你用try...catch...结构调用下面代码现是错误信息:  
  void   dump_com_error(_com_error   &e)  
        {  
  printf("Error\n");  
  printf("\a\tCode   =   %08lx\n",   e.Error());  
  printf("\a\tCode   meaning   =     %s",   e.ErrorMessage());  
  _bstr_t   bstrSource(e.Source());  
  _bstr_t   bstrDescription(e.Description());  
  printf("\a\tSource   =   %s\n",   (LPCSTR)   bstrSource);  
  printf("\a\tDescription   =   %s\n",   (LPCSTR)   bstrDescription);  
        }Top

31 楼xggpro()回复于 2003-06-05 13:12:11 得分 0

IDispatch   error   #3108  
   
  Microsoft   OLE   DB   provider   for   SQL   server  
   
  Rowset   does   not   support   fetching   backward  
   
  上面是捕捉到的错误信息  
  如何解决?Top

32 楼hooey(伍思水)回复于 2003-06-05 14:00:35 得分 0

很明显了,你的结果集游标不是双向的!好好看看有关结果集的属性。老兄,这不会还要我贴代码了吧?祝你成功!Top

33 楼xggpro()回复于 2003-06-05 15:19:26 得分 0

hooey(伍思水)   :  
  对不起  
  我以前没接触过多少数据库编程。。。。。  
   
  提示一下。。。。怎样让集游标支持双向?  
  谢谢Top

34 楼rferen(流水)回复于 2003-06-05 23:50:51 得分 0

vb中是if   not   rs.eof   then    
                rs.movenext        
              end   if    
  vc中应该是if(!rs->adoEOF)     rs->MoveNext()Top

相关问题

  • 如何移动指针到指定的记录?Ado+Access
  • ado记录集的指针移动问题,在线等待,50分恭候
  • 怎么向前移动记录指针?
  • 记录指针
  • ODBC查询结果中,怎样移动记录指针?? 
  • 关于用PHP操纵Mysql记录集的指针移动
  • 用TQuery构件时如何移动记录内的指针
  • 关于对数据记录指针的移动问题
  • SqlDataReader读取记录时,怎么把指针往前移动?
  • 在DATASET.table中如何移动记录指针?

关键词

  • c++
  • 移动
  • 连接
  • 数据库
  • toollib
  • precordset
  • recored
  • movelast
  • 记录
  • ipostion

得分解答快速导航

  • 帖主:xggpro
  • llm06
  • hooey

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo