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;
在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;