数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

SQL Server实用经验技巧集(2)


发布日期:2023年03月14日
 
SQL Server实用经验技巧集(2)

删除数据库中重复数据的几个方法

数据库的使用过程中由于程序方面的问题有时候会碰到重复数据重复数据导致了数据库部分设置不能正确设置……

方法一

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 结果

………

上一篇:如何使SQL Server的日志文件不会增大

下一篇:有效帮助保护 SQL Server 2000 的十个步骤