Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 标识列中存在重复值_Database_Sql Server 2005_Tsql_Identity - Fatal编程技术网

Database 标识列中存在重复值

Database 标识列中存在重复值,database,sql-server-2005,tsql,identity,Database,Sql Server 2005,Tsql,Identity,我有一个表,它有一个名为id的列,类型为Identity。但此列包含重复的值1..8,然后是1..10 这到底是怎么可能的?标识列与主键不同。如果在将id列设置为identity之前在id列中插入一些值,则它可以生成与手动插入的值相同的值。identity只是一个默认的新值。唯一性由主键和唯一性约束强制执行 标识列中的重复项可解释为: 列定义在某个时间点不包含默认标识(如Giorgi所说) 在某个时间点启用了选项SET IDENTITY INSERT TableName ON 要解决这种情况

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


这到底是怎么可能的?

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

identity只是一个默认的新值。唯一性由
主键
唯一性
约束强制执行

标识列中的重复项可解释为:

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

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

我测试了Giogri的说法,如果在表有行之后启用标识规范(至少在2008年,可能还有其他版本),DB将以最高整数值开始编号。如果有一行的列值为100,则启用标识,下一次插入将是101。即使将标识种子指定为1。这不是我所期望的,但事实就是如此

除了
SET IDENTITY INSERT
,还有一个reseed命令
DBCC CHECKIDENT
命令,该命令会将您的标识值重置回您指定的值

考虑到启用标识规范实际上从列中的最高整数开始,可能有人使用了
SET Identity\u INSERT
或执行了
DBCC CHECKIDENT

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

ALTER TABLE tbl
DROP COLUMN ident_column
GO
alter TABLE tbl
ADD ident_column int IDENTITY
SET IDENTITY\u INSERT
docs:

DBCC CHECKIDENT
docs:

如果关系中不涉及身份,则可以删除并重新创建该身份。如果有关系,情况就更复杂

首先,您需要以虚拟方式重新创建复制的id号记录,并将其重新插入表中,并为其获取新标识。您需要识别重复的ID的子记录,然后确定哪些记录指向两个新ID中的哪一个。这是最难的部分,甚至可能不可能

完成后,将这些子记录更新为新ID。然后,当不再有子记录时,删除旧的父记录。如果您(我指的是公司,不一定是程序员,有时这是只有用户才能做的事情)无法识别子记录指向哪个父记录,那么请删除这些子记录,然后删除旧的父记录。如果您有子记录,您不想删除,因为您需要用于成本历史报告或类似事情的数据,那么请保留一个旧的父记录。在本例中,我可能会将其中一个父记录更改为“未知”作为用户名或表中标识该记录的任何其他值,然后删除另一个重复id


祝你好运,像这样的数据完整性问题很难解决。此外,我会在您的代码库中搜索短语“setindentity\u insert”,以确保没有目光短浅的程序员避免正确使用identity字段。您不希望此问题再次发生。如果您找到了这段代码,并且知道是谁对您这样做的(源代码管理是一件很棒的事情),我建议您最好指派他来解决任何数据完整性问题。经历一次修复数据完整性问题的痛苦,您将在未来成为一名更加谨慎的程序员。

使用identity\u INSERT在identity列“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

顺便问一下,表是分区的吗?Cocker实际上我的代码或我的团队的代码对这一混乱不负责任,但我们只是想知道为什么会发生这种情况,以避免将来发生这种情况。我想当时正在进行数据库服务器迁移,有人把事情搞砸了。