2015-10-22 36 views
0

該問題應該簡單,但我找不出答案,也不知道爲什麼我的sp不工作。從存儲過程返回錯誤消息

CREATE PROCEDURE spTest_Delete 
@ID int 
AS 
    begin tran 
     declare @err int 
     declare @errMesage nvarchar(max) 
     set @errMesage = '' 
     set @err = 0 

     delete from Test 
     where ID = @ID 

     set @err = @@ERROR 
     set @errMesage = ERROR_MESSAGE() 

     if @err = 0 
      commit tran 
     else 
     begin 
      RAISERROR(N'Could not delete !Error nr: %d. Message: %s', 1, 16, @err, @errMesage) 
      rollback tran 
     end 

這個程序運行正常,但在對delete聲明FK約束的情況下,它運行到一個錯誤(這是很好),我想捕獲錯誤。

消息547,級別16,狀態0,過程spTest_Delete,第12行
DELETE語句衝突與基準約束 「FK_TEstFK_Test」。衝突發生在數據庫「測試」中,表 「dbo.Test」,列'ID'。該語句已終止。

無法刪除!
錯誤NR:547消息:(空)消息50000,級別1,狀態16

我總是空的我的信息變量,即使delete語句拋出一個錯誤。

回答

2

嘗試使用TRY CATCH,趕上你的錯誤是這樣的:

BEGIN TRY 
    delete from Test 
    where ID = @ID 
END TRY 
BEGIN CATCH 
    SET @ErrorMessage = ERROR_MESSAGE() 
    SET @ErrorSeverity = ERROR_SEVERITY() 
    SET @ErrorState = ERROR_STATE() 
    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState) 
    BREAK 
END CATCH 
+0

嘗試抓住了伎倆,但我仍然有點困惑,爲什麼它不工作沒有嘗試抓住。 – CiucaS

+0

@CiucaS: - 通常建議使用TRY..CATCH來捕捉錯誤。您可以嘗試使用'if ISNULL(@ err,0)= 0' –

+1

Error.Message如何在.net端捕獲ErrorMessage? – user3079364

5

你可能要開始在你的程序中使用TRY..CATCH

器具處理錯誤的Transact-SQL類似到Microsoft Visual C#和Microsoft Visual C++ 語言中的 異常處理。一組Transact-SQL語句可以包含在TRY 塊中。如果在TRY塊中發生錯誤,控制權將傳遞給另一組包含在CATCH塊中的語句。

所以,你的程序可以被改寫爲:

CREATE PROCEDURE spTest_Delete @ID INT 
AS 
BEGIN 
    SET NOCOUNT ON; 
    BEGIN TRY 
     BEGIN TRANSACTION 
      DELETE 
      FROM Test 
      WHERE ID = @ID; 
     COMMIT TRANSACTION 
    END TRY 
    BEGIN CATCH 
     IF @@TRANCOUNT > 0 
      ROLLBACK TRANSACTION 
     SELECT ERROR_NUMBER(), ERROR_MESSAGE(); 
    END CATCH 
END 

而且,請注意,您正在運行單delete語句。這意味着它不需要包含在交易中。 This問題解釋了原因。

你的代碼變得這樣:

CREATE PROCEDURE spTest_Delete @ID INT 
AS 
BEGIN 
    SET NOCOUNT ON; 
    BEGIN TRY 
     DELETE 
     FROM Test 
     WHERE ID = @ID; 
    END TRY 
    BEGIN CATCH 
     SELECT ERROR_NUMBER(), ERROR_MESSAGE(); 
    END CATCH 
END 

現在爲什麼你@errMessage始終是NULL?因爲ERROR_MESSAGE()僅在捕獲塊中有效。這是寫在documentation

返回導致 TRY ... CATCH構造的CATCH塊運行的錯誤消息文本。

Using TRY..CATCH in Transact-SQL告訴此:

錯誤信息是通過使用從在TRY ... CATCH構造的CATCH塊的範圍的任何地方 這些功能中檢索。如果在CATCH 塊的範圍之外調用,則錯誤 函數將返回NULL。