SQL数据库表坏了的手动恢复方法

      今天接到客户电话,说操作数据无法保存。经过分析,发现他的数据库已经有5G多的大小,而最终发现有张表的索引出错了,用DBCC CHECK也无力回天。

每次用select * from ln003082 语句查询,都报如下错误:

 

服务器: 消息 605,级别 21,状态 1,行 1
试图从数据库 'ln_fl0125' 中提取的逻辑页 (1:629904) 属于对象 '869578136',而非对象 'LN003082'。

连接中断

 

没办法,只能想办法恢复了。还好有几位老手在身边。于是通如以下步骤勉强恢复有效数据,当然,有部份单子数据是丢失了。只能叫客户再去补了。

 首先要确定哪些数据回不来了,通过游标来一一确定哪些数据无效了。

declare @bill_no varchar(20)
declare @shop_no varchar(20)
DECLARE  @QTY INT

DECLARE terminal_changecursor CURSOR FOR
   select bill_no,shop_no from terminal_change
   group by shop_no,bill_no
   ORDER by shop_no,bill_no


OPEN terminal_changecursor
FETCH NEXT FROM terminal_changecursor into  @bill_no ,@shop_no
WHILE @@FETCH_STATUS = 0
BEGIN
 FETCH NEXT FROM terminal_changecursor into  @bill_no ,@shop_no

 PRINT  @bill_no +'-'+@shop_no
 IF  NOT (
(@bill_no='MB10010033' AND @shop_no = 'P9ZT') OR  
(@bill_no='MT90910001' AND @shop_no = 'P9ZT') OR
(@bill_no='MT00110002' AND @shop_no = 'P10D') OR
(@bill_no='MB10010034' AND @shop_no = 'P9ZT') OR
(@bill_no='MB10010035' AND @shop_no = 'P9ZT') 
 

)
 select @QTY=sum(bill_qty) from LN003082 WHERE   bill_no=@bill_no AND  shop_no=@shop_no
ENDEND

DEALLOCATE terminal_changecursor
GO

 

通过上面的语句,可以查到哪些单号的数据出了问题。用IF跳过有问题的数据,当select sum通过游标查询时,如果有问题的数据,就会停下来中断,根据print出来的单号,将其加入下次IF中,这个步骤很枯燥。不过一般不会出现过多丢失的数据,也只能这样一一确定了。

 

接下来就是根据查询出来有问题的数据,进行过滤恢复了。

 

恢复方法脚本如下:

主要有3步。

--说明:终端变动数据表坏了,丢失五张数据,请通知重传


--1。重建表LN003082为LN003082_new,用于转移有效数据
select * into LN003082_new from LN003082 where 1=2
GO

 CREATE  INDEX [IX_TERMINAL_CHANGE_BILL_NO] ON [dbo].[LN003082_new]([BILL_NO], [SHOP_NO]) ON [PRIMARY]
GO

 CREATE  INDEX [R_TC_GOODS_FK] ON [dbo].[LN003082_new]([GOODS_NO]) ON [PRIMARY]
GO

 CREATE  INDEX [R_TC_SHOP_FK] ON [dbo].[LN003082_new]([SHOP_NO]) ON [PRIMARY]
GO

 CREATE  INDEX [IX_TERMINAL_CHANGE_VALID_DATE] ON [dbo].[LN003082_new]([VALID_DATE]) ON [PRIMARY]
GO

 CREATE  INDEX [IX_TERMINAL_CHANGE] ON [dbo].[LN003082_new]([ACC_VALID_DATE]) ON [PRIMARY]
GO

 CREATE  INDEX [IX_TERMINAL_CHANGE_INTER_BILLNO] ON [dbo].[LN003082_new]([INTER_BILLNO], [SHOP_NO]) ON [PRIMARY]
GO

--2。将有效数据导入LN003082_new

declare @bill_no varchar(20)
declare @shop_no varchar(20)
DECLARE  @QTY INT

DECLARE terminal_changecursor CURSOR FOR
   select bill_no,shop_no from terminal_change
   group by shop_no,bill_no
   ORDER by shop_no,bill_no


OPEN terminal_changecursor
FETCH NEXT FROM terminal_changecursor into  @bill_no ,@shop_no
WHILE @@FETCH_STATUS = 0
BEGIN
 FETCH NEXT FROM terminal_changecursor into  @bill_no ,@shop_no

 IF  NOT (
  (@bill_no='MB10010033' AND @shop_no = 'P9ZT') OR  
  (@bill_no='MT90910001' AND @shop_no = 'P9ZT') OR
  (@bill_no='MT00110002' AND @shop_no = 'P10D') OR
  (@bill_no='MB10010034' AND @shop_no = 'P9ZT') OR
  (@bill_no='MB10010035' AND @shop_no = 'P9ZT')
  )
  INSERT INTO LN003082_new SELECT * FROM LN003082 WHERE   bill_no=@bill_no AND  shop_no=@shop_no
END

DEALLOCATE terminal_changecursor
GO

--3。将转移好数据的表改名为LN003082
exec sp_rename  'LN003082','LN003082olderror'
exec sp_rename  'LN003082_new','LN003082'

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值