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

Ser*_*gio 254 sql-server sql-server-2008-express

我有一个MS SQL Server 2008 Express系统,它包含一个我想要"复制和重命名"的数据库(用于测试目的),但我不知道实现这一目的的简单方法.

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

有问题的数据库是围绕着一个演出.我试图恢复我要复制到新数据库的数据库的备份,但没有运气.

Tom*_*bes 348

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

    版本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. 将原始数据库备份到文件(db - >任务 - >备份).
  4. 使用新名称(克隆)创建空数据库.
  5. 单击以克隆数据库并打开还原对话框(参见图像) 恢复对话框
  6. 选择设备并添加步骤1中的bakcup文件. 添加备份文件
  7. 将目标更改为测试数据库 改变目的地
  8. 更改数据库文件的位置,它必须与原始文件不同.您可以直接在文本框中输入,只需添加后缀即可.(注意:订单很重要.选择复选框,然后更改文件名.) 换地点
  9. 检查WITH REPLACE和WITH KEEP_REPLICATION 与替换

  • 1.不要创建空数据库并将.bak文件还原到它.2.通过右键单击SQL Server Management Studio的"数据库"分支,可以访问"还原数据库"选项,并提供数据库名称,同时提供要还原的源.参考:http://stackoverflow.com/questions/10204480/the-backup-set-holds-a-backup-of-a-database-other-than-the-existing (74认同)
  • 不起作用 - "由于数据库正在使用,无法获得独占访问权限". (4认同)
  • 我的原始数据库卡在“正在恢复”上 (4认同)
  • 我还必须取消选中"在恢复前进行尾部日志备份".默认情况下检查了这一点,导致"因为数据库正在使用中无法获取独占访问"错误. (3认同)

DFo*_*k42 107

右键单击要克隆的数据库,单击Tasks,单击Copy Database....按照向导,你就完成了.

  • 以下是它在Express中的工作原理:http://stackoverflow.com/questions/4269450/copy-a-database-within-sql-server-express (7认同)
  • 如果您的数据库中已加密对象,则此方法不起作用。 (2认同)
  • 不可能!任务 - >没有要复制数据库的菜单项 (2认同)

Joe*_*lli 91

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

在SQL中:

USE master;
GO 
EXEC sp_detach_db
    @dbname = N'OriginalDB';
GO
Run Code Online (Sandbox Code Playgroud)

在命令提示符下(为了这个例子,我简化了文件路径):

copy c:\OriginalDB.mdf c:\NewDB.mdf
copy c:\OriginalDB.ldf c:\NewDB.ldf
Run Code Online (Sandbox Code Playgroud)

再次在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
Run Code Online (Sandbox Code Playgroud)

  • `select*from OriginalDB.sys.sysfiles`以查找DB文件的位置. (9认同)
  • 如果您可以停止sql服务,复制mdf和ldf文件,为新数据库重命名它们,重新启动sql服务并仅在master:USE master下运行最后一个create database命令,则不必分离原始数据库。 ; 转到创建数据库NewDB ON(FILENAME ='C:\ NewDB.mdf'),(FILENAME ='C:\ NewDB.ldf')进行连接; 走 (2认同)

Ser*_*gio 29

事实证明,我曾试图从备份中错误地恢复.

最初我创建了一个新数据库,然后尝试在此处恢复备份.我应该做的以及最终的工作是打开恢复对话框并在目标字段中键入新数据库的名称.

因此,简而言之,从备份中恢复就可以了.

感谢所有的反馈和建议

  • Neils,默认情况下,文件在您拍摄的快照中是相同的.您可以更改它们的名称以为新命名的数据库创建新文件. (2认同)

Abd*_*RIB 20

来自 SSMS :

1 - 将原始数据库备份到 .BAK 文件(your_source_db -> 任务 -> 备份)。

2 - 右键单击​​“数据库”和“恢复数据库”

3 - 设备 > ...(按钮)> 添加 > 选择 your_source_db.bak

4 - 在“常规”选项卡的“目标”部分中,将“数据库”中的 your_source_db 重命名为 new_name_db

5 - 在“文件”选项卡中,勾选“将所有文件重新定位到文件夹”,

  • 在“恢复为”列中重命​​名两个线,以与 new_name_db (.mdf、_log.ldf) 保持一致

6 - 在“选项”选项卡的“恢复选项”部分中,勾选两个第一个选项(“覆盖...”、“保留...”)和“恢复状态”:“恢复恢复”

  • 还要确保在“尾日志备份”部分中的选项未选中,以避免将源数据库保持在“恢复状态”!

在此输入图像描述


blu*_*ish 16

这是我使用的脚本.有点棘手,但它的工作原理.在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
Run Code Online (Sandbox Code Playgroud)

  • 在我的环境中,文件名与db名称(来自_another_ restore)不匹配所以我需要`SET @sourceDb_log =(SELECT files.name FROM sys.databases dbs INNER JOIN sys.master_files文件ON dbs.database_id = files .database_id WHERE dbs.name=@sourceDb AND files.type = 1)`和@sourceDb_data的单独变量,具有类似的查询(替换为`files.type = 0`).HTH! (2认同)

小智 9

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

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

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

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

    • 右键单击目标数据库,然后选择" 任务"和" 导入数据"
    • 数据源下拉设置为" SQL Server的.net框架数据提供程序 "+在DATA ex下设置连接字符串文本字段:Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • 对目的地做同样的事情
    • 检查要传输的表或"source:..."旁边的复选框以检查所有这些

你完成了.


Ema*_*chi 8

这里提到的解决方案都不适用于我 - 我正在使用SQL Server Management Studio 2014.

相反,我必须取消选中"选项"屏幕中的"在恢复前进行尾部日志备份"复选框:在我的版本中,默认情况下会检查它并阻止恢复操作完成.取消选中后,还原操作没有问题.

在此输入图像描述

  • 这个答案拯救了我的一天。 (2认同)
  • 也拯救了我的一天:) (2认同)

And*_*ber 6

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

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

  • 对; 那不是最好的方法。相反,您可以使用脚本数据库在新数据库中创建结构,然后导入/导出以移动数据。一定要先做脚本数据库;如果表不存在,导入/导出将创建它们,您可能不喜欢它的工作方式。 (2认同)

pab*_*ndo 6

在SQL Server 2008 R2中,将数据库作为文件备份到文件夹中.然后选择"数据库"文件夹中显示的还原选项.在向导中,在目标数据库中输入所需的新名称.并选择restore frrom文件并使用刚刚创建的文件.我做了它,而且速度非常快(我的DB很小,但仍然是)Pablo.


Moh*_*eia 5

另一种方法是使用导入/导出向导,首先创建一个空数据库,然后选择源,即具有源数据库的服务器,然后在目标中选择与目标数据库相同的服务器(使用空数据库你首先创建的),然后点击完成

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


Evg*_*nov 5

基于 Joe 答案的脚本(分离、复制文件、附加两者)。

  1. 以管理员帐户运行 Management 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
Run Code Online (Sandbox Code Playgroud)
  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
Run Code Online (Sandbox Code Playgroud)


Pav*_*nko 5

解决方案,基于此评论: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
Run Code Online (Sandbox Code Playgroud)