繁体   English   中英

还原数据库时,SQL Server指定mdf文件名

[英]SQL Server specify mdf file name when restoring database

我正在尝试使用以下命令从BAK文件还原数据库,以对db的干净副本执行单元测试:

RESTORE DATABASE MyDbUnitTest FROM DISK = 'c:\db\MyDb.bak';

它尝试还原数据库,但会抛出一个错误,表明MyDb.mdf正在使用-正确-是-用于在我的机器上进行开发的原始数据库。

有没有办法指定MDF文件的名称,它将在开发数据库旁边导入该文件?

可能是因为您在还原中完成了尾日志备份。

更改为此:

RESTORE DATABASE [MyDB2] FROM  DISK = N'C:\db\MyDb.BAK' WITH  FILE = 1,  MOVE N'MyDb' TO N'C:\db\MyDb2.mdf',  MOVE N'Mydb_log' TO N'D:\SQLLogs\MyDb2_log.ldf',  NORECOVERY,  NOUNLOAD,  STATS = 5
RESTORE LOG [MyDB2] FROM  [MyDB_Log] WITH  FILE = 3,  NOUNLOAD,  STATS = 5

请注意,所列数字与我的环境示例有关,因此您需要确保对其进行修改以适合您的需求。

无需脚本即可执行此操作的另一种方法是,只需在Management Studio中右键单击数据库名称,然后选择Tasks-> Restore-> Database 然后在“选项”选项卡上,删除“还原前进行尾日志备份”选项。

最简单的方法是在Management Studio中进行操作,并让Management Studio为您生成脚本,如下所示:

在此处输入图片说明

您需要知道此备份文件中的内容。 因此,您需要通过执行两种类型的还原来检查此文件的内容,然后才能实际从该备份中重新分配数据库。

强力恢复

RESTORE HEADERONLY 
FROM DISK = N'c:\db\MyDb.bak'
GO

这将提供此备份文件中的备份列表。 您应该使用备份类型= 1查找数据库MyDb 。获取该文件的位置,然后执行以下操作

FILELISTONLY还原

RESTORE FILELISTONLY 
FROM DISK = N'c:\db\MyDb.bak'
 WITH FILE = 1   --<-- this will be the position of the backup from headerOnly restore
GO

这将返回该备份中该数据库的所有文件。

主文件,任何.ndf和日志文件名。

使用这些文件名并编写恢复命令,如下所示。...

数据库还原

RESTORE [DatabaseName]
 FROM DISK = N'c:\db\MyDb.bak'
 WITH RECOVERY , 
 MOVE N'PrimaryFile' TO N'C:\Folder\MyDB.mdf',    --<-- should be a valid path
 MOVE N'LogFile'     TO N'C:\Folder\MyDB_Logs.ldf' --<-- should be a valid path
 -- anymore files ......
 GO

这是我使用的(在批处理文件中)从备份还原特定的现有数据库的方法。 “替换”使它覆盖现有文件,因此无需指定它们。

RESTORE DATABASE [%DatabaseName%] 
FROM DISK = N'%DestinationFolder%\%backupFile%' 
WITH FILE = 1, NOUNLOAD, REPLACE, STATS = 10

这可能无法完全满足您的需求, 但我认为这可能对其他搜索此问题的人有用。

(显然,您可以设置环境变量DatatbaseName,DestinationFold和backupFile…或将这些占位符替换为硬编码的名称和路径,并根据您的特定目的进行替换……只是想清楚一点)

(并且,如果您只编写脚本来创建要还原的数据库,那么使用REPLACE还原到数据库也应该可以正常工作,这样既可以保留原始数据库,也可以保留还原的副本,两者都可以正常工作)

为了更加相关,这是我拼凑而成的脚本,该脚本会将所有备份还原到任何数据库(无论是否存在),并执行适当的MOVE使其始终有效:

USE master;

DECLARE @dbNameDestination sysname
DECLARE @backupFileName nvarchar(max)
DECLARE @sql nvarchar(max)
DECLARE @restoreSql nvarchar(max)
DECLARE @params nvarchar(max)
DECLARE @mdfFile nvarchar(400)
DECLARE @ldfFile nvarchar(400)

SET @dbNameDestination = 'TestUserTest'   -- The name of the database you want to restore to
SET @backupFileName = 'D:\DB\TestDB.bak'  -- The full path to the *.bak file you wish to restore

IF NOT EXISTS (SELECT 1 FROM sys.databases WHERE [name] = @dbNameDestination)
BEGIN
    -- Create Destination DB
    SET @sql = 'CREATE DATABASE [' + @dbNameDestination + ']'
    EXEC (@sql)
END
ELSE
BEGIN
    -- Force other users off:
    SET @sql = 'ALTER DATABASE [' + @dbNameDestination + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE'
    EXEC (@sql);
    SET @sql = 'ALTER DATABASE [' + @dbNameDestination + '] SET MULTI_USER'
    EXEC (@sql);
END

-- Restore database WITH REPLACE
SET @params = '@mdfOUT nvarchar(400) OUTPUT, @ldfOut nvarchar(400) OUTPUT'
SET @sql = N'USE ' + @dbNameDestination + N';
SELECT @mdfOUT = physical_name FROM sys.database_files WHERE type = 0
SELECT @ldfOUT = physical_name FROM sys.database_files WHERE type = 1'
EXEC sp_ExecuteSql @sql, @params, @mdfOUT=@mdfFile OUTPUT, @ldfOUT=@ldfFile OUTPUT

DECLARE @FileList TABLE ( 
    LogicalName nvarchar(128) NOT NULL, 
    PhysicalName nvarchar(260) NOT NULL, 
    Type char(1) NOT NULL, 
    FileGroupName nvarchar(120) NULL, 
    Size numeric(20, 0) NOT NULL, 
    MaxSize numeric(20, 0) NOT NULL, 
    FileID bigint NULL, 
    CreateLSN numeric(25,0) NULL, 
    DropLSN numeric(25,0) NULL, 
    UniqueID uniqueidentifier NULL, 
    ReadOnlyLSN numeric(25,0) NULL , 
    ReadWriteLSN numeric(25,0) NULL, 
    BackupSizeInBytes bigint NULL, 
    SourceBlockSize int NULL, 
    FileGroupID int NULL, 
    LogGroupGUID uniqueidentifier NULL, 
    DifferentialBaseLSN numeric(25,0)NULL, 
    DifferentialBaseGUID uniqueidentifier NULL, 
    IsReadOnly bit NULL, 
    IsPresent bit NULL, 
    TDEThumbprint varbinary(32) NULL 
 ); 

SET @restoreSql =  N'RESTORE FILELISTONLY FROM DISK=N''' + @backupFileName + '''' 
INSERT INTO @FileList EXEC(@restoreSql); 

DECLARE @logical_data nvarchar(max)
DECLARE @logical_log nvarchar(max); 
SET @logical_data = (SELECT [LogicalName] FROM @FileList WHERE [Type] = 'D' AND [FileID] = 1) 
SET @logical_log = (SELECT [LogicalName] FROM @FileList WHERE [Type] = 'L' AND [FileID] = 2) 

-- Now issue RESTORE command
RESTORE DATABASE @dbNameDestination 
FROM DISK = @backupFileName 
WITH REPLACE,
MOVE @logical_data TO @mdfFile, 
MOVE @logical_log TO @ldfFile 
GO

只需编辑脚本顶部的两个常量,以指定要还原到的数据库名称(是否已经存在),以及要还原的备份文件的完整路径。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM