ADO中,如何将指针移动到末记录?
在查询后返回到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



