十万火急!!!急!急!急!Delphi中Table的onUpdateRecord 事件到底是什么回事?

watermelon 2000-05-13 03:23:00
在Delphi中,有一个表Table1,将其CachedUpdate属性设为true,当增、删、改多条记录后,一起用一按钮
的单击来提交,在其OnClick事件中写入——

Table1.ApplyUpdates;

当需要处理缓冲区数据同时,还需要在Table的onUpdateRecord 事件写代码中,而Table1.ApplyUpdate;
会每提交一条记录就会自动触发一次Table的onUpdateRecord 事件,于是出现——

Project Project1.exe raised exception class EBDEEnginError with message 'Table is read only'

的出错信息。若不引用Table的onUpdateRecord 事件则一点没有问题,但我又必须只在Table的onUpdateRecord
事件中写语句——百般苦苦思索却不得其解,几天几夜,滴米未进,形销骨立,今以csdn允许能给到的最高分
求解,请各位高手多多指点!凡回答问题者均有分!深深鞠躬!!!多谢!

(Delphi5 + SQL Server 7.0)
...全文
497 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
halfdream 2000-05-14
  • 打赏
  • 举报
回复
commitupdates 只是清空缓存。
OnUpdateRecord赋了值后,ApplyUpdates 只是调用你写的。
如果用TUpdateSQL,设TTable->UpdateObject指向它后,
鼠标右键选择UpdateSQL Editor...
然后,这样加几句就行了。
UpdateSQL1->SetParams(UpdateKind);
UpdateSQL1->ExecSQL(UpdateKind);
//。。这儿加什么,随你。。
UpdateAction=uaApplied;
另外,你说的那些commit什么的,都是事务处理,也就是说是利用服务器对事务的
支持,那是另一回事,为了清楚,把它放在一边吧。
BCB和DELPHI 数据库有个特点是把相当部分的操作放到非数据库服务端完成,以
减经服务器负担。缓存更新则体现了这一点。
强烈建议你用sql monitor 跟踪一下,仔细想想,你会明白怎么回事的。
只要理解其中的原理,概念虽杂,但还是可以理解的。
watermelon 2000-05-13
  • 打赏
  • 举报
回复
我这个问题解决了!!添加一个TUpdateSQL控件,并设置其属性,之后把Table的UpdateObject属性设为该控件,最后在OnUpdateRecoud事件如下处理即可。
void __fastcall TDbase::TprovinceUpdateRecord(TDataSet *DataSet,
TUpdateKind UpdateKind, TUpdateAction &UpdateAction)
{
UpdateSQL->Apply(UpdateKind);
UpdateAction=uaApplied;
}
watermelon 2000-05-13
  • 打赏
  • 举报
回复
回KXY:假如不使用TUpdateSQL控件和设置Table的UpdateObject属性,就不能把缓存里的记录提交吗?我写如下的语句没有办法保存这些记录。
Fmain->Database1->StartTransaction();
Dbase->Tprovince->ApplyUpdates();
Fmain->Database1->Commit();
Dbase->Tprovince->CommitUpdates();
请问这是怎么的情况呢?
watermelon 2000-05-13
  • 打赏
  • 举报
回复
回KXY:假如不使用TUpdateSQL控件和设置Table的UpdateObject属性,就不能把缓存里的记录提交吗?我写如下的语句却没有办法保存这些记录。
Fmain->Database1->StartTransaction();
Dbase->Tprovince->ApplyUpdates();
Fmain->Database1->Commit();
Dbase->Tprovince->CommitUpdates();
请问这是怎么的情况呢?
watermelon 2000-05-13
  • 打赏
  • 举报
回复
回kxy: 就是我不是将表Table1的CachedUpdate属性设为true了吗,
但在Table1的UpdateRecord事件中加入UpDateAction := uaApplied; 后
我在对Table1表进行加、删、改多条记录后,实际却保存不住,反正加、删、改
的结果写不进数据库!
我是用如下语句来提交所修改的记录:
Table1.ApplyUpdate;
Table1.CommitUpdate;
kxy 2000-05-13
  • 打赏
  • 举报
回复
李维的《delphi3.0从入门到精通〉对使用CachedUpdate和UpdateSql有很好
的解释,delphi 的demo中有一个CachedUpdate和Updatesql的例子。
watermelon 2000-05-13
  • 打赏
  • 举报
回复
回halfdream:谢谢你的指点,请问该怎么添加更新代码,TUpdateSQL不是用来处理read_only的查询结果的吗?假如配合使用TUpdateSQL,那该怎么处理?
halfdream 2000-05-13
  • 打赏
  • 举报
回复
在那个事件最后应该加上一句:
UpdateAction=uaApplied;不然系统就认为没有更新没有成功。
即提示出数据集只读。但是这样数据集实际上没有更新。
那OnUpdateRecord我的理解是这样。
一旦定义了这个事件,则要自己添加更新代码。系统不再做更新处理,
所以常要配合TUpdateSQL一起运用。
watermelon 2000-05-13
  • 打赏
  • 举报
回复
回kxy: 就是我不是将表Table1的CachedUpdate属性设为true了吗,
但在Table1的UpdateRecord事件中加入UpDateAction := uaApplied; 后
我在对Table1表进行加、删、改多条记录后,实际却保存不住,反正加、删、改
的结果写不进数据库!
我是用如下语句来提交所修改的记录:
Table1.ApplyUpdate;
Table1.CommitUpdate;
kxy 2000-05-13
  • 打赏
  • 举报
回复
没有明白你的意思:)
watermelon 2000-05-13
  • 打赏
  • 举报
回复
回kxy: 假如UpDateAction := uaApplied的话,缓存里的记录不能保存,而且OnUpdateRecord事件所操作的是同一条记录(同时编辑多条记录的情况下)。请指点,谢谢!
kxy 2000-05-13
  • 打赏
  • 举报
回复
sorry,我多层的应用看多了,
你的写法是对的,但是OnUpdateRecord的处理不对,请看delphi的help
UpdateAction indicates the action taken by the OnUpdateRecord handler
before it exits. On entry into the handler, UpdateAction is always set to
uaFail. If OnUpdateRecord is successful, it should set UpdateAction to
uaApplied before exiting.
你忘记给UpdateAction赋值了,这样TTabel的UpdateAction的值为uaFail,TTable
就放弃此纪录的更新,变为read only.(你跟踪一下就会看到)
(这也是为什么OnUpdateRecord中不做操作也错误的原因)
加入 UpDateAction := uaApplied;(或者你想的操作)就可以了。


watermelon 2000-05-13
  • 打赏
  • 举报
回复
回kxy: 非常感谢!
kxy 2000-05-13
  • 打赏
  • 举报
回复
我在实验.pls wait
watermelon 2000-05-13
  • 打赏
  • 举报
回复
回kxy: 两个TTable控件是何意思?具体怎么分?请指点!
kxy 2000-05-13
  • 打赏
  • 举报
回复
你为何不用多层结构?
分成两个TTable控件试试。
kxy 2000-05-13
  • 打赏
  • 举报
回复
OnupdateRecord是这样,
一个TTable,cacheUpdate为true,此table在客户端,一个TTabel在服务端。处理
OnUpdateRecord,
你是在一个TTable中处理吗?applyUpdates,和OnUpdateRecord是一个TTable控件
中的吗?
OnUpdateRecord的Help中
Note: The code in an OnUpdateRecord handler must not call any
methods that make a different record the current one.
watermelon 2000-05-13
  • 打赏
  • 举报
回复
#include <vcl.h>
#include "Unit1.h"
#pragma hdrstop
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Table1->ApplyUpdates(); //Table1的CachedUpdate属性设为true
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Table1UpdateRecord(TDataSet *DataSet,
TUpdateKind UpdateKind, TUpdateAction &UpdateAction)
{
int aa;
if(UpdateKind==ukModify)
{
aa=DataSet->FieldByName("ID")->AsInteger;
}
if(UpdateKind==ukInsert)
{
aa=Table1ID->AsInteger;
}
if(UpdateKind==ukDelete)
{
aa=Table1ID->AsInteger;
}
ShowMessage(UpdateAction);
}
//---------------------------------------------------------------------------
watermelon 2000-05-13
  • 打赏
  • 举报
回复
我这个问题产生的原因是我需要编一段同时更新两个数据库的程序, 都是SQL SERVER7.0的。我的构思是先用DBGrid连接一个数据库的表,之后把表的CachedUpdate属性设为true,当该表经过编辑以后便Table->ApplyUpdate(),把缓存里的记录写给数据集,同时也触发OnUpdateRecoud事件,有几条记录需要提交,则该事件便触发几次,而且能判断每一条记录的编辑状态(delete、insert、update..)。这样一来我可以在OnUpdateRecoud事件中根据每一条记录的编辑状态来改变另外一个数据库里的相应的表的记录,达到了同时更新两个数据库的目的。可是当OnUpdateRecoud事件执行到结束时(只执行一次),便出现‘Table is read only'的EDBEngineError错误,尽管OnUpdateRecoud事件里一条语句都没有也发生这个错误,假如Table没有连上OnUpdateRecoud事件则执行Table->ApplyUpdate()就没有任何问题。
我看了联机帮助,里面所提到的read_only这种情况是一个查询结果,但我的这种情况是直接操作数据表里的记录,我想应该不存在read_only的情况,所以我也没有用TUpdateSQL控件和设置Table的UpdateObject属性。
我看了清华大学出的《BCB3数据库编程指南》,它是这样说OnUpdateRecoud事件的:当程序调用ApplyUpdate函数,要把缓存中的数据写到数据集中时就会触发这个事件。缓存中有多少条记录,这个事件就会触发多少次。
按照书里说的应该是没有问题的,但事实ApplyUpdate一触发OnUpdateRecoud事件便存在这样的问题,真令人想不通,是不是BCB本身的问题呢。
kxy 2000-05-13
  • 打赏
  • 举报
回复
你的程序是什么结构的?
加载更多回复(1)

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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