当前位置:首页 > 技术心得 > 正文内容

SQL Server 2012 自动增长列,值跳跃问题(自增增加1000)【转载】

xjtudll2年前 (2023-11-08)技术心得3060

介绍

从 SQL Server 2012 版本开始, 当SQL Server 实例重启之后,表格的自动增长列的值会发生跳跃,而具体的跳跃值的大小是根据增长列的数据类型而定的。如果数据类型是 整型(int),那么跳跃值为 1000;如果数据类型为 长整型(bigint),那么跳跃值为 10000。从我们的项目来看,这种跳跃问题是不能被接受的,尤其是展示在客户端的时候。这个奇怪的问题只在 SQL Server 2012 及更高的版本中存在,SQL Server 2012之前版本不存在此问题。

背景

几天前,我们QA组的同事提出: 我们表格的自增列的值莫名奇妙的跳跃了 10000。也就是说,我们之前表格自增列的最后一个值为 2200,而现在新增一条记录,自增列的值却直接变成了 12200。在我们的业务逻辑中像这样的情况是不允许展现在客户端的,因此我们要解决此难题。

代码使用

刚开始我们都很奇怪,这是怎么发生的?我们通常不会手动向自增列插入任何值(向自增列手动插入值是可以的),自增列的值是由数据库自行维护的。我们核心团队的一位成员开始研究这个问题并找到了答案。现在,我想详细讲解下这个问题,以及我同事找到的解决方案。

如何重现此bug

你需要安装SQL Server 2012 然后创建一个测试数据库。之后再创建一个带有自增列的表格:

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;

464634-20160315105002787-2110076472[1]

此时结果和我们预期的一样。 现在重启你的 SQL Server Service。重启SQL服务有多种方法,我们这里通过 SQL Server 管理器来重启:

464634-20160315103556256-699496677[1]

重启之后,我们向刚才的表格再插入2条数据:

insert into MyTestTable(Name) values ('Mr.Tom2');

insert into MyTestTable(Name) values ('Mr.Jackson2');

查看结果:

SELECT Id, Name FROM MyTestTable;

464634-20160315104909271-1107098834[1]

现在你看到重启SQL Server 2012 之后的结果,它的自增列的值从1002开始了。 也就是跳跃了 1000。之前说过,如果我们自增列的数据类型是 长整型(bigint)的话,它的跳跃值就将会是 10000。

它真的是个BUG吗?

微软声明这是一个功能而并非bug, 在很多场景下是很有用处的。 但是在我们的案例中,我们并不需要这样的一个功能,因为这个自增数据是要展示给客户的,客户如果看到这样跳跃性的数据,他们会感到很奇怪。并且跳跃值是根据你重启SQL Server的次数决定的。如果此数据不向客户展示,或许还可以接受。因此此功能通常只适合在内部使用。

解决方案

如果我们对微软提供的这个 “功能” 不感兴趣,我们可以通过两种途径来关闭它。

1. 使用序列 (Sequence)

2. 为SQL Server 注册启动参数 -t272

使用序列

首先,我们需要移除表格的自增列。然后创建一个不带缓存功能的序列,根据此序列插入数值。 下面是示例代码:

CREATE SEQUENCE Id_Sequence

    AS INT

    START WITH 1

    INCREMENT BY 1

    MINVALUE 0

    NO MAXVALUE

   NO CACHE

insert into MyTestTable values(NEXT VALUE FOR Id_Sequence, 'Mr.Tom');

insert into MyTestTable values(NEXT VALUE FOR Id_Sequence, 'Mr.Jackson');

 

注册启动参数 -t272

打开SQL Server配置管理器。 选择 SQL Server 2012 实例,右键, 选择属性菜单。在弹出的窗口中找到启动参数,然后注册 -t272。 完成之后重启下图中的SQL Server(SQLSERVER2012), 之后进行bug重现的操作,验证问题是否已解决。

464634-20160315104055928-298109471[1]

额外说明

如果在你的数据库中有很多自增列的表,并且这些表都存在数值跳跃问题,那么采用第2种方案更好一些。因为它非常简单,并且作用域是服务器级别的。采用第2种解决方案将会影响此服务实例上的所有数据库。

扫描二维码推送至手机访问。

版权声明:本文由鸟的天空发布,如需转载请注明出处。

本文链接:http://xjtudll.cn/Exp/659/

标签: SQL
分享给朋友:

“SQL Server 2012 自动增长列,值跳跃问题(自增增加1000)【转载】” 的相关文章

如何判断一个正整数是不是2的幂

估计用递归的方法大家都知道,就不赘述了 这里使用一个更简单的方法。 若一个正整数是2的幂,则这个数在计算中的表示肯定是以下形式:0x00...1000...B省略号表示若干个0.问题就转变为一个等价的命题:如何判断给定的一个正整数是如0x00...1000...B这种形式(二进制表示式中只有唯一...

运放运用中容易忽视的问题

本文收集于网络,原文作者:djyos。 在嵌入式设计中,数字部分的功能越来越强大,而模拟电路大有被边沿化的趋势,但不管怎样,传感器以及其调理电路,还是离不开模拟电路的,其中运放是不可或缺的模拟器件。 本文谈谈在设计运放电路中容易被设计人员疏忽的问题,不注意这些问题,可能导致你的电路看起来能够工作...

Altium如何增加机械层

Altium如何增加机械层

Altium的机械层(Mechanical),默认只有一层,想多加几层吧,发现与Protel99SE大不相同,折腾了半天,总算是搞定了。 增加机械层步骤如下(以英文版为例,中文版大同小异): 1、在PCB界面,按L键(需先切换到英文输入法),弹出了板层配置的窗口。如图所示。 去掉【Only sho...

Altium原理图update到PCB时某些元件老是自动先删除后添加

Altium原理图update到PCB时某些元件老是自动先删除后添加

现象:从原理图update到PCB时,明明原理图没有变更,但是某些元件老是被自动删除,然后又自动添加进去了,于是PCB里摆好的元件又到了右下角了,导致又要重新摆放元件。 如下图所示,C1~C21先是被remove了,然后又被add了。看起来没什么大碍,但是PCB上之前被摆放好的C1~C21又被自动放...

OKI单片机——ML610Q4XX Melody Driver

OKI单片机——ML610Q4XX Melody Driver

配置流程: (1) Select a buzzer mode by setting the BZMD bit of the melody 0 control register (MD0CON) to “1”. (MD0CON寄存器的BZMD位置一)。 (2) Select...

苹果电脑备份还原Windows操作系统

苹果电脑备份还原Windows操作系统

苹果电脑可以通过BootCamp安装Windows系统(毕竟,有很多“Just For Windows”和“IE Only”的软件和服务--比如国内的网上银行)。但是,苹果电脑的macOSX操作系统及其下的文件可以通过Time Machine备份、还原,通过BootCamp装的Windows系统及其...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。