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

时间:2014-10-16 15:35:48

标签: sql-server

我有这个存储过程:

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的信息。

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分:2)

为什么不删除TRY..CATCH,以便您可以看到问题?如果您无法修改原件,请复印。如果您甚至没有创建副本的权限,您仍然可以通过在名称前加#来创建临时sproc。

一般来说,拥有一个“不会失败”的程序是一个可怕的想法,但这只是因为它返回了一个无用的“出错了”的价值;让错误冒泡到调用者。 TRY..CATCH也无法确保数据完整性 - 您的语句失败并不意味着什么也没发生。要实现这一点,您需要将整个事物包装在一个事务中,并在您处于事件状态时发出SET XACT_ABORT ON以确保它在第一次出现问题时回滚。显然,所有这些都需要能够修改您可能没有的客户端代码。

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

答案 2 :(得分:1)

请务必在CATCH的{​​{1}}部分实施错误处理。

类似的东西:

TRY-CATCH