Sql server 避免在迁移后填补身份空白
我已通过事务复制将一系列表从SQL Server 2008迁移到新的SQL Server 2012计算机。到目前为止,这一切都很好,我还复制了索引和默认值,以确保复制的数据与原始数据相同 当我从复制中分离新机器以作为旧机器的替代品时,SQL Server开始填补我的标识列中的所有空白,这可能会导致不同的问题。也就是说,我的代码不能再依赖于最后插入行的最高ID。此外,以前删除的用户ID也会被回收,这可能会在用户端造成混乱Sql server 避免在迁移后填补身份空白,sql-server,sql-server-2008,replication,sql-server-2012,identity-column,Sql Server,Sql Server 2008,Replication,Sql Server 2012,Identity Column,我已通过事务复制将一系列表从SQL Server 2008迁移到新的SQL Server 2012计算机。到目前为止,这一切都很好,我还复制了索引和默认值,以确保复制的数据与原始数据相同 当我从复制中分离新机器以作为旧机器的替代品时,SQL Server开始填补我的标识列中的所有空白,这可能会导致不同的问题。也就是说,我的代码不能再依赖于最后插入行的最高ID。此外,以前删除的用户ID也会被回收,这可能会在用户端造成混乱 有没有办法使我的数据库的新实例与旧的复制实例完全相同?根据我的经验,数据库的
有没有办法使我的数据库的新实例与旧的复制实例完全相同?根据我的经验,数据库的运行实例永远不会填补以前删除的行的空白。我也从未见过这种情况。但是,可能是表在部署时被重新设定为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
产生以下结果(第一次成功插入填补了空白):
Msg 2627,第14级,状态1,第1行违反主键约束“PK_fooblat_3213E83F6BF0A0C6”。无法在对象“dbo.fooblat”中插入重复键。重复的键值为(1)。
Msg 2627,第14级,状态1,第1行
违反主键约束“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;
我也从来没见过这个。但是,可能是表在部署时被重新设定为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
产生以下结果(第一次成功插入填补了空白):
Msg 2627,第14级,状态1,第1行违反主键约束“PK_fooblat_3213E83F6BF0A0C6”。无法在对象“dbo.fooblat”中插入重复键。重复的键值为(1)。
Msg 2627,第14级,状态1,第1行
违反主键约束“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;