目录
第一步:数据库完整性检查
第二步:尝试检查修复数据库表
第三步:创建备份数据表
第四步:创建触发器
第五步:删除主键
第六步:删除重复主键元组
第七步: 查询删除数据情况
第八步:再次执行第二步,验证
第九步:数据导回
第十步:删除备份数据表
注意事项:在删除和插入数据时,保证系统没有触发器或关联表等情况的
第一步:数据库完整性检查
检查数据库完整性性,根据提示可以确认是那个数据表损坏,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 '备份数据表'