2011-03-29 62 views
1

我在SQL Server中使用try catch獲取存儲過程。我想在catch循環要做的就是打電話給我自己的存儲過程的所有錯誤變量記錄,像這樣:將錯誤細節從catch傳遞到日誌存儲過程

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() 

我想要做的是隻有一個行與參數卡列斯的存儲過程,因爲我有這個在很多存儲過程中,並且不希望在每個存儲過程中都有很多代碼設置錯誤參數(我將擁有這三個以上),並且我有try-catch。

有誰知道我可以如何將這些傳遞到另一個存儲過程?

問候, 約翰

回答

1

試着改變你的log.LogError過程,以便訪問ERROR_NUMBER(),並直接在其他錯誤功能。在documentation中有一個例子。

+0

謝謝 - 這將解決我的問題。 – gugguson 2011-03-30 08:36:16

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

相關問題