我们正在运行SQL Server 2012 SP1 x64(11.0.3000.0)
我有下表,其中的InvoiceId字段为自动递增的主键:
InvoiceId
CREATE TABLE Orders( InvoiceId bigint IDENTITY(1001,1) NOT FOR REPLICATION, OrderId varchar(8) NOT NULL, ... -- other fields removed for brevity CONSTRAINT [PK_ORDERS] PRIMARY KEY CLUSTERED (InvoiceId) ON [PRIMARY], )
通过简单的存储过程插入新行,如下所示:
SET XACT_ABORT ON SET NOCOUNT ON BEGIN TRANSACTION INSERT INTO Orders( OrderId, ... -- other fields removed for brevity ) VALUES ( @orderId, ... ) SELECT @newRowId = SCOPE_IDENTITY() COMMIT TRANSACTION
上面的存储过程将新创建的row-id(Orders.InvoiceId)返回给调用方。
Orders.InvoiceId
该代码运行良好,[InvoiceId]从1001开始,每个后续插入都加1。
[InvoiceId]
我们的用户插入了约130行。[InvoiceId]在1130,然后在下一个插入处,其值跳至 11091 !
这是数据截图:
我对这里发生的事情感到困惑。为什么自动加价计数器突然跳了将近10,000点?
我们使用的值[InvoiceId]来生成条形码,因此我们希望该值保持在特定范围内,最好是连续的。
我仔细阅读了T-SQL文档,但找不到与我的问题有关的任何内容。这是身份字段的正常行为(任意人口)吗?
更新感谢Marting&Aron,我找到了一种解决方法。这是微软的官方回应:
在SQL Server 2012中,标识属性的实现已更改,以适应对其他功能的投资。在早期版本的SQL Server中,对身份生成的跟踪依赖于生成的每个身份值的事务日志记录。在SQL Server 2012中,我们分批生成标识值,并且仅记录批处理的最大值。这减少了写入事务日志的信息的数量和频率,从而提高了插入的可伸缩性。
如果您需要与早期版本的SQL Server相同的身份生成语义,则有两个可用选项:
―使用跟踪标志272 o这将导致为每个生成的标识值生成一个日志记录。身份生成的性能可能会因打开此跟踪标志而受到影响。
使用带有NO CACHE设置的序列生成器(http://msdn.microsoft.com/en- us/library/ff878091.aspx)o这将导致为每个生成的序列值生成日志记录。请注意,使用NO CACHE可能会影响序列值生成的性能。
例子:
CREATE SEQUENCE s1 AS INT START WITH 1 NO CACHE; CREATE TABLE t1 (Id INT PRIMARY KEY DEFAULT NEXT VALUE FOR s1, col INT NOT NULL);