3

サーバーの1つをSQLServer2005からSQLServer2008に移行しています。このサーバーには、約50の小さなデータベースがあります。

私たちが取っている移行パスは次のとおりです。

  1. SQL2008で新しいサーバーを作成する
  2. 古いサーバーでSQLサービスをシャットダウンし、データベースを新しいサーバーにコピーします
  3. 古いサーバーをシャットダウンし、新しいサーバーの名前を古いサーバーと同じ名前に変更します。
  4. 50のデータベースを添付します

t-sqlを使用して50個のデータベースを新しいサーバーに接続する高速な方法はありますか?

すべてのデータファイルはE:\ DATAに配置され、トランザクションログはE:\TLOGに配置されます。

4

2 に答える 2

5

SQLCMDモードを使用すると、次のスクリプトを簡単に作成できます。

:setvar dbname YourDatabaseName
:setvar dbfile N'E:\DATA\YourDatabase.mdf'
:setvar logfile N'E:\TLOG\YourDatabase_log.ldf'
USE [master]
GO

CREATE DATABASE $(dbname) ON 
( FILENAME = $(dbfile) ),
( FILENAME = $(logfile) )
FOR ATTACH
GO

これsqlcmd.exeは、コマンドラインから機能するか(コマンドラインから変数の値を指定することもできdbname, dbfile, logfileます)、有効にした場合はSQL ServerManagementStudioで機能しますTools > Options > Query Execution > by default, open new queries in SQLCMD mode

SQLCMDユーティリティとそのすべてのパラメータの詳細については、MSDNを参照してください。

PS:もちろん、SQLCMDが有効なスクリプトを使用したこのアプローチは、バックアップ/復元サイクルでも機能します:-)(Aaronが推奨)

PPS:適切な命名規則があり、データファイルが常に$(dbname).mdfでログファイルが常に$(dbname)_log.ldfである場合は、次の短縮されたSQLCMDスクリプトを使用することもできます。

:setvar dbname YourDatabaseName
USE [master]
GO

CREATE DATABASE $(dbname) ON 
( FILENAME = N'E:\DATA\$(dbfile).mdf' ),
( FILENAME = N'E:\TLOG\$(logfile)_log.ldf' )
FOR ATTACH
GO

次に、コマンドラインからこれを呼び出します。

C:\>  sqlcmd.exe -S yourserver -E -i attach.sql -v dbname=YourDb1

など、データベースごとに1回、再接続する必要があります。

PPPS:バックアップを復元したい場合は、少し複雑です:

:setvar dbname YourDatabaseName
USE [master]
GO

RESTORE DATABASE $(dbname)
FROM DISK = N'E:\Backup\$(dbname).bak' 
WITH FILE = 1,  
MOVE N'$(dbname)' TO N'E:\DATA\$(dbname).mdf',  
MOVE N'$(dbname)_Log' TO N'E:\TLOG\$(dbname)_Log.ldf',  
NOUNLOAD, REPLACE
GO

これは、.bakファイルにデータベース名と同じ名前を付け、それらを固定の場所に配置する限り機能します(私はE:\Backupここで推測しました-必要に応じて適応します)。

于 2012-05-31T14:07:32.393 に答える
2

私のコメントを繰り返すために、デタッチ/アタッチのアプローチではなく、バックアップ/復元のアプローチを提案します(私の理由はここここに概説されています)。

@marc_sのSQLCMDアプローチは気に入っていますが、メタデータから直接このようなものを取得することを好みます。このようにして、すべての出力を検査し、実行したい部分を一度にではなくバッチでコピーして貼り付けることができます。

SET NOCOUNT ON;
DECLARE @folder nvarchar(512) = N'\\fileshare\folder\'; -- 'backup location

SELECT N'BACKUP DATABASE ' + QUOTENAME(name) 
  + N' TO DISK = N''' + @folder + name + N'.BAK'' WITH INIT;
  ALTER DATABASE ' + QUOTENAME(name) + N' SET OFFLINE;'
FROM sys.databases 
WHERE database_id > 4 -- AND other filter criteria

SELECT N'RESTORE DATABASE ' + QUOTENAME(d.name) 
  + N' FROM DISK = N''' + @folder + d.name + N'.BAK'' WITH ' 
  + STUFF(
    (SELECT N', 
      MOVE N''' + f.name + N''' TO ''E:\DATA\' + f.name + '.mdf''' 
      FROM master.sys.master_files AS f 
      WHERE f.database_id = d.database_id 
      AND type_desc = N'ROWS'
      FOR XML PATH(''), 
      TYPE).value(N'./text()[1]', N'nvarchar(max)'), 1, 1, N'') 
  + N', ' + STUFF(
    (SELECT N',
      MOVE N''' + f.name + N''' TO N''E:\TLOG\' + f.name + N'.mdf'''
      FROM master.sys.master_files AS f 
      WHERE f.database_id = d.database_id 
      AND type_desc = 'LOG'
      FOR XML PATH(''), 
      TYPE).value(N'./text()[1]', N'nvarchar(max)'), 1, 1, N'') + N';
  ALTER DATABASE ' + QUOTENAME(d.name) 
  + N' SET COMPATIBILITY_LEVEL = 100;'
FROM sys.databases AS d 
WHERE database_id > 4; -- AND other filter criteria

(これは、データ/ログファイルのみがあり、ファイルストリームなどがなく、両方のインスタンスにアクセスできる共通の場所にバックアップ/復元できることを前提としています。)

明確にするために、2005サーバーで両方のコマンドセットを生成し、そこでバックアップコマンドをコピーして実行し(そしておそらく直後にオフラインに設定し)、2008サーバーで復元コマンドをコピーして実行します。

また、キーテーブルの統計を更新することもできます。そうしないと、新しいサーバーのプランキャッシュが準備されるため、パフォーマンスが低下したときに深刻な問題が発生する可能性があります...

于 2012-05-31T14:46:33.120 に答える