【问题标题】:Duplicate Values in Identity Column身份列中的重复值
【发布时间】:2010-07-02 10:42:32
【问题描述】:

我有一个表,其中有一个名为id 的列,其类型为Identity。但此列包含重复值 1..8 和 1..10

这怎么可能?

【问题讨论】:

  • 万一,表分区了吗?

标签: database sql-server-2005 tsql identity


【解决方案1】:

我测试了 Giogri 所说的内容,如果您在表有行之后启用身份规范(至少在 2008 年,可能还有其他版本),数据库将从最高整数值开始编号。如果您有一行以 100 作为列值,则启用 Identity,下一个插入将是 101。即使 Identity Seed 指定为 1。这不是我所期望的,但它发生了。

除了SET IDENTITY INSERT,还有一个reseed 命令。 DBCC CHECKIDENT 命令将您的身份值重置回您指定的值。

鉴于启用身份规范实际上从列中的最高整数开始,有人可能使用了SET IDENTITY_INSERT 或使用了DBCC CHECKIDENT

正如 Andomar 所说,重新排序的最快方法是像这样删除/重新创建列

ALTER TABLE tbl
DROP COLUMN ident_column
GO
alter TABLE tbl
ADD ident_column int IDENTITY

SET IDENTITY_INSERT 文档:http://msdn.microsoft.com/en-us/library/aa259221(SQL.80).aspx
DBCC CHECKIDENT 文档:http://msdn.microsoft.com/en-us/library/aa258817(SQL.80).aspx

【讨论】:

  • Cocker 实际上我的代码或我的团队的代码不对这个混乱负责,但我们只是想知道为什么会发生这种情况,以避免将来发生这种情况。我认为那些日子正在进行一些数据库服务器迁移,然后有人把事情搞砸了。
【解决方案2】:

标识列与主键不同。如果您在 id 列中插入一些值,然后再将其设置为标识,则它可以生成与您手动插入的值相同的值。

【讨论】:

    【解决方案3】:

    身份只是一个默认的新值。唯一性由primary keyunique 约束强制执行。

    身份列中的重复可以通过以下方式解释:

    • 列定义在某个时间点不包含标识默认值(如 Giorgi 所说)
    • SET IDENTITY INSERT TableName ON 选项在某个时间点启用

    要解决这种情况,请删除并重新创建标识列。

    【讨论】:

      【解决方案4】:

      使用 IDENTITY_INSERT 在标识列“RecNo”中重复值的示例:

      create table names(RecNo INT IDENTITY (1,1), name VARCHAR(50))
      insert into names(name) VALUES ('maria')
      insert into names(name) VALUES ('maria2')
      
      set IDENTITY_INSERT names ON
      insert into names(RecNo, name) VALUES (1, 'maria3')
      set IDENTITY_INSERT names OFF
      
      select * from names
      
      RecNo   name
      1           maria
      2           maria2
      1           maria3
      

      如果设置了 identity_insert,建议不要更改它(以允许显式值)。通过再次设置种子,标识列“RecNo”中的重复值示例:

      create table names(RecNo INT IDENTITY (1,1), name VARCHAR(50))
      insert into names(name) VALUES ('maria')
      insert into names(name) VALUES ('maria2')
      
      DBCC CHECKIDENT(names, RESEED, 1)
      insert into names(name) VALUES ('maria3')
      set IDENTITY_INSERT names OFF
      
      select * from names;
      
      RecNo   name
      1          maria
      2          maria2
      2          maria3
      

      【讨论】:

        【解决方案5】:

        如果身份不涉及关系,是的,您可以删除并重新创建它。如果有关系,情况会更复杂。

        首先,您需要单独重新创建重复的 ID 号记录,并将它们重新插入表中并为它们获取新的身份。您需要识别重复的 id 的子记录,然后找出哪些到两个新 id 中的哪一个。这是最难的部分,甚至可能是不可能的。

        完成此操作后,您将这些子记录更新为新 ID。然后当不再有子记录时删除旧的父记录。如果您(以及您,我的意思是公司不一定是程序员,有时这是只有用户才能做的事情)无法确定子记录进入哪个父记录,然后删除这些子记录,然后删除旧父记录记录。如果您有不想删除的子记录,因为您需要用于成本历史报告或类似事情的数据,请保留其中一个旧的父记录。在这种情况下,我可能会将其中一个父记录更改为 Unknown 作为用户名或表中也标识该记录的任何其他值,然后删除另一个重复的 id。

        祝你好运,这样的数据完整性问题很难解决。此外,我会在您的代码库中搜索短语“set indentity_insert”,以确保没有短视的程序员避免正确使用标识字段。您不希望此问题再次发生。如果你找到了这段代码并且知道是谁对你做了这件事(源代码管理是一件很棒的事情),我建议这是解决任何数据完整性问题的最佳人选。经历一次修复数据完整性问题的痛苦,你将来会成为一个更加细心的程序员。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-05-29
          • 1970-01-01
          • 1970-01-01
          • 2018-09-15
          • 2012-02-24
          • 2012-01-19
          • 2012-12-07
          • 2019-06-25
          相关资源
          最近更新 更多