SQL MERGE错误?

时间:2018-03-08 12:20:43

标签: sql sql-server-2012

请参阅下面的代码 - 我是SQL新手,之前没有看到过这个错误。有人可以建议它出错的地方吗?我得到的错误是

  

(41669行受影响)Msg 8672,Level 16,State 1,Line 41 MERGE   语句尝试多次更新或删除同一行。   当目标行与多个源行匹配时会发生这种情况。一个   MERGE语句不能UPDATE / DELETE目标表的同一行   多次。优化ON子句以确保目标行匹配   大多数一个源行,或使用GROUP BY子句对源进行分组   行。

我的代码在

下面
DECLARE @FromDate DateTime = '31 jan 2018'
DECLARE @ToDate DateTime = '28 Feb 2018'


DECLARE @FromDate_In DateTime = @FromDate
DECLARE @ToDate_In DateTime = @ToDate
DECLARE @DirectDebit_In INT = 0

/**************************/
/*     Agreement view     */
/**************************/

SELECT
    sag.[AgreementID]
    ,sca.CustomerID
    ,'Lost' AS [Type]
INTO #AgreementSet
FROM Money.dbo.[Fin_SS_TblAgreements] sag WITH (NOLOCK)
INNER JOIN Money.dbo.[Fin_SS_TblCustomersAgreements] [sca] WITH (NOLOCK) ON sca.DealID = sag.DealID AND sca.IsMasterCustomer = 1 AND sca.[SnapShot] = sag.[SnapShot]
INNER JOIN ( 
            SELECT 
                sps.DealID
            FROM Money.dbo.[Fin_SS_TblPaymentSchedule] sps WITH (NOLOCK, INDEX(IX_NC_Snapshot))
            WHERE sps.[SnapShot] = @FromDate_In
            GROUP BY sps.DealID
            ) sps ON sag.DealID = sps.DealID

WHERE sag.[SnapShot] = @FromDate_In
AND (sag.AgreementID IS NOT NULL)
AND ((sag.EndDate > sag.[SnapShot]) OR (sag.EndDate = sag.[SnapShot] AND sag.Autorenew = 1))
AND (sag.AgreementStartsOn <= sag.[SnapShot]) 
AND ( (@DirectDebit_In = 0 AND sag.ContractTypeID <> 3) OR (@DirectDebit_In = 1 AND sag.ContractTypeID = 3) OR (@DirectDebit_In = 3) )

DECLARE @MaxAgIDFrom INT 
SELECT @MaxAgIDFrom = MAX(AgreementID) FROM Money.dbo.[Fin_SS_TblAgreements] WHERE [SnapShot] = @FromDate_In

DECLARE @MaxCIDFrom INT 
SELECT @MaxCIDFrom = MAX(CustomerID) FROM #AgreementSet

MERGE INTO #AgreementSet L
   USING    (
            SELECT
                sag.[AgreementID]
                ,sca.CustomerID
                ,'New' AS [Type]
            FROM Money.dbo.[Fin_SS_TblAgreements] sag WITH (NOLOCK)
            INNER JOIN Money.dbo.[Fin_SS_TblCustomersAgreements] [sca] WITH (NOLOCK) ON sca.DealID = sag.DealID AND sca.IsMasterCustomer = 1 AND sca.[SnapShot] = sag.[SnapShot]
            INNER JOIN ( 
                        SELECT 
                            sps.DealID
                        FROM Money.dbo.[Fin_SS_TblPaymentSchedule] sps WITH (NOLOCK, INDEX(IX_NC_Snapshot))
                        WHERE sps.[SnapShot] = @ToDate_In
                        GROUP BY sps.DealID
                        ) sps ON sag.DealID = sps.DealID

            WHERE sag.[SnapShot] = @ToDate_In
            AND (sag.AgreementID IS NOT NULL)
            AND ((sag.EndDate > sag.[SnapShot]) OR (sag.EndDate = sag.[SnapShot] AND sag.Autorenew = 1))
            AND (sag.AgreementStartsOn <= sag.[SnapShot]) 
            AND ( (@DirectDebit_In = 0 AND sag.ContractTypeID <> 3) OR (@DirectDebit_In = 1 AND sag.ContractTypeID = 3) OR (@DirectDebit_In = 3) )
            )  N
      ON L.AgreementID = N.AgreementID
WHEN MATCHED THEN
    UPDATE SET [Type] =      
        CASE    WHEN L.CustomerID = n.CustomerID THEN 'B/F'
                ELSE 'Swap'
        END
WHEN NOT MATCHED THEN
  INSERT (AgreementID, CustomerID, [Type])
  VALUES (n.AgreementID, n.CustomerID, n.[Type])

1 个答案:

答案 0 :(得分:2)

我们经常这样做。

这是因为在多行中使用的唯一列。

在您的情况下,这可能是因为两个或更多不同客户的同意情况。

再次检查数据并再次执行相同的操作。