sql server 系统表sysobjects、sysindexes、syscolumns损坏修复方法
第一步: 处理可以访问的数据表 (1.1) 找出哪些表不可访问; 新建立一个sql svr数据库,数据库实体名为AisNew。进入查询分析器,执行如下SQL: –**************************************************** use AIS20030529181217 DECLARE @TbName VARCHAR(80) DECLARE FindErrTable SCROLL CURSOR FOR select name from AisNew.dbo. sysobjects where xtype=‘u’ order by name OPEN FindErrTable FETCH FindErrTable INTO @TbName WHILE @@FETCH_STATUS<>-1 BEGIN print @TbName exec( ‘select top 1 * from’ + @TbName) FETCH FindErrTable INTO @TbName END PRINT ‘Scan Complate…’ CLOSE FindErrTable DEALLOCATE FindErrTable –**************************************************** 执行此SQL给出的报告的最后几行为: … T_voucher 服务器: 消息 644,级别 21,状态 3,行 1 未能在索引页 (1:29262) 中找到 RID ‘161dd201a100′ 的索引条目(索引 ID 0,数据库 ‘AIS20030529181217′)。 连接中断
根据以上报告可以知道 T_voucher 表在sysobjects表中的对应记录出错,造成T_voucher不能访问。修改上面的SQL:在声明游标的记录集中屏蔽T_voucher 表。即: … DECLARE FindErrTable SCROLL CURSOR FOR select name from AisNew.dbo. sysobjects where xtype=‘u’ and name != ‘t_voucher’ order by name … 修改完毕,继续执行此SQL。如此反复,就能够不断报告出sysobjects中那些表不能访问。 (1.2) 导 库 用SQL DTS工具将AIS20030529181217中可以访问的数据表导入AisNew。 第二步:处理不可访问的数据表: (2.1) 找出系统表中错误记录的ID –获得AIS20030529181217中T_voucher表在sysobjects中的ID : SELECT id FROM AIS20030529181217.dbo.sysobjects WHERE name=‘ t_voucher’ ==》123 ( 说明:通常即使sysobjects表损坏,不能做 select * from sysobjects 查询,但是可以做 select ID,name from sysobjects 查询。如果select ID,name from sysobjects 查询也不能执行,可以对照AisNew和AIS20030529181217两个数据库中的同名表: syscolumns。根据AisNew.dbo.syscolumns表中T_voucher所占字段的个数以及各个字段的名称,在AIS20030529181217.dbo.syscolumns中找出T_voucher所对应的记录,由此获得T_voucher在AIS20030529181217数据库的系统表中所分配的ID。)
–获得AisNew中T_voucher表在sysobjects中的ID : SELECT id FROM AisNew.dbo.sysobjects WHERE name=‘ t_voucher’ ==》456
(2.2) 删除AIS20030529181217中系统表中错误记录: DELETE AIS20030529181217.dbo.sysobjects WHERE id=123 DELETE AIS20030529181217.dbo.sysindexes WHERE id=123 DELETE AIS20030529181217.dbo.syscolumns WHERE id=123
(2.3) 重建系统表记录 –重建AIS20030529181217.dbo.sysobjects表中T_voucher表对应的记录: INSERT INTO AIS20030529181217.dbo.sysobjects (name,id,xtype,uid,info,status,base_schema_ver,replinfo,parent_obj,crdate,ftcatid) SELECT ‘t_voucher_b’,123,xtype,uid,info,status,base_schema_ver,replinfo,parent_obj,crdate,ftcatid FROM AisNew.dbo. sysobjects WHERE id=456
–重建AIS20030529181217.dbo.sysindexes表中t_voucher表对应的记录: INSERT INTO AIS20030529181217.dbo.sysindexes (id,status,first,indid,root,minlen,keycnt,groupid,dpages,reserved,used,rowcnt,rowmodctr,reserved3,reserved4,xmaxlen,maxirow,OrigFillFactor,StatVersion,reserved2,FirstIAM,impid,lockflags,pgmodctr,keys,name,statblob) SELECT 123,status,first,indid,root,minlen,keycnt,groupid,dpages,reserved,used,rowcnt,rowmodctr,reserved3,reserved4,xmaxlen,maxirow,OrigFillFactor,StatVersion,reserved2,FirstIAM,impid,lockflags,pgmodctr,keys,name,statblob FROM AisNew.dbo.sysindexes WHERE id=456
–重建AIS20030529181217.dbo.syscolumns表中t_voucher表对应的记录: INSERT INTO AIS20030529181217.dbo.syscolumns (name,id,xtype,typestat,xusertype,length,xprec,xscale,colid,xoffset,bitpos,reserved,colstat,cdefault,domain,number,colorderby,autoval,offset,collationid,language) SELECT name,123,xtype,typestat,xusertype,length,xprec,xscale,colid,xoffset,bitpos,reserved,colstat,cdefault,domain,number,colORDERBY,autoval,offset,collationid,language FROM AisNew.dbo.syscolumns WHERE id=456
(2.4)用DTS单独将t_voucher_b表导入新的DataBase 经过以上操作,AIS20030529181217中t_voucher_b 表与原t_voucher表共用同一ID。 试试看可否执行SELECT * FROM t_voucher_b 查询 - 如果可以,那么t_voucher_b就一定继承原t_voucher表中的全部数据。再用INSERT INTO AisNew.dbo.T_voucher FROM AIS20030529181217.dbo.t_voucher_b 或DTS 将t_voucher_b中的数据导入AisNew。 如果执行SELECT * FROM t_voucher_b 查询仍然报错,这张表彻底没戏了。 (2.5) 其他”不可访问的数据表”处理方式同上,重复(2.1)~(2.4) 步。
|