【问题标题】:SQL Merge Update gives Subquery returned more than 1 value ErrorSQL合并更新给子查询返回超过1个值错误
【发布时间】:2017-07-31 10:38:05
【问题描述】:

我有一个使用 Merge 语句的存储过程。 当我尝试执行这个 sp 时,它会出现以下错误。

Msg 6401, Level 16, State 1, Procedure AnnualBudgetExcelUpload_I_U, Line 66
Cannot roll back Tran1. No transaction or savepoint of that name was found.
Msg 50000, Level 16, State 1, Procedure AnnualBudgetExcelUpload_I_U, Line 79
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Msg 266, Level 16, State 2, Procedure AnnualBudgetExcelUpload_I_U, Line 0
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.
Msg 3998, Level 16, State 1, Line 1
Uncommittable transaction is detected at the end of the batch. The transaction is rolled back.

我认为问题在于 Merge 的更新语句。因为如果我尝试使用一条记录或一条不可用的新记录,它会起作用..

这是我的sp

BEGIN TRANSACTION [AnnualBudgetTransaction]

BEGIN TRY

MERGE [dbo].[AnnualBudget] AS ab
USING @AnnualBudgetLines  AS bl
ON bl.Year = ab.Year 
AND ab.BudgetBreakdownId = bl.BudgetBreakdownId 
AND  ab.BudgetTypeId = bl.BudgetTypeId 
AND  ab.DepartmentSectionId = bl.DepartmentSectionId
AND  ab.BudgetCategoryId = bl.BudgetCategoryId
AND  ab.StatusId = 1
WHEN MATCHED THEN
  UPDATE
  SET ab.Value = ab.Value + bl.Value

WHEN NOT MATCHED BY TARGET THEN
  INSERT ([Year]
           ,[BudgetBreakdownId]
           ,[FromDate]
           ,[ToDate]
           ,[BudgetTypeId]
           ,[DepartmentSectionId]
           ,[BudgetCategoryId]
           ,[Value]
           ,[AdjustmentValue]
           ,[StatusId]
           ,[CreatedUserId]
           ,[CreatedDate]
           ,[ModifiedUserId]
           ,[ModifiedDate]
           ,[Remark])
     VALUES
           (bl.Year
           ,bl.BudgetBreakdownId
           ,bl.FromDate
           ,bl.ToDate
           ,bl.BudgetTypeId
           ,bl.DepartmentSectionId
           ,bl.BudgetCategoryId
           ,bl.Value
           ,bl.AdjustmentValue
           ,bl.StatusId
           ,bl.CreatedUserId
           ,GETDATE()
           ,bl.ModifiedUserId
           ,GETDATE()
           ,NULL);

COMMIT TRANSACTION [Tran1]
END TRY
BEGIN CATCH
  ROLLBACK TRANSACTION [Tran1]
   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.  
               );  
END CATCH  

还有我用来执行我的 sp 的测试脚本 (单行即可)

DECLARE @AnnualBudgetLines AS [dbo].[AnnualBudgetList]
--INSERT INTO @Plants VALUES(2,'')
INSERT INTO @AnnualBudgetLines VALUES(117,27,2,2017,'1/1/2017 12:00:00 AM','1/31/2017 12:00:00 AM',2,1000,0,1,3430,'3/10/2017 11:58:12 AM',3430,'3/10/2017 11:58:12 AM')
INSERT INTO @AnnualBudgetLines VALUES(117,27,3,2017,'1/1/2017 12:00:00 AM','1/31/2017 12:00:00 AM',2,1000,0,1,3430,'3/10/2017 11:58:12 AM',3430,'3/10/2017 11:58:12 AM')
--INSERT INTO @Plants VALUES(117,27,4,2017,'1/1/2017 12:00:00 AM','1/31/2017 12:00:00 AM',2,1000,0,1,3430,'3/10/2017 11:58:12 AM',3430,'3/10/2017 11:58:12 AM')
--INSERT INTO @Plants VALUES(117,27,5,2017,'1/1/2017 12:00:00 AM','1/31/2017 12:00:00 AM',2,1000,0,1,3430,'3/10/2017 11:58:12 AM',3430,'3/10/2017 11:58:12 AM')
--INSERT INTO @Plants VALUES(117,27,6,2017,'1/1/2017 12:00:00 AM','1/31/2017 12:00:00 AM',2,1000,0,1,3430,'3/10/2017 11:58:12 AM',3430,'3/10/2017 11:58:12 AM')
--INSERT INTO @Plants VALUES(117,27,16,2017,'1/1/2017 12:00:00 AM','1/31/2017 12:00:00 AM',2,555,0,1,3430,'3/10/2017 11:58:12 AM',3430,'3/10/2017 11:58:12 AM')
--INSERT INTO @Plants VALUES(117,27,17,2017,'1/1/2017 12:00:00 AM','1/31/2017 12:00:00 AM',2,666,0,1,3430,'3/10/2017 11:58:12 AM',3430,'3/10/2017 11:58:12 AM')
--INSERT INTO @AnnualBudgetLines VALUES(117,27,18,2017,'1/1/2017 12:00:00 AM','1/31/2017 12:00:00 AM',2,777,0,1,3430,'3/10/2017 11:58:12 AM',3430,'3/10/2017 11:58:12 AM')

EXEC [dbo].[AnnualBudgetExcelUpload_I_U]  @AnnualBudgetLines

【问题讨论】:

    标签: sql sql-server merge


    【解决方案1】:

    我发现了问题。它不是存储过程或合并语句。 我编写了以下触发器来保留表数据的历史记录,并且该触发器导致了问题。

    ALTER TRIGGER [dbo].[Trg_AnnualBudgetRivision]
       ON  [dbo].[AnnualBudget]
       AFTER UPDATE 
    AS 
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
    
         DECLARE @MaxId AS INT
            SELECT  @MaxId = MAX(dbo.AnnualBudgetVersion.VersionNo)
            FROM dbo.AnnualBudgetVersion  
            WHERE 
            dbo.AnnualBudgetVersion.AnnualBudgetId = (SELECT Id FROM DELETED)
    
            IF(@MAXId IS NULL )
            BEGIN
                SET @MAXId = 0;
            END
            ELSE
            BEGIN
              SET @MAXId = @MAXId +1;
            END
    
            INSERT INTO [dbo].[AnnualBudgetVersion]
            SELECT *,@MAXId
            FROM DELETED;
    
    
    END
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多