2009-09-22 133 views
0

我對下面的TSQL存儲過程使用下面的一般構造。這適用於將錯誤信息返回給調用應用程序代碼。但是,我也想將錯誤記錄在數據庫本身中。我如何在SQL Server 2005中完成這項工作?在SQL Server 2005數據庫中記錄存儲過程錯誤

BEGIN TRY 

TSQL... 

END TRY 
BEGIN CATCH 
DECLARE @ErrorMessage NVARCHAR(4000) 
DECLARE @ErrorSeverity INT 
DECLARE @ErrorState INT 

SELECT @ErrorMessage = ERROR_MESSAGE(), 
    @ErrorSeverity = ERROR_SEVERITY(), 
    @ErrorState = ERROR_STATE() 

-- Use RAISERROR inside the CATCH block to return error 
-- information about the original error that caused 
-- execution to jump to the CATCH block. 
RAISERROR (@ErrorMessage, -- Message text. 
    @ErrorSeverity, -- Severity. 
    @ErrorState -- State. 
     ) 
END CATCH 

SET NOCOUNT OFF 
SET @Error = @@ERROR 
RETURN @Error 

回答

0

這裏是回滾嵌套過程記錄的例子...

這將創建兩個測試表和三個過程,可以嵌套的方式與交易被稱爲:

if exists (select * from sysobjects where id = object_id(N'[dbo].ProcedureA') and OBJECTPROPERTY(id, N'IsProcedure') = 1) drop procedure [dbo].ProcedureA 
if exists (select * from sysobjects where id = object_id(N'[dbo].ProcedureB') and OBJECTPROPERTY(id, N'IsProcedure') = 1) drop procedure [dbo].ProcedureB 
if exists (select * from sysobjects where id = object_id(N'[dbo].ProcedureC') and OBJECTPROPERTY(id, N'IsProcedure') = 1) drop procedure [dbo].ProcedureC 
if exists (select * from sysobjects where id = object_id(N'YourLogTable') and OBJECTPROPERTY(id, N'IsTable') = 1) drop table YourLogTable 
if exists (select * from sysobjects where id = object_id(N'YourTestTable') and OBJECTPROPERTY(id, N'IsTable') = 1) drop table YourTestTable 

go 
CREATE TABLE YourLogTable 
(
    LogID int    not null primary key identity(1,1) 
    ,LogDate datetime   not null default GETDATE() 
    ,ProcedureName varchar(50) null default OBJECT_NAME(@@PROCID) 
    ,LogText varchar(8000)  not null 
) 
go 
CREATE TABLE YourTestTable 
(
    TestID int not null primary key identity(1,1) 
    ,TestData varchar(100) not null 
) 

go 
----------------------------------------------------------------------- 
----------------------------------------------------------------------- 
CREATE PROCEDURE ProcedureA 
(
    @ParamA1  int 
    ,@ParamA2  varchar(10) 
    ,@ErrorMsg varchar(1000) OUTPUT 
) 
AS 

DECLARE @LogValue  varchar(8000) 
DECLARE @ReturnValueX int 
DECLARE @ErrorMsgX  varchar(1000) 

DECLARE @TempValue  int 

BEGIN TRY 

    SET @LogValue=ISNULL(OBJECT_NAME(@@PROCID), 'unknown') 
     +': @ParamA1='+COALESCE(''''+CONVERT(varchar(10),@ParamA1)+'''','null') 
     +', @ParamA2='+COALESCE(''''[email protected]+'''','null') 


    BEGIN TRANSACTION --<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<, 

    INSERT INTO YourTestTable (TestData) VALUES ('I was in top of ProdecureA') 



    --your logic logic here--- 
    IF @ParamA1=1 
    BEGIN 
     RAISERROR('testing, bad parameter',16,1) --send control to the BEGIN CATCH block 
    END 

    SET @[email protected]/@ParamA1 

    EXEC @ReturnValueX=ProcedureB @ParamA1,@ParamA2,@ErrorMsgX OUTPUT 
    IF @ReturnValueX!=0 
    BEGIN 
     SET @ErrorMsg='Call to ProcedureB failed, ReturnValueX='+COALESCE(''''+CONVERT(varchar(10),@ReturnValueX)+'''','null')+', @ErrorMsgX='+COALESCE(''''+CONVERT(varchar(10),@ErrorMsgX)+'''','null') 
     RAISERROR(@ErrorMsg,16,1) --send control to the BEGIN CATCH block 
    END 

    --your logic logic here--- 
    INSERT INTO YourTestTable (TestData) VALUES ('I was in bottom of ProdecureA') 


END TRY 
BEGIN CATCH 

    IF XACT_STATE()!=0 
    BEGIN 
     ROLLBACK TRANSACTION 
    END 

    SET @[email protected]+'; ' 
        +CASE WHEN ERROR_NUMBER()  IS NOT NULL THEN 'Msg '   +CONVERT(varchar(30), ERROR_NUMBER() ) ELSE '' END 
        +CASE WHEN ERROR_SEVERITY() IS NOT NULL THEN ', Level '  +CONVERT(varchar(30), ERROR_SEVERITY() ) ELSE '' END 
        +CASE WHEN ERROR_STATE()  IS NOT NULL THEN ', State '  +CONVERT(varchar(30), ERROR_STATE()  ) ELSE '' END 
        +CASE WHEN ERROR_PROCEDURE() IS NOT NULL THEN ', Procedure ' +      ERROR_PROCEDURE() ELSE '' END 
        +CASE WHEN ERROR_LINE()  IS NOT NULL THEN ', Line '  +CONVERT(varchar(30), ERROR_LINE()  ) ELSE '' END 
        +CASE WHEN ERROR_MESSAGE() IS NOT NULL THEN ', '   +      ERROR_MESSAGE()  ELSE '' END 
    INSERT INTO YourLogTable (LogText) VALUES (@ErrorMsg) 
    RETURN 999 

END CATCH 

IF XACT_STATE()!=0 
BEGIN 
    COMMIT 
END 

--PRINT ISNULL(OBJECT_NAME(@@PROCID), 'unknown')+' OK' 
RETURN 0 
GO 

----------------------------------------------------------------------- 
----------------------------------------------------------------------- 
CREATE PROCEDURE ProcedureB 
(
    @ParamB1  int 
    ,@ParamB2  varchar(10) 
    ,@ErrorMsg varchar(1000) OUTPUT 
) 
AS 

DECLARE @LogValue  varchar(8000) 
DECLARE @ReturnValueX int 
DECLARE @ErrorMsgX  varchar(1000) 

DECLARE @TempValue  int 

BEGIN TRY 

    SET @LogValue=ISNULL(OBJECT_NAME(@@PROCID), 'unknown') 
     +': @ParamB1='+COALESCE(''''+CONVERT(varchar(10),@ParamB1)+'''','null') 
     +', @ParamB2='+COALESCE(''''[email protected]+'''','null') 

    BEGIN TRANSACTION --<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<, 

    INSERT INTO YourTestTable (TestData) VALUES ('I was in top of ProdecureB') 

    --your logic logic here--- 
    IF @ParamB1=10 
    BEGIN 
     RAISERROR('testing, bad parameter',16,1) --send control to the BEGIN CATCH block 
    END 

    SET @[email protected]/@ParamB1 

    EXEC @ReturnValueX=ProcedureC @ParamB1,@ErrorMsgX OUTPUT 
    IF @ReturnValueX!=0 
    BEGIN 
     SET @ErrorMsg='Call to ProcedureC failed, ReturnValueX='+COALESCE(''''+CONVERT(varchar(10),@ReturnValueX)+'''','null')+', @ErrorMsgX='+COALESCE(''''+CONVERT(varchar(10),@ErrorMsgX)+'''','null') 
     RAISERROR(@ErrorMsg,16,1) --send control to the BEGIN CATCH block 
    END 

    --your logic logic here--- 
    INSERT INTO YourTestTable (TestData) VALUES ('I was in bottom of ProdecureB') 


END TRY 
BEGIN CATCH 

    IF XACT_STATE()!=0 
    BEGIN 
     ROLLBACK TRANSACTION 
    END 

    SET @[email protected]+'; ' 
        +CASE WHEN ERROR_NUMBER()  IS NOT NULL THEN 'Msg '   +CONVERT(varchar(30), ERROR_NUMBER() ) ELSE '' END 
        +CASE WHEN ERROR_SEVERITY() IS NOT NULL THEN ', Level '  +CONVERT(varchar(30), ERROR_SEVERITY() ) ELSE '' END 
        +CASE WHEN ERROR_STATE()  IS NOT NULL THEN ', State '  +CONVERT(varchar(30), ERROR_STATE()  ) ELSE '' END 
        +CASE WHEN ERROR_PROCEDURE() IS NOT NULL THEN ', Procedure ' +      ERROR_PROCEDURE() ELSE '' END 
        +CASE WHEN ERROR_LINE()  IS NOT NULL THEN ', Line '  +CONVERT(varchar(30), ERROR_LINE()  ) ELSE '' END 
        +CASE WHEN ERROR_MESSAGE() IS NOT NULL THEN ', '   +      ERROR_MESSAGE()  ELSE '' END 
    INSERT INTO YourLogTable (LogText) VALUES (@ErrorMsg) 

    RETURN 999 

END CATCH 

IF XACT_STATE()!=0 
BEGIN 
    COMMIT 
END 
--PRINT ISNULL(OBJECT_NAME(@@PROCID), 'unknown')+' OK' 
RETURN 0 
GO 

----------------------------------------------------------------------- 
----------------------------------------------------------------------- 
CREATE PROCEDURE ProcedureC 
(
    @ParamC1  int 
    ,@ErrorMsg varchar(1000) OUTPUT 
) 
AS 

DECLARE @LogValue  varchar(8000) 
DECLARE @ReturnValueX int 
DECLARE @ErrorMsgX  varchar(1000) 

DECLARE @TempValue  int 


BEGIN TRY 

    BEGIN TRANSACTION --<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<, 

    SET @LogValue=ISNULL(OBJECT_NAME(@@PROCID), 'unknown') 
     +': @ParamC1='+COALESCE(''''+CONVERT(varchar(10),@ParamC1)+'''','null') 

    --your logic logic here--- 
    INSERT INTO YourTestTable (TestData) VALUES ('I was in top of ProdecureC') 

    IF @ParamC1=100 
    BEGIN 
     RAISERROR('testing, bad parameter',16,1) --send control to the BEGIN CATCH block 
    END 

    SET @[email protected]/@ParamC1 


    --your logic logic here--- 
    INSERT INTO YourTestTable (TestData) VALUES ('I was in bottom of ProdecureC') 


END TRY 
BEGIN CATCH 

    IF XACT_STATE()!=0 
    BEGIN 
     ROLLBACK TRANSACTION 
    END 

    SET @[email protected]+'; ' 
        +CASE WHEN ERROR_NUMBER()  IS NOT NULL THEN 'Msg '   +CONVERT(varchar(30), ERROR_NUMBER() ) ELSE '' END 
        +CASE WHEN ERROR_SEVERITY() IS NOT NULL THEN ', Level '  +CONVERT(varchar(30), ERROR_SEVERITY() ) ELSE '' END 
        +CASE WHEN ERROR_STATE()  IS NOT NULL THEN ', State '  +CONVERT(varchar(30), ERROR_STATE()  ) ELSE '' END 
        +CASE WHEN ERROR_PROCEDURE() IS NOT NULL THEN ', Procedure ' +      ERROR_PROCEDURE() ELSE '' END 
        +CASE WHEN ERROR_LINE()  IS NOT NULL THEN ', Line '  +CONVERT(varchar(30), ERROR_LINE()  ) ELSE '' END 
        +CASE WHEN ERROR_MESSAGE() IS NOT NULL THEN ', '   +      ERROR_MESSAGE()  ELSE '' END 
    INSERT INTO YourLogTable (LogText) VALUES (@ErrorMsg) 

    RETURN 999 

END CATCH 

IF XACT_STATE()!=0 
BEGIN 
    COMMIT 
END 
--PRINT ISNULL(OBJECT_NAME(@@PROCID), 'unknown')+' OK' 
RETURN 0 
GO 

這將運行四個測試用例上面的程序:

  • 了失效,YourTestTable中沒有任何數據,YourLogTable顯示日誌的信息
  • 信息
  • 無法在B,YourTestTable中沒有任何數據,YourLogTable顯示日誌信息爲B和A
  • 無法在C,YourTestTable中沒有任何數據,YourLogTable顯示日誌信息爲C,B和A
  • 所有工作,YourTestTable中有數據,YourLogTable中有

    代碼在這裏沒有數據:

    DECLARE @ReturnValue int 
    DECLARE @ErrorMsg  varchar(1000) 
    
    print '###########################################################################' 
    print 'will error out in A - should log A>>> EXEC ProcedureA 1,''abcd''' 
    delete from YourTestTable; delete from YourLogTable; 
    EXEC @ReturnValue=ProcedureA 1,'abcd',@ErrorMsg OUTPUT; SELECT @ReturnValue AS '@ReturnValue' ,@ErrorMsg AS '@ErrorMsg'; select 'YourTestTable' AS 'YourTestTable',* from YourTestTable; select 'YourLogTable' AS 'YourLogTable',* from YourLogTable; 
    print '###########################################################################' 
    print 'will error out in B - should log B and A>>> EXEC ProcedureA 10,''abcd''' 
    delete from YourTestTable; delete from YourLogTable; 
    EXEC @ReturnValue=ProcedureA 10,'abcd',@ErrorMsg OUTPUT; SELECT @ReturnValue AS '@ReturnValue' ,@ErrorMsg AS '@ErrorMsg'; select 'YourTestTable' AS 'YourTestTable',* from YourTestTable; select 'YourLogTable' AS 'YourLogTable',* from YourLogTable; 
    print '###########################################################################' 
    print 'will error out in C - should log C, B and A>>>> EXEC ProcedureA 100,''123''' 
    delete from YourTestTable; delete from YourLogTable; 
    EXEC @ReturnValue=ProcedureA 100,'123',@ErrorMsg OUTPUT; SELECT @ReturnValue AS '@ReturnValue' ,@ErrorMsg AS '@ErrorMsg'; select 'YourTestTable' AS 'YourTestTable',* from YourTestTable; select 'YourLogTable' AS 'YourLogTable',* from YourLogTable; 
    print '###########################################################################' 
    print 'will complete, YourTestTable will contain data >>>> EXEC ProcedureA 2,''123''' 
    delete from YourTestTable; delete from YourLogTable; 
    EXEC @ReturnValue=ProcedureA 2,'123',@ErrorMsg OUTPUT; SELECT @ReturnValue AS '@ReturnValue' ,@ErrorMsg AS '@ErrorMsg'; select 'YourTestTable' AS 'YourTestTable',* from YourTestTable; select 'YourLogTable' AS 'YourLogTable',* from YourLogTable; 
    print '###########################################################################' 
    

這裏是輸出,這說明在日誌中堆棧,儘管回滾:

########################################################################### 
will error out in A - should log A>>> EXEC ProcedureA 1,'abcd' 

(6 row(s) affected) 

(0 row(s) affected) 

(1 row(s) affected) 

(1 row(s) affected) 
@ReturnValue @ErrorMsg 
------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
999   ProcedureA: @ParamA1='1', @ParamA2='abcd'; Msg 50000, Level 16, State 1, Procedure ProcedureA, Line 33, testing, bad parameter 

(1 row(s) affected) 

YourTestTable TestID  TestData 
------------- ----------- ---------------------------------------------------------------------------------------------------- 

(0 row(s) affected) 

YourLogTable LogID  LogDate     ProcedureName          LogText 
------------ ----------- ----------------------- -------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
YourLogTable 37   2009-09-08 15:04:39.663 ProcedureA           ProcedureA: @ParamA1='1', @ParamA2='abcd'; Msg 50000, Level 16, State 1, Procedure ProcedureA, Line 33, testing, bad parameter 

(1 row(s) affected) 

########################################################################### 
will error out in B - should log B and A>>> EXEC ProcedureA 10,'abcd' 

(0 row(s) affected) 

(1 row(s) affected) 

(1 row(s) affected) 

(1 row(s) affected) 

(1 row(s) affected) 

(1 row(s) affected) 
@ReturnValue @ErrorMsg 
------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
999   ProcedureA: @ParamA1='10', @ParamA2='abcd'; Msg 266, Level 16, State 2, Procedure ProcedureB, Line 0, Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 1, current count = 0. 

(1 row(s) affected) 

YourTestTable TestID  TestData 
------------- ----------- ---------------------------------------------------------------------------------------------------- 

(0 row(s) affected) 

YourLogTable LogID  LogDate     ProcedureName          LogText 
------------ ----------- ----------------------- -------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
YourLogTable 38   2009-09-08 15:04:39.680 ProcedureB           ProcedureB: @ParamB1='10', @ParamB2='abcd'; Msg 50000, Level 16, State 1, Procedure ProcedureB, Line 31, testing, bad parameter 
YourLogTable 39   2009-09-08 15:04:39.680 ProcedureA           ProcedureA: @ParamA1='10', @ParamA2='abcd'; Msg 266, Level 16, State 2, Procedure ProcedureB, Line 0, Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 1, current count = 0. 

(2 row(s) affected) 

########################################################################### 
will error out in C - should log C, B and A>>>> EXEC ProcedureA 100,'123' 

(0 row(s) affected) 

(2 row(s) affected) 

(1 row(s) affected) 

(1 row(s) affected) 

(1 row(s) affected) 

(1 row(s) affected) 

(1 row(s) affected) 

(1 row(s) affected) 
@ReturnValue @ErrorMsg 
------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
999   ProcedureA: @ParamA1='100', @ParamA2='123'; Msg 266, Level 16, State 2, Procedure ProcedureB, Line 0, Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 1, current count = 0. 

(1 row(s) affected) 

YourTestTable TestID  TestData 
------------- ----------- ---------------------------------------------------------------------------------------------------- 

(0 row(s) affected) 

YourLogTable LogID  LogDate     ProcedureName          LogText 
------------ ----------- ----------------------- -------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
+0

從長遠來看,混合的try-catch邏輯*和*返回錯誤代碼不會起作用。保證有人會忘記檢查一個程序返回代碼,並依靠存在已經回滾的交易來繼續前進!無論單獨依靠異常還是通過使用保存點正確處理XACT_STATE的所有3個狀態,從而允許調用者決定是否在錯誤情況下回滾或在其他路徑上繼續,都可以說是更好。許多錯誤是可以恢復的。請參閱http://rusanu.com/2009/06/11/exception-handling-and-nested-transactions/ – 2009-09-22 22:10:56

+0

謝謝你這樣一個徹底的例子! – javacavaj 2009-09-23 02:13:24

+0

@Remus Rusanu,我們從不使用保存點並總是回滾,所以調用者沒有多少選項,因爲事務計數不匹配,並且會自動進入catch。 – 2009-09-23 13:17:15

0

創建列(MessageText中,嚴重性,狀態,DateTimeOccurred)和INSERT信息到它的錯誤表。

2

創建ErrorLog表並在CATCH塊中寫入此表。

這不是那麼容易,因爲,雖然......

但是,你要測試「@@ TRANCOUNT = 0」,首先是因爲它稍後將回滾,說如果你巢存儲與程序TRY/CATCH或進行客戶交易。如果你使用SET XACT_ABORT ON

這意味着你可能有多個錯誤信息,如果您有嵌套這並不適用,所以我都登錄和ERROR_PROCEDURE()OBJECT_NAME(@@PROCID)區分兩種情況的發生錯誤,並在那裏它被記錄下來。

2

簡單的答案是'寫入日誌表',但實際上這有點複雜,因爲您製作的任何表都受到當前事務的影響,並且catch塊受到錯誤處理的影響三態交易。您必須使用XACT_STATE來檢查當前事務狀態。如果是一個註定要失敗的事務(狀態-1),那麼您必須先回滾然後再登錄,否則嘗試插入日誌表會導致批處理異常終止。

有關使用T-SQL try/catch塊並正確處理事務的過程模板示例,請參見Exception handling and nested transactions