t-sql中的事务控制及错误处理
------------------------------------------------事务控制-----------------------------------------------------
Sql Server 2005/2008中提供了begin tran,commit tran和rollback tran来使用事务。
begin tran表示开始事务, commit tran表示提交事务,rollback tran表示回滚事务
begin tran 可以理解成新建一个还原点;
commit tran提交这个自begin tran开始的修改;
rollback tran 表示还原到上个还原点。
先创建工作表
USE master
CREATE TABLE student
(
stuid INT NOT NULL PRIMARY KEY,
stuname VARCHAR(50)
)
CREATE TABLE score
(
stuid INT NOT NULL REFERENCES student(stuid),
score INT
)
如下示例不太恰当, 但正确使用了事务
begin tran
INSERT INTO student VALUES (101,'zhangsan')
INSERT INTO student VALUES (102,'wangwu')
INSERT INTO score VALUES (101,190)
INSERT INTO score VALUES (102,78)
if exists(select 1 from score where score>100)--如果有>100分的成绩,则回滚整个事务
rollback
else
commit tran
因为事务里有插入分数为190(>100)的记录, 所以整个事务回滚。
------------------------------------------------错误处理 Error Handling-----------------------------------------------------
对于运行时错误或异常呢?
先准备如下数据:
INSERT INTO student VALUES (101,'zhangsan')
INSERT INTO student VALUES (102,'wangwu')
INSERT INTO student VALUES (103,'lishi')
INSERT INTO student VALUES (104,'maliu')
--调用一个运行时错误
SET XACT_ABORT OFF
BEGIN TRAN
INSERT INTO score VALUES (101,90)
INSERT INTO score VALUES (102,78)
INSERT INTO score VALUES (107, 76) /* 外键错误 */
INSERT INTO score VALUES (103,81)
INSERT INTO score VALUES (104,65)
COMMIT TRAN
执行如上sql,出现了运行时错误(外键冲突), 整个事务无法回滚
如果产生异常,则事务是不会回滚的, 此时要借助如下2种方法:
1)SET XACT_ABORT ON
SET XACT_ABORT ON时,在事务中,若出现错误,系统即默认回滚事务,但只对非自定义错误有效
SET XACT_ABORT OFF,默认值,在事务中,回滚一个语句还是整个事务视错误的严重程序而定,用户级错误一般不会回滚整个事务
When SET XACT_ABORT is ON, if a Transact-SQL statement raises a run-time error, the entire transaction is terminated and rolled back.
The setting of SET XACT_ABORT is set at execute or run time and not at parse(从语法上分析;解析) time.
SET XACT_ABORT ON
BEGIN TRAN
INSERT INTO score VALUES (101,90)
INSERT INTO score VALUES (102,78)
INSERT INTO score VALUES (107, 76) /* 外键错误 */
INSERT INTO score VALUES (103,81)
INSERT INTO score VALUES (104,65)
COMMIT TRAN
SET XACT_ABORT OFF
执行后会抛出异常:
消息 547,级别 16,状态 0,第 6 行
INSERT 语句与 FOREIGN KEY 约束"FK__score__stuid__5C37ACAD"冲突。该冲突发生于数据库"master",表"dbo.student", column 'stuid'。
2)使用TRY...CATCH构造,并调用一个运行时错误
SET XACT_ABORT OFF
BEGIN TRY
BEGIN TRAN
INSERT INTO score VALUES (101,90)
INSERT INTO score VALUES (102,78)
INSERT INTO score VALUES (107, 76) /* 外键错误 */
INSERT INTO score VALUES (103,81)
INSERT INTO score VALUES (104,65)
COMMIT TRAN
PRINT '事务提交'
END TRY
BEGIN CATCH
ROLLBACK
PRINT '事务回滚'
SELECT ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() as ErrorState,
ERROR_MESSAGE() as ErrorMessage;
END CATCH
此时,会print出“事务回滚”, 错误信息为:
ErrorNumber | ErrorSeverity | ErrorState | ErrorMessage |
547 | 16 | 0 | INSERT 语句与 FOREIGN KEY 约束"FK__score__stuid__5C37ACAD"冲突。该冲突发生于数据库"master",表"dbo.student", column 'stuid'。 |
当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge
本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/buguge/archive/2012/03/08/2385477.html