重置 SQL Server 中的标识列

发布于 2024-07-16 01:52:56 字数 201 浏览 4 评论 0原文

我正在制作一个存储联系人的 SQL 数据库。 我希望能够删除联系人,每个联系人的正确 ID 对于我的软件连接到它至关重要。 假设我已经联系了詹姆斯,他是第一个联系的。 他的id是0。我添加Mary,她的id是1。如果我删除James,如何将Mary的id设置为0而不是保持1? 由于她现在是第一个,所以必须重置。 换句话说,当某人被删除时,如何重置数据库中的所有 ID? 谢谢

I am making an SQL database that stores contacts. I want to be able to delete contacts, and the correct id for each contact is crucial for my software connecting to it. Lets say I have contact James and he is the first one. His id is 0. I add Mary and her id is 1. If I delete James, how can Mary's id be set to 0 instead of staying 1? It has to reset since she is the first one now. In other words, how can I reset all of the IDs in the database when someone gets deleted? Thanks

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

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

发布评论

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

评论(10

浅浅 2024-07-23 01:52:56

从很多方面来说,这都是一个糟糕的主意。 我正在考虑是否应该向您展示如何做到这一点。 一旦设置了行的标识,就不应该有理由更改它。

如果存在,您可能使用了错误的字段作为 PK 标识符。 我在这里假设你正在谈论你的 PK 字段,它也是一个身份列。

请记住,如果您创建任何链接到您的联系人表的表并且开始更改您的 ID,您也需要更新所有这些表。 哪个会变得很贵...

This is such a bad idea in so many ways. I am debating if I should show you how to do this. There should never be a reason to change a row's identity once it's set.

If there is you are probably using the wrong field as your PK identifier. I am making an assumption here that you're talking about your PK field which is also an identity column.

Keep in mind if you create any tables which link to your contact table and you start changing your Id you need to update all those tables as well. Which will get expensive...

离不开的别离 2024-07-23 01:52:56

一旦数据库中的记录数量过多,速度就会变得非常慢。 标识列对您不起作用,您需要执行一些自定义 T-SQL 来不断更改所有数字 - 但在我看来,这是一个非常糟糕的主意。

如果您需要跟踪它们的添加顺序,为什么不使用日期/时间戳呢?

您需要重新考虑您的设计。

That's going to get real slow once you have more than a trivial amount of records in the database. The identity column will not work for you, you need to do some custom T-SQL to keep changing all the numbers - but a very bad idea, IMO.

Why not use a date/time stamp if you need to keep track of the order they were added?

You need to re-think your design.

心安伴我暖 2024-07-23 01:52:56

ID 不是这样工作的,也不应该是这样工作的。 ID 永远不应该改变,否则所有链接的信息都会指向错误的行。

相反,为什么不添加您控制的“External_ID”列呢? 或者在查询中动态地对它们进行编号(使用计算列?)

That's not how IDs work, and not how they should work. The ID should never change, or all the linked information would point to the wrong row.

Instead, why not add a "External_ID" column that you control? Or number them dynamically in your query (with a computed column?)

甜中书 2024-07-23 01:52:56

在自动递增主键列上执行此操作是没有意义的,即使这样做很简单,如果没有相关表中的大量更新,您也会影响数据完整性。 为此,您可能需要从列中删除索引和主键约束(此时您的应用程序可能会崩溃),对所有后续记录重新编号,对所有相关表重新编号,然后重新应用主键约束和索引。

如果您确实必须拥有某种形式的线性标识符,该标识符始终从 0 开始(这可能表明软件设计存在问题),那么除了主键之外,您还可以拥有辅助 ID 列,然后将其更新以随机排列更高的值向下一级声明如下:

UPDATE table
SET secondaryID = secondaryID - 1
WHERE secondaryID > (SELECT secondaryID FROM table WHERE primaryID = [id to delete]);

DELETE FROM table
WHERE primaryID = [id to delete];

我强烈反对这种做法 - 如果您的 ID 由于删除记录而“丢失”值,则软件应该测试这些值是否存在,而不是仅仅删除。

It makes no sense to do this on an auto-incrementing primary key column, as even if it was trivial to do, without mass updates in related tables you affect your data integrity. To do so you would likely need to drop the index and primary key constraint from the column (at which point your application may flake out), renumber all later records, renumber all related tables, then re-apply the primary key constraint and index.

If you really must have some form of linear identifier which always starts at 0 (this may then indicate a problem with the software design) then you can have a secondary ID column in addition to the primary key, which you then update to shuffle higher values down a rung with a statement such as:

UPDATE table
SET secondaryID = secondaryID - 1
WHERE secondaryID > (SELECT secondaryID FROM table WHERE primaryID = [id to delete]);

DELETE FROM table
WHERE primaryID = [id to delete];

I strongly discourage such a practice - if your IDs are 'missing' values because of deleted records, the software should test for existence of these values rather than just wigging out.

小…楫夜泊 2024-07-23 01:52:56

ID 是行的唯一标识符

它可用于将一行链接到另一个表中的另一行。 ID 的缺失本身也包含信息,因为它清楚地表明它已被删除。 开始回收 ID 号码完全违背了拥有唯一标识符的目的,并且实际上没有任何意义。 一旦将ID分配给一行,就不能随意更改它。

想象一下,当有人去世时,他们会将他的社会保险号码 (ID) 交给其他人。 这将导致将与死者社会保险号码相关的所有旧信息转移给新人,这是没有任何意义的。 ID 也会发生同样的情况,如果重新分配 ID,它将继承之前链接到它的任何旧数据。

The ID is the unique identifier of the row.

It can be used to link a row to another row in another table. The absence of ID holds information in itself as well, as it would clearly say that it was deleted. Starting to recycle ID numbers defeats completely the purpose of having a unique identifier, and doesn't make any sense really. Once an ID is assigned to a row, you must not arbitrarily change it.

Imagine for a second that when someone dies, they hand over his social insurance number (ID) to someone else. That will result in transferring all the old information that was linked to the dead person's social insurance number to that new person, which doesn't make any sense. Same happens with IDs, if an ID is reassigned, it'll be inheriting any old data that was previously linked to it.

眼眸 2024-07-23 01:52:56

使用另一种方法可以比每次删除行时对标识列重新编号更好地解决这个问题。

如果不知道应用程序为何有此需求,很难确切地说您还会做什么,但您的应用程序需要此功能这一事实可能表明某个地方存在设计问题。

This would be much better solved using another method than renumbering the identity column each time a row is deleted.

Hard to say exactly what else you would do without knowing why your application has this need, but the fact that your application needs this functionality is probably indicative of a design problem somewhere.

分分钟 2024-07-23 01:52:56

您使用 id 不仅仅是一个标识符。 如果是这种情况,您将无法使用自动增量字段。 您需要在代码中处理这个问题。

You're using id's as more than just an identifier. If that's the case, you won't be able to use an auto increment field. You'll need to handle this in your code.

叫嚣ゝ 2024-07-23 01:52:56

1 分钟的谷歌搜索给了我一个无法显示的页面。 谷歌一下,它将成为您截至 2​​009 年 6 月 1 日的第一个链接: tsql fix "identity column"

本质上,我建议在执行任何操作之前在所有关系字段之间添加一个外键约束到相关 ID 字段重新编号(如果存在任何关系,这也是一个可怕的想法,严格来说,因为如果你问这个问题,你会很开心)。

如果您的联系人表是您的唯一表或基于此 ID 字段具有零关系,您可以将 Identity 属性设置为 NO,将值从 1 重新编号为 COUNT(ID),然后将 Identity 属性设置为 YES,并重新设定身份种子要完成使用:

DECLARE @MaxID INT

SELECT @MaxID = COUNT(ID) FROM TableID

DBCC CHECKIDENT('TableID', RESEED, @MaxID)

在这种情况下,您可以在每组删除之后使用上述重新设定种子脚本(但更改 COUNT (ID) 到 MAX(ID) 一旦所有内容最初并正确设置,这会在任何其他插入或外键约束更新之前增加一点速度(随着表变大)。 确保使用包含删除和重新播种块的 TRANSACTIONS,并确保表只允许同步事务,这将防止在重新播种过程中存储任何数据。

复杂吧? 这就是为什么最好从正确的开始。 ;)(我从经验中学到了这一点)如果您有任何其他问题,请给我发送电子邮件至 mraarone et yahoo d0t com。

A 1 minute google search gave me a page that I can't display. Google this and it'll be your first link as of 6/1/2009: tsql fix "identity column"

Essentially, I would suggest adding a foreign key constraint between all of your relational fields to the ID field in question prior to doing any renumbering (which is also a horrible idea if there are any relationships whatsoever, strictly because if you are asking this question, you will have a heck of a time).

If your contacts table is your ONLY table or has ZERO relationships based on this ID field, you could set the Identity property to NO, renumber the values from 1 to COUNT(ID), then set the Identity property to YES, and reseed the identity for completion using:

DECLARE @MaxID INT

SELECT @MaxID = COUNT(ID) FROM TableID

DBCC CHECKIDENT('TableID', RESEED, @MaxID)

In this scenario, you could use the above reseed script after each set of deletions (but change COUNT(ID) to MAX(ID) once everything is initially and correctly set up, this adds a little speed as the table gets larger), prior to any additional inserts or foreign key constraint updates. Ensure you use TRANSACTIONS wrapped around the deletes and reseeding blocks, and ensure the table only allows synchronous transactions, this will prevent any data hosing in the middle of the reseeds.

Complex eh? That's why it's best to start out on the right foot. ;) (I learned this from experience) E-mail me at mraarone et yahoo d0t com if you have any more questions.

动次打次papapa 2024-07-23 01:52:56

我编写了一个应用程序来处理多级销售计划。
当然,人们会退出。 在我们的系统中,也必须插入人员。

只需进行一项修改,您就走上了正确的道路。

身份号(ID)和序列号(seq)是两个不同的东西。
他们彼此之间根本没有任何关系。

切勿更改 ID。 一旦分配,始终分配。

在表中为序列创建一个列 (cNEXT) 并用 ID 填充它。
“这个序列中的下一个 ID 是什么?”

随意调整 cNEXT 中的 ID,随时重新分配 cNEXT。
任何存储过程都可以做到这一点。

然后,您还可以灵活地创建非连续的 ID 链。
当人们搬到不同地区时这很有用
或获得晋升到不同的群体。

希望这可以帮助! :)

I wrote an application to handle a multi-level sales program.
Of course, people drop out. In ours, people had to be inserted as well.

You're on the right track with one modification.

The identity number (ID) and the sequence number (seq) are two different things.
They have no relationship with each other at all.

Never change an ID. Once assigned, always assigned.

Create a column (cNEXT) in your table for the sequence and populate it with IDs.
"What ID is to be the next one in this sequence?"

Shuffle the IDs in cNEXT around, reassigning cNEXT, any time you want.
Any stored proc can do that.

Then you also have the flexibility to create non-sequential chains of IDs.
This is useful when people move to different regions
or get promotions to different groups.

Hope this helps! :)

痞味浪人 2024-07-23 01:52:56

所有答案都假设这是生产环境。 如果您测试数据库设计,然后想要快速截断所有表,应该有一个简单的方法来完成此操作:

DBCC CHECKIDENT({table name}, reseed, 0)

*首先使用 id 从所有表中删除所有行

All the answers are assuming this is a production environment. If your testing a database design, then want to quickly truncate all the tables there should be an easy way to accomplish this:

DBCC CHECKIDENT({table name}, reseed, 0)

*Delete all rows from all tables using the id first

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