再次请求Delphi超一流高手(100分) (100分)

  • 主题发起人 主题发起人 jetcoyuan
  • 开始时间 开始时间
J

jetcoyuan

Unregistered / Unconfirmed
GUEST, unregistred user!
使用TUpdateSql控件,假设目前Detail中有两条记录,并都作了修改,
在QueryDtl的updaterecord事件中作校验(必须在updaterecord事件中作校验),
又假设第一条校验成功,而第二条校验出错(可能主键重复或不满足其它计算范围
). 那么当Applyupdate时应该报错,并且rollback(因为同时需要更新库存,所以必须rollback),
但是当我把第二条数据改正以后,在存盘时,第二条数据正确存盘,而第一条数据还是修改以前
的数据.
1.原因是第一次存盘时,第一条数据已经执行updaterecord事件并apply,
因此第二次存盘时,只有第二条数据执行了updaterecord事件.请问高手如何解决 !!!
2.当最后存盘时使用uaSkip,虽然解决了二条数据都执行了updaterecord事件,但是
每条记录却都执行了两次,即每条记录都两次调用了updaterecord事件,请问如何
做到每条记录只调用一次updaterecord事件???

BestRecards/jetcoyuan


我的示例程序如下:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dia
logs,
Db, DBTables, Grids, DBGrids, StdCtrls;

type
TForm1 = class(TForm)
Database1: TDatabase;
Query1: TQuery;
DataSource1: TDataSource;
UpdateSQL1: TUpdateSQL;
DBGrid1: TDBGrid;
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Query1UpdateRecord(DataSet: TDataSet;
UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
procedure Button2Click(Sender: TObject);
procedure Query1UpdateError(DataSet: TDataSet; E: EDatabaseError;

UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
with query1 do
begin
database.StartTransaction;
try
ApplyUpdates;
database.Commit;
CommitUpdates;
except
on e:exception do
begin
Database.RollBack;
if e is EDBEngineError then
showmessage(e.ClassName+':'+e.message);
exit;
end;
end;
end;
end;

procedure TForm1.Query1UpdateRecord(DataSet: TDataSet;
UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
begin
if updatekind in [ukinsert, ukmodify] then
begin
{ if vartostr(DataSet.FieldByName('header').NewValue) = '' then
begin
UpdateAction:=uafail;
raise exception.Create(vartostr(updatekind)+':dept_id:'
+vartostr(dataset.fieldbyname('dept_id').newvalue));
end;}
end;
updatesql1.Apply(UpdateKind);
UpdateAction:=uaApplied; ///?????
// UpdateAction:=uaSkip; ///?????
//不能使用uaSkip,否则此事件将调用两次(每条//记录).
end;
 
我看得头都晕了,
我建议你用存储过程来实现这个事务流程
(我最近老向人推荐这样做,哪位来反对一下,提点意见)
 
query1里面是什么sql语句?
总之我觉得这样写不太好控制.
最简单的方法是通过程序控制,不要用数据库自己带的回滚啊,什么的.
比如在用户输入修改记录时就判断输入是否合法,如果不合法就马上提示,
这样交互性很好,比修改了很多在存盘时告诉用户的好.
 
两位大侠的回答似乎不正确,能否在回答的深入一些???
 
AGREE 小猪
建议多用STOREDPROCEDURE。
 
我建议你将数据的校验放到Query的OnBeforePost事件中去实现,保证数据保存到物理表
中时不出错。
 
I have agree the answer of BaKuBaKu
 
嘿嘿,那就发分吧。:-))))
 
AGREE 小猪
建议使用支持存储过程的数据库,将你的事务处理写道数据库中
在delphi中通过odbc执行数据库中的存储过程
 
但是当我把第二条数据改正以后,在存盘时,第二条数据正确存盘,而第一条数据还是修改以前
的数据.
1.原因是第一次存盘时,第一条数据已经执行updaterecord事件并apply,
因此第二次存盘时,只有第二条数据执行了updaterecord事件.请问高手如何解决 !!!
>我怎么就是看不明白你的意思?你要问问题,能不能表达得清楚一些?
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
604
import
I
I
回复
0
查看
549
import
I
I
回复
0
查看
625
import
I
后退
顶部