27,579
社区成员
发帖
与我相关
我的任务
分享
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
/*
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
对 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 构造。
试试
try catch 的语法
begin try
begin tran
... ...
commit tran
end try
begin catch
rollback tran
end catch
--原始状态A
SET XACT_ABORT ON
BEGIN TRANSACTION
SQL语句1
SQL语句2
SQL语句3
SQL语句4
COMMIT TRANSACTION