我在SQL Server中有一个名为Personal_Info
的表。该表有一个名为Vol_ID
的列,(Is Identity)
属性为Yes
。
现在我插入了大约175568行作为测试。然后我删除了大约568行,但是当我再次插入数据时,列Vol_ID
从175569开始而不是从175001开始。
我想插入数据,让列Vol_ID
从其中的最后一个数字开始。例如,如果最后一行是15,则下一行应该从16开始,即使我已经插入但是我将其删除。
我需要一个存储过程或触发器,它可以强制插入操作填充缺少的id,检查最后存在的行,如果在存在之后缺少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)
请帮我写下遗失的身份证明
答案 0 :(得分:2)
您需要重新设置标识列,如下所示
DBCC CHECKIDENT(Personal_Info, RESEED, 175001)
引自MSDN
许可:
调用者必须拥有该表,或者是sysadmin固定服务器的成员 角色,db_owner固定数据库角色或db_ddladmin已修复 数据库角色。
因此。它是表的所有者(OR)DBA可以执行标识列的reseed
而不是普通用户。此外,为什么您甚至允许您的应用程序用户重新设置标识列值?这根本没有意义。
修改强>
在那种情况下,请查看下面的@Brennan回答。简而言之,您应该从存储过程执行插入。我的意思是你的APP应该调用SP并执行插入。如下(示例代码)。此外,在这种情况下,删除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
您的应用程序将调用此程序
exec sp_insert-person @name = 'user2251369'
最终编辑:
请参阅此帖子RESEED identity columns on the database,了解为什么要避免reseeding
IDENTITY值(由marc_s给出的一个很好的小解释)。
您的最终程序应如下所示
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
答案 1 :(得分:2)
您要做的不是身份列的用途 - 不能保证不会有间隙,删除记录不会重复使用缺少的身份。
如果你真的需要一个顺序的自动增量id字段,没有间隙,那么你最好使用存储过程来进行插入(你需要添加逻辑来重用缺少的id) ,或者定义一个强制执行你想要的触发器 - 但是试图强制标识列执行你想要做的事情是错误的方法。
答案 2 :(得分:0)
正如其他人所说,你可以重新定位身份。但是,这只有在最后删除时才有效。填补身份的空白将是非常具有挑战性的,你最终将不得不关闭身份。
如果这是种子数据的小例子,您可以打开身份插入。 enter link description here
SET IDENTITY_INSERT {your table} ON
答案 3 :(得分:0)
这是神奇的。在插入之前执行此操作。
declare @i int
select @i=max(id) from Personal_Info
DBCC CHECKIDENT (Personal_Info, RESEED, @i)