迁移后避免填补身份空白

时间:2013-02-13 00:54:05

标签: sql-server sql-server-2008 replication sql-server-2012 identity-column

我已经通过事务复制将一系列表从SQL Server 2008迁移到新的SQL Server 2012计算机。到目前为止工作正常,我还复制了索引和默认值,以确保复制的数据等于原始数据。

当我将新计算机从复制拆分为独立操作以替换旧计算机时,SQL Server开始填补我的标识列中的所有空白,这可能会导致不同的麻烦。即我的代码不能再依赖于最后一个插入行的最高ID。此外,之前删除的用户ID也会被回收,这可能会在用户端引起混淆。

有没有办法让我的数据库的新实例完全像旧的复制实例一样?根据我的经验,正在运行的数据库实例永远不会填补以前删除的行的空白。

1 个答案:

答案 0 :(得分:1)

我也从未见过这个。但是,它可能会在部署时重新设置为0。观察这个例子:

SET NOCOUNT ON;
GO
CREATE TABLE dbo.fooblat(id INT IDENTITY(1,1));
GO
INSERT dbo.fooblat DEFAULT VALUES;
GO 3
DELETE dbo.fooblat WHERE id = 2;
GO
DBCC CHECKIDENT('dbo.fooblat', RESEED, 0);
GO
INSERT dbo.fooblat DEFAULT VALUES;
GO 3
SELECT id FROM dbo.fooblat ORDER BY id;
GO
DROP TABLE dbo.fooblat;

结果:

id
----
1
1
2
3
3

现在,如果标识列也是主键或其他唯一标识,则同样的操作仍然可以填补空白,只有重复的违规才会失败。所以再次重复这个表定义:

CREATE TABLE dbo.fooblat(id INT IDENTITY(1,1) PRIMARY KEY);
GO

产生这个(第一个成功的插入填补了空白):

id
----
1
2
3
  

Msg 2627,Level 14,State 1,Line 1
  违反PRIMARY KEY约束' PK_ fooblat _3213E83F6BF0A0C6'。无法在对象' dbo.fooblat'中插入重复键。重复键值为(1)   Msg 2627,Level 14,State 1,Line 1
  违反PRIMARY KEY约束' PK_ fooblat _3213E83F6BF0A0C6'。无法在对象' dbo.fooblat'中插入重复键。重复键值为(3)。

您可以通过确保将表放在另一个系统上时正确播种表来避免这种情况。这可能仅仅意味着使用更可靠的部署技术,或者它可能意味着 - 在填充之后和让任何用户进入之前 - 你做这样的事情:

DECLARE @i INT, @sql NVARCHAR(MAX);
SELECT @i = MAX(id) FROM dbo.fooblat;
SET @sql = N'DBCC CHECKIDENT(''dbo.fooblat'', RESEED, ' + RTRIM(@i) + ');';
EXEC sp_executesql @sql;