模拟实现异常堆栈,报告调用链和异常位置,代码如下:
CREATE PROC [MyHelper].[ThrowError] @ProcId INT AS --对于重新封装Error,微软有个raiserror方案:[sys].[sp_replrethrow] IF ERROR_NUMBER() IS NULL RETURN; DECLARE @_ProcName SYSNAME=ISNULL(LTRIM(RTRIM(OBJECT_NAME(@ProcId))),'出错位置不详') ,@_Num INT=ERROR_NUMBER() ,@_Msg NVARCHAR(4000)=ERROR_MESSAGE() ,@_Line NVARCHAR(100)=ISNULL(CONVERT(NVARCHAR,ERROR_LINE()),'未知') ,@_State TINYINT=ERROR_STATE() ,@_NumCaption NVARCHAR(50) ,@_MsgCaption NVARCHAR(50) ,@_Severity INT=ERROR_SEVERITY() ; IF @_Num<50000 BEGIN SET @_NumCaption=' ,ErrorNum:'+CONVERT(NVARCHAR,@_Num); SET @_Num=100000+@_Num; SET @_MsgCaption=',Message:'; END ELSE BEGIN SET @_NumCaption=''; SET @_State=@_State+1; SET @_MsgCaption=';'+CHAR(13)+char(10); END SET @_Msg='第'+CONVERT(NVARCHAR,@_State)+'层:' +'Procedure:'+@_ProcName+',Line:'+@_Line +@_NumCaption + @_MsgCaption +@_Msg; THROW @_Num,@_Msg,@_State;
使用方法:
BEGIN TRY EXEC SP_EXECUTESQL N'SELECT 1 FROM tbl;'; END TRY BEGIN CATCH EXEC MyHelper.ThrowError @@PROCID; END CATCH SET NOCOUNT OFF;