Try-Catch会捕获@@ ERROR可以发现的所有错误吗?在下面的代码片段中,检查@@ ERROR是否值得? RETURN 1111会发生吗?
SET XACT_ABORT ON
BEGIN TRANSACTION
BEGIN TRY
--do sql command here <<<<<<<<<<<
SELECT @Error=@@ERROR
IF @Error!=0
BEGIN
IF XACT_STATE()!=0
BEGIN
ROLLBACK TRANSACTION
END
RETURN 1111
END
END TRY
BEGIN CATCH
IF XACT_STATE()!=0
BEGIN
ROLLBACK TRANSACTION
END
RETURN 2222
END CATCH
IF XACT_STATE()=1
BEGIN
COMMIT
END
RETURN 0
答案 0 :(得分:14)
以下文章是SQL Server MVP的Erland Sommarskog必读的:Implementing Error Handling with Stored Procedures
另请注意Your TRY block may fail, and your CATCH block may be bypassed
还有一件事:使用旧式错误处理和保存点的存储过程在与TRY ... CATCH块一起使用时可能无法正常工作。Avoid mixing old and new styles of error handling.
答案 1 :(得分:8)
TRY / CATCH陷阱更多。它非常棒,而且非常好。
DECLARE @foo int
SET @foo = 'bob' --batch aborting pre-SQL 2005
SELECT @@ERROR
GO
SELECT @@ERROR --detects 245. But not much use, really if the batch was a stored proc
GO
DECLARE @foo int
BEGIN TRY
SET @foo = 'bob'
SELECT @@ERROR
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE(), ERROR_NUMBER()
END CATCH
GO
在触发器中使用TRY / CATCH也有效。触发器回滚过去也是批量中止:如果触发器中也使用了TRY / CATCH,则不再使用。
如果BEGIN / ROLLBACK / COMMIT在内部,而不在构造外部,那么你的例子会更好
答案 2 :(得分:4)
尝试Catch不会捕获所有内容
这里有一些代码来演示
BEGIN TRY
BEGIN TRANSACTION TranA
DECLARE @cond INT;
SET @cond = 'A';
END TRY
BEGIN CATCH
PRINT 'a'
END CATCH;
COMMIT TRAN TranA
服务器:消息3930,级别16,状态1,行9 当前事务无法提交,也无法支持写入日志文件的操作。回滚交易。 服务器:消息3998,级别16,状态1,行1 在批处理结束时检测到不可提交的事务。该事务将被回滚。
答案 3 :(得分:0)
我不相信控制会到达RETURN语句 - 一旦你处于TRY块,任何引发的错误都会将控制转移到CATCH块。但是,有一些非常严重的错误可能导致批处理甚至连接本身中止(Erland Sommarskog已经写过SQL Server here和here中的错误主题 - 不幸的是,他没有没有更新它们以包括TRY ... CATCH)。我不确定你是否可以捕获那些错误,但是,@@ ERROR也不好。
答案 4 :(得分:0)
根据我的经验,根据联机丛书,TRY ... CATCH块将捕获所有会产生错误的事件(因此,将@@ ERROR设置为非零值)。我认为这不适用于任何情况。所以不,返回值永远不会设置为1111,并且包含@@错误检查是不值得的。
然而,错误处理可能非常关键,而且我会对DTC,链接服务器,通知或经纪服务以及我很少有经验的其他SQL功能等边缘情况进行对冲。如果可以,请测试更奇怪的情况,看看实际会发生什么。
答案 5 :(得分:0)
“Try..Catch”的重点在于您无需为每个语句检查@@ ERROR。
所以这不值得。