0

我有一个复杂的问题。我有一个不带参数的存储过程。目前,当我运行它时,我收到一条错误消息,告诉我

在 EXECUTE 之后表示 BEGIN 和 COMMIT 语句的数量不匹配。先前计数 = 0,当前计数 = 1。

本质上,存储过程看起来像这样:

    USE FirstDatabase
    GO

    SET ANSI_NULLS ON
    GO

    SET QUOTED_IDENTIFIER ON
    GO

    CREATE PROCEDURE [schema].[Procedure]
    AS

    SET NOCOUNT ON
    SET XACT_ABORT ON

    BEGIN TRY

DECLARE @WholeBunchOfVariables varchar(max); --All these are ofcourse separated and different data types

IF(SELECT OBJECT_ID('tempdb..#tempTable')) IS NOT NULL
BEGIN
    DROP TABLE #tempTable
END

CREATE TABLE #tempTable (
    ...,  --bunch of fields to be populated
    IsProcessed bit) -- this field is used later to run through a temp table variable one record at a time, once done, this is set to 1

DECLARE @tempTableVar TABLE (
    ...)

    --Insert data from the accounts table(s) into the temp table.  Only process data
    --that has been modified in the past day.

    INSERT INTO #tempTable
    SELECT DISTINCT
        ... -- bunch of fields from different tables
    FROM
        SomeTables

    --Loop through the data in the temp table, one record at a time.  Process it and 
    --once done, set the IsProcessed field in the temp table to 1 so that it can pick 
    --up the next record to process.

    WHILE (1=1)
    BEGIN

    INSERT INTO @tempTableVar
SELECT TOP 1
    ... --bunch of fields from temp table
FROM
    #tempTable
WHERE
    IsProcessed = 0  -- check for first unprocessed record

    --The following variables need to be initiated so that it can be used for executing 
    --The main stored procedure that popuplates the marketing tables.

    SELECT
        ... --bunch of variables initiated from the temp table variable
    FROM
        @tempTableVar

    BEGIN TRY

    BEGIN TRANSACTION

    IF (SELECT COUNT(*) FROM @tempTableVar) = 0
    BEGIN
            BREAK;
        ROLLBACK TRANSACTION;
    END

    --Another stored procedure is called here to be executed with the variables that 
    --were initiated a bit further up, as input parameters.


    EXEC [SomeDatabase].[Schema].[SomeOtherStoredProcedure]
        ... --bunch of input parameters / variables

COMMIT TRANSACTION

    END TRY

    BEGIN CATCH

IF (XACT_STATE() <> 0)
ROLLBACK TRAN;

SELECT 
        @ErrorNumber = ERROR_NUMBER(),
    @ErrorSeverity = ERROR_SEVERITY(),
    @ErrorState = ERROR_STATE(),
    @ErrorLine = ERROR_LINE(),
    @ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-');

SELECT @ErrorMessage = ERROR_MESSAGE() +  '(Error %d, Level %d, State %d, Procedure %s, Line %d).'

    --Errors on this level, essentially raised by the secondary stored procedure, are
    --stored in an error logging table for later reference

    INSERT INTO [schema].[ImportErrors] (
        ErrorType,
        ErrorMessaae) VALUES (
        'Some Type',
        @ErrorMessage);

UPDATE
    #tempTable
SET
    IsProcessed = 1
WHERE
    someField = @someVariable ...

DELETE
FROM
    @tempTableVar

    END CATCH

    --Update the temp table's IsProcessed field to 1 for the affected record, if there 
    --are no errors.

    UPDATE #tempTable
    SET
        IsProcessed = 1
    WHERE
        someField = @someVariable ...

    --Delete the entry from the temp table variable so that it can be used for the next
    --record.

    DELETE
    FROM
        @tempTableVar

    END

    IF(SELECT OBJECT_ID('tempdb..#tempTable')) IS NOT NULL
    BEGIN
        DROP TABLE #tempTable
    END

    SET NOCOUNT OFF
    SET XACT_ABORT OFF

    END TRY

    BEGIN CATCH

        IF (XACT_STATE() <> 0)
            ROLLBACK TRAN;

        -- Do the error handling.
        -- Assign variables to error-handling functions that 
        -- capture information for RAISERROR.
        SELECT 
            @ErrorNumber = ERROR_NUMBER(),
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE(),
            @ErrorLine = ERROR_LINE(),
            @ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-');

        -- Building the message string that will contain original
        -- error information.
        SELECT @ErrorMessage =
    'Message: '+ ERROR_MESSAGE() + N' (Error %d, Level %d, State %d, Procedure %s, Line %d).';

--SELECT @ErrorMessage = @ErrorMessage + @CustomerCategoryID + ' ' + @CustomerID + ' ' + @EmailAddress

-- Raise an error: msg_str parameter of RAISERROR will contain
-- the original error information.
RAISERROR (
    @ErrorMessage, 
    @ErrorSeverity, 
    1,
    @ErrorNumber,    -- parameter: original error number.
    @ErrorSeverity,  -- parameter: original error severity.
    @ErrorState,     -- parameter: original error state.
    @ErrorProcedure, -- parameter: original error procedure name.
    @ErrorLine);       -- parameter: original error line number.

    END CATCH

有人可以告诉我我做错了什么吗?

4

1 回答 1

0

这是要解析的大量代码 - 您的代码中有很多事务开始/结束,并且在回滚/提交之前您没有检查任何一个事务是否仍处于打开状态。

理想情况下,每个逻辑插入集都应该有一个事务提交/回滚语句。

于 2012-08-15T12:49:37.730 回答