Sql 如何处理递归过程中的错误?

Sql 如何处理递归过程中的错误?,sql,sql-server,Sql,Sql Server,如何处理递归过程中的错误?我正在使用SQL Server 2012 CREATE PROCEDURE [dbo].[TEST] @i INT AS BEGIN SET NOCOUNT ON; SET XACT_ABORT ON; BEGIN TRANSACTION [T] BEGIN TRY PRINT @i IF @i = 10 BEGIN COMMIT TRANSACTION

如何处理递归过程中的错误?我正在使用SQL Server 2012

CREATE PROCEDURE [dbo].[TEST]
    @i INT
AS
BEGIN
    SET NOCOUNT ON;
    SET XACT_ABORT ON;

    BEGIN TRANSACTION [T]
    BEGIN TRY

        PRINT @i

        IF @i = 10
        BEGIN
            COMMIT TRANSACTION [T]
            RETURN;
        END
        ELSE
        BEGIN
            SET @i = @i + 1;
            EXEC DBO.TEST @i;
        END

        COMMIT TRANSACTION [T]

    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT>0
            ROLLBACK TRANSACTION [T]
        SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_MESSAGE() AS ErrorMessage;
    END CATCH  
    
END

这只是一个例子,因为我无权发布原始代码。

这会是什么错误?你能发布存储过程吗?这样我们才能真正提供帮助。我不知道提交的位置,以及SQL是否有一个变量来检查递归性级别。这是纯粹的、纯粹的邪恶。T-SQL在它最好的时候是一种糟糕的编程语言;使用它来实现递归并将其与事务混为一谈会带来麻烦。在您发布的示例中,
@i
将指示递归级别,应该会有所帮助。如果没有这样的变量,可以使用临时表中存储的行。在T-SQL中无法访问堆栈跟踪之类的内容(尽管我希望在这方面被证明是错误的);但是,您可以使用探查器跟踪或扩展事件来跟踪过程外部的调用。
CREATE PROCEDURE [dbo].[TEST]
    @i INT
AS
BEGIN
    SET NOCOUNT ON;
    SET XACT_ABORT ON;

    DECLARE @InNestedTransaction BIT;

    BEGIN TRY

        IF (@@TRANCOUNT = 0)
        BEGIN
            SET @InNestedTransaction = 0;
            BEGIN TRAN; -- only start a transaction if not already in one
        END;
        ELSE
        BEGIN
            SET @InNestedTransaction = 1;
        END;

        /*********************************************/
        PRINT @i

        IF @i = 8
        BEGIN
            DECLARE @ForceError INT;
            --set @ForceError = 1/0; -- uncomment this line to force error.
        END
        IF @i = 10
        BEGIN
            RETURN;
        END
        ELSE
        BEGIN
            SET @i = @i + 1;
            EXEC DBO.TEST @i;
        END
        /*********************************************/

        IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0)
        BEGIN
           COMMIT;
        END;

    END TRY 
    BEGIN CATCH
        IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0)
        BEGIN
            ROLLBACK;
            SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_MESSAGE() AS ErrorMessage;
        END;
        ELSE
        BEGIN
            THROW;
        END

    END CATCH

END