简体   繁体   English

如何在 SQL Server 中重新设定身份列?

[英]How to reseed the identity column in SQL Server?

I have a table in SQL Server called Personal_Info .我在 SQL Server 中有一个名为Personal_Info的表。 Tthis table has a column called Vol_ID and the (Is Identity) property is Yes .该表有一个名为Vol_ID的列,并且(Is Identity)属性为Yes

Now I inserted about 175568 rows as a test.现在我插入了大约 175568 行作为测试。 And then I deleted about 568 rows, BUT when I insert the data again the column Vol_ID start from 175569 not from 175001.然后我删除了大约 568 行,但是当我再次插入数据时, Vol_ID列从 175569 开始而不是从 175001 开始。

I want to insert the data and let the column Vol_ID start from the last number in it.我想插入数据并让Vol_ID列从其中的最后一个数字开始。 For example if the last row is 15, the next row should be start from 16, even if I already inserted but I delete it.例如,如果最后一行是 15,下一行应该从 16 开始,即使我已经插入但我删除了它。

I need a stored procedure or a trigger that can force the insert operation to filled that missing id's, check the last exist row and if there is missing id's after the exist one then filled it.我需要一个存储过程或触发器,可以强制插入操作填充缺少的 id,检查最后一个存在行,如果存在后缺少 id,然后填充它。

I have this procedure to make the insertion我有这个程序来进行插入



      USE [VolunteersAffairs] 

    go 

    /****** Object:  StoredProcedure [dbo].[AddVolunteer]    Script Date: 05/02/2014      21:12:36 ******/ 
    SET ansi_nulls ON 

    go 

    SET quoted_identifier ON 

    go 

    ALTER PROCEDURE [dbo].[Addvolunteer] @Vol_Name                 NVARCHAR(255), 
                                         @Vol_Zone                 NVARCHAR(255), 
                                         @vol_street               NVARCHAR(255), 
                                         @Vol_Sex                  INT, 
                                         @Vol_Date_of_Birth        DATE, 
                                         @Vol_Home_Phone           INT, 
                                         @Vol_Work_Phone           INT, 
                                         @Vol_Mobile1              INT, 
                                         @Vol_Mobile2              INT, 
                                         @Vol_Email                NVARCHAR(255), 
                                         @Vol_Job                  NVARCHAR(255), 
                                         @Vol_Affiliation          NVARCHAR(255), 
                                         @vol_Education            INT, 
                                         @vol_Education_Place      NVARCHAR(255), 
                                         @vol_Education_Department NVARCHAR(255), 
                                         @vol_Interesting          INT, 
                                         @vol_Notes                NVARCHAR(255), 
                                         @Team_ID                  INT 
    AS 
        INSERT INTO personal_info 
                    (vol_name, 
                     vol_zone, 
                     vol_street, 
                     vol_sex, 
                     vol_date_of_birth, 
                     vol_home_phone, 
                     vol_work_phone, 
                     vol_mobile1, 
                     vol_mobile2, 
                     vol_email, 
                     vol_job, 
                     vol_affiliation, 
                     vol_education, 
                     vol_education_place, 
                     vol_education_department, 
                     vol_interesting, 
                     team_id, 
                     vol_notes) 
        VALUES      (@Vol_Name, 
                     @Vol_Zone, 
                     @vol_street, 
                     @Vol_Sex, 
                     @Vol_Date_of_Birth, 
                     @Vol_Home_Phone, 
                     @Vol_Work_Phone, 
                     @Vol_Mobile1, 
                     @Vol_Mobile2, 
                     @Vol_Email, 
                     @Vol_Job, 
                     @Vol_Affiliation, 
                     @vol_Education, 
                     @vol_Education_Place, 
                     @vol_Education_Department, 
                     @vol_Interesting, 
                     @Team_ID, 
                     @vol_Notes) 

Please Help me to write the missing id's请帮我写下丢失的ID

you need to reseed the identity column like below您需要像下面一样重新设定身份列

DBCC CHECKIDENT(Personal_Info, RESEED, 175001)

Quoted from MSDN引用自 MSDN

Permission:允许:

Caller must own the table, or be a member of the sysadmin fixed server role, the db_owner fixed database role, or the db_ddladmin fixed database role.调用者必须拥有该表,或者是 sysadmin 固定服务器角色、db_owner 固定数据库角色或 db_ddladmin 固定数据库角色的成员。

So.所以。 it's either the owner of the table (OR) DBA can do the reseed of identity column and not normal user.它要么是表的所有者 (OR) DBA 可以reseed身份列,而不是普通用户。 moreover, why will you even allow your application user to reseed identity columns value?此外,为什么您甚至允许您的应用程序用户重新设定身份列值? that won't make sense at all.那完全没有意义。

EDIT:编辑:

In that case check @Brennan answer below.在这种情况下,请检查下面的@Brennan 答案。 in a nutshell, you should perform your insert from stored procedure.简而言之,您应该从存储过程执行插入。 I mean your APP should call SP and perform the insert.我的意思是你的 APP 应该调用 SP 并执行插入。 Like below(a sample code).如下所示(示例代码)。 Also, in such case remove the identity property of vol_id column (vol_id should just be vol_id int not null unique )此外,在这种情况下,删除 vol_id 列的标识属性(vol_id 应该只是vol_id int not null unique

create procedure sp_insert-person
@name varchar(10)
as 
begin
declare @last_id int;
select @last_id = top 1 Vol_ID from Personal_Info order by Vol_ID desc;
insert into Personal_Info(Vol_ID,name) 
values(@last_id+1,@name);
end

Your application will call the procedure like您的应用程序将调用这样的过程

exec sp_insert-person @name = 'user2251369'

Final EDIT:最终编辑:

See this post RESEED identity columns on the database about why you should avoid reseeding IDENTITY value (A nice small explanation given by marc_s).请参阅数据库上的 RESEED identity columns帖子了解为什么应该避免reseeding IDENTITY 值(由 marc_s 给出的一个很好的小解释)。

Your Final procedure should look like below您的最终程序应如下所示

USE [VolunteersAffairs]
GO
/****** Object:  StoredProcedure [dbo].[AddVolunteer]    
 Script Date: 05/02/2014      21:12:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[AddVolunteer]
@Vol_Name nvarchar(255), 
@Vol_Zone nvarchar(255), 
@vol_street nvarchar(255), 
@Vol_Sex int, 
@Vol_Date_of_Birth date, 
@Vol_Home_Phone int, 
@Vol_Work_Phone int, 
@Vol_Mobile1 int,    
@Vol_Mobile2 int, 
@Vol_Email nvarchar(255), 
@Vol_Job nvarchar(255), 
@Vol_Affiliation nvarchar(255), 
@vol_Education int, 
@vol_Education_Place nvarchar(255), 
@vol_Education_Department nvarchar(255), 
@vol_Interesting int, 
@vol_Notes nvarchar(255), 
@Team_ID int
As
BEGIN
DECLARE @last_vol_id int;
select top 1 @last_vol_id = Vol_ID from Personal_Info order by Vol_ID desc;

insert into Personal_Info
(Vol_Id,
Vol_Name, 
Vol_Zone, 
vol_street, 
Vol_Sex, 
Vol_Date_of_Birth, 
Vol_Home_Phone, 
Vol_Work_Phone, 
Vol_Mobile1, 
Vol_Mobile2, 
Vol_Email, 
Vol_Job, 
Vol_Affiliation, 
vol_Education, 
vol_Education_Place, 
vol_Education_Department, 
vol_Interesting, 
Team_ID, 
vol_Notes) 
values 
(@last_vol_id+1,
@Vol_Name, 
@Vol_Zone, 
@vol_street, 
@Vol_Sex, 
@Vol_Date_of_Birth, 
@Vol_Home_Phone, 
@Vol_Work_Phone, 
@Vol_Mobile1, 
@Vol_Mobile2, 
@Vol_Email, 
@Vol_Job, 
@Vol_Affiliation, 
@vol_Education, 
@vol_Education_Place, 
@vol_Education_Department, 
@vol_Interesting, 
@Team_ID, 
@vol_Notes);
END

What you are trying to do is not what the identity column was made for - there is no guarantee that there won't be gaps, and deleting records does not re-use the missing identities.您尝试做的不是标识列的用途 - 不能保证不会有间隙,并且删除记录不会重新使用丢失的标识。

If you really need a sequential, auto increment id field, with no gaps, then you are better of either using a stored procedure to do your inserts (to which you will need to add the logic to re-use missing id's), or else define a trigger that enforces what you want - but trying to force the identity column to do what you are trying to do is the wrong way to go about it.如果你真的需要一个连续的、自动递增的 id 字段,没有间隙,那么你最好使用存储过程来做你的插入(你需要添加逻辑以重新使用丢失的 id),或者定义一个强制执行您想要的触发器 - 但试图强制标识列执行您正在尝试执行的操作是错误的方法。

So as other have said, you can reseed the identity.正如其他人所说,您可以重新设定身份。 However, this will only work if you remove at the end.但是,这仅在您最后删除时才有效。 Filling in the gaps in the identity will be really challenging and you will end up having to turn off the identity.填补身份的空白将非常具有挑战性,您最终将不得不关闭身份。

If this is a small case for seeding data, you could turn identity insert on.如果这是播种数据的小案例,您可以打开身份插入。 enter link description here在此处输入链接描述

SET IDENTITY_INSERT {your table} ON

Here is another question highlighting the other concerns 这是另一个突出其他问题的问题

This is the magic.这就是魔法。 Do this just before your insert.在插入之前执行此操作。

declare @i int
select @i=max(id) from Personal_Info
DBCC CHECKIDENT (Personal_Info, RESEED, @i)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM