标识列中存在重复值

发布于 2024-09-08 10:19:34 字数 111 浏览 6 评论 0原文

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

这怎么可能?

I've got a table which has a column named id which is of type Identity. But this column contains duplicate values 1..8 and then again 1..10

How in the world is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

德意的啸 2024-09-15 10:19:34

我测试了 Giogri 所说的内容,如果在表有行后启用身份规范(至少在 2008 年,也可能是其他版本),数据库将从最高整数值开始编号。如果您有一行的列值为 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

I tested what Giogri says and if you enable the Identity Specification (at least on 2008, probably other versions, too) after the table has rows, the DB will start the numbering at the highest integer value. If you have one row with 100 as the column value, then enable Identity, the next insert will be 101. Even with Identity Seed specified as 1. Wasn't what I would have expected, but its what happened.

In addition to SET IDENTITY INSERT, there's also a reseed command. DBCC CHECKIDENT command which will reset your identity values back to what you specify.

Given that enabling the Identity Specification actually starts at the highest integer in the column, someone probably either used SET IDENTITY_INSERT or did a DBCC CHECKIDENT.

The quickest way to resequence as Andomar says is to drop/recreate the column like this

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

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

柠檬 2024-09-15 10:19:34

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

Identity column is not the same as primary key. If you insert some values in id column before setting it to identity then it can generate the same values as you have inserted manually.

日裸衫吸 2024-09-15 10:19:34

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

Example of duplicate value in identity column 'RecNo' using IDENTITY_INSERT:

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

When identity_insert is set, it is advisable not to change it (to allow explicit values). Example of duplicate value in identity column 'RecNo' by setting seed again:

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
近箐 2024-09-15 10:19:34

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

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

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

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

Identity is merely a default new value. Uniqueness is enforced by primary key and unique constraints.

Duplicates in an identity column can be explained by:

  • The column definition did not contain the identity default at some point in time (like Giorgi says)
  • The option SET IDENTITY INSERT TableName ON was enabled at some point in time

To fix this situation, drop and recreate the identity column.

别挽留 2024-09-15 10:19:34

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

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

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

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

If the identity is not involved in relationships, yes you can drop and recreate it. If there are relationships the situation is more complex.

First, you need to recreate the dupped id number records invididually and reinsert them into the table and get a new identity for them. You need to identify the child records for the ids which are repeated and then figure out which ones go to which of the two new ids. This is the hardest part and may not even be possible.

Once this is done you update those child records to the new ids. then you drop the old parent records when no child records are there anymore. If you (and by you, I mean the company not necessarily the programmer, sometimes this is something only the users can do) can't identify which parent record a child record goes to, then drop those child records and then drop the old parent records. If you have child records you don't want to drop becasue you need the data for historical reporting of costs or some such thing, then retain one of the old parent records. In this case, I would probably change one of the parent records to say Unknown as the user name or whatever other value you have in the table that also identifies the record and then delete the other duplicated id.

Good luck, data integrity issues like this are hard to fix. Also I would search through your code base for the phrase "set indentity_insert" to make sure no short-sighted programmer is avoiding using the identity field properly. You do not want this problem to re-occur. If you find this code and know who did this to you (source control is a wonderful thing), I would suggest this is the best person to assign to fix any data integrity issues. Go through the pain of fixing a data integrity problem once and you will be a much more careful programmer in the future.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文