0

我需要每周缩小每个数据库的日志文件。我正在编写一个while循环查询来循环每个数据库。但我认为不允许执行以下操作:

declare @database_id int
declare @database varchar(255)
declare @log varchar(255)
declare @cmd varchar(500)

while (select count(*) from #LogFiles where processed = 0) > 0
begin 

    set @database_id = (select min(database_id) from #LogFiles where processed = 0)
    set @database = (select name from #LogFiles where database_id = @database_id and [type] = 0)
    set @log = (select name from #LogFiles where database_id = @database_id and [type] = 1)

    select @database, @log

        set @cmd = 'Use ' + @Database
        exec(@cmd)

    set @cmd = 'DBCC SHRINKFILE (' + @log + ');'

    exec(@cmd)

    update #LogFiles 
    set processed = 1
    where database_id = @database_id

end

还是有其他方法可以做到这一点?

谢谢

4

1 回答 1

5

正如多条评论中提到的,这真的,真的,真的不是一个好主意。缩小这些文件只是为了让它们在下周再次增长是浪费精力,而且由于日志文件自动增长事件不能利用即时文件初始化(因为,与数据文件分配不同,日志文件分配在使用前必须清零) ,这确实会以您无法预测或控制的方式影响最终用户的性能。

也就是说,放弃#temp 表和游标while 循环。从技术上讲,这仍然使用循环来连接,但设置和查看要容易得多。

DECLARE @sql NVARCHAR(MAX); SET @sql = N'';

SELECT @sql = @sql + N'
  USE ' + QUOTENAME(db) + ';
  PRINT DB_NAME();
  CHECKPOINT; -- since we now know it is simple recovery
  DBCC SHRINKFILE(' + QUOTENAME(f) + ') WITH NO_INFOMSGS;'
FROM
(
  SELECT DB_NAME(database_id), name
   FROM sys.master_files
   WHERE database_id > 4 AND [type] = 1
   -- AND LOWER(name) NOT IN (N'reportserver', N'reportservertempdb')
) AS x(db, f);

PRINT @sql;
--EXEC sp_executesql @sql;

检查PRINT输出。当你满意它会按照你的想法去做时,取消注释EXEC并再次运行它。

于 2013-07-31T23:00:29.177 回答