如何在SQL Server 2008 Express的同一服务器上克隆SQL Server数据库?


271

我有一个MS SQL Server 2008 Express系统,该系统包含一个我想“复制并重命名”(出于测试目的)的数据库,但是我不知道实现此目的的简单方法。

我注意到在R2版本的SQL Server中有一个复制数据库向导,但可惜我无法升级。

该数据库大约是演出。我试图将要复制的数据库备份还原到新数据库中,但是没有运气。


2
还原备份应该可以。您能否提供更多有关如何失败的详细信息?
Ed Harper

7
我意识到从备份还原时犯了一个错误。我首先创建了一个新的空数据库,然后尝试从那里还原备份。我应该做的是调出还原对话框,并在其中键入新数据库的名称,而不是先创建它。这样做很好地克隆了数据库!
塞尔吉奥(Sergio)2010年

Answers:


372
  1. 安装Microsoft SQL Management Studio,您可以从Microsoft网站免费下载:

    2008版

    Microsoft SQL Management Studio 2008是带有高级服务SQL Server 2008 Express的一部分

    2012版

    点击下载按钮并检查ENU\x64\SQLManagementStudio_x64_ENU.exe

    2014版

    单击下载按钮并检查MgmtStudio64BIT\SQLManagementStudio_x64_ENU.exe

  2. 打开Microsoft SQL Management Studio

  3. 将原始数据库备份到.BAK文件(db-> Task-> Backup)。
  4. 使用新名称(克隆)创建空数据库。请注意以下注释,因为这是可选的。
  5. 单击以克隆数据库并打开还原对话框(参见图片) 恢复对话框
  6. 选择设备,然后从步骤3添加备份文件。 添加备份文件
  7. 更改目标以测试数据库 改变目的地
  8. 更改数据库文件的位置,它必须与原始文件不同。您可以直接在文本框中输入内容,只需添加后缀即可。(注意:顺序很重要。选中复选框,然后更改文件名。) 换地点
  9. 检查WITH REPLACE和WITH KEEP_REPLICATION 与替换

84
1.不要创建一个空数据库并将.bak文件还原到该数据库上。2.使用“还原数据库”选项,方法是在SQL Server Management Studio的“数据库”分支上单击鼠标右键,并提供数据库名称,同时提供要还原的源。REF:stackoverflow.com/questions/10204480/...
taynguyen

1
微软SQL Management Studio中-它是免费的
托马斯Kubes

4
不起作用-“由于正在使用数据库,因此无法获得独占访问”。
Emanuele Ciriachi

5
我还必须取消选中“还原前先进行尾日志备份”。默认情况下,这已检查,并导致“由于数据库正在使用中而无法获得独占访问”错误。
萝卜

2
我原来的数据库卡在了“恢复”上
Divi perdomo

113

右键单击要克隆的数据库,单击Tasks,然后单击Copy Database...。按照向导完成操作。


我认为这只能在SQL Server的R2版本中使用:-(
Sergio 2010年

7
这里是它如何工作的快递:stackoverflow.com/questions/4269450/...
钍00毫安小号

2
如果您的数据库中已加密对象,则此方法不起作用。
cjbarth

1
我要说的是,重点实际上是在哪里做?您所描述的内容非常直观。之前,我曾在某些工具(0xDBE,Visual Studio SQL Server对象资源管理器)中尝试过这种方法,但是在那里没有找到这种功能。
David FerenczyRogožan2015年

3
不可能!任务->没有要复制数据库的菜单项
–racerle

95

您可以尝试分离数据库,在命令提示符下将文件复制到新名称,然后附加两个数据库。

在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.sysfiles查找数据库文件的位置。
JohnLBevan 2014年

是的,我也最喜欢此解决方案,因为它不需要任何特殊工具。但是,我无法创建一个NewDB,它Permission denied.mdf文件中说。我现在不需要它,我只需要备份原始数据库,因此以后可以覆盖原始数据库,我很好奇为什么会出现这样的错误。
David FerenczyRogožan2015年

2
如果您可以停止sql服务,复制mdf和ldf文件,为新数据库重命名它们,再次启动sql服务并仅在master:USE master下运行最后一个create database命令,则不必分离原始数据库。 ; 创建数据库NewDB ON(FILENAME ='C:\ NewDB.mdf'),(FILENAME ='C:\ NewDB.ldf')进行连接; GO
danpop

1
+1是最快的方式。除了@JohnLBevan出色的评论外,您还可以使用exec sp_helpdb @dbname='TEMPDB';
jean

30

事实证明,我试图从备份中错误地还原。

最初,我创建了一个新数据库,然后尝试在此处还原备份。我应该做的,最后起作用的是,弹出还原对话框,并在目标字段中键入新数据库的名称。

因此,简而言之,从备份还原就可以了。

谢谢大家的反馈和建议


当我这样做时,对话框会告诉我文件与我最初备份的数据库位于同一位置。因此,我没有胆量恢复,因为担心文件将被覆盖。
Niels Brinch 2012年

2
尼尔,默认情况下,快照中的文件是相同的。您可以更改它们的名称以为新命名的数据库创建新文件。
柯林·达布里兹

PS:此方法需要SQL Agent服务,请确保它在启动数据库复制操作之前正在运行。
dvdmn

您现在已经为我提供了三遍此答案。我一直忘记输入而不是创建它。+啤酒
Piotr Kula 2014年

并在“文件”窗口中重命名.mdf和.log文件对我有用。
Wollan '16

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)一个@sourceDb_data的单独变量,并带有类似的查询(替换为files.type=0)。HTH!
Dan Caseley

11

此处提到的解决方案都不适用于我-我正在使用SQL Server Management Studio 2014。

取而代之的是,我必须取消选中“选项”屏幕中的“还原前先进行尾日志备份”复选框:在我的版本中,默认情况下已选中该复选框并阻止还原操作完成。取消选中后,还原操作将继续进行,不会出现问题。

在此处输入图片说明


2
这个答案救了我一天。
Dilhan Jayathilake

2
也保存了我的一天:)
ashilon '12

1
如果不使用SQL Server 2017执行此操作,则原始数据库将保留在“正在还原...”中。您的解决方案成功了-谢谢!
mu88 '19

9

使用MS SQL Server 2012,您需要执行3个基本步骤:

  1. 首先,生成.sql仅包含源数据库结构的文件

    • 右键单击源数据库,然后 任务,然后生成脚本
    • 按照向导并保存 .sql本地文件
  2. 第二,将源数据库替换为.sql文件中的目标数据库

    • 在目标文件点击右键,选择新建查询Ctrl-H或(编辑 - 查找和替换 - 快速更换
  3. 最后,填充数据

    • 右键单击目标数据库,然后选择“ 任务导入数据”
    • 数据源下拉菜单设置为“ 用于SQL Server的.net框架数据提供程序 ”,并在DATA ex下设置连接字符串文本字段:Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • 与目的地相同
    • 选中您要转移的表格,或选中“来源:...”旁边的复选框以选中所有表格

大功告成


顺便说一句,我想如果目标表中不存在导入数据,则可以创建表。.简单解决方案+1
Khurram Ishaque 2015年

6

在SQL Server 2008 R2中,将数据库作为文件备份到文件夹中。然后选择出现在“数据库”文件夹中的还原选项。在向导中,输入要在目标数据库中使用的新名称。然后选择“还原frrom文件”并使用您刚创建的文件。我jsut做到了,而且速度非常快(我的DB虽然很小,但仍然)Pablo。


4

如果数据库不是很大,则可以查看SQL Server Management Studio Express中的“脚本数据库”命令,该命令位于资源管理器中数据库项本身旁边的上下文菜单中。

您可以选择全部编写脚本;当然,您需要对象和数据。然后,您将整个脚本保存到单个文件中。然后,您可以使用该文件重新创建数据库。只需确保将USE顶部的命令设置为正确的数据库即可。


1
谢谢,但是数据库很大(大约演出),所以我认为可能会发生坏事:-)
Sergio 2010年

2
对; 那不是最好的方法。相反,您可以使用脚本数据库在新数据库中创建结构,然后使用导入/导出来移动数据。只要确保您先执行脚本数据库即可;如果表不存在,导入/导出将创建表,并且您可能不喜欢它的操作方式。
Andrew Barber 2010年

4

基于此注释的解决方案:https : //stackoverflow.com/a/22409447/2399045。只需设置设置:数据库名称,临时文件夹,数据库文件文件夹。运行后,您将获得名称为“ sourceDBName_yyyy-mm-dd”格式的数据库副本。

-- 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. 配置SQL Server以执行xp_cmdshel
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

另一种通过使用导入/导出向导来完成此操作的方法,首先创建一个空数据库,然后选择与源数据库一起作为您的服务器的源,然后在目标中选择与目标数据库相同的服务器(使用空数据库)您首先创建的),然后点击完成

它将创建所有表并将所有数据传输到新数据库中,

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.