SQL Server 2008 Expressの同じサーバーにSQL Serverデータベースを複製するにはどうすればよいですか?


272

(テスト目的で)「コピーして名前を変更」したいデータベースを含むMS SQL Server 2008 Expressシステムを持っていますが、これを実現する簡単な方法がわかりません。

SQL ServerのR2バージョンにはデータベースコピーウィザードがあることに気付きましたが、残念ながらアップグレードできません。

問題のデータベースはギグの周りにあります。新しいデータベースにコピーしたいデータベースのバックアップを復元しようとしましたが、うまくいきませんでした。


2
バックアップの復元は機能するはずです。それがどのように失敗したかについて詳細を教えていただけますか?
Ed Harper

7
バックアップから復元するときに間違いを犯したことに気付きました。最初に新しい空のDBを作成し、そこからバックアップを復元しようとしました。最初にデータベースを作成するのではなく、復元ダイアログを表示して、そこに新しいデータベースの名前を入力します。これを行うと、データベースが適切に複製されます。
Sergio

回答:


372
  1. Microsoft SQL Management Studioをインストールします。これは、MicrosoftのWebサイトから無料でダウンロードできます。

    バージョン2008

    Microsoft SQL Management Studio 2008は、 、高度なサービスを備えたSQL Server 2008 Expressの

    バージョン2012

    クリックしてダウンロードボタンやチェックをENU\x64\SQLManagementStudio_x64_ENU.exe

    バージョン2014

    クリックしてダウンロードボタンをとMgmtStudioをチェック64BIT\SQLManagementStudio_x64_ENU.exe

  2. Microsoft SQL Management Studioを開きます

  3. 元のデータベースを.BAKファイルにバックアップします(db->タスク->バックアップ)。
  4. 新しい名前(クローン)で空のデータベースを作成します。これはオプションであるため、以下のコメントに注意してください。
  5. クリックしてデータベースを複製し、復元ダイアログを開きます(画像を参照) 復元ダイアログ
  6. デバイスを選択し、ステップ3のバックアップファイルを追加します。 バックアップファイルを追加
  7. テストデータベースへの宛先の変更 目的地を変更
  8. データベースファイルの場所を変更します。元の場所とは異なる必要があります。テキストボックスに直接入力することができ、後置記号を追加するだけです。(注:順序は重要です。チェックボックスを選択して、ファイル名を変更してください。) 地域を変更
  9. WITH REPLACEおよびWITH KEEP_REPLICATIONを確認してください 置換あり

84
1.空のデータベースを作成して.bakファイルを復元しないでください。2. SQL Server Management Studioの[データベース]ブランチを右クリックしてアクセスできる[データベースの復元]オプションを使用し、復元するソースを提供しながらデータベース名を指定します。参照:stackoverflow.com/questions/10204480/…–
taynguyen

1
Microsoft SQL Management
Studio-

4
機能しません-「データベースが使用中のため、排他アクセスを取得できませんでした」。
エマヌエレチリアチ

5
また、「復元する前にログ末尾のバックアップを取る」のチェックを外す必要がありました。これはデフォルトでチェックされ、「データベースが使用中のため、排他アクセスを取得できませんでした」というエラーが発生しました。
カブ2018年

3
元のデータベースが「復元中」でスタックした
Divi perdomo

114

クローンを作成するデータベースを右クリックし、をクリックしてTasks、をクリックしますCopy Database...。ウィザードに従って、完了です。


悲しいことに、SQL ServerのR2リリースでのみ利用可能だと思います:-(
Sergio

7
それは急行でどのように動作するかここにある:stackoverflow.com/questions/4269450/...
のTh 00 MAの

2
データベースに暗号化されたオブジェクトがある場合、これは機能しません。
cjbarth 14年

1
要は、実際にどこでそれを行うかということでしょうか。あなたが説明したことはかなり直感的です。私は以前にいくつかのツール(0xDBE、Visual Studio SQL Server Object Explorer)でそれを正確に試しましたが、そのような機能はそこで見つかりませんでした。
David FerenczyRogožan2015年

3
ありえない!タスク->データベースをコピーするためのメニュー項目がない
レイザー

95

データベースをデタッチし、コマンドプロンプトでファイルを新しい名前にコピーしてから、両方のDBをアタッチすることができます。

SQLの場合:

USE master;
GO 
EXEC sp_detach_db
    @dbname = N'OriginalDB';
GO

コマンドプロンプトで(この例のためにファイルパスを簡略化しました):

copy c:\OriginalDB.mdf c:\NewDB.mdf
copy c:\OriginalDB.ldf c:\NewDB.ldf

再びSQLで:

USE master;
GO
CREATE DATABASE OriginalDB
    ON (FILENAME = 'C:\OriginalDB.mdf'),
       (FILENAME = 'C:\OriginalDB.ldf')
    FOR ATTACH;
GO
CREATE DATABASE NewDB
    ON (FILENAME = 'C:\NewDB.mdf'),
       (FILENAME = 'C:\NewDB.ldf')
    FOR ATTACH;
GO

1
パーフェクト!これは私のために働いたユニークなソリューションです!どうもありがとう!
thiagoh 2014年

9
select * from OriginalDB.sys.sysfilesDBのファイルの場所を検索します。
JohnLBevan 2014

ええ、特別なツールを必要としないので、私もこのソリューションが一番好きです。しかし、私はNEWDBを作成することができませんでした、それは言うPermission denied.mdfファイル。今は必要ありません。元のDBのバックアップが必要なだけなので、後で元のDBを上書きできるので、なぜこのようなエラーが発生するのか知りたいです。
David FerenczyRogožan2015年

2
sqlサービスを停止し、mdfファイルとldfファイルをコピーし、新しいデータベースの名前を変更し、sqlサービスを再起動して、masterで最後のcreate databaseコマンドを実行するだけで、元のデータベースをデタッチする必要はありません。USEmaster ; GO CREATE DATABASE NEWDB ON(FILENAME = 'C:\ NewDB.mdf')、(FILENAME = 'C:\ NewDB.ldf')FOR ATTACH; GO
danpop

1
最速の方法では+1。@JohnLBevanの優れたコメントに加えて、次も使用できますexec sp_helpdb @dbname='TEMPDB';
jean

30

バックアップから誤って復元しようとしたことがわかりました。

最初に新しいデータベースを作成してから、ここでバックアップを復元しようとしました。私がやるべきこと、そして最後に機能したことは、復元ダイアログを表示して、宛先フィールドに新しいデータベースの名前を入力することでした。

つまり、簡単に言うと、バックアップから復元することがうまくいきました。

みんなのフィードバックと提案をありがとう


これを行うと、ダイアログは、ファイルが最初にバックアップしたデータベースと同じ場所にあることを通知します。そのため、ファイルが上書きされることを恐れて、復元するための勇気がありません。
Niels Brinch

2
残念ながら、ファイルは、デフォルトでは、あなたが撮ったスナップショットと同じです。それらの名前を変更して、新しく名前を付けたデータベース用の新しいファイルを作成できます。
Colin Dabritz、2014年

PS:このメソッドにはSQLエージェントサービスが必要です。dbコピー操作を開始する前に、このサービスが実行されていることを確認してください。
dvdmn 14

あなたは今、この答えで私を3回助けました。作成するのではなく、入力することを忘れています。+ビール
Piotr Kula 2014年

これと、「ファイル」ウィンドウでの.mdfファイルと.logファイルの名前の変更は、私にとってはうまくいきました。
Wollan

17

これは私が使用するスクリプトです。少しトリッキーですが、うまくいきます。SQL Server 2012でテスト済み。

DECLARE @backupPath nvarchar(400);
DECLARE @sourceDb nvarchar(50);
DECLARE @sourceDb_log nvarchar(50);
DECLARE @destDb nvarchar(50);
DECLARE @destMdf nvarchar(100);
DECLARE @destLdf nvarchar(100);
DECLARE @sqlServerDbFolder nvarchar(100);

SET @sourceDb = 'db1'
SET @sourceDb_log = @sourceDb + '_log'
SET @backupPath = 'E:\tmp\' + sourceDb + '.bak' --ATTENTION: file must already exist and SQL Server must have access to it
SET @sqlServerDbFolder = 'E:\DB SQL\MSSQL11.MSSQLSERVER\MSSQL\DATA\'
SET @destDb = 'db2'
SET @destMdf = @sqlServerDbFolder + @destDb + '.mdf'
SET @destLdf = @sqlServerDbFolder + @destDb + '_log' + '.ldf'

BACKUP DATABASE @sourceDb TO DISK = @backupPath

RESTORE DATABASE @destDb FROM DISK = @backupPath
WITH REPLACE,
   MOVE @sourceDb     TO @destMdf,
   MOVE @sourceDb_log TO @destLdf

2
私の環境では、ファイル名がデータベース名と一致しなかったため(別の復元からSET @sourceDb_log = (SELECT files.name FROM sys.databases dbs INNER JOIN sys.master_files files ON dbs.database_id=files.database_id WHERE dbs.name=@sourceDb AND files.type=1)取得されたためfiles.type=0)、同様のクエリを使用して@sourceDb_dataの個別の変数が必要になります(で置換)。HTH!
Dan Caseley

11

ここで述べた解決策はどれもうまくいきませんでした-私はSQL Server Management Studio 2014を使用しています。

代わりに、「オプション」画面の「復元前にログ末尾のバックアップをとる」チェックボックスをオフにする必要がありました。私のバージョンでは、デフォルトでオンになっているため、復元操作を完了できません。チェックを外した後、復元操作は問題なく続行されました。

ここに画像の説明を入力してください


2
この答えは私の一日を救った。
Dilhan Jayathilake 2017

2
私の日も救った:)
ashilon

1
SQL Server 2017でこれを行わない場合、元のデータベースは「復元中...」のままでした。あなたの解決策がうまくいった-ありがとう!
mu88

9

MS SQL Server 2012を使用して、3つの基本的な手順を実行する必要があります。

  1. まず、.sqlソースDBの構造のみを含むファイルを生成します

    • ソースDBを右クリックし、[ タスク][ スクリプトの生成 ]の順にクリックします
    • ウィザードに従い、.sqlファイルをローカルに保存します
  2. 次に、ソースDBを.sqlファイル内の宛先DBに置き換えます

    • 宛先ファイルを右クリックして、[ 新しいクエリ ]を選択するCtrl-Hか、または([ 編集] -[ 検索と置換] -[ クイック置換]
  3. 最後に、データを入力します

    • 宛先DBを右クリックして、[ タスク]と[ データのインポート]を選択します
    • データソースのドロップダウンセットを「SQLサーバーの.netフレームワークデータプロバイダー」に設定し、DATA exの下の接続文字列テキストフィールドを設定します。Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • 目的地でも同じことをする
    • 転送するテーブルをチェックするか、「source:...」以外のチェックボックスをオンにして、すべてをチェックします

完了です。


ちなみに、インポート先のテーブルにデータがなければ、インポートデータでテーブルを作成できると思います。簡単な解決策+1
Khurram Ishaque

6

SQL Server 2008 R2では、データベースをファイルとしてフォルダーにバックアップします。次に、「データベース」フォルダに表示される復元オプションを選択します。ウィザードで、ターゲットデータベースに使用する新しい名前を入力します。そして、frromファイルの復元を選択し、先ほど作成したファイルを使用します。私はそれを実行し、それは非常に高速でした(私のDBは小さいですが、それでも)Pablo。


4

データベースがそれほど大きくない場合は、エクスプローラーのデータベースアイテム自体のコンテキストメニューにあるSQL Server Management Studio Expressの[スクリプトデータベース]コマンドを確認できます。

スクリプトを作成する対象をすべて選択できます。もちろん、オブジェクトとデータが必要です。次に、スクリプト全体を1つのファイルに保存します。次に、そのファイルを使用してデータベースを再作成できます。USE上部のコマンドが適切なデータベースに設定されていることを確認してください。


1
おかげで、データベースはかなり大きい(ギグあたり)ので、悪いことが起こると思います:-)
Sergio

2
正しい; それが最善の方法ではありません。代わりに、スクリプトデータベースを使用して新しいデータベースに構造を作成し、インポート/エクスポートでデータを移動することができます。最初にスクリプトデータベースを実行してください。テーブルが存在しない場合、インポート/エクスポートはテーブルを作成します。その方法が気に入らない場合があります。
Andrew Barber

4

このコメントに基づくソリューション:https : //stackoverflow.com/a/22409447/2399045。設定を設定するだけです:DB名、一時フォルダー、dbファイルフォルダー。実行後、「sourceDBName_yyyy-mm-dd」形式の名前を持つDBのコピーが作成されます。

-- Settings --
-- New DB name will have name = sourceDB_yyyy-mm-dd
declare @sourceDbName nvarchar(50) = 'MyDbName';
declare @tmpFolder nvarchar(50) = 'C:\Temp\'
declare @sqlServerDbFolder nvarchar(100) = 'C:\Databases\'

--  Execution --
declare @sourceDbFile nvarchar(50);
declare @sourceDbFileLog nvarchar(50);
declare @destinationDbName nvarchar(50) = @sourceDbName + '_' + (select convert(varchar(10),getdate(), 121))
declare @backupPath nvarchar(400) = @tmpFolder + @destinationDbName + '.bak'
declare @destMdf nvarchar(100) = @sqlServerDbFolder + @destinationDbName + '.mdf'
declare @destLdf nvarchar(100) = @sqlServerDbFolder + @destinationDbName + '_log' + '.ldf'

SET @sourceDbFile = (SELECT top 1 files.name 
                    FROM sys.databases dbs 
                    INNER JOIN sys.master_files files 
                        ON dbs.database_id = files.database_id 
                    WHERE dbs.name = @sourceDbName
                        AND files.[type] = 0)

SET @sourceDbFileLog = (SELECT top 1 files.name 
                    FROM sys.databases dbs 
                    INNER JOIN sys.master_files files 
                        ON dbs.database_id = files.database_id 
                    WHERE dbs.name = @sourceDbName
                        AND files.[type] = 1)

BACKUP DATABASE @sourceDbName TO DISK = @backupPath

RESTORE DATABASE @destinationDbName FROM DISK = @backupPath
WITH REPLACE,
   MOVE @sourceDbFile     TO @destMdf,
   MOVE @sourceDbFileLog  TO @destLdf

3

Joeの回答に基づいたスクリプト(分離、ファイルのコピー、両方の添付)。

  1. 管理者アカウントとしてManagment Studioを実行します。

必須ではありませんが、実行時にアクセス拒否エラーが発生する可能性があります。

  1. xp_cmdshelを実行するためのSQLサーバーの構成
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
  1. スクリプトを実行しますが、前に@dbName@copyDBName変数にデータベース名を入力します。
USE master;
GO 

DECLARE @dbName NVARCHAR(255) = 'Products'
DECLARE @copyDBName NVARCHAR(255) = 'Products_branch'

-- get DB files
CREATE TABLE ##DBFileNames([FileName] NVARCHAR(255))
EXEC('
    INSERT INTO ##DBFileNames([FileName])
    SELECT [filename] FROM ' + @dbName + '.sys.sysfiles')

-- drop connections
EXEC('ALTER DATABASE ' + @dbName + ' SET OFFLINE WITH ROLLBACK IMMEDIATE')

EXEC('ALTER DATABASE ' + @dbName + ' SET SINGLE_USER')

-- detach
EXEC('EXEC sp_detach_db @dbname = ''' + @dbName + '''')

-- copy files
DECLARE @filename NVARCHAR(255), @path NVARCHAR(255), @ext NVARCHAR(255), @copyFileName NVARCHAR(255), @command NVARCHAR(MAX) = ''
DECLARE 
    @oldAttachCommand NVARCHAR(MAX) = 
        'CREATE DATABASE ' + @dbName + ' ON ', 
    @newAttachCommand NVARCHAR(MAX) = 
        'CREATE DATABASE ' + @copyDBName + ' ON '

DECLARE curs CURSOR FOR 
SELECT [filename] FROM ##DBFileNames
OPEN curs  
FETCH NEXT FROM curs INTO @filename
WHILE @@FETCH_STATUS = 0  
BEGIN
    SET @path = REVERSE(RIGHT(REVERSE(@filename),(LEN(@filename)-CHARINDEX('\', REVERSE(@filename),1))+1))
    SET @ext = RIGHT(@filename,4)
    SET @copyFileName = @path + @copyDBName + @ext

    SET @command = 'EXEC master..xp_cmdshell ''COPY "' + @filename + '" "' + @copyFileName + '"'''
    PRINT @command
    EXEC(@command);

    SET @oldAttachCommand = @oldAttachCommand + '(FILENAME = "' + @filename + '"),'
    SET @newAttachCommand = @newAttachCommand + '(FILENAME = "' + @copyFileName + '"),'

    FETCH NEXT FROM curs INTO @filename
END
CLOSE curs 
DEALLOCATE curs

-- attach
SET @oldAttachCommand = LEFT(@oldAttachCommand, LEN(@oldAttachCommand) - 1) + ' FOR ATTACH'
SET @newAttachCommand = LEFT(@newAttachCommand, LEN(@newAttachCommand) - 1) + ' FOR ATTACH'

-- attach old db
PRINT @oldAttachCommand
EXEC(@oldAttachCommand)

-- attach copy db
PRINT @newAttachCommand
EXEC(@newAttachCommand)

DROP TABLE ##DBFileNames

3

新しいデータベースを作成してから、タスクに移動してデータをインポートし、複製するデータベースから作成したデータベースにすべてのデータをインポートすることができます。


2

インポート/エクスポートウィザードを使用してトリックを実行する別の方法、まず空のデータベースを作成し、次にソースデータベースを使用するサーバーであるソースを選択し、次に宛先で宛先データベースと同じサーバーを選択します(空のデータベースを使用)あなたが最初に作成しました)、それからフィニッシュを押します

すべてのテーブルを作成し、すべてのデータを新しいデータベースに転送します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.