标识列中的重复值

时间:2010-07-02 10:42:32

标签: database sql-server-2005 tsql identity

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

这个世界怎么可能?

5 个答案:

答案 0 :(得分:3)

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

除了SET IDENTITY INSERT之外,还有一个重新设定的命令。 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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

标识列中的重复项可以通过以下方式解释:

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

要解决此问题,请删除并重新创建标识列。

答案 3 :(得分:1)

使用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

答案 4 :(得分:0)

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

首先,您需要无需重新创建重复的ID号记录,然后将它们重新插入表中并为它们获取新的标识。您需要识别重复的ID的子记录,然后确定哪些记录会转到两个新ID中的哪一个。这是最难的部分,甚至可能不可能。

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

祝你好运,像这样的数据完整性问题很难解决。此外,我将在您的代码库中搜索短语“set indentity_insert”,以确保没有短视的程序员正在避免正确使用身份字段。您不希望重新发生此问题。如果您找到此代码并知道是谁为您执行此操作(源代码控制是一件很棒的事情),我建议这是分配以解决任何数据完整性问题的最佳人选。经历一次修复数据完整性问题的痛苦,将来你将成为一个更加谨慎的程序员。