关于bookmark的问题!超级郁闷ing

waller 2004-12-21 03:55:45
我周末在家里写的程序,在家里编译后,运行,一切良好!
但是到了公司,执行exe文件,一旦执行到有bookmark的程序,就报错。
出错信息:Project pdtjc.exe raised exception class EoleException
with message '书签无效。'
我家里的机器配置是
Win2000 Server(pack2)+delphi6(pack1)+SQL Server 2000(pack2)
我公司的机器配置是
Win2000 Server(pack4)+delphi6(pack2)+SQL Server 2000(pack3)

我的程序是
procedure Tgytd_crxx.BitBtn3Click(Sender: TObject);
var bk:tbookmark;
begin
bk:= manage_data.ADOQuery1.GetBookmark;//获得书签
adoquery1.Edit;
adoquery1.Post;
manage_data.adoquery1.Close;
manage_data.ADOQuery1.SQL.Clear;
manage_data.ADOQuery1.SQL.Add('select * FROM crzdxx where 行政区编号='''+login.edit2.text+'''');
manage_data.ADOQuery1.ExecSQL;
manage_data.ADOQuery1.Open;
manage_data.ADOQuery1.GotoBookmark(bk);//重新获得书签
end;

我有两个form,
一个是manage_data,放了一个dbgrideh,adoquery,adoconnect,datasource等;
一个是gytd_crxx,有若干dbedit等,以及adoquery,adoconnect,datasource;
具体执行的流程是这样的:
选中manage_data中dbgrideh中记录,自动弹出gytd_crxx,在上面修改确认。
上面那段代码就是gytd_crxx中bitbtn3的代码。

为什么会报这样的错误呢?
...全文
310 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
>> yuvotesyg518(小不点)
>>如果记录删除了呢,locate会出错的。

這是你個人認為, 要不你先去嚐試下再來做結論!
sunkevin 2004-12-21
  • 打赏
  • 举报
回复
这么多人讲过了
yuvotesyg518 2004-12-21
  • 打赏
  • 举报
回复
如果记录删除了呢,locate会出错的。
还是用我的吧!!
waller 2004-12-21
  • 打赏
  • 举报
回复
搞定了。就是用
key:=adoquery1.fieldbyname('customerid').asstring;
adoquery1.locate('customerid',key,[]);
waller 2004-12-21
  • 打赏
  • 举报
回复
locate语句怎么用啊?
yuvotesyg518 2004-12-21
  • 打赏
  • 举报
回复
我用的是这样:
//定义书签
var
lcBookMark: String;
//书签工作过程,可能会抛出异常,不用管它。
try
lcBookMark:= ADOQuery.BookMark;
ADOQuery.Close;
ADOQuery.Open;
ADOQuery.BookMark:= lcBookMark;
except
end;
waller 2004-12-21
  • 打赏
  • 举报
回复
pinyu(品雨)说的直接refresh好象不对,那样显示的出错信息
是“缺少刷新或更新的键列信息”
  • 打赏
  • 举报
回复


像你這種方式用BOOKMark不出問題才怪!! 很多文章內不推荐使用bookmark.

還有種解決方案:

修改或刷新數據後用Locate定位!!!

key:=mydataset.fieldbyname('customerid').asstring;

所有你想要的操作...
.....


mydataset.locate('customerid',key,[]);

有個缺點是當數據量超大時,定位數據較慢!!


function Locate(const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean;


pinyu 2004-12-21
  • 打赏
  • 举报
回复
实在不行,你用另一个办法,保证不会错。那就是纪录下当前光标所在的主键值,或者具有唯一性约束的字段,等刷新数据后再重新locate到这条纪录上。
pinyu 2004-12-21
  • 打赏
  • 举报
回复
Most datasets try to maintain the current record position when you call refresh. However, this is not always possible. For example, the current record may have been deleted from the server by another user. Unidirectional datasets have no mechanism for locating the current record after a refresh, and always move back to the first record.

这是delphi的帮助文件说的refresh,在一定条件下是可以不用bookmark,也会保存当前光标的。所以如果你没删除当前光标所在的纪录或者插入(我猜测)新纪录,是可以不用bookmark,而直接调用refresh,从而不影响当前光标。
waller 2004-12-21
  • 打赏
  • 举报
回复
就如pinyu(品雨)说的那样,我就是“想用新窗口来修改数据,完毕后在旧窗口中刷新数据”
pinyu 2004-12-21
  • 打赏
  • 举报
回复
你这样肯定会错啊,数据机都变了,并且怎么在EXESQL后还Open?你应该删掉这句:manage_data.ADOQuery1.ExecSQL;
书签只能在对应的数据集上使用,都搞不懂你会什么要这么用,这样用的意图是什么?
其实你没有必要这么写的,我猜测你是想用新窗口来修改数据,完毕后在旧窗口中刷新数据,并且定位在原来的纪录上?那要是这样的话,我建议你这么写:
procedure Tgytd_crxx.BitBtn3Click(Sender: TObject);
var bk:tbookmark;
begin
bk:= manage_data.ADOQuery1.GetBookmark;//获得书签
adoquery1.Edit;
adoquery1.Post;
manage_data.ADOQuery1.refresh;
manage_data.ADOQuery1.GotoBookmark(bk);//重新获得书签
manage_data.ADOQuery1.FreeBookmark(bk);
end;
按照这样写的目的是我还不清楚refresh会不会引起当光标的变化,如果不会,那么你的书签就可以完全省略掉了。
bee2518 2004-12-21
  • 打赏
  • 举报
回复
先检查书签是否有效
if adodataset1.bookmarkvalid(MBookMark) then
ADODataSet1.GotoBookmark(MBookMark);

2,507

社区成员

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

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