2014-10-16 23 views
0

我有这个存储过程:如何找出存储过程的哪个部分给我一个错误?

CREATE PROCEDURE sp_purchase_test 
    @AdminTestId int, 
    @PurchaseDate DATETIME OUTPUT, 
    @RC  INT OUTPUT, 
    @UserId INT 
AS 

BEGIN 
    BEGIN TRY 

     DECLARE @UserTestId INT; 

     INSERT INTO dbo.UserTest 
     ( 
      AdminTestId, 
      PurchaseDate, 
      UserId, 
      Sequence    
     ) 
     SELECT AdminTestId, 
       @PurchaseDate, 
       @UserId, 
       1 
     FROM AdminTest 
     WHERE AdminTestId = @AdminTestId 

     SET @UserTestId = SCOPE_IDENTITY() 

     INSERT INTO dbo.UserTestQuestion 
     ( 
      UserTestId,  
      QuestionNumber, 
      QuestionUId,    
      UserId      
     ) 
     SELECT @UserTestId, 
       ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS [QuestionNumber], 
       QuestionUId, 
       @UserId 
     FROM AdminTestQuestion 
     WHERE AdminTestId = @AdminTestId 
    END TRY 
    BEGIN CATCH 
     SET @RC = 0 
     RETURN 
    END CATCH 
    SET @RC = 1 
    RETURN 
END 

我打电话这样说:

DECLARE @PurchaseDate DATETIME 
DECLARE @RC  INT 
exec sp_purchase_test 119, @PurchaseDate OUT, @RC OUT, 4 
SELECT @RC 

它返回一个“0”,但我看不出有什么失败。如何调试这个给我,为什么它返回一个0

+0

取出TRY/CATCH?或者只是打印错误消息? – DavidG 2014-10-16 15:39:38

+0

http://msdn.microsoft.com/en-us/library/ms175976.aspx这是文档:查看有关查看错误内容的部分。 – 2014-10-16 15:43:13

回答

2

SQL Server documentation,在CATCH块你可以得到已经陷入了错误的详细信息

检索出错信息在CATCH块的范围内,以下系统功能可以用于获得关于导致要执行的CATCH块的错误信息:

ERROR_NUMBER()返回错误的数量。

ERROR_SEVERITY()返回严重性。

ERROR_STATE()返回错误状态编号。

ERROR_PROCEDURE()返回发生错误的存储过程或触发器的名称。

ERROR_LINE()返回导致错误的例程内的行号。

ERROR_MESSAGE()返回错误消息的完整文本。文本包含为任何可替换参数提供的值,如长度,对象名称或时间。

例如,SQL:

SELECT 
ERROR_NUMBER() AS ErrorNumber 
,ERROR_SEVERITY() AS ErrorSeverity 
,ERROR_STATE() AS ErrorState 
,ERROR_PROCEDURE() AS ErrorProcedure 
,ERROR_LINE() AS ErrorLine 
,ERROR_MESSAGE() AS ErrorMessage; 
2

你为什么不只是删除TRY..CATCH所以你可以看到这个问题?如果无法修改原稿,请复印一份。如果您甚至没有权限创建副本,您仍应该能够通过在#前加上名称来创建一个临时存储过程。

一般来说,拥有一个“不能失败”的程序是一个糟糕的主意,但仅仅是因为它返回了一个无益的“出错”的价值;只是让错误冒泡到呼叫者。 TRY..CATCH也无法确保数据的完整性 - 您的陈述失败并不意味着什么也没有发生。为了达到这个目的,你需要将整个事情包装在一个交易中,并且在你处理时发出一个SET XACT_ABORT ON,以确保它在出现问题的第一个迹象时能够回滚。显然,所有这些都需要修改客户端代码的能力,而这些代码可能并不是你所需要的。

这一切都说,它可能调试存储过程。我听说过传说。我从来没有能够在我自己的系统上配置它,我不确定这是否值得麻烦。 :-)

1

请务必在您的TRY-CATCHCATCH部分实施错误处理。

喜欢的东西:

DECLARE @errorMessage nvarchar(4000), 
     @errorNumber int, 
     @errorSeverity int, 
     @errorState int, 
     @errorLine int, 
     @errorProcedure nvarchar(128); 

BEGIN TRY 

    /* Your code. */ 

END TRY 
BEGIN CATCH 

    SELECT @errorMessage = ERROR_MESSAGE(), 
      @errorNumber = ERROR_NUMBER(), 
      @errorSeverity = ERROR_SEVERITY(), 
      @errorState = ERROR_STATE(), 
      @errorLine = ERROR_LINE(), 
      @errorProcedure = ERROR_PROCEDURE(); 

    /* You can ROLLBACK here, as needed. */ 

    RAISERROR('%s (Error %d occurred at line %d in %s.)', 
       @errorSeverity, 
       @errorState, 
       @errorMessage, 
       @errorNumber, 
       @errorLine, 
       @errorProcedure); 

END CATCH 
相关问题