サーバー上のすべてのデータベースの復旧モデルを変更するためのプログラム可能な方法が特に必要です。このソリューションはすべての「データベースの変更」コマンドに適用できることを知っています。 PowerShellのSMOがこの問題を非常に簡単に解決できることは知っていますが、
Import-Module SQLPS
CD SQL\*ServerName*\*InstanceName*\databases
foreach ($database in (ls -force)){
$database.recoverymodel = 'Full'
$database.update
}
最も効率的なT-SQLソリューションを探しています。カーソルをすべてのコストで回避するために頭の中に根付いていますが、alterステートメントを実行するためのセットベースのソリューションは考えられません。これがカーソルベースのソリューションです。
DECLARE @sql varchar(MAX), @name varchar(50)
DECLARE cur CURSOR FOR
SELECT name
FROM sys.databases
where name <> 'tempdb';
OPEN cur
FETCH NEXT FROM cur
INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = 'ALTER DATABASE ' + @name + ' SET RECOVERY FULL;'
exec(@sql)
FETCH NEXT FROM cur INTO @name
END
CLOSE CUR
DEALLOCATE cur
ループがこのタイプのことを行う限り、心配する必要はありません。ループとカーソルは、通常はより高速なセットベースのアプローチがよくあるため、評判が悪い。管理関連の場合、ループが唯一の方法である場合があり、この春を念頭に置くセットベースの方法はありませんが、DOS、SSIS、Powershellなどのツールでタスクを並列化できます。
そうは言っても、私はこのタイプのものに [〜#〜] sqlcmd [〜#〜] モードを使用することを好みます。これは、SQL Server Management Studio(SSMS)でメインメニュー> [クエリ]> [SQLCMDモード]を使用して、次のように切り替えることができる特別なモードです。
このモードをオンにすると、別のサーバーに接続する:connect
、ファイルを読み取る:r
、出力をリダイレクトする:out
、SQLCMD変数など、あらゆる種類のコマンドにアクセスできます。 DOSコマンドの前に2つの感嘆符を付けることで、たとえば!!dir
のようにします。
あなたの例では、次のようなことをすることができます:
:connect .\sql2014
SET NOCOUNT ON
GO
-- Redirect output back to normal
:out d:\temp\temp.sql
GO
SELECT 'ALTER DATABASE ' + name + ' SET RECOVERY FULL;'
FROM sys.databases
WHERE recovery_model_desc != 'FULL'
AND database_id > 4
AND name Not In ( 'distribution', 'SSISDB' )
GO
PRINT 'GO'
GO
-- Redirect output back to normal
:out STDOUT
-- Optionally read/run the temp file you have scripted
--:r d:\temp\temp.sql
GO
これにより、「スクリプトをスクリプト化」して、それを確認し、必要に応じて変更することができ、実行された内容の監査証跡があります。 SQLCMDモードをお試しください!
ループ構造を必要としない1つの方法を次に示します。
DECLARE @sql nvarchar(MAX) = N'';
SELECT
@sql += N'ALTER DATABASE '
+ QUOTENAME(name)
+ N' SET RECOVERY FULL;
'
FROM sys.databases
WHERE database_id > 4
AND name NOT IN ( N'distribution', N'SSISDB' );
PRINT @sql;
--EXEC(@sql);
WBobの answer に同意します。これは、頻繁に実行されない管理スクリプトのパフォーマンスに過度に関与する必要がないという点です。
上記の文字列連結メソッドが this Connect item に従って複数の行に影響を与えるステートメントに対して期待される結果を常に生成することは保証されていません。動作はプランに依存するためです。
カーソル以外のメソッドには、CLRとXMLがあります。以下はXMLメソッドの例です。これは重要な計画に対してより信頼性が高く、ORDER BY
が必要です。
DECLARE @sql varchar(MAX) = N'';
SET @sql = (
SELECT N'ALTER DATABASE '
+ QUOTENAME(name)
+ N' SET RECOVERY FULL;
'
FROM sys.databases
WHERE
database_id > 4
AND name NOT IN ( N'distribution', N'SSISDB' )
FOR XML PATH(''), TYPE
).value('.', 'nvarchar(MAX)');
PRINT @sql;
--EXEC(@sql);