一键帮你收缩所有DB文件大小(Shrink Files for All Databases in SQL Server)

栏目: 数据库 · SQL Server · 发布时间: 7年前

内容简介:一键帮你收缩所有DB文件大小(Shrink Files for All Databases in SQL Server)

本文介绍一个简单的 SQL 脚本,实现收缩整个Microsoft SQL Server实例所有非系统DB文件大小的功能。

作为一个与SQL天天打交道的程序猿,经常会遇到DB文件太大,把空间占满的情况:

一键帮你收缩所有DB文件大小(Shrink Files for All Databases in SQL Server)

而对于开发测试人员来说,如果DB数据不是特别重要的话,不会特意扩大磁盘空间,而是直接利用SQL的Shrink File功能缩小DB文件大小,详见: https://docs.microsoft.com/en-us/sql/relational-databases/databases/shrink-a-file

这里介绍一个脚本,支持一键收缩整个SQL Server实例上所有非系统DB文件大小。

脚本支持功能和相关逻辑如下:

  • 五个系统DB(master、model、msdb、tempdb、Resource)不会执行Shrink File操作;
  • 如果DB的Recovery Model是FULL或者BULK_LOGGED,会自动改成SIMPLE,Shrink File操作后再改回原来的;
  • 只会对DB状态为ONLINE的DB进行Shrink File操作;
  • DB的所有文件,包括数据文件和日志文件都会被执行收缩操作(Shrink Database Data Files & Shrink Database Log Files);
  • 执行SQL脚本的用户需要有sysadmin或者相关数据库的DBO权限。

脚本如下:

-- Created by Bob from http://www.cnblogs.com/lavender000/

use master

DECLARE dbCursor CURSOR for select name from [master].[sys].[databases] where state = 0 and is_in_standby = 0;

DECLARE @dbname NVARCHAR(255)

DECLARE @recoveryModel NVARCHAR(255)

DECLARE @tempTSQL NVARCHAR(255)

DECLARE @dbFilesCursor CURSOR

DECLARE @dbFile NVARCHAR(255)

DECLARE @flag BIT

OPEN dbCursor

FETCH NEXT FROM dbCursor INTO @dbname

WHILE @@FETCH_STATUS = 0

BEGIN

if((@dbname <> 'master') and (@dbname <> 'model') and (@dbname <> 'msdb') and (@dbname <> 'tempdb') and (@dbname <> 'Resource'))

begin

print('')

print('Database [' + @dbname + '] will be shrinked log...')

SET @flag = 1

SET @recoveryModel = (SELECT recovery_model_desc FROM sys.databases WHERE name = @dbname)

if((@recoveryModel = 'FULL') or (@recoveryModel = 'BULK_LOGGED'))

begin

SET @tempTSQL = (select CONCAT('ALTER DATABASE [', @dbname, '] SET RECOVERY SIMPLE with no_wait'))

EXEC sp_executesql @tempTSQL

if (@@ERROR = 0)

begin

print('    Database [' + @dbname + '] recovery model has been changed to ''SIMPLE''.')

SET @flag = 1

end

else

begin

print('Database [' + @dbname + '] recovery model failed to be changed to ''SIMPLE''.')

SET @flag = 0

end

end

if(@flag = 1)

begin

SET @tempTSQL = (select CONCAT('use [', @dbname, ']'))

EXEC sp_executesql @tempTSQL           

SET @dbFilesCursor = CURSOR for select sys.master_files.name from sys.master_files, [master].[sys].[databases] where databases.name = @dbname and databases.database_id = sys.master_files.database_id

open @dbFilesCursor

FETCH NEXT FROM @dbFilesCursor INTO @dbFile

WHILE @@FETCH_STATUS = 0

BEGIN

SET @tempTSQL = (select CONCAT('use [', @dbname, '] DBCC SHRINKFILE (N''', @dbFile, ''') with NO_INFOMSGS'))

EXEC sp_executesql @tempTSQL

if(@@ERROR = 0)    print('        Database file [' + @dbFile + '] has been shrinked log successfully.')

FETCH NEXT FROM @dbFilesCursor INTO @dbFile

END

CLOSE @dbFilesCursor

DEALLOCATE @dbFilesCursor

if(@recoveryModel <> 'SIMPLE')

begin

-- Finally changed back

SET @tempTSQL = (select CONCAT('ALTER DATABASE [', @dbname, '] SET RECOVERY ', @recoveryModel, ' with no_wait'))

EXEC sp_executesql @tempTSQL

if (@@ERROR = 0)

begin

print('    Database [' + @dbname + '] recovery model has been changed back to ''' + @recoveryModel + '''')

end

else

begin

print('    Database [' + @dbname + '] recovery model failed to be changed back to ''' + @recoveryModel + '''')

end

end

end

end

FETCH NEXT FROM dbCursor INTO @dbname

END

CLOSE dbCursor

DEALLOCATE dbCursor

执行完效果如下:

一键帮你收缩所有DB文件大小(Shrink Files for All Databases in SQL Server)

一键帮你收缩所有DB文件大小(Shrink Files for All Databases in SQL Server)

Note:

  • 如果不放心使用,可提前备份相关数据库;
  • 使用前请仔细阅读脚本支持功能和相关逻辑,如与自己需求不符,请不要使用该脚本,或者请根据自己需求自行修改脚本;
  • 脚本为简易脚本,仅用于测试学习,可能有BUG ,不可生产环境使用,如有错误,请留言。

更新:该脚本在SQL Server 2008R2上执行可能会报如下错误:

'CONCAT' is not a recognized built-in function name.

由于脚本中使用了CONCAT函数,该函数是TSQL在SQL Server 2012中新引入的函数,具体详见: https://docs.microsoft.com/en-us/sql/t-sql/functions/concat-transact-sql

因此如果想在SQL Server 2012以下版本中使用的话需要把CONCAT函数改成string +方法,具体如下:

-- Created by Bob from http://www.cnblogs.com/lavender000/

use master

DECLARE dbCursor CURSOR for select name from [master].[sys].[databases] where state = 0 and is_in_standby = 0;

DECLARE @dbname NVARCHAR(255)

DECLARE @recoveryModel NVARCHAR(255)

DECLARE @tempTSQL NVARCHAR(255)

DECLARE @dbFilesCursor CURSOR

DECLARE @dbFile NVARCHAR(255)

DECLARE @flag BIT

OPEN dbCursor

FETCH NEXT FROM dbCursor INTO @dbname

WHILE @@FETCH_STATUS = 0

BEGIN

if((@dbname <> 'master') and (@dbname <> 'model') and (@dbname <> 'msdb') and (@dbname <> 'tempdb') and (@dbname <> 'Resource'))

begin

print('')

print('Database [' + @dbname + '] will be shrinked log...')

SET @flag = 1

SET @recoveryModel = (SELECT recovery_model_desc FROM sys.databases WHERE name = @dbname)

if((@recoveryModel = 'FULL') or (@recoveryModel = 'BULK_LOGGED'))

begin

SET @tempTSQL = ('ALTER DATABASE [' + @dbname + '] SET RECOVERY SIMPLE with no_wait')

EXEC sp_executesql @tempTSQL

if (@@ERROR = 0)

begin

print('    Database [' + @dbname + '] recovery model has been changed to ''SIMPLE''.')

SET @flag = 1

end

else

begin

print('Database [' + @dbname + '] recovery model failed to be changed to ''SIMPLE''.')

SET @flag = 0

end

end

if(@flag = 1)

begin

SET @tempTSQL = ('use [' + @dbname + ']')

EXEC sp_executesql @tempTSQL           

SET @dbFilesCursor = CURSOR for select sys.master_files.name from sys.master_files, [master].[sys].[databases] where databases.name = @dbname and databases.database_id = sys.master_files.database_id

open @dbFilesCursor

FETCH NEXT FROM @dbFilesCursor INTO @dbFile

WHILE @@FETCH_STATUS = 0

BEGIN

SET @tempTSQL = ('use [' + @dbname + '] DBCC SHRINKFILE (N''' + @dbFile + ''') with NO_INFOMSGS')

EXEC sp_executesql @tempTSQL

if(@@ERROR = 0)    print('        Database file [' + @dbFile + '] has been shrinked log successfully.')

FETCH NEXT FROM @dbFilesCursor INTO @dbFile

END

CLOSE @dbFilesCursor

DEALLOCATE @dbFilesCursor

if(@recoveryModel <> 'SIMPLE')

begin

-- Finally changed back

SET @tempTSQL = ('ALTER DATABASE [' + @dbname + '] SET RECOVERY ' + @recoveryModel + ' with no_wait')

EXEC sp_executesql @tempTSQL

if (@@ERROR = 0)

begin

print('    Database [' + @dbname + '] recovery model has been changed back to ''' + @recoveryModel + '''')

end

else

begin

print('    Database [' + @dbname + '] recovery model failed to be changed back to ''' + @recoveryModel + '''')

end

end

end

end

FETCH NEXT FROM dbCursor INTO @dbname

END

CLOSE dbCursor

DEALLOCATE dbCursor

给大家带来的不变深表歉意。

本文永久更新链接地址 http://www.linuxidc.com/Linux/2017-06/144839.htm


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Android群英传

Android群英传

徐宜生 / 电子工业出版社 / 2015-9 / 69.00元

《Android群英传》对具有一定Android开发基础的读者,以通俗易懂的语言介绍了Android开发的进阶技巧。《Android群英传》共分为13章,讲解了Android体系与系统架构、Android开发工具新接触、Android控件架构与自定义控件详解、ListView使用技巧、Android Scroll分析、Android绘图机制与处理技巧、Android动画机制与使用技巧、Activi......一起来看看 《Android群英传》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

随机密码生成器
随机密码生成器

多种字符组合密码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器