2015-08-13 3 views
-1

Я получаю это сообщение об ошибке и не знаю, как его отладить.SQL Server MERGE возвращает сообщение об ошибке 8672

Вот мой код:

DECLARE @CurMonth int 
DECLARE @CurYear int 
DECLARE @Date datetime 

SET @Date = DATEADD(m, -1, CAST(CAST(GETDATE() AS date) AS datetime)) 
SET @CurMonth = MONTH(@Date) 
SET @CurYear = YEAR(@Date) 

EXEC Tablename.dbo.ps_ProcedureTable1 @CurMonth, @CurYear 


SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[ps_ProcedureTable1] 
(
    @CurMonth int, 
    @CurYear int 
) 
AS 
MERGE 
    Tablename.dbo.table1 AS target 
USING 
    (SELECT 
     a.Ti, a.G, a.A, a.R, a.D, a.U, 
     a.FullName, a.W, 
     a.SDay, a.EDay, a.HDay, 
     a.C, a.QC, a.FC, a.CH, a.TH, a.FH, 
     a.LH, a.TtH, a.WKH, a.Va, a.Tr, 
     a.OT, a.Other, a.M, a.P, a.Ve, 
     a.SCa, a.HWK, a.AHr, a.SPF, a.AfTl, 
     a.TtHC, a.WKHRs, a.Days, a.ISWD, 
     a.HInD, a.OT, a.RT, a.HrSt, a.Sk 
    FROM Tablename.dbo.vw_Table1 a WITH (NOLOCK) 
    WHERE MONTH(a.W) = @CurMonth AND YEAR(a.W) = @CurYear) AS Source 
     ON Source.U = Target.U AND Source.W = Target.W 

WHEN MATCHED THEN 
    UPDATE SET 
     SDay = Source.SDay, 
     EDay = Source.EDay, 
     HDay = Source.HDay, 
     C = Source.C, 
     QC = Source.QC, 
     FC = Source.FC, 
     CH = Source.CH, 
     TH = Source.TH, 
     FH = Source.FH, 
     LH = Source.LH, 
     TtH = Source.TtH, 
     WKH = Source.WKH, 
     Va = Source.Va, 
     Tr = Source.Tr, 
     OT = Source.OT, 
     Other = Source.Other, 
     M = Source.M, 
     P = Source.P, 
     Ve = Source.Ve, 
     SCa = Source.SCa, 
     HWK = Source.HWK, 
     AHr = Source.AHr, 
     SPF = Source.SPF, 
     AfTl = Source.AfTl, 
     TtHC = Source.TtHC, 
     WKHRs = Source.WKHRs, 
     Days = Source.Days, 
     ISWD = Source.ISWD, 
     HInD = Source.HInD, 
     OT = Source.OT, 
     RT = Source.RT, 
     HrSt = Source.HrSt, 
     Sk = Source.Sk 

WHEN NOT MATCHED THEN 
    INSERT (Ti, G, A, R, D, U, 
      FullName, W, SDay, EDay, HDay, 
      C, QC, FC, CH, TH, FH, LH, 
      TtH, WKH, Va, Tr, OT, Other, 
      M, P, Ve, SCa, HWK, AHr, SPF, 
      AfTl, TtHC, WKHRs, Days, ISWD, HInD, 
      OT, RT, HrSt, Sk) 
    VALUES (Source.Ti, Source.G, Source.A, Source.R, Source.D, Source.U, 
      Source.FullName, Source.W, Source.SDay, Source.EDay, Source.HDay, 
      Source.C, Source.QC, Source.FC, Source.CH, Source.TH, Source.FH, Source.LH, 
      Source.TtH, Source.WKH, Source.Va, Source.Tr, Source.OT, Source.Other, 
      Source.M, Source.P, Source.Ve, Source.SCa, Source.HWK, Source.AHr, Source.SPF, 
      Source.AfTl, Source.TtHC, Source.WKHRs, Source.Days, Source.ISWD, Source.HInD, 
      Source.OT, Source.RT, Source.HrSt, Source.Sk); 
GO 

Я получаю сообщение об ошибке.

Msg 8672, уровень 16, состояние 1, процедура ps_EAGenerateWorkHours, Линия 12
Оператор MERGE попытался UPDATE или DELETE в той же строке несколько раз. Это происходит, когда целевая строка соответствует более чем одной строке источника. Оператор MERGE не может обновлять/удалять одну и ту же строку целевой таблицы несколько раз. Уточните предложение ON, чтобы гарантировать, что целевая строка соответствует не более одной исходной строке, или используйте предложение GROUP BY для группировки исходных строк.
Предупреждение: значение Null исключается агрегатом или другой операцией SET.

Я посмотрел и исследовал онлайн, но просто не могу понять, что не так с моими кодами.

+4

Я думаю, что сообщение об ошибке очень ясно: «Это происходит, когда целевая строка ma tches больше, чем одна строка источника ', поэтому ваш' Source.U = Target.U AND Source.W = Target.W' дает несколько результатов – Lamak

+0

И избавиться от этого намека NOLOCK, или эта ошибка будет отображаться случайным образом, потому что когда вы запрашиваете с подсказкой он может и будет возвращать отсутствующие и/или повторяющиеся строки. http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/ –

ответ

0

выполнения Объединить запрос возвращает ошибку «Повторяющиеся строки», если

SELECT U, W, count(*) 
FROM Tablename.dbo.vw_Table1 a WITH (NOLOCK) 
WHERE MONTH(a.W) = @CurMonth AND YEAR(a.W) = @CurYear 
group by U, W 
having count(*)>1 

или

SELECT U, W, count(*) 
FROM Tablename.dbo.table1 a WITH (NOLOCK) 
group by U, W 
having count(*)>1 

возвращают строки

один из этих возвращений запроса повторяющихся строк на основе «на пункте» запроса слияния

Смежные вопросы