2017-03-10 102 views
1

我有一个存储过程,我使用合并语句。 而当我尝试执行此sp时,它会产生以下错误。SQL合并更新给子查询返回多个值错误

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. 

我认为问题在于合并的更新语句。因为如果我尝试这与一个记录或一个新的记录是不存在,它的工作原理..

这里是我的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 

回答

0

我发现了这个问题。而不是存储过程或合并声明。 我已经写了下面的触发器来保留表的数据的历史记录和该触发器引起的问题。

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