获取变量名称'@ErrorMessage'已经声明

时间:2016-02-23 20:21:19

标签: sql sql-server

我有一个SQL服务器脚本,其中包含多个try catch批次。我运行脚本并得到以下错误:

  

已声明变量名'@ErrorMessage'。变量名在查询批处理或存储过程中必须是唯一的。

我在多个地方声明了变量,但它在每个catch begin .. end范围内。不知道为什么会抛出错误。

我尝试在BEGIN TRANSACTION之前和之后移动声明,但我得到了

  

必须声明标量变量“@ErrorMessage”

如何修复此错误?

USE [TestWebDb2_Local]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

SET XACT_ABORT ON
GO

BEGIN TRANSACTION

BEGIN TRY 

    IF COLUMNPROPERTY(OBJECT_ID('[dbo].[MY_TABL]'), 'MY_REQID', 'ColumnId') IS NULL
    BEGIN
        ALTER TABLE [dbo].[MY_TABL] ADD MY_REQID INT NOT NULL DEFAULT(0) 
    END

    IF COLUMNPROPERTY(OBJECT_ID('dbo.MY_TABL'), 'MY_ISCOMPLETED', 'ColumnId') IS NULL
    BEGIN
        ALTER TABLE [dbo].[MY_TABL] ADD MY_ISCOMPLETED BIT NOT NULL DEFAULT(0)
    END
END TRY
BEGIN CATCH
        -- Test whether the transaction is uncommittable.
        IF (XACT_STATE()) = -1
        BEGIN
            DECLARE @ErrorMessage NVARCHAR(4000);
            DECLARE @ErrorSeverity INT;
            DECLARE @ErrorState INT;

            SELECT 
                @ErrorMessage = ERROR_MESSAGE(),
                @ErrorSeverity = ERROR_SEVERITY(),
                @ErrorState = ERROR_STATE();

            -- Use RAISERROR inside the CATCH block to return error
            -- information about the original error that caused
            -- execution to jump to the CATCH block.
            RAISERROR (@ErrorMessage, -- Message text.
                       @ErrorSeverity, -- Severity.
                       @ErrorState -- State.
                       );

            PRINT 'The transaction from Alter table is in an uncommittable state.' +
                  ' Rolling back transaction.'
            ROLLBACK TRANSACTION;
        END;
END CATCH;
GO 


 BEGIN TRY 
    UPDATE [dbo].[MY_TABL] SET MY_REQID = 20 WHERE PENDTRANS_ABBREV = '1035'


END TRY
BEGIN CATCH
        -- Test whether the transaction is uncommittable.
        IF (XACT_STATE()) = -1
        BEGIN
            DECLARE @ErrorMessage NVARCHAR(4000);
            DECLARE @ErrorSeverity INT;
            DECLARE @ErrorState INT;

            SELECT 
                @ErrorMessage = ERROR_MESSAGE(),
                @ErrorSeverity = ERROR_SEVERITY(),
                @ErrorState = ERROR_STATE();

            -- Use RAISERROR inside the CATCH block to return error
            -- information about the original error that caused
            -- execution to jump to the CATCH block.
            RAISERROR (@ErrorMessage, -- Message text.
                       @ErrorSeverity, -- Severity.
                       @ErrorState -- State.
                       );

            PRINT 'The transaction from UPDATE table is in an uncommittable state.' +
                  ' Rolling back transaction.'
            ROLLBACK TRANSACTION;
        END;
END CATCH;


BEGIN TRY
        CREATE UNIQUE NONCLUSTERED INDEX idxReqId ON [dbo].[MY_TABL](MY_REQID)
        PRINT 'Index created'
END TRY
BEGIN CATCH
        -- Test whether the transaction is uncommittable.
        IF (XACT_STATE()) = -1
        BEGIN
            DECLARE @ErrorMessage NVARCHAR(4000);
            DECLARE @ErrorSeverity INT;
            DECLARE @ErrorState INT;

            SELECT 
                @ErrorMessage = ERROR_MESSAGE(),
                @ErrorSeverity = ERROR_SEVERITY(),
                @ErrorState = ERROR_STATE();

            -- Use RAISERROR inside the CATCH block to return error
            -- information about the original error that caused
            -- execution to jump to the CATCH block.
            RAISERROR (@ErrorMessage, -- Message text.
                       @ErrorSeverity, -- Severity.
                       @ErrorState -- State.
                       );


            PRINT 'The transaction from Create Index is in an uncommittable state.' +
                  ' Rolling back transaction.'
            ROLLBACK TRANSACTION;
        END;
END CATCH;
GO

if XACT_STATE() = 1
BEGIN
    COMMIT TRANSACTION  
    PRINT 'Transaction committed.';
END;

1 个答案:

答案 0 :(得分:2)

整个批次的变量都存在,最常见的是由GO语句分隔; T-SQL不使用BEGIN / END来确定范围。因此,第2个和第3个TRY / CATCH块需要GO来分隔它们,因为这会使它们成为单独的批次。