2016-02-23 52 views
0

我有一个SQL服务器脚本,其中包含多个批次,其编号为try catch。我跑了剧本,并得到了以下错误:获取变量名'@ErrorMessage'已被声明

The variable name '@ErrorMessage' has already been declared. Variable names must be unique within a query batch or stored procedure.

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

我尝试过和BEGIN TRANSACTION后移动的声明,但是我得到

Must declare the scalar variable "@ErrorMessage"

我怎样才能修复这个bug?

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; 

回答

2

整个批次的变量都存在,最典型的是GO陈述; T-SQL不使用BEGIN/END来确定范围。因此,第二个和第三个块需要GO将它们分开,因为这会使它们分开分批。