插入复制表失败 - 标识范围检查

时间:2010-02-02 07:01:52

标签: sql-server tsql

我正在尝试将几千行插入到跨两个服务器复制的数据库中的表中。无论是发布者还是订阅者,我都会遇到同样的错误:

Msg 548, Level 16, State 2, Line 1
The insert failed. It conflicted with an identity range check constraint in database 'XXX', replicated table 'dbo.NODE_ATTRIB_RSLT', column 'ID'. If the identity column is automatically managed by replication, update the range as follows: for the Publisher, execute sp_adjustpublisheridentityrange; for the Subscriber, run the Distribution Agent or the Merge Agent.
The statement has been terminated.

检查表上的约束,在我看来,我应该能够在遇到问题之前一次插入至少1000行。但是,当我尝试插入几十行时,我得到了同样的错误!

以下是我试图插入数据的方法:

insert into NODE_ATTRIB_RSLT 
([NODE_ID]
      ,[ATTRIB_ID]
      ,[STATE_ID]
      ,[PLAN_REVISION_ID]
      ,[TIMESTAMP]
      ,[VALUE]
      ,[VALUE_TEXT]
      ,[LAST_MODIFIED]) 
SELECT [NODE_ID]
          ,[ATTRIB_ID]
          ,[STATE_ID]
          ,[PLAN_REVISION_ID]
          ,[TIMESTAMP]
          ,[VALUE]
          ,[VALUE_TEXT]
          ,[LAST_MODIFIED]   FROM [NODE_ATTRIB_RSLT_TEMP]

PK列是一个名为ID的自动生成标识。为了尝试一次插入更少的行,我在select的末尾添加了一个WHERE子句,如下所示:

WHERE ID >= 1000 and ID <1100

但无济于事。

在发布服务器上运行sp_adjustpublisheridentityrange会成功执行但不起作用。

如何使用插入修复此问题? 如何在保持复制运行的同时将缩进范围约束的范围修改为更合理的级别?

2 个答案:

答案 0 :(得分:23)

我想我找出了问题所在。

查看复制表的属性,它具有Publisher的标准默认标识范围10000和Subcriber的标准默认标识范围。

但是,检查实际表上的标识约束(使用SP_HELPCONSTRAINT'node_attrib_rslt')显示两个服务器上只有一个包含1000个ID的池。这使得批量插入失败,即使我限制了要插入的行数 - 我猜测SQL Server在运行INSERT INTO时检查约束时甚至没有那么远。

为了解决这个问题,我必须做几件事:

更改表的标识范围。我为Publisher和Subcriber设置了20K。

  1. 在发布服务器上,展开复制 - &gt;当地出版物
  2. 右键单击特定订阅,然后选择“属性”。
  3. 选择文章页面。
  4. 突出显示相应的表格。
  5. 单击文章属性'按钮',然后选择'设置突出显示的表文章的属性'。
  6. 在“文章属性”窗口中,查找“标识范围管理”选项。
  7. 更改适当的值。
  8. 按对话窗口上的确定和确定。
  9. 在发布服务器上运行sp_adjustpublisheridentityrange存储过程。

    1. 服务器上的新查询窗口
    2. 选择正确的数据库
    3. 执行sp_adjustpublisheridentityrange @table_name ='node_attrib_rslt'
    4. 从订阅者强制同步服务器。

      1. 在订阅服务器上,展开复制 - &gt;本地订阅
      2. 右键单击特定订阅,然后选择“查看订阅状态”。
      3. 在出现的对话框中,按下显示器按钮。
      4. 在出现的“复制监视器”窗口中,展开左侧窗格中的特定发布服务器。
      5. 点击要编辑的订阅。
      6. 在右侧窗格中,右键单击订阅状态,然后选择“开始同步”。
      7. 当状态发生时,状态应更新为“正在同步”。
      8. 完成后,单击“警告和代理”选项卡。我在下方窗格中列出了“快照代理”。右键单击该代理并启动它。运行一段时间后,服务器上的属性更改应该已迁移到客户端。
      9. 可能:在表格中插入一些测试行。

        编辑:我最近不得不再次执行此任务,并且在我将一堆虚拟数据插入表中以消耗默认约束之前,对表的约束不会更新。然后我重新同步了服务器,并将约束更新为新值。

        之后,检查身份约束显示我最终有一个20K ID范围要在Publisher和Subcriber上插入。

答案 1 :(得分:2)

我有同样的问题,上面的解决方案对我没有任何帮助。 相反,最终解决问题的方法是在发布中的表上设置新的更大的标识范围,然后在表上删除标识约束 最后运行此命令设置当前标识。

DBCC CHECKIDENT ('TableName', RESEED, 1000000000);

不再将值设置为1000000000,而是再次创建约束,并将其设置为当前在发布中的表上指定的正确标识范围值。 看起来CHECKIDENT命令强制以某种方式更新约束。

上述解决方案对我有用,但实际上我只是尝试放弃约束并设置发布者和订阅者使用不同的标识范围,以便他们能够在表中插入行。幸运的是,CHECKIDENT似乎刷新了约束,这是我最初期望sp_adjustpublisheridentityrange存储过程要做的事情 - 除了它什么也没做。

我在发布者和订阅者上运行了上述命令。