关于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的代码。

为什么会报这样的错误呢?
...全文
212 点赞 收藏 13
写回复
13 条回复
JonnySun 2004年12月22日
>> 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好象不对,那样显示的出错信息
是“缺少刷新或更新的键列信息”
回复 点赞
JonnySun 2004年12月21日


像你這種方式用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);
回复 点赞
发动态
发帖子
数据库相关
创建于2007-08-02

1211

社区成员

8.8w+

社区内容

Delphi 数据库相关
社区公告
暂无公告