2015-10-22 34 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。