sqlserver 自增列(id)跳跃问题

标签:
sqlserverid跳跃自增混乱 |
分类: 数据库 |
Introduction
From SQL Server 2012 version, when SQL Server
instance is restarted, then table's Identity
value is jumped and the
actual jumped value depends on identity column data type. If it is
integer (int
) data type, then jump value
is 1000
and if big integer
(bigint
), then jump value
is 10000
. From our application point of view, this
increment is not acceptable for all the business cases specially
when the value shows to the client. This is the special case/issue
ships with only SQL Server 2012 and older versions have no such
issue.
Background
A few days ago, our QA Engineer claims that
one of our table's identity column
jumped 10000
. That means the last identity value of that
table was 2200
now it
is 12001
. In our business logic is like that the
value shows to the client and it will not be accepted by the
client. So we must solve the issue.
Using the Code
The first time, we all are surprised and confused as to how it is possible? We usually do not insert any value in identity column (insert value to identity column is possible). The identity value is maintained by SQL Server itself. One of our core team members started investigation the issue and found out the solution. Now, I want to elaborate the issue and solution that was found out by my colleague.
How to Reproduce That?
You need to setup SQL Server 2012 and create a test database. Then create a table with auto identity column:
create table MyTestTable(Id int Identity(1,1), Name varchar(255));
Now insert 2 rows there:
insert into MyTestTable(Name) values ('Mr.Tom');
insert into MyTestTable(Name) values ('Mr.Jackson');
You see the result:
SELECT Id, Name FROM MyTestTable;
https://www.codeproject.com/KB/database/668042/NormalTable.png自增列(id)跳跃问题" />
The result is as expected. Now just restart your SQL Server service. There are various ways in which you can do it. We did it from SQL Server management studio.
https://www.codeproject.com/KB/database/668042/ReStart.png自增列(id)跳跃问题" TITLE="sqlserver
Now, insert another 2 rows to the same table again:
insert into MyTestTable(Name) values ('Mr.Tom2');
insert into MyTestTable(Name) values ('Mr.Jackson2');
Now see the result:
SELECT Id, Name FROM MyTestTable;
https://www.codeproject.com/KB/database/668042/FullTable.png自增列(id)跳跃问题" TITLE="sqlserver
Now you see that after restarting the SQL
Server 2012 instance, then identity value starts
with 1002
. It means it
jumped 1000
. Previously, I said that we also see if the
data type of that identity column is bigint
, then it will
jump 10000
.
Is it really a bug?
Microsoft declares it is a feature rather than a bug and in many scenarios it would be helpful. But in our case, it would not be acceptable because that number is shown to the client and the client will be surprised to see that new number after jump and the new number depends on how many times SQL Server is restarted. If it is not visible to the client, then it might be acceptable so that the number is used internally.
Solutions
If we are not interested in this so called feature, then we can do two things to stop that jump.
- Using Sequence
- Register -t272 to SQL Server Startup Parameter
Using Sequence
First, we need to remove Identity
column from tables.
Then create a sequence without cache feature and insert number from
that sequence. The following is the code sample:
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');
Register -t272 to SQL Server Startup Parameter
Open SQLServer configuration manager from your
server. Select SQL Server 2012 instance there right client and
select Properties menu. You will find a tabbed dialog window. You
select start up parameters tab from there and
register
https://www.codeproject.com/KB/database/668042/StartupParameter.png自增列(id)跳跃问题" />
Points of Interest
If too many tables contain identity column to your database and all contain existing values, then it is better to go for solution 2. Because it is a very simple solution and its scope is server wise. This means if you add SQL Server 2012 parameter -t272 there, then it will affect all your databases there. If you want to create a new database and you need auto generated number field, then you can use solution 1, that means use sequence value to a column instead of auto Identity value. There are so many articles you can find online about when you will use auto identity column when using sequence and advantages/disadvantages of each other. I hope you will read all those and take the appropriate decision.
解决办法:
1 打开配置管理器
2左面点击sql服务
3右面 右键点击SQL Server(MSSQLSERVER)
4点击 启动参数
5 在参数 里输入
原文地址:https://www.codeproject.com/Tips/668042/SQL-Server-2012-Auto-Identity-column-Value-Jump-Is