我有一张桌子:
CREATE TABLE [dorkOrder] (
[doId] int identity(1,1) NOT NULL,
[shId] int NOT NULL,
[mopId] int NOT NULL,
[dorkOrderNo] varchar(20) NULL,
[doDate] date NULL
);
现在当我向其中插入数据而不是以这种方式doId
生成1,2,3,4,5,6,7
时,它会以下面的奇怪方式生成数据:
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
2002
2003
2004
2005
2006
2007
2008
2013
请帮我解决这个问题。
答案 0 :(得分:5)
这是known issue in SQL Server 2012。但即使没有这个错误(可能会在某一天修复,但可能不会修复),您应该期望您的IDENTITY列可能存在空白。这些可能由于各种原因而发生,包括删除和回滚。
如果要实现没有间隙的顺序列,则停止使用IDENTITY,在插入新行的基础上构建强大的可序列化进程,并拒绝对该表上的所有人执行删除/截断。
否则,由于微软表示他们已经absolutely no intention of offering a "gapless sequential" feature,所以要学会忍受差距。
答案 1 :(得分:0)
这是一个小小的测试脚本,向您展示有关标识列的一些有趣的事情
1 - 大多数人使用(1,1)。
然而,您可以使用(1,5)增加5,这将留下空白 如果你愿意,也可以从(2000,1)两千开始。
2 - 删除表中的所有记录不会重置计数器。
3 - 截断表格会将计数器重置为基数。
4 - 差距可能是由于删除或阻止插入的条件造成的。
示例触发器最后显示是否没有播放大笔资金,会出现差距。
5 - 最后但并非最不重要的是,你可以从一个类型的负范围开始。
对于INT,从-2147483648开始向2147483647递增,给出两倍的数字。 但是,如果用户看到id,您可能不希望这样。然后使用BIGINT。
-- Just playing
use tempdb;
go
-- drop existing
if object_id('superbowl_pool') > 0
drop table superbowl_pool
go
-- create new
create table superbowl_pool
(
id int identity (1,1) primary key,
cash smallmoney
);
-- add data
declare @a int = 0;
while (@a < 100)
begin
insert into superbowl_pool (cash) values (rand(checksum(newid())) * 50);
set @a += 1;
end
go
-- show the data
select * from superbowl_pool;
显示删除的用户不要重置计数器。
-- delete does not reset the counter
delete from superbowl_pool;
go
-- Two records
insert into superbowl_pool (cash) values (rand(checksum(newid())) * 50);
insert into superbowl_pool (cash) values (rand(checksum(newid())) * 50);
go
-- Gaps in id column
delete from superbowl_pool where id = 102;
insert into superbowl_pool (cash) values (rand(checksum(newid())) * 50);
-- show the data
select * from superbowl_pool;
向用户显示截断重置计数器。
-- truncate table
truncate table superbowl_pool;
-- Two records
insert into superbowl_pool (cash) values (rand(checksum(newid())) * 50);
insert into superbowl_pool (cash) values (rand(checksum(newid())) * 50);
go
-- show the data
select * from superbowl_pool;
用户必须玩20美元或更多
-- create ins trigger
create trigger dbo.trg_big_money on dbo.superbowl_pool
FOR INSERT
AS
BEGIN
IF EXISTS (SELECT * FROM inserted where cash < 20)
ROLLBACK;
END