代码如下:
try
FPurchase.Connection.BeginTrans;
FPurchase.Save; //1
FPurchaseDetail.Save; //2
FPurchase.Connection.CommitTrans;
except
FPurchase.Connection.RollbackTrans;
on e: Exception do
begin
StatuseInfo(Caption + ':' + e.Message);
end;
end;FPurchase和FPurchaseDetail用的同一个ADOConnection;
1,2位置的Save方法都是使用的DataSet.UpdateBatch;问题:
当代码1的保存成功,代码2的保存出现异常回滚的时候,如果用户修改FPurchaseDetail中的数据,再次保存,则代码2处的保存成功,代码1处的保存不会出现异常,但是实际上数据没有能够存入数据库。个人考虑:
当第一次保存的时候,因为代码1的保存没有出现异常DataSet的状态发生变化,应该变成了浏览状态。
第二次保存时,因为1位置的DataSet已经是浏览状态,而且没有发生变化所以不再保存。而仅仅执行代码2,将明细保存了。不知是否正确,尝试了一些方法,觉得不妥,是否有更好的方法,大家讨论,谢谢
try
FPurchase.Connection.BeginTrans;
FPurchase.Save; //1
FPurchaseDetail.Save; //2
FPurchase.Connection.CommitTrans;
except
FPurchase.Connection.RollbackTrans;
on e: Exception do
begin
StatuseInfo(Caption + ':' + e.Message);
end;
end;FPurchase和FPurchaseDetail用的同一个ADOConnection;
1,2位置的Save方法都是使用的DataSet.UpdateBatch;问题:
当代码1的保存成功,代码2的保存出现异常回滚的时候,如果用户修改FPurchaseDetail中的数据,再次保存,则代码2处的保存成功,代码1处的保存不会出现异常,但是实际上数据没有能够存入数据库。个人考虑:
当第一次保存的时候,因为代码1的保存没有出现异常DataSet的状态发生变化,应该变成了浏览状态。
第二次保存时,因为1位置的DataSet已经是浏览状态,而且没有发生变化所以不再保存。而仅仅执行代码2,将明细保存了。不知是否正确,尝试了一些方法,觉得不妥,是否有更好的方法,大家讨论,谢谢
解决方案 »
- 求控件下载地址
- delphi中sql语句字符连接的写法
- D版的兄弟同胞们帮个忙
- 为什么TWebBrowse控件不能复制文本??急!!!!!!!!!!!!!!!!!!!!!!!
- 关于论坛和人生的思索
- select aa.nextval as temp from dual
- 在QReport中,主副明细报表中,为什么只能显示一条主表记录和相应的副表记录?(有N条记录)
- 送分!关于panel上的控件问题
- 边个可以话比我知,installshieldprofessional6.21的安装密码
- 如何用DELPHI 5编写MP3播放器和.MPG播放器??
- delphi的对象如何序列化
- 关于delphi 得reportmechine设计报表的分组统计问题
这个代码应该在异常内部,上面写的有点小问题,但是不影响讨论啊
adoConnection.BeginTrans;
adodataset1.UpdateBatch();
adodataset2.UpdateBatch();
adoConnection.CommitTrans; 只要中间有异常 都会回滚
begin
adoconnection1.BeginTrans;
try
adodataset1.UpdateBatch();
if adodataset2.FieldByName('ProductID').AsString='' then
raise exception.Create('ProductID not null');
adodataset2.UpdateBatch();
adoconnection1.CommitTrans;
except
adoconnection1.RollbackTrans;
end;
end;
to kaper 你的代码如果继续修改adodataset2里面的数据直到满足要求,第二次提交的时候稍adodataset1是会提交的,但是,数据没有写到数据库,因为现在sataset的状态是UnModified,这个问题其实很多人发现了,只是现在好像没有人继续讨论了,我就问问,是不是大家都已经有了解决的方法了?http://www.delphibbs.com/delphibbs/dispq.asp?lid=2090654
下面有很长的讨论,大家可以看看,保存文件据说很好,不过如果操作的表超过2个,保存文件也有点力不从心了下面是一个方法,但是我认为没有实际上解决问题
http://www.01cn.net/cgi-bin/threaded_show.cgi?tid=2332&h=1&bpg=1&age=0
[ID] [int] IDENTITY (1, 1) NOT NULL ,
[BillNo] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,
CONSTRAINT [PK_Master] PRIMARY KEY CLUSTERED
(
[ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [Detail] (
[ID] [int] IDENTITY (1, 1) NOT NULL ,
[BillID] [int] NULL ,
[ProductID] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,
[A] [int] NULL ,
[B] [int] NULL ,
[C] AS ([A] - [B]) ,
CONSTRAINT [PK_Detail] PRIMARY KEY CLUSTERED
(
[ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO你自己先试试看嘛
我已经尝试了很多次,这个问题已经困扰了我很久了,相信不是我一个人有这样的问题。你的代码是有问题的!你的判断只是对数据本身的判断,我明白你的意思,就是对所有用户输入的数据进行验证,只有全部符合数据库的约束和规则才能提交。可是就算所有的数据都能够满足验证,adodataset2.UpdateBatch(); 这一行代码还是可能发生异常的!!比如你在明细选择的产品很可能有其他人已经删除了,这个时候客户端的验证是可以满足的,但是当你提交数据的时候确违背了外键约束,在这种情况下发生异常的时候回滚,如果更换了另一个产品再提交的时候adodataset1.UpdateBatch(); 是不会有任何数据保存的!!应该还是DataSet的状态变成了UnModified,无法回到历史状态造成的。不知道我说的是否清晰,感谢kaper。
adodataset1,adodataset2的recordset取其变化值
再合成SQL回写数据库。自己来处理生成SQL
其实updateBatch也是一样的合成SQL,只不过有一个属性,如果设置成严格更新,
会把所有的字段值当成条件来更新,为避免出现更新覆盖。
===
分享快乐:www.delphichm.com
不使用批提交方式,新建单据的时候(这个问题主要出现在新建的时候),同时新建一个明细数据,在明细DataSet的BeforePost事件中提交单据头.