【问题标题】:Violation of PRIMARY Key (Duplicate key) on a table where the PK is Identity?在 PK 是身份的表上违反主键(重复键)?
【发布时间】:2016-12-16 23:11:26
【问题描述】:

所以我有这张桌子:

CREATE TABLE [Snapshots].[Crashproof](
    [EmoteCountId] [int] IDENTITY(1,1) NOT NULL,
    [SnapshotId] [int] NOT NULL,
    [Emote] [nvarchar](42) NOT NULL,
    [EmoteCountTypeId] [int] NOT NULL,
    [Count] [decimal](19, 6) NOT NULL,
    CONSTRAINT [PK_SnapshotsCrashproof] PRIMARY KEY CLUSTERED ([EmoteCountId] ASC) ON [PRIMARY],
    CONSTRAINT [FK_SnapshotsCrashproof_Snapshots] FOREIGN KEY ([SnapshotId]) REFERENCES [Snapshots].[Snapshots] ([SnapshotId]) ON DELETE CASCADE,
    CONSTRAINT [FK_SnapshotsCrashproof_EmoteCountTypes] FOREIGN KEY ([EmoteCountTypeId]) REFERENCES [dbo].[EmoteCountTypes] ([EmoteCountTypeId])
) ON [PRIMARY]
GO

以及插入其中的代码:

using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.Default, trans))
{
    bulkCopy.DestinationTableName = "Snapshots.Crashproof";
    bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("SnapshotId", "SnapshotId"));
    bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("EmoteCountTypeId", "EmoteCountTypeId"));
    bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("Emote", "Emote"));
    bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("Count", "Count"));

    using (IDataReader reader = ObjectReader.Create(emoteCountTypesToSnapshot))
    {
        bulkCopy.WriteToServer(reader);
    }
}

它在 99.99% 的时间内运行良好(并且每分钟完成一次批量复制),但是我确实有一次异常,它在最后一行 (bulkCopy.WriteToServer(reader);):

违反 PRIMARY KEY 约束...无法在对象“Snapshots.Crashproof”中插入重复键。重复键值为 (247125)。

我知道不建议直接在最终表中批量插入,我将修改我的代码以批量插入临时表,然后从那里插入。但这是导致此异常的原因吗?

我真的不明白身份字段上如何出现重复键:|

【问题讨论】:

  • 目标表中是否可能已经存在数据,其中手动添加了 EmoteCountId = 247125 的记录?也许是在 IDENTITY_INSERT 开启时手动插入?
  • 批量复制是否需要超过一分钟,所以它会在第一个完成之前开始另一个写入?
  • @DeanGoodman 不,我从不手动插入此表
  • 通常情况下,0.01% 的情况除外??
  • @MethodMan 我没有为这个操作的连接声明一个事务,所以它是隐式的(这就是你的意思?)。我会尝试使用var trans = connection.BeginTransaction()trans.Commit() 进行明确的提交,也许会有所帮助

标签: c# sql .net sql-server sql-server-2012


【解决方案1】:

我的建议是使用 ETL 产品来完成这些任务。他们为您组织一切,只是做如此干净的工作。搞乱批量复制和存储过程并制作临时表(我做了多年)现在对我来说太难看了。

过去几年我一直在使用 Pentaho Kettle,并且完全爱上了它。这项任务只需要我几分钟甚至不到一分钟的时间来实施,并完成所有繁重的工作,将数据从一个地方转移到另一个地方。

我知道这不是对您问题的直接回答,但如果有人来找我解决这个问题,我会立即建议这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多