如何在SQL Server中重新设置标识列的种子?
我在SQL Server中有一个名为如何在SQL Server中重新设置标识列的种子?,sql,sql-server,sql-server-2008,sql-server-2008-r2,Sql,Sql Server,Sql Server 2008,Sql Server 2008 R2,我在SQL Server中有一个名为Personal\u Info的表。t该表有一个名为Vol\u ID的列,而(Is Identity)属性是Yes 现在我插入了大约175568行作为测试。然后我删除了大约568行,但是当我再次插入数据时,列volu ID从175569开始,而不是从175001开始 我想插入数据,让列volu ID从其中的最后一个数字开始。例如,如果最后一行是15,那么下一行应该从16开始,即使我已经插入但删除了它 我需要一个存储过程或触发器,可以强制insert操作填充缺少
Personal\u Info
的表。t该表有一个名为Vol\u ID
的列,而(Is Identity)
属性是Yes
现在我插入了大约175568行作为测试。然后我删除了大约568行,但是当我再次插入数据时,列volu ID
从175569开始,而不是从175001开始
我想插入数据,让列volu ID
从其中的最后一个数字开始。例如,如果最后一行是15,那么下一行应该从16开始,即使我已经插入但删除了它
我需要一个存储过程或触发器,可以强制insert操作填充缺少的id,检查最后一个exist行,如果exist行之后缺少id,则填充它
我有这个程序来进行插入
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)
请帮我写下缺少的id您需要像下面那样重新设置标识列的种子
DBCC CHECKIDENT(Personal_Info, RESEED, 175001)
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
引用自MSDN
许可:
调用方必须拥有该表,或者是sysadmin固定服务器的成员
角色、db_所有者固定数据库角色或db_ddladmin固定数据库角色
数据库角色
所以。表的所有者(或者DBA)可以对标识列进行重新设置种子
,而不是普通用户。此外,为什么您甚至会允许您的应用程序用户为标识列值重新设定种子?那毫无意义
编辑:
在这种情况下,请检查下面的@Brennan答案。简而言之,您应该从存储过程执行insert。我的意思是你的应用程序应该调用SP并执行插入。如下所示(示例代码)。此外,在这种情况下,删除vol_id列的identity属性(vol_id应该是vol_id int not null unique
)
您的应用程序将调用以下过程
exec sp_insert-person @name = 'user2251369'
最终编辑:
请参阅这篇文章,了解您为什么应该避免重新播种
标识值(marc_s给出了一个很好的小解释)
您的最终过程如下所示
DBCC CHECKIDENT(Personal_Info, RESEED, 175001)
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
您需要重新设置标识列的种子,如下所示
DBCC CHECKIDENT(Personal_Info, RESEED, 175001)
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
引用自MSDN
许可:
调用方必须拥有该表,或者是sysadmin固定服务器的成员
角色、db_所有者固定数据库角色或db_ddladmin固定数据库角色
数据库角色
所以。表的所有者(或者DBA)可以对标识列进行重新设置种子
,而不是普通用户。此外,为什么您甚至会允许您的应用程序用户为标识列值重新设定种子?那毫无意义
编辑:
在这种情况下,请检查下面的@Brennan答案。简而言之,您应该从存储过程执行insert。我的意思是你的应用程序应该调用SP并执行插入。如下所示(示例代码)。此外,在这种情况下,删除vol_id列的identity属性(vol_id应该是vol_id int not null unique
)
您的应用程序将调用以下过程
exec sp_insert-person @name = 'user2251369'
最终编辑:
请参阅这篇文章,了解您为什么应该避免重新播种
标识值(marc_s给出了一个很好的小解释)
您的最终过程如下所示
DBCC CHECKIDENT(Personal_Info, RESEED, 175001)
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
您试图做的并不是创建identity列的目的——不能保证不会有间隙,删除记录也不会重复使用丢失的标识
如果您确实需要一个连续的、自动递增的id字段,并且没有间隙,那么最好使用存储过程来执行插入(您需要向其中添加逻辑以重用缺少的id),或者定义一个触发器来强制执行您想要的操作-但是尝试强制标识列执行您尝试执行的操作是错误的。您尝试执行的操作并不是标识列的目的-无法保证不会有间隙,删除记录不会重复使用丢失的标识
如果您确实需要一个连续的、自动递增的id字段,并且没有间隙,那么最好使用存储过程来执行插入(您需要向其中添加逻辑以重用缺少的id),或者定义一个触发器来强制执行您想要的操作,但试图强制标识列执行您试图执行的操作是错误的。因此,正如其他人所说,您可以重新设置标识的种子。但是,只有在最后删除时,这才有效。填补身份中的空白将非常具有挑战性,最终你将不得不关闭身份 如果这是种子数据的小案例,则可以启用identity insert
因此,正如其他人所说,您可以重新设定身份。但是,只有在最后删除时,这才有效。填补身份中的空白将非常具有挑战性,最终你将不得不关闭身份 如果这是种子数据的小案例,则可以启用identity insert
这就是魔法。在插入之前执行此操作
declare @i int
select @i=max(id) from Personal_Info
DBCC CHECKIDENT (Personal_Info, RESEED, @i)
这就是魔法。在插入之前执行此操作
declare @i int
select @i=max(id) from Personal_Info
DBCC CHECKIDENT (Personal_Info, RESEED, @i)
你需要重新设置身份栏的种子。一个建议:不要这样做!永远不要“回收”以前用于新行的标识值。不要这样做-如果你这样做,你将在数据库地狱中结束!,不要再担心差距了——它们真的不是问题!你需要重新设置身份栏的种子。一个建议:不要这样做!永远不要“回收”以前用于新行的标识值。不要这样做-如果你这样做,你将在数据库地狱中结束!,不要再担心差距了——它们真的不是问题!这将适用于我,而不是应该使用应用程序的普通用户,如果他/她插入一些行,然后将其删除,那么当他们插入新数据时,应检查最后一行,然后重新设置种子。thanks@user2251369,请参阅编辑后的答案。你不应该允许你的应用程序用户这样做