由于以下错误,我无法修复我的数据库,运行dbcc checkdb(DBNAME, REPAIR_ALLOW_DATA_LOSS)
时出现此处列出的错误。
当我为这些键值运行选择查询时,它只返回一行,但是当我运行时dbcc checkdb(DBNAME, REPAIR_ALLOW_DATA_LOSS)
会抛出这些错误:
消息 1505,级别 16,状态 1,第 2 行
CREATE UNIQUE INDEX 语句终止,因为找到了对象名称“dbo.MSmerge_contents”和索引名称“uc1SycContents”的重复键。重复的键值为 (7696031, 08703987-557d-e111-9888-e61f13c44f03)。
消息 1505,级别 16,状态 1,第 2 行
CREATE UNIQUE INDEX 语句终止,因为找到了对象名称“dbo.MSmerge_contents”和索引名称“nc2MSmerge_contents”的重复键。重复的键值为 (424222, 7696031, 08703987-557d-e111-9888-e61f13c44f03)。
消息 1505,级别 16,状态 1,第 2 行
CREATE UNIQUE INDEX 语句终止,因为找到了对象名称“dbo.MSmerge_contents”和索引名称“nc4MSmerge_contents”的重复键。重复的键值为 (08703987-557d-e111-9888-e61f13c44f03, 7696031)。
消息 1505,级别 16,状态 1,第 2 行
CREATE UNIQUE INDEX 语句终止,因为找到了对象名称“dbo.MSmerge_contents”和索引名称“nc3MSmerge_contents”的重复键。重复的键值为 (-425819, 7696031, bf8a5a9c-6f7d-e111-9888-e61f13c44f03)。
消息 2601,级别 14,状态 1,第 2
行无法在具有唯一索引“unc1MSmerge_genhistory”的对象“dbo.MSmerge_genhistory”中插入重复的键行。
消息 1505,级别 16,状态 1,第 2 行
CREATE UNIQUE INDEX 语句终止,因为找到了对象名称“dbo.MSmerge_genhistory”和索引名称“unc1MSmerge_genhistory”的重复键。重复的键值为 (236bfa48-965e-4a65-b4cd-ac527de04d1b, )。
如何修复我的数据库?
如果您考虑错误,消息 1505,级别 16,状态 1,第 2 行 CREATE UNIQUE INDEX 语句终止,因为发现对象名称“dbo.MSmerge_contents”和索引名称“uc1SycContents”存在重复键。重复的键值是 (7696031, 08703987-557d-e111-9888-e61f13c44f03)......我在查询下面运行
select * from msmerge_contents where rowguid='08703987-557d-e111-9888-e61f13c44f03'
,它只返回 1 行
当您遇到索引损坏问题(即键存在于 NC 索引中但不在基表中,反之亦然)时,您必须非常小心用于验证数据的 SQL。此时您的数据不一致,但查询优化器不知道这一点并完全信任您的架构,包括这些不正确的索引。因此,它可能会优化您的查询以使用缺少键的 NC 索引之一,并且结果也会错过一个键,错误地返回不重复项。为了解决这个 catch-22 情况,您需要通过显式请求索引或其他索引来强制优化器,并确保您强制执行的索引可以满足预计的列列表(即 no *
)。假设uc1SycContents
不是聚集索引,请尝试以下操作:
select rowguid
from msmerge_contents with INDEX (1)
where rowguid='08703987-557d-e111-9888-e61f13c44f03';
select rowguid
from msmerge_contents with INDEX ([uc1SycContents])
where rowguid='08703987-557d-e111-9888-e61f13c44f03';
Run Code Online (Sandbox Code Playgroud)
这将强制检查 rowguid 是否在基表聚集索引(索引 id 1)与索引中具有该 guid 的重复项uc1SycContents
。我期望第一个查询返回 2(或更多)行,而第二个查询返回 1。