buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

统计

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'。

posted on   buguge  阅读(2128)  评论(0编辑  收藏  举报

编辑推荐:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
阅读排行:
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 【全网最全教程】使用最强DeepSeekR1+联网的火山引擎,没有生成长度限制,DeepSeek本体
点击右上角即可分享
微信分享提示