在非唯一索引中插入数据时出错

时间:2010-08-15 18:33:17

标签: sql-server sql-server-2008 merge indexing

我有一个批处理作业,它使用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表中的数据。所有这些表的模式都是相同的。

1 个答案:

答案 0 :(得分:2)

我的一个想法是检查并查看表上是否有触发器,以及其中一个是否插入另一个具有唯一索引的表。

查看您的代码,这是一个完全疯狂的猜测。您正在使用IGNORE_DUP_KEY = OFF,它通常仅用于唯一约束,因此我想知道即使没有unique关键字,它是否也将其视为唯一约束。尝试创建没有该短语的索引,看看会发生什么。