我正在尝试将几千行插入到跨两个服务器复制的数据库中的表中。无论是发布者还是订阅者,我都会遇到同样的错误:
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会成功执行但不起作用。
如何使用插入修复此问题? 如何在保持复制运行的同时将缩进范围约束的范围修改为更合理的级别?
答案 0 :(得分:23)
我想我找出了问题所在。
查看复制表的属性,它具有Publisher的标准默认标识范围10000和Subcriber的标准默认标识范围。
但是,检查实际表上的标识约束(使用SP_HELPCONSTRAINT'node_attrib_rslt')显示两个服务器上只有一个包含1000个ID的池。这使得批量插入失败,即使我限制了要插入的行数 - 我猜测SQL Server在运行INSERT INTO时检查约束时甚至没有那么远。
为了解决这个问题,我必须做几件事:
编辑:我最近不得不再次执行此任务,并且在我将一堆虚拟数据插入表中以消耗默认约束之前,对表的约束不会更新。然后我重新同步了服务器,并将约束更新为新值。
之后,检查身份约束显示我最终有一个20K ID范围要在Publisher和Subcriber上插入。
答案 1 :(得分:2)
我有同样的问题,上面的解决方案对我没有任何帮助。 相反,最终解决问题的方法是在发布中的表上设置新的更大的标识范围,然后在表上删除标识约束 最后运行此命令设置当前标识。
DBCC CHECKIDENT ('TableName', RESEED, 1000000000);
不再将值设置为1000000000,而是再次创建约束,并将其设置为当前在发布中的表上指定的正确标识范围值。 看起来CHECKIDENT命令强制以某种方式更新约束。
上述解决方案对我有用,但实际上我只是尝试放弃约束并设置发布者和订阅者使用不同的标识范围,以便他们能够在表中插入行。幸运的是,CHECKIDENT似乎刷新了约束,这是我最初期望sp_adjustpublisheridentityrange存储过程要做的事情 - 除了它什么也没做。
我在发布者和订阅者上运行了上述命令。