【问题标题】:Avoid filling identity gaps after migration避免在迁移后填补身份空白
【发布时间】:2013-02-13 00:54:05
【问题描述】:

我已通过事务复制将一系列表从 SQL Server 2008 迁移到新的 SQL Server 2012 机器。到目前为止效果很好,我还复制了索引和默认值,以确保复制的数据与原始数据相同。

当我将新机器从复制中分离出来作为旧机器的替代品时,SQL Server 开始填充我的标识列中的所有空白,这可能会导致不同的问题。 IE。我的代码不能再依赖于最后插入的行的最高 ID。以前删除的用户 ID 也会被回收,这也可能导致用户方面的混乱。

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

【问题讨论】:

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


    【解决方案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
    

    消息 2627,第 14 级,状态 1,第 1 行
    违反主键约束“PK_fooblat_3213E83F6BF0A0C6”。无法在对象“dbo.fooblat”中插入重复键。重复键值为 (1)。
    消息 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;
    

    【讨论】:

      猜你喜欢
      • 2015-08-19
      • 2020-09-25
      • 2018-10-18
      • 2017-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-23
      • 1970-01-01
      相关资源
      最近更新 更多