http://wang2855.spaces.live.com/ 我的BLOG.
CREATE PROCEDURE SP_TEST
AS
BEGIN
BEGIN TRAN
INSERT INTO DIC_PAY_TYPE
(PAY_ID, PAY_NAME)
VALUES ('AA', 'SDF') ---A 语句 (错误语句)
INSERT INTO DIC_FEE(id,FEE_TYPE,FEE_YEAR,MONEY) VALUES (1,'AA',1,500)
--B语句 (正确语句)
IF @@ERROR<>0
BEGIN
ROLLBACK TRAN
PRINT 'ROLLBACK'
END
ELSE
BEGIN
COMMIT TRAN
PRINT 'COMMIT'
ENDEND一开始我认为这样写在一个存储过程中是没问题的,后来一个同事认为,@@Error是指最后一条语句的错误,经过查找也是这么回事。她认为需要对每条语句的@@Error判断,
经过测试后,发现当A语句执行失败的时候根本执行不到下面
的判断,而且事务自动回滚。而当我把B语句写到A语句前面,则能执行到A语句,
结果也是自动回滚。
那么我的红字部分判断, IF @@ERROR<>0就是多余的。
我只需要Commit Tran(提交所有成功的).这个是必须的,否则会Lock Table.进一步研究后发现:SET IMPLICIT_TRANSACTIONS off
是用来设置是否开启隐含事务,如果开启后,自动提交(也就是说,sqlserver自动
在你的语句前面加begin tran,后面加commit tran 和oracle 一样,如果你再写begin tran
也必须再写commit)
纠正上面的错误结论:
当A语句执行失败的时候根本执行不到下面
发现当出现的错误比较非数据错误,比如是数字字段却插入字符内容,这些错误是会马上跳出,当是数据错误,比如主键冲突,约束,等等这些错误还是会往下执行的.进一步发现,Commit Tran如果提交时有错误,系统会自动RollBack,所以和Oracle一样,
一般不需要RollBack.(大家可以讨论)
CREATE PROCEDURE SP_TEST
AS
BEGIN
BEGIN TRAN
INSERT INTO DIC_PAY_TYPE
(PAY_ID, PAY_NAME)
VALUES ('AA', 'SDF') ---A 语句 (错误语句)
INSERT INTO DIC_FEE(id,FEE_TYPE,FEE_YEAR,MONEY) VALUES (1,'AA',1,500)
--B语句 (正确语句)
IF @@ERROR<>0
BEGIN
ROLLBACK TRAN
PRINT 'ROLLBACK'
END
ELSE
BEGIN
COMMIT TRAN
PRINT 'COMMIT'
ENDEND一开始我认为这样写在一个存储过程中是没问题的,后来一个同事认为,@@Error是指最后一条语句的错误,经过查找也是这么回事。她认为需要对每条语句的@@Error判断,
经过测试后,发现当A语句执行失败的时候根本执行不到下面
的判断,而且事务自动回滚。而当我把B语句写到A语句前面,则能执行到A语句,
结果也是自动回滚。
那么我的红字部分判断, IF @@ERROR<>0就是多余的。
我只需要Commit Tran(提交所有成功的).这个是必须的,否则会Lock Table.进一步研究后发现:SET IMPLICIT_TRANSACTIONS off
是用来设置是否开启隐含事务,如果开启后,自动提交(也就是说,sqlserver自动
在你的语句前面加begin tran,后面加commit tran 和oracle 一样,如果你再写begin tran
也必须再写commit)
纠正上面的错误结论:
当A语句执行失败的时候根本执行不到下面
发现当出现的错误比较非数据错误,比如是数字字段却插入字符内容,这些错误是会马上跳出,当是数据错误,比如主键冲突,约束,等等这些错误还是会往下执行的.进一步发现,Commit Tran如果提交时有错误,系统会自动RollBack,所以和Oracle一样,
一般不需要RollBack.(大家可以讨论)
SET XACT_ABORT { ON | OFF }注释
当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句产生运行时错误,整个事务将终止并回滚。为 OFF 时,只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。编译错误(如语法错误)不受 SET XACT_ABORT 的影响。
CREATE PROCEDURE SP_TEST
AS
BEGIN
DECLARE @Insert1_error int, @Insert2_error int
BEGIN TRAN
INSERT INTO DIC_PAY_TYPE
(PAY_ID, PAY_NAME)
VALUES ('AA', 'SDF') ---A 语句 (错误语句)
SELECT @Insert1_error = @@ERROR
INSERT INTO DIC_FEE(id,FEE_TYPE,FEE_YEAR,MONEY) VALUES (1,'AA',1,500)
Select @Insert2_error=@@ERROR
--B语句 (正确语句)
IF @Insert1_error<>0 Or @Insert2_error<>0
BEGIN
ROLLBACK TRAN
PRINT 'ROLLBACK'
END
ELSE
BEGIN
COMMIT TRAN
PRINT 'COMMIT'
ENDEND一般不需要RollBack??我认为还是要吧,具体无测试
如果其中有些语句出现错误(错误大于一定级别的)会自动撤消所有语句的改动
有。但有些用户级别的错误需要自己判断。
可以save tran
出现错误后
rollback tran