删除数据库中重复数据的几个方法
数据库的使用过程中由于程序方面的问题有时候会碰到重复数据重复数据导致了数据库部分设置不能正确设置……
方法一
declare @max integer@id integer
declare cur_rows cursor local for select 主字段count(*) from 表名 group by 主字段 having count(*) >
open cur_rows
fetch cur_rows into @id@max
while @@fetch_status=
begin
select @max = @max
set rowcount @max
delete from 表名 where 主字段 = @id
fetch cur_rows into @id@max
end
close cur_rows
set rowcount
方法二
有两个意义上的重复记录一是完全重复的记录也即所有字段均重复的记录二是部分关键字段重复的记录比如Name字段重复而其他字段不一定重复或都重复可以忽略
对于第一种重复比较容易解决使用
select distinct * from tableName
就可以得到无重复记录的结果集
如果该表需要删除重复的记录(重复记录保留条)可以按以下方法删除
select distinct * into #Tmp from tableName
drop table tableName
select * into tableName from #Tmp
drop table #Tmp
发生这种重复的原因是表设计不周产生的增加唯一索引列即可解决
这类重复问题通常要求保留重复记录中的第一条记录操作方法如下
假设有重复的字段为NameAddress要求得到这两个字段唯一的结果集
select identity(int) as autoID * into #Tmp from tableName
select min(autoID) as autoID into #Tmp from #Tmp group by NameautoID
select * from #Tmp where autoID in(select autoID from #tmp)
最后一个select即得到了NameAddress不重复的结果集(但多了一个autoID字段实际写时可以写在select子句中省去此列)
更改数据库中表的所属用户的两个方法
大家可能会经常碰到一个数据库备份还原到另外一台机器结果导致所有的表都不能打开了原因是建表的时候采用了当时的数据库用户……
更改某个表
exec sp_changeobjectowner tablenamedbo
存储更改全部表
CREATE PROCEDURE dboUser_ChangeObjectOwnerBatch
@OldOwner as NVARCHAR()
@NewOwner as NVARCHAR()
AS
DECLARE @Name as NVARCHAR()
DECLARE @Owneras NVARCHAR()
DECLARE @OwnerNameas NVARCHAR()
DECLARE curObject CURSOR FOR
select Name = name
Owner = user_name(uid)
from sysobjects
where user_name(uid)=@OldOwner
order by name
OPENcurObject
FETCH NEXT FROM curObject INTO @Name @Owner
WHILE(@@FETCH_STATUS=)
BEGIN
if @Owner=@OldOwner
begin
set @OwnerName = @OldOwner + + rtrim(@Name)
exec sp_changeobjectowner @OwnerName @NewOwner
end
select @name@NewOwner@OldOwner
FETCH NEXT FROM curObject INTO @Name @Owner
END
close curObject
deallocate curObject
GO
SQL SERVER中直接循环写入数据
没什么好说的了大家自己看有时候有点用处
declare @i int
set @i=
while @i<
begin
insert into test (userid) values(@i)
set @i=@i+
end
无数据库日志文件恢复数据库方法两则
数据库日志文件的误删或别的原因引起数据库日志的损坏
方法一
新建一个同名的数据库
再停掉sql server(注意不要分离数据库)
用原数据库的数据文件覆盖掉这个新建的数据库
再重启sql server
此时打开企业管理器时会出现置疑先不管执行下面的语句(注意修改其中的数据库名)
完成后一般就可以访问数据库中的数据了这时数据库本身一般还要问题解决办法是利用
数据库的脚本创建一个新的数据库并将数据导进去就行了
USE MASTER
GO
SP_CONFIGURE ALLOW UPDATES RECONFIGURE WITH OVERRIDE
GO
UPDATE SYSDATABASES SET STATUS = WHERE NAME=置疑的数据库名
Go
sp_dboption 置疑的数据库名 single user true
Go
DBCC CHECKDB(置疑的数据库名)
Go
update sysdatabases set status = where name=置疑的数据库名
Go
sp_configure allow updates reconfigure with override
Go
sp_dboption 置疑的数据库名 single user false
方法二
事情的起因
昨天系统管理员告诉我我们一个内部应用数据库所在的磁盘空间不足了我注意到数据库事件日志文件XXX_Dataldf文件已经增长到了GB于是我决意缩小这个日志文件经过收缩数据库等操作未果后我犯了一个自进入行业以来的最大最愚蠢的错误竟然误删除了这个日志文件!后来我看到所有论及数据库恢复的文章上都说道无论如何都要保证数据库日志文件存在它至关重要甚至微软甚至有一篇KB文章讲如何只靠日志文件恢复数据库的我真是不知道我那时候是怎么想的?!
这下子坏了!这个数据库连不上了企业管理器在它的旁边写着(置疑)而且最要命的这个数据库从来没有备份了我唯一找得到的是迁移半年前的另外一个数据库服务器应用倒是能用了但是少了许多记录表和存储过程真希望这只是一场噩梦!
没有效果的恢复步骤
附加数据库
_Rambo讲过被删除日志文件中不存在活动日志时可以这么做来恢复
分离被置疑的数据库可以使用sp_detach_db
附加数据库可以使用sp_attach_single_file_db
但是很遗憾执行之后SQL Server质疑数据文件和日志文件不符所以无法附加数据库数据文件
DTS数据导出
不行无法读取XXX数据库DTS Wizard报告说初始化上下文发生错误
紧急模式
怡红公子讲过没有日志用于恢复时可以这么做
把数据库设置为emergency mode
重新建立一个log文件
把SQL Server 重新启动一下
把应用数据库设置成单用户模式
做DBCC CHECKDB
如果没有什么大问题就可以把数据库状态改回去了记得别忘了把系统表的修改选项关掉
我实践了一下把应用数据库的数据文件移走重新建立一个同名的数据库XXX然后停掉SQL服务把原来的数据文件再覆盖回来之后按照怡红公子的步骤走
但是也很遗憾除了第步之外其他步骤执行非常成功可惜重启SQL Server之后这个应用数据库仍然是置疑!
不过让我欣慰的是这么做之后倒是能够Select数据了让我大出一口气只不过组件使用数据库时报告说发生错误未能在数据库 XXX 中运行 BEGIN TRANSACTION因为该数据库处于回避恢复模式
最终成功恢复的全部步骤
设置数据库为紧急模式
停掉SQL Server服务
把应用数据库的数据文件XXX_Datamdf移走
重新建立一个同名的数据库XXX
停掉SQL服务
把原来的数据文件再覆盖回来
运行以下语句把该数据库设置为紧急模式
运行Use Master
Go
sp_configure allow updates
reconfigure with override
Go
执行结果
DBCC 执行完毕如果 DBCC 输出了错误信息请与系统管理员联系
已将配置选项 allow updates 从 改为 请运行 RECONFIGURE 语句以安装
接着运行update sysdatabases set status = where name = XXX
执行结果
(所影响的行数为 行)
重启SQL Server服务
运行以下语句把应用数据库设置为Single User模式
运行sp_dboption XXX single user true
执行结果
命令已成功完成
ü 做DBCC CHECKDB
运行DBCC CHECKDB(XXX)
执行结果
XXX 的 DBCC 结果
sysobjects 的 DBCC 结果
对象 sysobjects 有 行这些行位于 页中
sysindexes 的 DBCC 结果
对象 sysindexes 有 行这些行位于 页中
syscolumns 的 DBCC 结果
………