请教数据回滚操作

hsanjin 2010-07-02 05:38:53
原始状态A

SQL语句1
SQL语句2
SQL语句3
SQL语句4
依次执行

任意一个执行错误,就要恢复到原始状态A

怎样写执行语句?用try吗?怎样写?
...全文
226 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
老版本的数据库不支持try catch。
还是用事务好一些。
htl258_Tony 2010-07-05
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 hsanjin 的回复:]
2000的
[/Quote]
DECLARE @er INT

BEGIN TRAN
SQL语句1
SET @er=@@ERROR
SQL语句2
SET @er=@er+@@ERROR
SQL语句3
SET @er=@er+@@ERROR
SQL语句4
SET @er=@er+@@ERROR

IF @er<>0
ROLLBACK
ELSE
COMMIT
hsanjin 2010-07-05
  • 打赏
  • 举报
回复
2000的
SQL_Hhy 2010-07-04
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 hsanjin 的回复:]

try catch

直接语法不通过
[/Quote]
这个是05的 你是2k的?
hsanjin 2010-07-04
  • 打赏
  • 举报
回复
不明白
zkm87 2010-07-04
  • 打赏
  • 举报
回复
进行原子操作,rollback回滚
hsanjin 2010-07-04
  • 打赏
  • 举报
回复
try catch

直接语法不通过
SQL_Hhy 2010-07-04
  • 打赏
  • 举报
回复
/*
A. 使用 TRY…CATCH
此示例显示的 SELECT 语句将生成被零除错误。该错误会导致跳转至相关 CATCH 块的执行。
*/
USE AdventureWorks;
GO

BEGIN TRY
-- Generate a divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
GO

/*
B. 在事务内使用 TRY…CATCH
此示例显示 TRY…CATCH 块如何在事务内工作。TRY 块内的语句会生成违反约束的错误。
*/
USE AdventureWorks;
GO
BEGIN TRANSACTION;

BEGIN TRY
-- Generate a constraint violation error.
DELETE FROM Production.Product
WHERE ProductID = 980;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() as ErrorState,
ERROR_PROCEDURE() as ErrorProcedure,
ERROR_LINE() as ErrorLine,
ERROR_MESSAGE() as ErrorMessage;

IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;

IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
GO

/*
C. 将 TRY…CATCH 与 XACT_STATE 配合使用
此示例显示如何使用 TRY…CATCH 构造来处理事务内发生的错误。XACT_STATE 函数确定应提交事务还是应回滚事务。在本示例中,SET XACT_STATE 为 ON,在发生违反约束的错误时,这会使事务处于不可提交状态。
*/
USE AdventureWorks;
GO

-- Check to see if this stored procedure exists.
IF OBJECT_ID (N'usp_GetErrorInfo', N'P') IS NOT NULL
DROP PROCEDURE usp_GetErrorInfo;
GO

-- Create procedure to retrieve error information.
CREATE PROCEDURE usp_GetErrorInfo
AS
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() as ErrorState,
ERROR_LINE () as ErrorLine,
ERROR_PROCEDURE() as ErrorProcedure,
ERROR_MESSAGE() as ErrorMessage;
GO

-- SET XACT_ABORT ON will render the transaction uncommittable
-- when the constraint violation occurs.
SET XACT_ABORT ON;

BEGIN TRY
BEGIN TRANSACTION;
-- A foreign key constrain exists on this table. This
-- statement will generate a constraint violation error.
DELETE FROM Production.Product
WHERE ProductID = 980;

-- If the DELETE statement succeeds, commit the transaction.
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
-- Execute error retrieval routine.
EXECUTE usp_GetErrorInfo;

-- Test XACT_STATE:
-- If 1, the transaction is committable.
-- If -1, the transaction is uncommittable and should
-- be rolled back.
-- XACT_STATE = 0 means that there is no transaction and
-- a COMMIT or ROLLBACK would generate an error.

-- Test if the transaction is uncommittable.
IF (XACT_STATE()) = -1
BEGIN
PRINT
N'The transaction is in an uncommittable state.' +
'Rolling back transaction.'
ROLLBACK TRANSACTION;
END;

-- Test if the transaction is committable
IF (XACT_STATE()) = 1
BEGIN
PRINT
N'The transaction is committable.' +
'Committing transaction.'
COMMIT TRANSACTION;
END;
END CATCH;
GO

SQL_Hhy 2010-07-04
  • 打赏
  • 举报
回复

对 Transact-SQL 实现类似于 C# 和 C++ 语言中的异常处理的错误处理。Transact-SQL 语句组可以包含在 TRY 块中。如果 TRY 块内部发生错误,则会将控制传递给 CATCH 块中包含的另一个语句组。

语法

BEGIN TRY
{ sql_statement | statement_block }
END TRY
BEGIN CATCH
{ sql_statement | statement_block }
END CATCH
[ ; ]


备注
TRY...CATCH 构造捕捉所有严重级别大于 10 但不终止数据库连接的错误。

TRY 块后必须紧跟相关联的 CATCH 块。在 END TRY 和 BEGIN CATCH 语句之间放置任何其他语句都将生成语法错误。

TRY…CATCH 构造不能跨越多个批处理。TRY…CATCH 构造不能跨越多个 Transact-SQL 语句块。例如,TRY…CATCH 构造不能跨越 Transact-SQL 语句的两个 BEGIN…END 块,且不能跨越 IF…ELSE 构造。

如果 TRY 块所包含的代码中没有错误,则当 TRY 块中最后一个语句完成时,会将控制传递给紧跟在相关联的 END CATCH 语句之后的语句。如果 TRY 块所包含的代码中有错误,则会将控制传递给相关联的 CATCH 块的第一个语句。如果 END CATCH 语句是存储过程或触发器的最后一个语句,则会将控制传递回调用存储过程或触发器的语句。

当 CATCH 块中的代码完成时,会将控制传递给紧跟在 END CATCH 语句之后的语句。由 CATCH 块捕获的错误不会返回到调用应用程序。如果任何错误消息都必须返回到应用程序,则 CATCH 块中的代码必须使用 SELECT 结果集或 RAISERROR 和 PRINT 语句之类的机制执行此操作。有关将 TRY…CATCH 与 RAISERROR 结合使用的详细信息,请参阅在 Transact-SQL 中使用 TRY...CATCH。

TRY…CATCH 构造可以是嵌套式的。TRY 块或 CATCH 块均可包含嵌套的 TRY…CATCH 构造。例如,CATCH 块可以包含内嵌的 TRY…CATCH 构造,以处理 CATCH 代码所遇到的错误。

处理 CATCH 块中遇到的错误的方法与处理任何其他位置生成的错误一样。如果 CATCH 块包含嵌套的 TRY…CATCH 构造,则嵌套的 TRY 块中的任何错误都会将控制传递给嵌套的 CATCH 块。如果没有嵌套的 TRY…CATCH 构造,则会将错误传递回调用方。

TRY…CATCH 构造可以从存储过程或触发器(由 TRY 块中的代码执行)捕捉未处理的错误。或者,存储过程或触发器也可以包含其自身的 TRY…CATCH 构造,以处理由其代码生成的错误。例如,当 TRY 块执行存储过程且存储过程中发生错误时,可以使用以下方式处理错误:

错误会将控制返回与包含 EXECUTE 语句的 TRY 块相关联的 CATCH 块。


如果存储过程包含 TRY…CATCH 构造,则错误会将控制传输给存储过程中的 CATCH 块。当 CATCH 块代码完成时,控制会传递回调用存储过程的 EXECUTE 语句之后的语句。


不能使用 GOTO 语句输入 TRY 或 CATCH 块,也不能使用 GOTO 语句跳转至同一 TRY 或 CATCH 块内的某个标签,或离开 TRY 或 CATCH 块。

不能在用户定义函数内使用 TRY…CATCH 构造。

SQL_Hhy 2010-07-04
  • 打赏
  • 举报
回复
试试
try catch 的语法
hsanjin 2010-07-04
  • 打赏
  • 举报
回复
begin tran
SQL语句1
SQL语句2
SQL语句3
SQL语句4
if @@error<>0
rollback tran
else
commit tran
-----------------------------------------------------------------
该操作未能执行,因为 OLE DB 提供程序 'SQLOLEDB' 无法启动分布式事务。
[OLE/DB provider returned message: 新事务不能登记到指定的事务处理器中。 ]
OLE DB 错误跟踪[OLE/DB Provider 'SQLOLEDB' ITransactionJoin::JoinTransaction returned 0x8004d00a]。
流氓兔 2010-07-03
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 xman_78tom 的回复:]
SQL code

begin try
begin tran
... ...
commit tran
end try
begin catch
rollback tran
end catch
[/Quote]
SQL77 2010-07-03
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 guguda2008 的回复:]
引用 6 楼 ldslove 的回复:

引用 5 楼 guguda2008 的回复:
BEGIN TRAN
SQL语句1
SQL语句2
SQL语句3
SQL语句4
IF @@ERROR<>0
ROLLBACK TRAN
ELSE
COMMIT TRAN
END TRAN
类似这样的



鸭爷没有END TRAN

手误
[/Quote]
永生天地 2010-07-03
  • 打赏
  • 举报
回复
首推
[Quote=引用 8 楼 feilniu 的回复:]
SQL code

--原始状态A
SET XACT_ABORT ON
BEGIN TRANSACTION
SQL语句1
SQL语句2
SQL语句3
SQL语句4
COMMIT TRANSACTION
[/Quote]
ChinaITOldMan 2010-07-03
  • 打赏
  • 举报
回复
please use transaction
htl258_Tony 2010-07-02
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 feilniu 的回复:]
SQL code

--原始状态A
SET XACT_ABORT ON
BEGIN TRANSACTION
SQL语句1
SQL语句2
SQL语句3
SQL语句4
COMMIT TRANSACTION
[/Quote]

SQL2005以上版本建议用这个方法
xman_78tom 2010-07-02
  • 打赏
  • 举报
回复

begin try
begin tran
... ...
commit tran
end try
begin catch
rollback tran
end catch
feilniu 2010-07-02
  • 打赏
  • 举报
回复

--原始状态A
SET XACT_ABORT ON
BEGIN TRANSACTION
SQL语句1
SQL语句2
SQL语句3
SQL语句4
COMMIT TRANSACTION

guguda2008 2010-07-02
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ldslove 的回复:]

引用 5 楼 guguda2008 的回复:
BEGIN TRAN
SQL语句1
SQL语句2
SQL语句3
SQL语句4
IF @@ERROR<>0
ROLLBACK TRAN
ELSE
COMMIT TRAN
END TRAN
类似这样的



鸭爷没有END TRAN
[/Quote]
手误
东那个升 2010-07-02
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 guguda2008 的回复:]
BEGIN TRAN
SQL语句1
SQL语句2
SQL语句3
SQL语句4
IF @@ERROR<>0
ROLLBACK TRAN
ELSE
COMMIT TRAN
END TRAN
类似这样的
[/Quote]


鸭爷没有END TRAN
加载更多回复(5)
1.项目代码均经过功能验证ok,确保稳定可靠运行。欢迎下载体验!下载完使用问题请私信沟通。 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师、企业员工。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈! 【资源说明】 C#开发基于FreeSql多库分布式事务、跨库查询、跨库分页查询、跨库增删改等功能实现源码+项目说明+sln.zip **前言** 话说2021年开始了一个基于ASP.NET Core 微服务的项目,谈到微服务 多库环境下 分布式事务、分库分表这些问题都是逃不开的,于是首先从ORM开始调研,需要考虑到一些重要的因素 **功能强大、支持多种数据库(并且行为一致,防止出现换库的情况)、支持分库分表** 等等,这时候第一时间就想到了 [FreeSql](https://github.com/dotnetcore/FreeSql) ,FreeSql的架构设计非常好,每一种支持的数据库都有对应的Provider实现 做到行为一致,而且支持CodeFirst和DbFirst,分库分表FreeSql也有比较简单切有效的方案,本人也经常向FreeSql的作者叶老板请教学习,非常佩服他的技术与人品,也非常感谢他能做出这么好的ORM框架。 **分布式事务** 既然分库了 分布式事务怎么处理,说到分布式事务 常见的解决方案有TCC/SAGA/消息队列最终一致性,在.NET生态中有基于消息队列实现的分布式事务 [CAP](https://github.com/dotnetcore/CAP) ,TCC和SAGA调研了很久没有发现有比较成熟的实现,那么就决定使用`CAP(最终一致性事务)` 由于项目持续的改版,业务的实时性变得越来越高,基于消息队列的这种最终一致性或者说异步事务的方案 越来越不适合我们的项目,这时候就需要同步的事务方案,TCC/SAGE又没有太好的解决方案(我真的没有找到。。),于是想着自己设计一个,基于FreeSql实现事务管理器。 想要的效果:和单库事务一样,出现错误回滚 但是问题来了 多库呢?不同的数据库呢? * 在多库事务的开启时,每个库管理开启自己的事务 * 如果某一个库事务开启后的操作出现异常,则回滚全部数据库事务 * 在多库事务提交时,每个库的事务统一提交 * 记录日志,第一个执行Common的数据库称之为主库,会自动创建一个日志表,用于记录多库事务的信息、执行的SQL、业务模块 用于人工介入或者事务补偿 * 如果主库(第一个库)Common成功后,其他某一个库可能由于网络原因、数据库宕机 无法Common事务,导致数据不一致,这时候要根据日志进行事务补偿或者人工介入,例如 存在三个库(订单库、物流库、商品库) 订单库就是主库(会记录日志) 在Common事务时,如果订单库(主库)Common失败,则(订单库、物流库、商品库)事务全部回滚,如果`订单库`(主库)Common成功,但是`物流库`由于其他原因无法Common成功 则会被日志记录并跳过,然后再去Common `商品库` 以及其他库.. **跨库查询/跨库分页查询** 通过时间分片定位、事件委托、分页算法实现跨库分页查询 1.appsettings.json配置 2.初始化数据库 3.获取IFreeSql操作对象 5.跨库分页查询 6. 跨库增删改 7.跨库并行查询(不分页) 8.跨库ToOne查询 9.跨库Any查询 10.分布式事务、多库事务

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧