我有一个MS SQL Server 2008 Express系统,其中包含一个数据库,我想“复制和重命名”(用于测试目的),但我不知道一个简单的方法来实现这一点。

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

我们讨论的数据库大约是1g。 我试图恢复我想复制到一个新数据库的数据库的备份,但没有运气。


当前回答

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

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

其他回答

您可以尝试分离数据库,在命令提示符下将文件复制到新的名称,然后附加两个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

脚本基于乔回答(分离,复制文件,附加两者)。

以Administrator帐户运行management Studio。

这是不必要的,但可能在执行时访问被拒绝错误。

为执行xp_cmdshel配置sql server

EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO

运行脚本,但在@dbName和@copyDBName变量之前输入你的db名称。

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

解决方案,基于这条评论: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

原来我试图从备份中错误地进行恢复。

最初我创建了一个新数据库,然后尝试在这里恢复备份。 我本应该做的,也是最终有效的,是打开恢复对话框,并在目标字段中输入新数据库的名称。

因此,简而言之,从备份中恢复是有效的。

谢谢大家的反馈和建议

这里提到的解决方案都不适合我-我使用的是SQL Server Management Studio 2014。

相反,我不得不取消“选项”屏幕中的“在恢复前进行尾日志备份”复选框:在我的版本中,默认情况下它是选中的,并阻止恢复操作完成。 取消检查后,还原操作继续进行,没有出现问题。