目录

第一步:数据库完整性检查

第二步:尝试检查修复数据库表

第三步:创建备份数据表

第四步:创建触发器

第五步:删除主键

第六步:删除重复主键元组

第七步: 查询删除数据情况

第八步:再次执行第二步,验证

第九步:数据导回

第十步:删除备份数据表

注意事项:在删除和插入数据时,保证系统没有触发器或关联表等情况的


 


第一步:数据库完整性检查

检查数据库完整性性,根据提示可以确认是那个数据表损坏,SQL脚本如下:

dbcc checkdb('数据库名称')

第二步:尝试检查修复数据库表

根据第一步检查结果确认修复数据库表,SQL脚本如下:

use '数据库名称'
declare @dbname varchar(255) 
set @dbname='数据库名称' 
exec sp_dboption @dbname,'single user','true' 
dbcc checktable('待修数据表',REPAIR_ALLOW_DATA_LOSS) 
dbcc checktable('待修数据表',REPAIR_REBUILD) 
exec sp_dboption @dbname,'single user','false'

如果第二步后仍存在主键重复的问题,执行以下步骤

第三步:创建备份数据表

为待修数据表创建备份表,SQL脚本如下:

USE '数据库名称'
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].['备份表名称'](
--。。。。。。。。。。
	--与待修表字段完全一致,为避免主键重复,备份表不要建立主键
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO

第四步:创建触发器

为待修数据库创建出发器,使得在删除重复主键的元组时,能够备份到备份表中,SQL脚本如下:

USE '数据库名称'
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].['触发器名称'] ON [dbo].['待修数据表'] FOR Delete
AS
BEGIN  
    INSERT INTO '备份数据表' select * from deleted
END
GO

第五步:删除主键

删除待修数据表,为下一步删除重复主键元组做准备

ALTER TABLE '待修数据表' DROP PRIMARY KEY

第六步:删除重复主键元组

/*假设待修数据表为test
待修数据表主键字段包含
{
 a1  varchar(25)
 a2  Datetime
 a3  int
 a4  char(8)
}
*/
declare cur_test CURSOR FOR
select a1,a2,a3,a4 from test 
	group by a1,a2,a3,a4
	having COUNT(*)>1 order by a1
OPEN cur_test
declare @ma1 varchar(25)
declare @ma2 Datetime
declare @ma3 int
declare @ma4 char(8)
fetch Next from cur_test into @ma1,@ma2,@ma3,@ma4
while @@FETCH_STATUS=0 
begin 
delete from test where a1=@ma1 and a2=@ma2 and a3=@ma3 and a4=@ma4
fetch Next from cur_test into @ma1,@ma2,@ma3,@ma4
end
close    cur_test
deallocate cur_test

第七步: 查询删除数据情况

Select * from '备份数据表'

第八步:再次执行第二步,验证

第九步:数据导回

根据具体情况,将备份表部分数据导入到修复好的数据表中

insert into '修复数据表' select distinct * from '备份数据表'

第十步:删除备份数据表

drop table '备份数据表'

注意事项:在删除和插入数据时,保证系统没有触发器或关联表等情况的