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 に答える