我在SQL Server中使用try catch有一个存储过程。我想在catch循环中做的是调用我自己的Stored过程来记录所有错误变量,如下所示:
BEGIN TRY
-- Generate a divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
exec log.LogError ERROR_NUMBER(), ERROR_SEVERITY(), ERROR_MESSAGE();
END CATCH;
当我运行时,我在括号上出现错误。
我可以跑:
select ERROR_NUMBER(), ERROR_SEVERITY(), ERROR_MESSAGE();
我也可以
print ERROR_NUMBER()
我想要做的是只有一行用参数调用存储过程,因为我将在许多存储过程中使用它,并且不希望有很多代码设置错误参数(我会有更多比这三个)在我尝试捕获的每个存储过程中。
有人知道如何将这些传递给另一个存储过程吗?
此致 约翰
答案 0 :(得分:2)
不幸的是,T-SQL不是DRY代码重用紧凑语法程序员友好语言。你必须以艰难的方式去做,这意味着在每个CATCH块内至少编写4-5行代码。此外,您还需要考虑事务语义:它是否已回滚?或者更糟糕的是,你是否处于注定的交易中?这就是为什么我创建了这个T-SQL error handling template:
create procedure [usp_my_procedure_name]
as
begin
set nocount on;
declare @trancount int;
set @trancount = @@trancount;
begin try
if @trancount = 0
begin transaction
else
save transaction usp_my_procedure_name;
-- Do the actual work here
lbexit:
if @trancount = 0
commit;
end try
begin catch
declare @error int, @message varchar(4000), @xstate int;
select @error = ERROR_NUMBER()
, @message = ERROR_MESSAGE()
, @xstate = XACT_STATE();
if @xstate = -1
rollback;
if @xstate = 1 and @trancount = 0
rollback
if @xstate = 1 and @trancount > 0
rollback transaction usp_my_procedure_name;
raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
return;
end catch
end
它比你想要的更长吗?我打赌。它是正确的?是。
最后,您如何处理事务环境中的日志记录?如果出现错误,插入到日志表中的内容将与其他所有内容一起回滚。有时这是可以的,其他时间甚至是需要的,但有时是有问题的。其中一个最有趣的解决方案是Simon Sabin的Logging messages during a transaction。
答案 1 :(得分:1)
尝试更改log.LogError过程,以便直接访问ERROR_NUMBER()和其他错误函数。 documentation中有一个例子。