我有一个批处理作业,它使用MERGE语句在两个相同的数据库之间同步数据。有时,我收到以下错误:无法在对象'dbo.MatchPlayerStatistics'中插入具有唯一索引'IX_MatchPlayerStatistics_Player'的重复键行。这没有意义,因为IX_MatchPlayerStatistics_Player不是唯一索引,我能够手动插入完全相同的数据。如果我删除索引,插入数据,然后重新创建索引,它就可以正常工作。
为什么会出现此错误?如何防止错误?
该表的创建脚本如下:
CREATE TABLE [dbo].[MatchPlayerStatistics](
[ExternalID] [nvarchar](50) NULL,
[ProviderID] [int] NOT NULL,
[MatchID] [int] NOT NULL,
[PlayerPersonID] [int] NOT NULL,
[TeamID] [int] NOT NULL,
[YellowCards] [smallint] NULL,
[DoubleYellowCards] [smallint] NULL,
[RedCards] [smallint] NULL,
[Fouls] [smallint] NULL,
[Goals] [smallint] NULL,
[PenaltyGoals] [smallint] NULL,
[PenaltiesMissed] [smallint] NULL,
[PenaltiesSaved] [smallint] NULL,
[Shots] [smallint] NULL,
[Attacks] [smallint] NULL,
[Corners] [smallint] NULL,
[Offsides] [smallint] NULL,
[Assists] [smallint] NULL,
[OwnGoals] [smallint] NULL,
[GoalsConcedeed] [smallint] NULL,
[CreatedBy] [int] NOT NULL,
[CreatedOn] [datetime] NOT NULL,
[ModifiedBy] [int] NOT NULL,
[ModifiedOn] [datetime] NOT NULL,
CONSTRAINT [PK_MatchPlayerStatistics] PRIMARY KEY CLUSTERED
(
[ProviderID] ASC,
[MatchID] ASC,
[PlayerPersonID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_MatchPlayerStatistics_Player] ON [dbo].[MatchPlayerStatistics]
(
[ProviderID] ASC,
[PlayerPersonID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
MERGE声明如下:
MERGE MatchPlayerStatistics AS M
USING (
SELECT [ExternalID]
,[ProviderID]
,[MatchID]
,[PlayerPersonID]
,[TeamID]
,[YellowCards]
,[DoubleYellowCards]
,[RedCards]
,[Fouls]
,[Goals]
,[PenaltyGoals]
,[PenaltiesMissed]
,[PenaltiesSaved]
,[Shots]
,[Attacks]
,[Corners]
,[Offsides]
,[Assists]
,[OwnGoals]
,[GoalsConcedeed]
,[CreatedBy]
,[CreatedOn]
,[ModifiedBy]
,[ModifiedOn]
FROM [Replication].MatchPlayerStatistics
WHERE ProviderID = 1
) AS R
ON (M.MatchID = R.MatchID AND M.PlayerPersonID = R.PlayerPersonID AND M.ProviderID = R.ProviderID )
WHEN NOT MATCHED
THEN
INSERT ([ExternalID]
,[ProviderID]
,[MatchID]
,[PlayerPersonID]
,[TeamID]
,[YellowCards]
,[DoubleYellowCards]
,[RedCards]
,[Fouls]
,[Goals]
,[PenaltyGoals]
,[PenaltiesMissed]
,[PenaltiesSaved]
,[Shots]
,[Attacks]
,[Corners]
,[Offsides]
,[Assists]
,[OwnGoals]
,[GoalsConcedeed]
,[CreatedBy]
,[CreatedOn]
,[ModifiedBy]
,[ModifiedOn])
VALUES
( R.[ExternalID]
,R.[ProviderID]
,R.[MatchID]
,R.[PlayerPersonID]
,R.[TeamID]
,R.[YellowCards]
,R.[DoubleYellowCards]
,R.[RedCards]
,R.[Fouls]
,R.[Goals]
,R.[PenaltyGoals]
,R.[PenaltiesMissed]
,R.[PenaltiesSaved]
,R.[Shots]
,R.[Attacks]
,R.[Corners]
,R.[Offsides]
,R.[Assists]
,R.[OwnGoals]
,R.[GoalsConcedeed]
,R.[CreatedBy]
,R.[CreatedOn]
,R.[ModifiedBy]
,R.[ModifiedOn])
WHEN MATCHED
THEN
UPDATE
SET [ExternalID] = R.[ExternalID]
,[ProviderID] = R.[ProviderID]
,[MatchID] = R.[MatchID]
,[PlayerPersonID] = R.[PlayerPersonID]
,[TeamID] = R.[TeamID]
,[YellowCards] = R.[YellowCards]
,[DoubleYellowCards] = R.[DoubleYellowCards]
,[RedCards] = R.[RedCards]
,[Fouls] = R.[Fouls]
,[Goals] = R.[Goals]
,[PenaltyGoals] = R.[PenaltyGoals]
,[PenaltiesMissed] = R.[PenaltiesMissed]
,[PenaltiesSaved] = R.[PenaltiesSaved]
,[Shots] = R.[Shots]
,[Attacks] = R.[Attacks]
,[Corners] = R.[Corners]
,[Offsides] = R.[Offsides]
,[Assists] = R.[Assists]
,[OwnGoals] = R.[OwnGoals]
,[GoalsConcedeed] = R.[GoalsConcedeed]
,[CreatedBy] = R.[CreatedBy]
,[CreatedOn] = R.[CreatedOn]
,[ModifiedBy] = R.[ModifiedBy]
,[ModifiedOn] = R.[ModifiedOn]
WHEN NOT MATCHED BY SOURCE AND M.ProviderID = 1
THEN DELETE;
[Replication] .MatchPlayerStatistics表是一个中间表,其中填充了数据库另一个副本上[dbo] .MatchPlayerStatistics表中的数据。所有这些表的模式都是相同的。
答案 0 :(得分:2)
我的一个想法是检查并查看表上是否有触发器,以及其中一个是否插入另一个具有唯一索引的表。
查看您的代码,这是一个完全疯狂的猜测。您正在使用IGNORE_DUP_KEY = OFF,它通常仅用于唯一约束,因此我想知道即使没有unique关键字,它是否也将其视为唯一约束。尝试创建没有该短语的索引,看看会发生什么。