我们在使用SQlServer2012数据库的时候,当数据库实例被重启后,表里的IDENTITY类型的字段,实际的跳转取决于该字段的类型,如果是INT类型,自动跳转为1000,如果是bigint,跳转为10000,从我们程序开发的角度,这个是无法接受的,目前只是在SQLServer2012种出现,其他版本的没有出现。
就在几天前,我们的一个工程师声称,我们一个IDENTITY列的值直接增加了10000,本来应该是2200现在是12001,现在我们必须解决这个问题。
按照道理,每次跳转的值不应该改变,于是开始找原因,最后解决了该问题。
我们进行问题重现。
我们安装一台新的SQL Server 2012的测试服务器,并且创建一个测试数据库。然后创建一个包含IDENTITY列的表:
create table MyTestTable(Id int Identity(1,1), Name varchar(255));
现在插入两条数据:
insert into MyTestTable(Name) values ('Mr.Tom');
insert into MyTestTable(Name) values ('Mr.Jackson');
然后通过下面的查询语句得到
SELECT Id, Name FROM MyTestTable;
目前的结果没有问题,现在我们只需要重启SQLServer服务,现在我们从SQL Server Management Studio重启服务。
现在我们将向这个表继续插入两条数据。
insert into MyTestTable(Name) values ('Mr.Tom2');
insert into MyTestTable(Name) values ('Mr.Jackson2');
这个时候进行数据查询,结果就成这样了:
当SQLServer2012的服务重启后,则标识从1002开始,这意味着它跳了1000,如果将字段设置为bigint,它会条高10000。
怎么会这样呢,如何解决,难道是bug,但是在咨询后,微软声称这个不是bug,是一个新的功能,在某些情况下可以受益,但是对我们来说这个是不允许的,因为客户端如果看到这样的数据,肯定会觉得是一个问题,现在跳转的数量取决于服务重启的次数,如果这个值在客户端不被看到,到还好,如果被看到,那肯定需要处理。
解决方法有两个
1:使用序列
2:配置数据库实例的启动参数
1:使用序列
现在我们移除Identity字段,然后创建一个序列字段,并插入值。
CREATE SEQUENCE Id_Sequence
AS INT
START WITH 1
INCREMENT BY 1
MINVALUE 0
NO MAXVALUE
NO CACHE
2:修改数据库实例的启动参数
然后修改SQLServer启动参数,打开SQLServer configuration manager,然后选择服务实例,点击右键属性,查看实例的属性界面,然后启动参数选项输入-t272,然后保存数据后重启服务。这样就可以看到差别。
这两个方法都可以解决,但是第一种方法可以对某一个库进行解决,而第二个修改后,将影响整个数据库。
如果需要调整整个数据库,那么可以使用第二个解决方法。