doxpix在嗎?請問在主從表新增過程中, 一旦從表存盤出錯,在Rollback后,再存盤,主表就不再insert了,這要如何解決. (50分)

Y

yuso

Unregistered / Unconfirmed
GUEST, unregistred user!
我的主從表是用ADODataSet,在插入后存盤,程序如下.
DM.ADOConnection.BeginTrans;
try
DataSet1.UpdateBatch();
DataSet2.UpdateBatch();
except
ADOConnection.RollbackTrans;
end;
跟蹤SQL-SERVER 的SQL Profiler得出分別用了針對兩個表用了insert語句, 當在存
盤時明細表的存儲過程出錯, 系統回滾, 當我修正明細數據后, 再存盤,跟蹤SQL-SERVER
的SQL Profiler 發現程序默認主表已插入,只插入從表,這要如何解決.

 
>>的SQL Profiler 發現程序默認主表已插入,只插入從表,這要如何解決.
是主表插入了而从表没有插入,对吧。

SET XACT_ABORT ON
即可。
XACT_ABORT参见联机帮助如下——
________________________________________________________________________________
SET XACT_ABORT
指定当 Transact-SQL 语句产生运行时错误时,Microsoft® SQL Server™ 是否自动回滚当前事务。

语法
SET XACT_ABORT { ON | OFF }

注释
当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句产生运行时错误,整个事务将终止并回滚。为 OFF 时,只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。编译错误(如语法错误)不受 SET XACT_ABORT 的影响。

对于大多数 OLE DB 提供程序(包括 SQL Server),隐性或显式事务中的数据修改语句必须将 XACT_ABORT 设置为 ON。唯一不需要该选项的情况是提供程序支持嵌套事务时。有关更多信息,请参见分布式查询和分布式事务。

SET XACT_ABORT 的设置是在执行或运行时设置,而不是在分析时设置。

________________________________________________________________________________
 
或許開始沒講清楚,我把這個過程再詳細描述一遍吧.我新增一張單據時程序如下.
DM.ADOConnection.BeginTrans;
DetailADODataSet2.Post;
MasterADODataSet2.Post;
try
MasterADODataSet1.UpdateBatch();
DetailADODataSet2.UpdateBatch(); //在這條句更新時,該表所涉及的觸發器出錯.
DM.ADOConnection.CommitTrans;
except
ADOConnection.RollbackTrans; //因為上面出錯,所以回滾.
end;
照道理回滾后表示新增不成功,這時我把數據修正后,再存盤執行上面語句,
應該SQL-SERVER 的SQL Profiler為先主表insert再明細表insert,但只有明細表insert
這時就出現了外鍵錯誤.因為不存在主鍵.
以上如果是主表的觸發器出現問題,就不會有該問題.

照doxpix兄台的說法,如果在SQL-server的存儲過程中執行事務應該沒問題, 但我的事務
是通過delphi程序來實現的,所以set xact_abort on 不知放在哪里好, 我試放在主表的存
儲過程中, 沒有反應!請問要放在哪呢?
 
在SQL SERVER的SQL查询分析器里执行一遍
SET XACT_ABORT ON
即可。
 
我試了問題依舊.
我想因為我的事務是在delphi中建立的,設置SET XACT_ABORT ON后雖然可以全部回滾,但
MasterADODataSet1的ADO解析程序並不知道已全部回滾, 仍然認為已插入成功,所以就不再
做插入動作了,如果能將的MasterADODataSet1.state改為insert,或許它就可以插入了但
它是只讀屬性,無法修改.

 
>>我想因為我的事務是在delphi中建立的,設置SET XACT_ABORT ON后雖然可以全部回滾,但
>>MasterADODataSet1的ADO解析程序並不知道已全部回滾, 仍然認為已插入成功,所以就不再
>>做插入動作了。

Delphi建立的事务最终还是在SQL SERVER上执行。所以这个不是问题所在。


建议改成这样,但还是有点小问题:

DM.ADOConnection.BeginTrans;
MasterADODataSet2.Post;
try
MasterADODataSet2.UpdateBatch();
DM.ADOConnection.CommitTrans;
except
DM.ADOConnection.RollbackTrans;
end;

DM.ADOConnection.BeginTrans;
DetailADODataSet2.Post;
try
DetailADODataSet2.UpdateBatch();
DM.ADOConnection.CommitTrans;
except
DM.ADOConnection.RollbackTrans;
end;
 
[:(]有勞doxpix兄了,按兄臺的說法,我的程序是不能這樣的,看來只有改觸發器,不讓它出錯
這一條路了.
 
Access has rollback?
 
还有一个方法就是对从表的数据操作都放在主表的触发器里,而不是在客户端用SQL语句去执行。
在SQL SERVER2K上是支持触发器事务嵌套的,这样你在主表的触发器里启动一个事务,如果无错
则对从表进行数据操作,有错则回滚。
 
辛苦doxpix兄了,因為我用的是sql-server7.0所以這個方案行不通,但分是一定要加給你的.
 
顶部