SQL Server 2017中能否恢复表中已删除索引?查询及重建均报错
SQL Server 2017索引误删后的严重错误修复与索引恢复方案
先解决“严重错误”问题
你重建索引时也触发相同错误,说明表本身可能存在数据页损坏或结构异常,必须先修复这个问题,才能处理索引恢复:
检查数据库完整性
运行以下命令扫描目标数据库,定位损坏点:DBCC CHECKDB('你的数据库名称') WITH NO_INFOMSGS, ALL_ERRORMSGS;命令会返回所有损坏对象、错误代码及说明。
修复数据库损坏
- 若检查结果显示为轻度损坏,执行带
REPAIR_REBUILD的命令(无数据丢失风险):DBCC CHECKDB('你的数据库名称', REPAIR_REBUILD); - 若为严重损坏,需使用
REPAIR_ALLOW_DATA_LOSS(会丢失部分数据,必须先备份数据库):DBCC CHECKDB('你的数据库名称', REPAIR_ALLOW_DATA_LOSS);
修复完成后,再次尝试查询或重建索引,确认错误是否消除。
- 若检查结果显示为轻度损坏,执行带
恢复误删的索引
表损坏修复后,可通过以下方式恢复索引:
1. 从备份提取索引脚本
如果有索引删除前的数据库完整备份:
- 新建临时数据库,还原该备份
- 执行以下脚本,生成目标表的所有索引创建语句:
SELECT 'CREATE ' + CASE WHEN is_unique = 1 THEN 'UNIQUE ' ELSE '' END + ix.type_desc + ' INDEX ' + ix.name + ' ON ' + OBJECT_SCHEMA_NAME(ix.object_id) + '.' + OBJECT_NAME(ix.object_id) + ' (' + STUFF((SELECT ', ' + col.name + CASE WHEN ic.is_descending_key = 1 THEN ' DESC' ELSE '' END FROM sys.index_columns ic JOIN sys.columns col ON ic.object_id = col.object_id AND ic.column_id = col.column_id WHERE ic.object_id = ix.object_id AND ic.index_id = ix.index_id ORDER BY ic.key_ordinal FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + ')' + CASE WHEN ix.has_filter = 1 THEN ' WHERE ' + ix.filter_definition ELSE '' END FROM sys.indexes ix WHERE ix.object_id = OBJECT_ID('你的架构名.你的表名') AND ix.type <> 0; -- 排除堆索引(聚集索引删除后表变为堆) - 将生成的脚本在生产数据库中执行,重建所有误删索引。
2. 事务日志时间点恢复(仅适用于完整恢复模式)
如果数据库采用完整恢复模式,且有连续的日志备份:
- 先备份当前数据库的尾日志:
BACKUP LOG '你的数据库名称' TO DISK = 'D:\Backup\你的数据库名_尾日志.bak' WITH NORECOVERY; - 还原最近的完整备份到临时库(保持NORECOVERY状态):
RESTORE DATABASE '你的数据库名_临时' FROM DISK = 'D:\Backup\你的数据库名_完整备份.bak' WITH NORECOVERY, REPLACE; - 依次还原后续的差异备份(如果有)和日志备份,最后还原尾日志并指定索引删除前的时间点:
RESTORE LOG '你的数据库名_临时' FROM DISK = 'D:\Backup\你的数据库名_日志备份1.bak' WITH NORECOVERY; RESTORE LOG '你的数据库名_临时' FROM DISK = 'D:\Backup\你的数据库名_尾日志.bak' WITH RECOVERY, STOPAT = '202X-XX-XX XX:XX:XX'; -- 替换为索引删除前的准确时间 - 从临时库提取索引脚本,在生产库执行重建。
3. 手动重建索引
如果明确记得索引的结构(字段、排序方式、是否唯一等),直接写CREATE INDEX语句重建:
-- 示例:创建非聚集索引 CREATE NONCLUSTERED INDEX IX_订单表_客户ID ON dbo.订单表 (客户ID ASC); -- 示例:创建唯一聚集索引(如果原聚集索引被删除) CREATE UNIQUE CLUSTERED INDEX PK_订单表_订单ID ON dbo.订单表 (订单ID ASC);
内容的提问来源于stack exchange,提问作者Alfredo_Medina15
相关产品推荐
相关产品推荐

