【发布时间】:2010-07-02 10:42:32
【问题描述】:
我有一个表,其中有一个名为id 的列,其类型为Identity。但此列包含重复值 1..8 和 1..10
这怎么可能?
【问题讨论】:
-
万一,表分区了吗?
标签: database sql-server-2005 tsql identity
我有一个表,其中有一个名为id 的列,其类型为Identity。但此列包含重复值 1..8 和 1..10
这怎么可能?
【问题讨论】:
标签: database sql-server-2005 tsql identity
我测试了 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).aspxDBCC CHECKIDENT 文档:http://msdn.microsoft.com/en-us/library/aa258817(SQL.80).aspx
【讨论】:
标识列与主键不同。如果您在 id 列中插入一些值,然后再将其设置为标识,则它可以生成与您手动插入的值相同的值。
【讨论】:
身份只是一个默认的新值。唯一性由primary key 和unique 约束强制执行。
身份列中的重复可以通过以下方式解释:
SET IDENTITY INSERT TableName ON 选项在某个时间点启用要解决这种情况,请删除并重新创建标识列。
【讨论】:
使用 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
【讨论】:
如果身份不涉及关系,是的,您可以删除并重新创建它。如果有关系,情况会更复杂。
首先,您需要单独重新创建重复的 ID 号记录,并将它们重新插入表中并为它们获取新的身份。您需要识别重复的 id 的子记录,然后找出哪些到两个新 id 中的哪一个。这是最难的部分,甚至可能是不可能的。
完成此操作后,您将这些子记录更新为新 ID。然后当不再有子记录时删除旧的父记录。如果您(以及您,我的意思是公司不一定是程序员,有时这是只有用户才能做的事情)无法确定子记录进入哪个父记录,然后删除这些子记录,然后删除旧父记录记录。如果您有不想删除的子记录,因为您需要用于成本历史报告或类似事情的数据,请保留其中一个旧的父记录。在这种情况下,我可能会将其中一个父记录更改为 Unknown 作为用户名或表中也标识该记录的任何其他值,然后删除另一个重复的 id。
祝你好运,这样的数据完整性问题很难解决。此外,我会在您的代码库中搜索短语“set indentity_insert”,以确保没有短视的程序员避免正确使用标识字段。您不希望此问题再次发生。如果你找到了这段代码并且知道是谁对你做了这件事(源代码管理是一件很棒的事情),我建议这是解决任何数据完整性问题的最佳人选。经历一次修复数据完整性问题的痛苦,你将来会成为一个更加细心的程序员。
【讨论】: